mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-27 18:48:31 +00:00
feat: multi-currency payroll
This commit is contained in:
@@ -3,11 +3,13 @@
|
||||
|
||||
cur_frm.set_query("default_account", "accounts", function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
var company_currency = erpnext.get_currency(d.company);
|
||||
return{
|
||||
filters: [
|
||||
['Account', 'account_type', 'in', 'Bank, Cash, Receivable'],
|
||||
['Account', 'is_group', '=', 0],
|
||||
['Account', 'company', '=', d.company]
|
||||
['Account', 'company', '=', d.company],
|
||||
['Account', 'account_currency', '=', company_currency]
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
@@ -453,7 +453,7 @@ class PaymentEntry(AccountsController):
|
||||
frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction"))
|
||||
|
||||
def set_remarks(self):
|
||||
if self.custom_remarks: return
|
||||
# if self.custom_remarks: return
|
||||
|
||||
if self.payment_type=="Internal Transfer":
|
||||
remarks = [_("Amount {0} {1} transferred from {2} to {3}")
|
||||
@@ -909,17 +909,19 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
||||
exchange_rate = 1
|
||||
outstanding_amount = get_outstanding_on_journal_entry(reference_name)
|
||||
elif reference_doctype != "Journal Entry":
|
||||
if party_account_currency == company_currency:
|
||||
if ref_doc.doctype == "Expense Claim":
|
||||
if ref_doc.doctype == "Expense Claim":
|
||||
total_amount = flt(ref_doc.total_sanctioned_amount) + flt(ref_doc.total_taxes_and_charges)
|
||||
elif ref_doc.doctype == "Employee Advance":
|
||||
elif ref_doc.doctype == "Employee Advance":
|
||||
total_amount = ref_doc.advance_amount
|
||||
else:
|
||||
exchange_rate = ref_doc.get("exchange_rate")
|
||||
if not total_amount:
|
||||
if party_account_currency == company_currency:
|
||||
total_amount = ref_doc.base_grand_total
|
||||
exchange_rate = 1
|
||||
else:
|
||||
total_amount = ref_doc.grand_total
|
||||
exchange_rate = 1
|
||||
else:
|
||||
total_amount = ref_doc.grand_total
|
||||
|
||||
if not exchange_rate:
|
||||
# Get the exchange rate from the original ref doc
|
||||
# or get it based on the posting date of the ref doc
|
||||
exchange_rate = ref_doc.get("conversion_rate") or \
|
||||
|
||||
@@ -1,92 +1,47 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2016-07-27 17:24:24.956896",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"actions": [],
|
||||
"creation": "2016-07-27 17:24:24.956896",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"company",
|
||||
"default_account",
|
||||
"account_currency"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Company",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Company",
|
||||
"options": "Company"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Default Bank / Cash account will be automatically updated in Salary Journal Entry when this mode is selected.",
|
||||
"fieldname": "default_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Default Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
"description": "Default Bank / Cash account will be automatically updated in Salary Journal Entry when this mode is selected.",
|
||||
"fieldname": "default_account",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Default Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"fetch_from": "default_account.account_currency",
|
||||
"fieldname": "account_currency",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Account Currency",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-09-02 07:49:06.567389",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Salary Component Account",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_seen": 0
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-09-30 13:50:06.809353",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Salary Component Account",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
@@ -15,11 +15,15 @@ frappe.ui.form.on('Employee Advance', {
|
||||
});
|
||||
|
||||
frm.set_query("advance_account", function() {
|
||||
if (!frm.doc.employee) {
|
||||
frappe.msgprint(__("Please select employee first"))
|
||||
}
|
||||
return {
|
||||
filters: {
|
||||
"root_type": "Asset",
|
||||
"is_group": 0,
|
||||
"company": frm.doc.company
|
||||
"company": frm.doc.company,
|
||||
"account_currency": frm.doc.currency,
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -48,7 +52,7 @@ frappe.ui.form.on('Employee Advance', {
|
||||
frm.add_custom_button(
|
||||
__("Expense Claim"),
|
||||
function() {
|
||||
frm.events.make_expense_claim(frm);
|
||||
frm.events.make_expense_claim(frm); //Change this
|
||||
},
|
||||
__('Create')
|
||||
);
|
||||
@@ -59,11 +63,11 @@ frappe.ui.form.on('Employee Advance', {
|
||||
|
||||
if (frm.doc.repay_unclaimed_amount_from_salary == 0 && frappe.model.can_create("Journal Entry")){
|
||||
frm.add_custom_button(__("Return"), function() {
|
||||
frm.trigger('make_return_entry');
|
||||
frm.trigger('make_return_entry'); //Change this
|
||||
}, __('Create'));
|
||||
}else if (frm.doc.repay_unclaimed_amount_from_salary == 1 && frappe.model.can_create("Additional Salary")){
|
||||
frm.add_custom_button(__("Deduction from salary"), function() {
|
||||
frm.events.make_deduction_via_additional_salary(frm)
|
||||
frm.events.make_deduction_via_additional_salary(frm) //Change this
|
||||
}, __('Create'));
|
||||
}
|
||||
}
|
||||
@@ -138,7 +142,7 @@ frappe.ui.form.on('Employee Advance', {
|
||||
|
||||
employee: function (frm) {
|
||||
if (frm.doc.employee) {
|
||||
return frappe.call({
|
||||
frappe.call({
|
||||
method: "erpnext.hr.doctype.employee_advance.employee_advance.get_pending_amount",
|
||||
args: {
|
||||
"employee": frm.doc.employee,
|
||||
@@ -148,6 +152,51 @@ frappe.ui.form.on('Employee Advance', {
|
||||
frm.set_value("pending_amount",r.message);
|
||||
}
|
||||
});
|
||||
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_payroll_payable_account_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('currency', r.message);
|
||||
frm.set_df_property('currency', 'hidden', 0);
|
||||
frm.refresh_fields()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
currency: function(frm) {
|
||||
var from_currency = frm.doc.currency;
|
||||
if (!frm.doc.company) {
|
||||
var company_currency = erpnext.get_currency(frappe.defaults.get_default("Company"));
|
||||
}
|
||||
else {
|
||||
var company_currency = erpnext.get_currency(frm.doc.company);
|
||||
}
|
||||
if(from_currency != company_currency) {
|
||||
frappe.call({
|
||||
method: "erpnext.setup.utils.get_exchange_rate",
|
||||
args: {
|
||||
from_currency: from_currency,
|
||||
to_currency: company_currency,
|
||||
},
|
||||
callback: function(r) {
|
||||
frm.set_value("exchange_rate", flt(r.message));
|
||||
frm.set_df_property('exchange_rate', 'hidden', 0);
|
||||
cur_frm.set_df_property("exchange_rate", "description", "1 " + frm.doc.currency
|
||||
+ " = [?] " + company_currency);
|
||||
frm.refresh_fields();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
frm.set_value("exchange_rate", 1.0);
|
||||
frm.set_df_property('exchange_rate', 'hidden', 1);
|
||||
frm.set_df_property("exchange_rate", "description", "" );
|
||||
frm.refresh_fields();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"department",
|
||||
"column_break_4",
|
||||
"posting_date",
|
||||
"currency",
|
||||
"exchange_rate",
|
||||
"repay_unclaimed_amount_from_salary",
|
||||
"section_break_8",
|
||||
"purpose",
|
||||
@@ -91,7 +93,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Advance Amount",
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -99,7 +101,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"label": "Paid Amount",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -107,7 +109,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"label": "Claimed Amount",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -161,7 +163,7 @@
|
||||
"fieldname": "return_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Returned Amount",
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -175,13 +177,33 @@
|
||||
"fieldname": "pending_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Pending Amount",
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "Company:company:default_currency",
|
||||
"depends_on": "eval:(doc.docstatus==1 || doc.employee)",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "currency",
|
||||
"fieldname": "exchange_rate",
|
||||
"fieldtype": "Float",
|
||||
"label": "Exchange Rate",
|
||||
"precision": "9",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-12 12:42:39.833818",
|
||||
"modified": "2020-09-30 19:05:42.364629",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Employee Advance",
|
||||
|
||||
@@ -19,7 +19,7 @@ class EmployeeAdvance(Document):
|
||||
|
||||
def validate(self):
|
||||
self.set_status()
|
||||
self.validate_employee_advance_account()
|
||||
# self.validate_employee_advance_account()
|
||||
|
||||
def on_cancel(self):
|
||||
self.ignore_linked_doctypes = ('GL Entry')
|
||||
@@ -38,12 +38,12 @@ class EmployeeAdvance(Document):
|
||||
elif self.docstatus == 2:
|
||||
self.status = "Cancelled"
|
||||
|
||||
def validate_employee_advance_account(self):
|
||||
company_currency = erpnext.get_company_currency(self.company)
|
||||
if (self.advance_account and
|
||||
company_currency != frappe.db.get_value('Account', self.advance_account, 'account_currency')):
|
||||
frappe.throw(_("Advance account currency should be same as company currency {0}")
|
||||
.format(company_currency))
|
||||
# def validate_employee_advance_account(self):
|
||||
# company_currency = erpnext.get_company_currency(self.company)
|
||||
# if (self.advance_account and
|
||||
# company_currency != frappe.db.get_value('Account', self.advance_account, 'account_currency')):
|
||||
# frappe.throw(_("Advance account currency should be same as company currency {0}")
|
||||
# .format(company_currency))
|
||||
|
||||
def set_total_advance_paid(self):
|
||||
paid_amount = frappe.db.sql("""
|
||||
@@ -107,15 +107,38 @@ def make_bank_entry(dt, dn):
|
||||
doc = frappe.get_doc(dt, dn)
|
||||
payment_account = get_default_bank_cash_account(doc.company, account_type="Cash",
|
||||
mode_of_payment=doc.mode_of_payment)
|
||||
if not payment_account:
|
||||
frappe.throw(_("Please set a Default Cash Account in Company defaults"))
|
||||
multi_currency = 0
|
||||
credit_in_account_currency = flt(doc.advance_amount)
|
||||
company_currency = erpnext.get_company_currency(doc.company)
|
||||
|
||||
if payment_account.account_currency != doc.currency:
|
||||
if return_account.account_currency != company_currency:
|
||||
frappe.throw(_("""Account currency of default Cash or Bank account in Mode of Payment for
|
||||
account type: {0} for company: {1} is different than company currency: {2} and currency: {3} specified
|
||||
in employee advance {4}. Please set default Cash or Bank account in either currency: {5} or {6}""")
|
||||
.format("Cash", doc.company, company_currency, doc.currency, doc.name,
|
||||
company_currency, doc.currency), title=_("Currency Mismatch"))
|
||||
else:
|
||||
multi_currency = 1
|
||||
credit_in_account_currency = flt(doc.advance_amount) * flt(doc.exchange_rate)
|
||||
|
||||
# if doc.currency != payment_account.account_currency:
|
||||
# multi_currency = 1
|
||||
# credit_in_account_currency = flt(doc.advance_amount) * flt(doc.exchange_rate)
|
||||
|
||||
je = frappe.new_doc("Journal Entry")
|
||||
je.posting_date = nowdate()
|
||||
je.voucher_type = 'Bank Entry'
|
||||
je.company = doc.company
|
||||
je.remark = 'Payment against Employee Advance: ' + dn + '\n' + doc.purpose
|
||||
je.multi_currency = multi_currency
|
||||
|
||||
je.append("accounts", {
|
||||
"account": doc.advance_account,
|
||||
"account_currency": doc.currency,
|
||||
"exchange_rate": doc.exchange_rate,
|
||||
"debit_in_account_currency": flt(doc.advance_amount),
|
||||
"reference_type": "Employee Advance",
|
||||
"reference_name": doc.name,
|
||||
@@ -128,7 +151,7 @@ def make_bank_entry(dt, dn):
|
||||
je.append("accounts", {
|
||||
"account": payment_account.account,
|
||||
"cost_center": erpnext.get_default_cost_center(doc.company),
|
||||
"credit_in_account_currency": flt(doc.advance_amount),
|
||||
"credit_in_account_currency": credit_in_account_currency,
|
||||
"account_currency": payment_account.account_currency,
|
||||
"account_type": payment_account.account_type
|
||||
})
|
||||
@@ -141,6 +164,7 @@ def create_return_through_additional_salary(doc):
|
||||
doc = frappe._dict(json.loads(doc))
|
||||
additional_salary = frappe.new_doc('Additional Salary')
|
||||
additional_salary.employee = doc.employee
|
||||
additional_salary.currency = doc.currency
|
||||
additional_salary.amount = doc.paid_amount - doc.claimed_amount
|
||||
additional_salary.company = doc.company
|
||||
additional_salary.ref_doctype = doc.doctype
|
||||
@@ -151,6 +175,24 @@ def create_return_through_additional_salary(doc):
|
||||
@frappe.whitelist()
|
||||
def make_return_entry(employee, company, employee_advance_name, return_amount, advance_account, mode_of_payment=None):
|
||||
return_account = get_default_bank_cash_account(company, account_type='Cash', mode_of_payment = mode_of_payment)
|
||||
if not return_account:
|
||||
frappe.throw(_("Please set a Default Cash Account in Company defaults"))
|
||||
company_currency = erpnext.get_company_currency(company)
|
||||
|
||||
employee_advance_doc = frappe.get_doc("Employee Advance", employee_advance_name)
|
||||
multi_currency = 0
|
||||
exchange_rate = 1
|
||||
|
||||
if return_account.account_currency != employee_advance_doc.currency:
|
||||
if return_account.account_currency != company_currency:
|
||||
frappe.throw(_("""Account currency of default Cash or Bank account in Mode of Payment for
|
||||
account type: {0} for company: {1} is different than company currency: {2} and currency: {3} specified
|
||||
in employee advance {4}. Please set default Cash or Bank account in either currency: {5} or {6}""")
|
||||
.format("Cash", company, company_currency, employee_advance_doc.currency, employee_advance_name,
|
||||
company_currency, employee_advance_doc.currency), title=_("Currency Mismatch"))
|
||||
else:
|
||||
exchange_rate = employee_advance_doc.exchange_rate
|
||||
multi_currency = 1
|
||||
|
||||
mode_of_payment_type = ''
|
||||
if mode_of_payment:
|
||||
@@ -165,10 +207,13 @@ def make_return_entry(employee, company, employee_advance_name, return_amount,
|
||||
je.voucher_type = '{} Entry'.format(mode_of_payment_type) if mode_of_payment_type else 'Cash Entry'
|
||||
je.company = company
|
||||
je.remark = 'Return against Employee Advance: ' + employee_advance_name
|
||||
je.multi_currency = multi_currency
|
||||
|
||||
je.append('accounts', {
|
||||
'account': advance_account,
|
||||
'credit_in_account_currency': return_amount,
|
||||
'account_currency': employee_advance_doc.currency,
|
||||
'exchange_rate': exchange_rate,
|
||||
'reference_type': 'Employee Advance',
|
||||
'reference_name': employee_advance_name,
|
||||
'party_type': 'Employee',
|
||||
@@ -178,7 +223,7 @@ def make_return_entry(employee, company, employee_advance_name, return_amount,
|
||||
|
||||
je.append("accounts", {
|
||||
"account": return_account.account,
|
||||
"debit_in_account_currency": return_amount,
|
||||
"debit_in_account_currency": flt(return_amount) * exchange_rate,
|
||||
"account_currency": return_account.account_currency,
|
||||
"account_type": return_account.account_type
|
||||
})
|
||||
|
||||
@@ -71,9 +71,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"oldfieldname": "tax_amount",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency"
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
@@ -81,9 +79,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Total",
|
||||
"oldfieldname": "total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -106,7 +102,7 @@
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-05-11 19:01:26.611758",
|
||||
"modified": "2020-09-23 20:27:36.027728",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Expense Taxes and Charges",
|
||||
|
||||
@@ -37,6 +37,19 @@ frappe.ui.form.on('Leave Encashment', {
|
||||
doc: frm.doc,
|
||||
callback: function(r) {
|
||||
frm.refresh_fields();
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_payroll_payable_account_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('currency', r.message);
|
||||
frm.set_df_property('currency', 'hidden', 0);
|
||||
frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
"encashable_days",
|
||||
"amended_from",
|
||||
"payroll",
|
||||
"encashment_amount",
|
||||
"encashment_date",
|
||||
"additional_salary"
|
||||
"additional_salary",
|
||||
"column_break_14",
|
||||
"currency",
|
||||
"encashment_amount"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -109,6 +111,7 @@
|
||||
"in_list_view": 1,
|
||||
"label": "Encashment Amount",
|
||||
"no_copy": 1,
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -124,11 +127,26 @@
|
||||
"no_copy": 1,
|
||||
"options": "Additional Salary",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "Company:company:default_currency",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_14",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2019-12-16 11:51:57.732223",
|
||||
"modified": "2020-09-24 19:21:56.856605",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Leave Encashment",
|
||||
|
||||
@@ -16,10 +16,16 @@ class LeaveEncashment(Document):
|
||||
def validate(self):
|
||||
set_employee_name(self)
|
||||
self.get_leave_details_for_encashment()
|
||||
self.validate_salary_structure()
|
||||
|
||||
if not self.encashment_date:
|
||||
self.encashment_date = getdate(nowdate())
|
||||
|
||||
def validate_salary_structure(self):
|
||||
if not frappe.db.exists('Salary Structure Assignment', {'employee': self.employee}):
|
||||
frappe.throw(_("There is no Salary Structure assigned to {0}. First assign a Salary Stucture.").format(self.employee))
|
||||
|
||||
|
||||
def before_submit(self):
|
||||
if self.encashment_amount <= 0:
|
||||
frappe.throw(_("You can only submit Leave Encashment for a valid encashment amount"))
|
||||
@@ -30,6 +36,7 @@ class LeaveEncashment(Document):
|
||||
additional_salary = frappe.new_doc("Additional Salary")
|
||||
additional_salary.company = frappe.get_value("Employee", self.employee, "company")
|
||||
additional_salary.employee = self.employee
|
||||
additional_salary.currency = self.currency
|
||||
earning_component = frappe.get_value("Leave Type", self.leave_type, "earning_component")
|
||||
if not earning_component:
|
||||
frappe.throw(_("Please set Earning Component for Leave type: {0}.".format(self.leave_type)))
|
||||
|
||||
@@ -12,5 +12,48 @@ frappe.ui.form.on('Additional Salary', {
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if(!frm.doc.currency) return;
|
||||
frm.set_query("salary_component", function() {
|
||||
return {
|
||||
query : "erpnext.payroll.doctype.salary_structure.salary_structure.get_earning_deduction_components",
|
||||
filters: {type: "earning", currency: frm.doc.currency, company: frm.doc.company}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
employee: function(frm) {
|
||||
debugger;
|
||||
if (frm.doc.employee) {
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_payroll_payable_account_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('currency', r.message);
|
||||
frm.set_df_property('currency', 'hidden', 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
frappe.call({
|
||||
method: "frappe.client.get_value",
|
||||
args:{
|
||||
doctype: "Employee",
|
||||
fieldname: "company",
|
||||
filters:{
|
||||
name: frm.doc.employee
|
||||
}
|
||||
},
|
||||
callback: function(data) {
|
||||
if(data.message){
|
||||
frm.set_value("company", data.message.company);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
frm.set_value("company", null);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -11,20 +11,21 @@
|
||||
"employee",
|
||||
"employee_name",
|
||||
"salary_component",
|
||||
"overwrite_salary_structure_amount",
|
||||
"deduct_full_tax_on_selected_payroll_date",
|
||||
"type",
|
||||
"amount",
|
||||
"ref_doctype",
|
||||
"ref_docname",
|
||||
"amended_from",
|
||||
"column_break_5",
|
||||
"company",
|
||||
"is_recurring",
|
||||
"department",
|
||||
"currency",
|
||||
"from_date",
|
||||
"to_date",
|
||||
"payroll_date",
|
||||
"type",
|
||||
"department",
|
||||
"amount",
|
||||
"amended_from"
|
||||
"is_recurring",
|
||||
"overwrite_salary_structure_amount",
|
||||
"deduct_full_tax_on_selected_payroll_date"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -59,6 +60,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"options": "currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -159,11 +161,22 @@
|
||||
"label": "Reference Document",
|
||||
"options": "ref_doctype",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "Company:company:default_currency",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 21:10:50.374063",
|
||||
"modified": "2020-09-24 12:55:51.660506",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Additional Salary",
|
||||
|
||||
@@ -22,10 +22,15 @@ class AdditionalSalary(Document):
|
||||
|
||||
def validate(self):
|
||||
self.validate_dates()
|
||||
self.validate_salary_structure()
|
||||
self.validate_recurring_additional_salary_overlap()
|
||||
if self.amount < 0:
|
||||
frappe.throw(_("Amount should not be less than zero."))
|
||||
|
||||
def validate_salary_structure(self):
|
||||
if not frappe.db.exists('Salary Structure Assignment', {'employee': self.employee}):
|
||||
frappe.throw(_("There is no Salary Structure assigned to {0}. First assign a Salary Stucture.").format(self.employee))
|
||||
|
||||
def validate_recurring_additional_salary_overlap(self):
|
||||
if self.is_recurring:
|
||||
additional_salaries = frappe.db.sql("""
|
||||
|
||||
@@ -36,6 +36,20 @@ frappe.ui.form.on('Employee Benefit Application', {
|
||||
filters: {date: frm.doc.date, employee: frm.doc.employee}
|
||||
};
|
||||
});
|
||||
if (frm.doc.employee) {
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_payroll_payable_account_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('currency', r.message);
|
||||
frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
payroll_period: function(frm) {
|
||||
@@ -56,6 +70,7 @@ frappe.ui.form.on('Employee Benefit Application', {
|
||||
});
|
||||
|
||||
var get_max_benefits=function(frm, method, args) {
|
||||
debugger;
|
||||
frappe.call({
|
||||
method: method,
|
||||
args: args,
|
||||
@@ -63,8 +78,11 @@ var get_max_benefits=function(frm, method, args) {
|
||||
if(!data.exc){
|
||||
if(data.message){
|
||||
frm.set_value("max_benefits", data.message);
|
||||
} else {
|
||||
frm.set_value("max_benefits", 0);
|
||||
}
|
||||
}
|
||||
frm.refresh_fields();
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -82,14 +100,19 @@ var calculate_all = function(doc) {
|
||||
var tbl = doc.employee_benefits || [];
|
||||
var pro_rata_dispensed_amount = 0;
|
||||
var total_amount = 0;
|
||||
for(var i = 0; i < tbl.length; i++){
|
||||
if(cint(tbl[i].amount) > 0) {
|
||||
total_amount += flt(tbl[i].amount);
|
||||
}
|
||||
if(tbl[i].pay_against_benefit_claim != 1){
|
||||
pro_rata_dispensed_amount += flt(tbl[i].amount);
|
||||
if (doc.max_benefits == 0) {
|
||||
doc.employee_benefits = []
|
||||
} else {
|
||||
for(var i = 0; i < tbl.length; i++){
|
||||
if(cint(tbl[i].amount) > 0) {
|
||||
total_amount += flt(tbl[i].amount);
|
||||
}
|
||||
if(tbl[i].pay_against_benefit_claim != 1){
|
||||
pro_rata_dispensed_amount += flt(tbl[i].amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doc.total_amount = total_amount;
|
||||
doc.remaining_benefit = doc.max_benefits - total_amount;
|
||||
doc.pro_rata_dispensed_amount = pro_rata_dispensed_amount;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"field_order": [
|
||||
"employee",
|
||||
"employee_name",
|
||||
"currency",
|
||||
"max_benefits",
|
||||
"remaining_benefit",
|
||||
"column_break_2",
|
||||
@@ -43,12 +44,14 @@
|
||||
"fieldname": "max_benefits",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Max Benefits (Yearly)",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "remaining_benefit",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Remaining Benefits (Yearly)",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -108,18 +111,30 @@
|
||||
"fieldname": "total_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Amount",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pro_rata_dispensed_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Dispensed Amount (Pro-rated)",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "Company:company:default_currency",
|
||||
"depends_on": "eval:(doc.docstatus==1 || doc.employee)",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 22:58:31.271922",
|
||||
"modified": "2020-09-24 19:35:37.250360",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Employee Benefit Application",
|
||||
|
||||
@@ -100,6 +100,8 @@ class EmployeeBenefitApplication(Document):
|
||||
if application:
|
||||
frappe.throw(_("Employee {0} already submited an apllication {1} for the payroll period {2}").format(self.employee, application, self.payroll_period))
|
||||
|
||||
# def assign
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_max_benefits(employee, on_date):
|
||||
sal_struct = get_assigned_salary_structure(employee, on_date)
|
||||
@@ -115,7 +117,7 @@ def get_max_benefits_remaining(employee, on_date, payroll_period):
|
||||
if max_benefits and max_benefits > 0:
|
||||
have_depends_on_payment_days = False
|
||||
per_day_amount_total = 0
|
||||
payroll_period_days = get_payroll_period_days(on_date, on_date, employee)[0]
|
||||
payroll_period_days = get_payroll_period_days(on_date, on_date, employee)[1]
|
||||
payroll_period_obj = frappe.get_doc("Payroll Period", payroll_period)
|
||||
|
||||
# Get all salary slip flexi amount in the payroll period
|
||||
@@ -239,4 +241,17 @@ def get_earning_components(doctype, txt, searchfield, start, page_len, filters):
|
||||
""", salary_structure)
|
||||
else:
|
||||
frappe.throw(_("Salary Structure not found for employee {0} and date {1}")
|
||||
.format(filters['employee'], filters['date']))
|
||||
.format(filters['employee'], filters['date']))
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_earning_components_max_benefits(employee, date, earning_component):
|
||||
salary_structure = get_assigned_salary_structure(employee, date)
|
||||
amount = frappe.db.sql("""
|
||||
select amount
|
||||
from `tabSalary Detail`
|
||||
where parent = %s and is_flexible_benefit = 1
|
||||
and salary_component = %s
|
||||
order by name
|
||||
""", salary_structure, earning_component)
|
||||
|
||||
return amount if amount else 0
|
||||
@@ -33,6 +33,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Max Benefit Amount",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -40,12 +41,13 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"options": "currency",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 23:45:00.519134",
|
||||
"modified": "2020-09-29 16:22:15.783854",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Employee Benefit Application Detail",
|
||||
|
||||
@@ -12,5 +12,24 @@ frappe.ui.form.on('Employee Benefit Claim', {
|
||||
},
|
||||
employee: function(frm) {
|
||||
frm.set_value("earning_component", null);
|
||||
if (frm.doc.employee) {
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_payroll_payable_account_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('currency', r.message);
|
||||
frm.set_df_property('currency', 'hidden', 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!frm.doc.earning_component){
|
||||
frm.doc.max_amount_eligible = null;
|
||||
frm.doc.claimed_amount = null;
|
||||
}
|
||||
frm.refresh_fields();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"department",
|
||||
"column_break_3",
|
||||
"claim_date",
|
||||
"currency",
|
||||
"benefit_type_and_amount",
|
||||
"earning_component",
|
||||
"max_amount_eligible",
|
||||
@@ -76,6 +77,7 @@
|
||||
"fieldname": "max_amount_eligible",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Max Amount Eligible",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -92,6 +94,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Claimed Amount",
|
||||
"options": "currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -119,11 +122,21 @@
|
||||
"fieldname": "attachments",
|
||||
"fieldtype": "Attach",
|
||||
"label": "Attachments"
|
||||
},
|
||||
{
|
||||
"default": "Company:company:default_currency",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 23:01:50.791676",
|
||||
"modified": "2020-09-23 11:58:09.049030",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Employee Benefit Claim",
|
||||
|
||||
@@ -11,12 +11,48 @@ frappe.ui.form.on('Employee Incentive', {
|
||||
};
|
||||
});
|
||||
|
||||
if(!frm.doc.currency) return;
|
||||
frm.set_query("salary_component", function() {
|
||||
return {
|
||||
filters: {
|
||||
"type": "Earning"
|
||||
}
|
||||
};
|
||||
return {
|
||||
query : "erpnext.payroll.doctype.salary_structure.salary_structure.get_earning_deduction_components",
|
||||
filters: {type: "earning", currency: frm.doc.currency, company: frm.doc.company}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
employee: function(frm) {
|
||||
frm.trigger("get_leave_details_for_encashment");
|
||||
if (frm.doc.employee) {
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_payroll_payable_account_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('currency', r.message);
|
||||
frm.set_df_property('currency', 'hidden', 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
frappe.call({
|
||||
method: "frappe.client.get_value",
|
||||
args:{
|
||||
doctype: "Employee",
|
||||
fieldname: "company",
|
||||
filters:{
|
||||
name: frm.doc.employee
|
||||
}
|
||||
},
|
||||
callback: function(data) {
|
||||
if(data.message){
|
||||
frm.set_value("company", data.message.company);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
frm.set_value("company", null);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"employee",
|
||||
"incentive_amount",
|
||||
"employee_name",
|
||||
"salary_component",
|
||||
"company",
|
||||
"currency",
|
||||
"incentive_amount",
|
||||
"column_break_5",
|
||||
"salary_component",
|
||||
"payroll_date",
|
||||
"department",
|
||||
"amended_from"
|
||||
@@ -28,6 +30,7 @@
|
||||
"fieldname": "incentive_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Incentive Amount",
|
||||
"options": "currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -70,11 +73,30 @@
|
||||
"label": "Salary Component",
|
||||
"options": "Salary Component",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "Company:company:default_currency",
|
||||
"depends_on": "eval:(doc.docstatus==1 || doc.employee)",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 22:42:51.209630",
|
||||
"modified": "2020-09-30 17:59:57.754477",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Employee Incentive",
|
||||
|
||||
@@ -7,11 +7,19 @@ import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class EmployeeIncentive(Document):
|
||||
def validate(self):
|
||||
self.validate_salary_structure()
|
||||
|
||||
def validate_salary_structure(self):
|
||||
if not frappe.db.exists('Salary Structure Assignment', {'employee': self.employee}):
|
||||
frappe.throw(_("There is no Salary Structure assigned to {0}. First assign a Salary Stucture.").format(self.employee))
|
||||
|
||||
def on_submit(self):
|
||||
company = frappe.db.get_value('Employee', self.employee, 'company')
|
||||
|
||||
additional_salary = frappe.new_doc('Additional Salary')
|
||||
additional_salary.employee = self.employee
|
||||
additional_salary.currency = self.currency
|
||||
additional_salary.salary_component = self.salary_component
|
||||
additional_salary.overwrite_salary_structure_amount = 0
|
||||
additional_salary.amount = self.incentive_amount
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 23:25:13.779032",
|
||||
"modified": "2020-09-30 12:40:07.999878",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Payroll Employee Detail",
|
||||
|
||||
@@ -17,6 +17,17 @@ frappe.ui.form.on('Payroll Entry', {
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("default_payroll_payable_account", function() {
|
||||
return {
|
||||
filters: {
|
||||
"company": frm.doc.company,
|
||||
"root_type": "Liability",
|
||||
"is_group": 0,
|
||||
"account_currency": frm.doc.currency
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
@@ -139,6 +150,30 @@ frappe.ui.form.on('Payroll Entry', {
|
||||
frm.events.clear_employee_table(frm);
|
||||
},
|
||||
|
||||
currency: function (frm) {
|
||||
debugger;
|
||||
if (!frm.doc.company) {
|
||||
var company_currency = erpnext.get_currency(frappe.defaults.get_default("Company"));
|
||||
}
|
||||
else {
|
||||
var company_currency = erpnext.get_currency(frm.doc.company);
|
||||
}
|
||||
if (frm.doc.currency) {
|
||||
if (company_currency != frm.doc.currency) {
|
||||
cur_frm.set_df_property("exchange_rate", "description", "1 " + frm.doc.currency
|
||||
+ " = [?] " + company_currency);
|
||||
cur_frm.set_df_property("exchange_rate", "hidden", 0);
|
||||
frm.set_value('exchange_rate', null);
|
||||
}
|
||||
else {
|
||||
cur_frm.set_df_property("exchange_rate", "description", "");
|
||||
cur_frm.set_df_property("exchange_rate", "hidden", 1);
|
||||
frm.doc.exchange_rate = 1;
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
department: function (frm) {
|
||||
frm.events.clear_employee_table(frm);
|
||||
},
|
||||
|
||||
@@ -11,8 +11,11 @@
|
||||
"column_break0",
|
||||
"posting_date",
|
||||
"payroll_frequency",
|
||||
"column_break1",
|
||||
"company",
|
||||
"column_break1",
|
||||
"currency",
|
||||
"exchange_rate",
|
||||
"default_payroll_payable_account",
|
||||
"section_break_8",
|
||||
"branch",
|
||||
"department",
|
||||
@@ -257,12 +260,37 @@
|
||||
{
|
||||
"fieldname": "column_break_33",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "company",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "company",
|
||||
"fieldname": "exchange_rate",
|
||||
"fieldtype": "Float",
|
||||
"label": "Exchange Rate",
|
||||
"precision": "9",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "company",
|
||||
"fieldname": "default_payroll_payable_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Default Payroll Payable Account",
|
||||
"options": "Account",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-cog",
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 20:06:06.953904",
|
||||
"modified": "2020-09-30 12:47:45.729777",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Payroll Entry",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
from frappe.model.document import Document
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from frappe.utils import cint, flt, nowdate, add_days, getdate, fmt_money, add_to_date, DATE_FORMAT, date_diff
|
||||
@@ -51,13 +51,15 @@ class PayrollEntry(Document):
|
||||
where
|
||||
docstatus = 1 and
|
||||
is_active = 'Yes'
|
||||
and company = %(company)s and
|
||||
and company = %(company)s
|
||||
and currency = %(currency)s and
|
||||
ifnull(salary_slip_based_on_timesheet,0) = %(salary_slip_based_on_timesheet)s
|
||||
{condition}""".format(condition=condition),
|
||||
{"company": self.company, "salary_slip_based_on_timesheet":self.salary_slip_based_on_timesheet})
|
||||
{"company": self.company, "currency": self.currency, "salary_slip_based_on_timesheet":self.salary_slip_based_on_timesheet})
|
||||
|
||||
if sal_struct:
|
||||
cond += "and t2.salary_structure IN %(sal_struct)s "
|
||||
cond += "and t2.default_payroll_payable_account = %(default_payroll_payable_account)s "
|
||||
cond += "and %(from_date)s >= t2.from_date"
|
||||
emp_list = frappe.db.sql("""
|
||||
select
|
||||
@@ -68,7 +70,7 @@ class PayrollEntry(Document):
|
||||
t1.name = t2.employee
|
||||
and t2.docstatus = 1
|
||||
%s order by t2.from_date desc
|
||||
""" % cond, {"sal_struct": tuple(sal_struct), "from_date": self.end_date}, as_dict=True)
|
||||
""" % cond, {"sal_struct": tuple(sal_struct), "from_date": self.end_date, "default_payroll_payable_account": self.default_payroll_payable_account}, as_dict=True)
|
||||
return emp_list
|
||||
|
||||
def fill_employee_details(self):
|
||||
@@ -217,7 +219,8 @@ class PayrollEntry(Document):
|
||||
self.check_permission('write')
|
||||
earnings = self.get_salary_component_total(component_type = "earnings") or {}
|
||||
deductions = self.get_salary_component_total(component_type = "deductions") or {}
|
||||
default_payroll_payable_account = self.get_default_payroll_payable_account()
|
||||
# default_payroll_payable_account = self.get_default_payroll_payable_account()
|
||||
default_payroll_payable_account = self.default_payroll_payable_account
|
||||
jv_name = ""
|
||||
precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")
|
||||
|
||||
@@ -230,14 +233,19 @@ class PayrollEntry(Document):
|
||||
journal_entry.posting_date = self.posting_date
|
||||
|
||||
accounts = []
|
||||
currencies = []
|
||||
payable_amount = 0
|
||||
multi_currency = 0
|
||||
company_currency = erpnext.get_company_currency(self.company)
|
||||
|
||||
# Earnings
|
||||
for acc_cc, amount in earnings.items():
|
||||
exchange_rate, conversion_rate = self.get_exchange_rate(acc_cc[0], company_currency, currencies)
|
||||
payable_amount += flt(amount, precision)
|
||||
accounts.append({
|
||||
"account": acc_cc[0],
|
||||
"debit_in_account_currency": flt(amount, precision),
|
||||
"debit_in_account_currency": flt((amount * conversion_rate), precision),
|
||||
"exchange_rate": flt(exchange_rate),
|
||||
"party_type": '',
|
||||
"cost_center": acc_cc[1] or self.cost_center,
|
||||
"project": self.project
|
||||
@@ -245,24 +253,31 @@ class PayrollEntry(Document):
|
||||
|
||||
# Deductions
|
||||
for acc_cc, amount in deductions.items():
|
||||
exchange_rate, conversion_rate = self.get_exchange_rate(acc_cc[0], company_currency, currencies)
|
||||
payable_amount -= flt(amount, precision)
|
||||
accounts.append({
|
||||
"account": acc_cc[0],
|
||||
"credit_in_account_currency": flt(amount, precision),
|
||||
"credit_in_account_currency": flt((amount * conversion_rate), precision),
|
||||
"exchange_rate": flt(exchange_rate),
|
||||
"cost_center": acc_cc[1] or self.cost_center,
|
||||
"party_type": '',
|
||||
"project": self.project
|
||||
})
|
||||
|
||||
# Payable amount
|
||||
exchange_rate, conversion_rate = self.get_exchange_rate(default_payroll_payable_account, company_currency, currencies)
|
||||
accounts.append({
|
||||
"account": default_payroll_payable_account,
|
||||
"credit_in_account_currency": flt(payable_amount, precision),
|
||||
"credit_in_account_currency": flt((payable_amount * conversion_rate), precision),
|
||||
"exchange_rate": flt(exchange_rate),
|
||||
"party_type": '',
|
||||
"cost_center": self.cost_center
|
||||
})
|
||||
|
||||
journal_entry.set("accounts", accounts)
|
||||
if len(currencies) > 1:
|
||||
multi_currency = 1
|
||||
journal_entry.multi_currency = multi_currency
|
||||
journal_entry.title = default_payroll_payable_account
|
||||
journal_entry.save()
|
||||
|
||||
@@ -275,6 +290,17 @@ class PayrollEntry(Document):
|
||||
|
||||
return jv_name
|
||||
|
||||
def get_exchange_rate(self, account, company_currency, currencies):
|
||||
conversion_rate = 1
|
||||
exchange_rate = self.exchange_rate
|
||||
account_currency = frappe.db.get_value('Account', account, 'account_currency')
|
||||
if account_currency not in currencies:
|
||||
currencies.append(account_currency)
|
||||
if account_currency == company_currency:
|
||||
conversion_rate = self.exchange_rate
|
||||
exchange_rate = 1
|
||||
return exchange_rate, conversion_rate
|
||||
|
||||
def make_payment_entry(self):
|
||||
self.check_permission('write')
|
||||
|
||||
@@ -303,31 +329,44 @@ class PayrollEntry(Document):
|
||||
self.create_journal_entry(salary_slip_total, "salary")
|
||||
|
||||
def create_journal_entry(self, je_payment_amount, user_remark):
|
||||
default_payroll_payable_account = self.get_default_payroll_payable_account()
|
||||
# default_payroll_payable_account = self.get_default_payroll_payable_account()
|
||||
default_payroll_payable_account = self.default_payroll_payable_account
|
||||
precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")
|
||||
|
||||
accounts = []
|
||||
currencies = []
|
||||
multi_currency = 0
|
||||
company_currency = erpnext.get_company_currency(self.company)
|
||||
|
||||
exchange_rate, conversion_rate = self.get_exchange_rate(self.payment_account, company_currency, currencies)
|
||||
accounts.append({
|
||||
"account": self.payment_account,
|
||||
"bank_account": self.bank_account,
|
||||
"credit_in_account_currency": flt(je_payment_amount * conversion_rate, precision),
|
||||
"exchange_rate": flt(exchange_rate),
|
||||
})
|
||||
|
||||
exchange_rate, conversion_rate = self.get_exchange_rate(default_payroll_payable_account, company_currency, currencies)
|
||||
accounts.append({
|
||||
"account": default_payroll_payable_account,
|
||||
"debit_in_account_currency": flt(je_payment_amount * conversion_rate, precision),
|
||||
"exchange_rate": flt(exchange_rate),
|
||||
"reference_type": self.doctype,
|
||||
"reference_name": self.name
|
||||
})
|
||||
|
||||
if len(currencies) > 1:
|
||||
multi_currency = 1
|
||||
|
||||
journal_entry = frappe.new_doc('Journal Entry')
|
||||
journal_entry.voucher_type = 'Bank Entry'
|
||||
journal_entry.user_remark = _('Payment of {0} from {1} to {2}')\
|
||||
.format(user_remark, self.start_date, self.end_date)
|
||||
journal_entry.company = self.company
|
||||
journal_entry.posting_date = self.posting_date
|
||||
journal_entry.multi_currency = multi_currency
|
||||
|
||||
payment_amount = flt(je_payment_amount, precision)
|
||||
|
||||
journal_entry.set("accounts", [
|
||||
{
|
||||
"account": self.payment_account,
|
||||
"bank_account": self.bank_account,
|
||||
"credit_in_account_currency": payment_amount
|
||||
},
|
||||
{
|
||||
"account": default_payroll_payable_account,
|
||||
"debit_in_account_currency": payment_amount,
|
||||
"reference_type": self.doctype,
|
||||
"reference_name": self.name
|
||||
}
|
||||
])
|
||||
journal_entry.set("accounts", accounts)
|
||||
journal_entry.save(ignore_permissions = True)
|
||||
|
||||
def update_salary_slip_status(self, jv_name = None):
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"options": "Company:company:default_currency"
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
@@ -160,7 +160,7 @@
|
||||
"fieldname": "default_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Default Amount",
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
@@ -169,6 +169,7 @@
|
||||
"hidden": 1,
|
||||
"label": "Additional Amount",
|
||||
"no_copy": 1,
|
||||
"options": "currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
@@ -177,6 +178,7 @@
|
||||
"fieldname": "tax_on_flexible_benefit",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Tax on flexible benefit",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -184,6 +186,7 @@
|
||||
"fieldname": "tax_on_additional_salary",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Tax on additional salary",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -206,38 +209,28 @@
|
||||
"collapsible": 1,
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Component properties and references ",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"label": "Component properties and references "
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_19",
|
||||
"fieldtype": "Section Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_18",
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_24",
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-07-01 12:13:41.956495",
|
||||
"modified": "2020-09-30 11:29:36.926796",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Salary Detail",
|
||||
|
||||
@@ -76,12 +76,39 @@ frappe.ui.form.on("Salary Slip", {
|
||||
}
|
||||
},
|
||||
|
||||
currency: function(frm) {
|
||||
calculate_totals(frm.doc);
|
||||
frm.trigger("set_dynamic_labels")
|
||||
frm.refresh()
|
||||
},
|
||||
|
||||
set_dynamic_labels: function(frm) {
|
||||
debugger;
|
||||
frm.set_currency_labels(["hour_rate", "gross_pay", "total_deduction", "net_pay", "rounded_total", "total_in_words"],
|
||||
frm.doc.currency);
|
||||
|
||||
// toggle fields
|
||||
if(frappe.meta.get_docfield(cur_frm.doctype, "net_total"))
|
||||
cur_frm.toggle_display("net_total", show);
|
||||
|
||||
frm.set_currency_labels(["amount", "default_amount", "additional_amount", "tax_on_flexible_benefit", "tax_on_additional_salary"],
|
||||
frm.doc.currency, "earnings");
|
||||
|
||||
frm.set_currency_labels(["amount", "default_amount", "additional_amount", "tax_on_flexible_benefit", "tax_on_additional_salary"],
|
||||
frm.doc.currency, "deductions");
|
||||
|
||||
frm.refresh_fields();
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
debugger;
|
||||
frm.trigger("set_dynamic_labels")
|
||||
frm.trigger("toggle_fields")
|
||||
|
||||
var salary_detail_fields = ["formula", "abbr", "statistical_component", "variable_based_on_taxable_salary"];
|
||||
cur_frm.fields_dict['earnings'].grid.set_column_disp(salary_detail_fields,false);
|
||||
cur_frm.fields_dict['deductions'].grid.set_column_disp(salary_detail_fields,false);
|
||||
calculate_totals(frm.doc);
|
||||
},
|
||||
|
||||
salary_slip_based_on_timesheet: function(frm) {
|
||||
@@ -118,6 +145,7 @@ frappe.ui.form.on("Salary Slip", {
|
||||
},
|
||||
|
||||
get_emp_and_working_day_details: function(frm) {
|
||||
debugger;
|
||||
return frappe.call({
|
||||
method: 'get_emp_and_working_day_details',
|
||||
doc: frm.doc,
|
||||
@@ -140,8 +168,14 @@ frappe.ui.form.on('Salary Slip Timesheet', {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
cur_frm.cscript.amount = function(doc, cdt, cdn){
|
||||
calculate_totals(doc, cdt, cdn);
|
||||
};
|
||||
|
||||
// calculate total working hours, earnings based on hourly wages and totals
|
||||
var total_work_hours = function(frm, dt, dn) {
|
||||
debugger;
|
||||
var total_working_hours = 0.0;
|
||||
$.each(frm.doc["timesheets"] || [], function(i, timesheet) {
|
||||
total_working_hours += timesheet.working_hours;
|
||||
@@ -166,3 +200,89 @@ var total_work_hours = function(frm, dt, dn) {
|
||||
refresh_many(['net_pay', 'rounded_total']);
|
||||
});
|
||||
}
|
||||
|
||||
var calculate_totals = function(doc) {
|
||||
debugger;
|
||||
var tbl1 = doc.earnings || [];
|
||||
var tbl2 = doc.deductions || [];
|
||||
|
||||
var total_earn = 0; var total_ded = 0;
|
||||
for(var i = 0; i < tbl1.length; i++){
|
||||
total_earn += flt(tbl1[i].amount);
|
||||
}
|
||||
for(var j = 0; j < tbl2.length; j++){
|
||||
total_ded += flt(tbl2[j].amount);
|
||||
}
|
||||
doc.gross_pay = total_earn;
|
||||
doc.total_deduction = total_ded;
|
||||
doc.net_pay = 0.0
|
||||
if(doc.salary_slip_based_on_timesheet == 0){
|
||||
doc.net_pay = flt(total_earn) - flt(total_ded) - flt(doc.total_loan_repayment);
|
||||
doc.rounded_total = Math.round(doc.net_pay)
|
||||
}
|
||||
refresh_many(['gross_pay', 'total_deduction', 'net_pay', 'rounded_total']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.validate = function(doc, cdt, cdn) {
|
||||
calculate_totals(doc);
|
||||
}
|
||||
|
||||
|
||||
frappe.ui.form.on('Salary Detail', {
|
||||
amount: function(frm) {
|
||||
calculate_totals(frm.doc);
|
||||
},
|
||||
|
||||
earnings_remove: function(frm) {
|
||||
calculate_totals(frm.doc);
|
||||
},
|
||||
|
||||
deductions_remove: function(frm) {
|
||||
calculate_totals(frm.doc);
|
||||
},
|
||||
|
||||
salary_component: function(frm, cdt, cdn) {
|
||||
debugger;
|
||||
var child = locals[cdt][cdn];
|
||||
if(child.salary_component){
|
||||
frappe.call({
|
||||
method: "frappe.client.get",
|
||||
args: {
|
||||
doctype: "Salary Component",
|
||||
name: child.salary_component
|
||||
},
|
||||
callback: function(data) {
|
||||
if(data.message){
|
||||
var result = data.message;
|
||||
frappe.model.set_value(cdt, cdn, 'condition', result.condition);
|
||||
frappe.model.set_value(cdt, cdn, 'amount_based_on_formula', result.amount_based_on_formula);
|
||||
if(result.amount_based_on_formula == 1){
|
||||
frappe.model.set_value(cdt, cdn, 'formula', result.formula);
|
||||
}
|
||||
else{
|
||||
frappe.model.set_value(cdt, cdn, 'amount', result.amount);
|
||||
}
|
||||
frappe.model.set_value(cdt, cdn, 'statistical_component', result.statistical_component);
|
||||
frappe.model.set_value(cdt, cdn, 'depends_on_payment_days', result.depends_on_payment_days);
|
||||
frappe.model.set_value(cdt, cdn, 'do_not_include_in_total', result.do_not_include_in_total);
|
||||
frappe.model.set_value(cdt, cdn, 'variable_based_on_taxable_salary', result.variable_based_on_taxable_salary);
|
||||
frappe.model.set_value(cdt, cdn, 'is_tax_applicable', result.is_tax_applicable);
|
||||
frappe.model.set_value(cdt, cdn, 'is_flexible_benefit', result.is_flexible_benefit);
|
||||
refresh_field("earnings");
|
||||
refresh_field("deductions");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
amount_based_on_formula: function(frm, cdt, cdn) {
|
||||
var child = locals[cdt][cdn];
|
||||
if(child.amount_based_on_formula == 1){
|
||||
frappe.model.set_value(cdt, cdn, 'amount', null);
|
||||
}
|
||||
else{
|
||||
frappe.model.set_value(cdt, cdn, 'formula', null);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"journal_entry",
|
||||
"payroll_entry",
|
||||
"company",
|
||||
"currency",
|
||||
"letter_head",
|
||||
"section_break_10",
|
||||
"start_date",
|
||||
@@ -67,6 +68,7 @@
|
||||
"rounded_total",
|
||||
"section_break_55",
|
||||
"total_in_words",
|
||||
"section_break_75",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
@@ -205,9 +207,13 @@
|
||||
{
|
||||
"fieldname": "salary_structure",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Salary Structure",
|
||||
"options": "Salary Structure",
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:(!doc.salary_slip_based_on_timesheet)",
|
||||
@@ -265,7 +271,7 @@
|
||||
"fieldname": "hour_rate",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Hour Rate",
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"print_hide_if_no_value": 1
|
||||
},
|
||||
{
|
||||
@@ -347,24 +353,13 @@
|
||||
"fieldname": "gross_pay",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Gross Pay",
|
||||
"oldfieldname": "gross_pay",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_25",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "total_deduction",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Deduction",
|
||||
"oldfieldname": "total_deduction",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "total_loan_repayment",
|
||||
"fieldname": "loan_repayment",
|
||||
@@ -420,9 +415,7 @@
|
||||
"fieldname": "net_pay",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Net Pay",
|
||||
"oldfieldname": "net_pay",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -434,22 +427,13 @@
|
||||
"fieldname": "rounded_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rounded Total",
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_55",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"description": "Net Pay (in words) will be visible once you save the Salary Slip.",
|
||||
"fieldname": "total_in_words",
|
||||
"fieldtype": "Data",
|
||||
"label": "Total in words",
|
||||
"oldfieldname": "net_pay_in_words",
|
||||
"oldfieldtype": "Data",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
@@ -500,13 +484,44 @@
|
||||
{
|
||||
"fieldname": "column_break_18",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "Company:company:default_currency",
|
||||
"depends_on": "eval:(doc.docstatus==1 || doc.salary_structure)",
|
||||
"fetch_from": "salary_structure.currency",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "total_deduction",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Deduction",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"description": "Net Pay (in words) will be visible once you save the Salary Slip.",
|
||||
"fieldname": "total_in_words",
|
||||
"fieldtype": "Data",
|
||||
"label": "Total in words",
|
||||
"length": 240,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_75",
|
||||
"fieldtype": "Section Break"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-file-text",
|
||||
"idx": 9,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-08-11 17:37:54.274384",
|
||||
"modified": "2020-09-30 17:31:21.909671",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Salary Slip",
|
||||
|
||||
@@ -50,9 +50,9 @@ class SalarySlip(TransactionBase):
|
||||
|
||||
self.calculate_net_pay()
|
||||
|
||||
company_currency = erpnext.get_company_currency(self.company)
|
||||
doc_currency = self.currency
|
||||
total = self.net_pay if self.is_rounding_total_disabled() else self.rounded_total
|
||||
self.total_in_words = money_in_words(total, company_currency)
|
||||
self.total_in_words = money_in_words(total, doc_currency)
|
||||
|
||||
if frappe.db.get_single_value("Payroll Settings", "max_working_hours_against_timesheet"):
|
||||
max_working_hours = frappe.db.get_single_value("Payroll Settings", "max_working_hours_against_timesheet")
|
||||
|
||||
@@ -41,20 +41,6 @@ frappe.ui.form.on('Salary Structure', {
|
||||
|
||||
frm.toggle_reqd(['payroll_frequency'], !frm.doc.salary_slip_based_on_timesheet)
|
||||
|
||||
frm.set_query("salary_component", "earnings", function() {
|
||||
return {
|
||||
filters: {
|
||||
type: "earning"
|
||||
}
|
||||
}
|
||||
});
|
||||
frm.set_query("salary_component", "deductions", function() {
|
||||
return {
|
||||
filters: {
|
||||
type: "deduction"
|
||||
}
|
||||
}
|
||||
});
|
||||
frm.set_query("payment_account", function () {
|
||||
var account_types = ["Bank", "Cash"];
|
||||
return {
|
||||
@@ -65,9 +51,55 @@ frappe.ui.form.on('Salary Structure', {
|
||||
}
|
||||
};
|
||||
});
|
||||
frm.trigger('set_earning_deduction_component');
|
||||
},
|
||||
|
||||
set_earning_deduction_component: function(frm) {
|
||||
if(!frm.doc.currency && !frm.doc.company) return;
|
||||
frm.set_query("salary_component", "earnings", function() {
|
||||
return {
|
||||
query : "erpnext.payroll.doctype.salary_structure.salary_structure.get_earning_deduction_components",
|
||||
filters: {type: "earning", currency: frm.doc.currency, company: frm.doc.company}
|
||||
};
|
||||
});
|
||||
frm.set_query("salary_component", "deductions", function() {
|
||||
return {
|
||||
query : "erpnext.payroll.doctype.salary_structure.salary_structure.get_earning_deduction_components",
|
||||
filters: {type: "deduction", currency: frm.doc.currency, company: frm.doc.company}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
currency: function(frm) {
|
||||
calculate_totals(frm.doc);
|
||||
frm.trigger("set_dynamic_labels")
|
||||
frm.trigger('set_earning_deduction_component');
|
||||
frm.refresh()
|
||||
},
|
||||
|
||||
set_dynamic_labels: function(frm) {
|
||||
debugger;
|
||||
frm.set_currency_labels(["net_pay","hour_rate", "leave_encashment_amount_per_day", "max_benefits", "total_earning",
|
||||
"total_deduction"], frm.doc.currency);
|
||||
|
||||
// toggle fields
|
||||
frm.toggle_display(["total_earning", "total_deduction"], true);
|
||||
|
||||
if(frappe.meta.get_docfield(cur_frm.doctype, "net_pay"))
|
||||
cur_frm.toggle_display("net_pay", true);
|
||||
|
||||
frm.set_currency_labels(["amount", "additional_amount", "tax_on_flexible_benefit", "tax_on_additional_salary"],
|
||||
frm.doc.currency, "earnings");
|
||||
|
||||
frm.set_currency_labels(["amount", "additional_amount", "tax_on_flexible_benefit", "tax_on_additional_salary"],
|
||||
frm.doc.currency, "deductions");
|
||||
|
||||
frm.refresh_fields();
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
frm.trigger("set_dynamic_labels")
|
||||
frm.trigger("toggle_fields");
|
||||
frm.fields_dict['earnings'].grid.set_column_disp("default_amount", false);
|
||||
frm.fields_dict['deductions'].grid.set_column_disp("default_amount", false);
|
||||
@@ -101,10 +133,12 @@ frappe.ui.form.on('Salary Structure', {
|
||||
fields: [
|
||||
{fieldname: "sec_break", fieldtype: "Section Break", label: __("Filter Employees By (Optional)")},
|
||||
{fieldname: "company", fieldtype: "Link", options: "Company", label: __("Company"), default: frm.doc.company, read_only:1},
|
||||
{fieldname: "currency", fieldtype: "Link", options: "Currency", label: __("Currency"), default: frm.doc.currency, read_only:1},
|
||||
{fieldname: "grade", fieldtype: "Link", options: "Employee Grade", label: __("Employee Grade")},
|
||||
{fieldname:'department', fieldtype:'Link', options: 'Department', label: __('Department')},
|
||||
{fieldname:'designation', fieldtype:'Link', options: 'Designation', label: __('Designation')},
|
||||
{fieldname:"employee", fieldtype: "Link", options: "Employee", label: __("Employee")},
|
||||
{fieldname:"employee", fieldtype: "Link", options: "Employee", label: __("Employee")},
|
||||
{fieldname:"default_payroll_payable_account", fieldtype: "Link", options: "Account", filters: {"company": frm.doc.company, "root_type": "Liability", "is_group": 0, "account_currency": frm.doc.currency}, label: __("Default Payroll Payable Account")},
|
||||
{fieldname:'base_variable', fieldtype:'Section Break'},
|
||||
{fieldname:'from_date', fieldtype:'Date', label: __('From Date'), "reqd": 1},
|
||||
{fieldname:'income_tax_slab', fieldtype:'Link', label: __('Income Tax Slab'), options: 'Income Tax Slab'},
|
||||
@@ -221,6 +255,7 @@ cur_frm.cscript.amount = function(doc, cdt, cdn){
|
||||
};
|
||||
|
||||
var calculate_totals = function(doc) {
|
||||
debugger;
|
||||
var tbl1 = doc.earnings || [];
|
||||
var tbl2 = doc.deductions || [];
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"column_break1",
|
||||
"is_active",
|
||||
"payroll_frequency",
|
||||
"currency",
|
||||
"is_default",
|
||||
"time_sheet_earning_detail",
|
||||
"salary_slip_based_on_timesheet",
|
||||
@@ -26,9 +27,9 @@
|
||||
"deductions",
|
||||
"conditions_and_formula_variable_and_example",
|
||||
"net_pay_detail",
|
||||
"column_break2",
|
||||
"total_earning",
|
||||
"total_deduction",
|
||||
"column_break2",
|
||||
"net_pay",
|
||||
"account",
|
||||
"mode_of_payment",
|
||||
@@ -43,23 +44,17 @@
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"remember_last_selected_value": 1,
|
||||
"reqd": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "letter_head",
|
||||
"fieldtype": "Link",
|
||||
"label": "Letter Head",
|
||||
"options": "Letter Head",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "Letter Head"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -72,9 +67,7 @@
|
||||
"oldfieldname": "is_active",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"reqd": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "Monthly",
|
||||
@@ -82,9 +75,7 @@
|
||||
"fieldname": "payroll_frequency",
|
||||
"fieldtype": "Select",
|
||||
"label": "Payroll Frequency",
|
||||
"options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily"
|
||||
},
|
||||
{
|
||||
"default": "No",
|
||||
@@ -95,62 +86,46 @@
|
||||
"no_copy": 1,
|
||||
"options": "Yes\nNo",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "time_sheet_earning_detail",
|
||||
"fieldtype": "Section Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "salary_slip_based_on_timesheet",
|
||||
"fieldtype": "Check",
|
||||
"label": "Salary Slip Based on Timesheet",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"label": "Salary Slip Based on Timesheet"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_17",
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"description": "Salary Component for timesheet based payroll.",
|
||||
"fieldname": "salary_component",
|
||||
"fieldtype": "Link",
|
||||
"label": "Salary Component",
|
||||
"options": "Salary Component",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "Salary Component"
|
||||
},
|
||||
{
|
||||
"fieldname": "hour_rate",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Hour Rate",
|
||||
"options": "Company:company:default_currency",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "leave_encashment_amount_per_day",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Leave Encashment Amount Per Day",
|
||||
"options": "Company:company:default_currency",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "max_benefits",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Max Benefits (Amount)",
|
||||
"options": "Company:company:default_currency",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"description": "Salary breakup based on Earning and Deduction.",
|
||||
@@ -158,9 +133,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"oldfieldname": "earning_deduction",
|
||||
"oldfieldtype": "Section Break",
|
||||
"precision": "2",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"precision": "2"
|
||||
},
|
||||
{
|
||||
"fieldname": "earnings",
|
||||
@@ -168,9 +141,7 @@
|
||||
"label": "Earnings",
|
||||
"oldfieldname": "earning_details",
|
||||
"oldfieldtype": "Table",
|
||||
"options": "Salary Detail",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "Salary Detail"
|
||||
},
|
||||
{
|
||||
"fieldname": "deductions",
|
||||
@@ -178,22 +149,16 @@
|
||||
"label": "Deductions",
|
||||
"oldfieldname": "deduction_details",
|
||||
"oldfieldtype": "Table",
|
||||
"options": "Salary Detail",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "Salary Detail"
|
||||
},
|
||||
{
|
||||
"fieldname": "net_pay_detail",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "Simple",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "Simple"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -201,63 +166,45 @@
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"label": "Total Earning",
|
||||
"oldfieldname": "total_earning",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "total_deduction",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"label": "Total Deduction",
|
||||
"oldfieldname": "total_deduction",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "net_pay",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"label": "Net Pay",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Account",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"label": "Account"
|
||||
},
|
||||
{
|
||||
"fieldname": "mode_of_payment",
|
||||
"fieldtype": "Link",
|
||||
"label": "Mode of Payment",
|
||||
"options": "Mode of Payment",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "Mode of Payment"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_28",
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "payment_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Payment Account",
|
||||
"options": "Account",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
@@ -266,23 +213,26 @@
|
||||
"no_copy": 1,
|
||||
"options": "Salary Structure",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "conditions_and_formula_variable_and_example",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Conditions and Formula variable and example",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"label": "Conditions and Formula variable and example"
|
||||
},
|
||||
{
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 17:07:26.129355",
|
||||
"modified": "2020-09-30 11:30:32.190798",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Salary Structure",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
|
||||
from frappe.utils import flt, cint, cstr
|
||||
from frappe import _
|
||||
@@ -88,24 +88,26 @@ class SalaryStructure(Document):
|
||||
return employees
|
||||
|
||||
@frappe.whitelist()
|
||||
def assign_salary_structure(self, company=None, grade=None, department=None, designation=None,employee=None,
|
||||
from_date=None, base=None, variable=None, income_tax_slab=None):
|
||||
employees = self.get_employees(company= company, grade= grade,department= department,designation= designation,name=employee)
|
||||
def assign_salary_structure(self, grade=None, department=None, designation=None,employee=None,
|
||||
default_payroll_payable_account=None, from_date=None, base=None, variable=None, income_tax_slab=None):
|
||||
employees = self.get_employees(company= self.company, grade= grade,department= department,designation= designation,name=employee)
|
||||
|
||||
if employees:
|
||||
if len(employees) > 20:
|
||||
frappe.enqueue(assign_salary_structure_for_employees, timeout=600,
|
||||
employees=employees, salary_structure=self,from_date=from_date,
|
||||
base=base, variable=variable, income_tax_slab=income_tax_slab)
|
||||
employees=employees, salary_structure=self,
|
||||
default_payroll_payable_account=default_payroll_payable_account,
|
||||
from_date=from_date, base=base, variable=variable, income_tax_slab=income_tax_slab)
|
||||
else:
|
||||
assign_salary_structure_for_employees(employees, self, from_date=from_date,
|
||||
base=base, variable=variable, income_tax_slab=income_tax_slab)
|
||||
assign_salary_structure_for_employees(employees, self,
|
||||
default_payroll_payable_account=default_payroll_payable_account,
|
||||
from_date=from_date, base=base, variable=variable, income_tax_slab=income_tax_slab)
|
||||
else:
|
||||
frappe.msgprint(_("No Employee Found"))
|
||||
|
||||
|
||||
|
||||
def assign_salary_structure_for_employees(employees, salary_structure, from_date=None, base=None, variable=None, income_tax_slab=None):
|
||||
def assign_salary_structure_for_employees(employees, salary_structure, default_payroll_payable_account=None, from_date=None, base=None, variable=None, income_tax_slab=None):
|
||||
salary_structures_assignments = []
|
||||
existing_assignments_for = get_existing_assignments(employees, salary_structure, from_date)
|
||||
count=0
|
||||
@@ -115,7 +117,7 @@ def assign_salary_structure_for_employees(employees, salary_structure, from_date
|
||||
count +=1
|
||||
|
||||
salary_structures_assignment = create_salary_structures_assignment(employee,
|
||||
salary_structure, from_date, base, variable, income_tax_slab)
|
||||
salary_structure, default_payroll_payable_account, from_date, base, variable, income_tax_slab)
|
||||
salary_structures_assignments.append(salary_structures_assignment)
|
||||
frappe.publish_progress(count*100/len(set(employees) - set(existing_assignments_for)), title = _("Assigning Structures..."))
|
||||
|
||||
@@ -123,11 +125,21 @@ def assign_salary_structure_for_employees(employees, salary_structure, from_date
|
||||
frappe.msgprint(_("Structures have been assigned successfully"))
|
||||
|
||||
|
||||
def create_salary_structures_assignment(employee, salary_structure, from_date, base, variable, income_tax_slab=None):
|
||||
def create_salary_structures_assignment(employee, salary_structure, default_payroll_payable_account, from_date, base, variable, income_tax_slab=None):
|
||||
if not default_payroll_payable_account:
|
||||
default_payroll_payable_account = frappe.db.get_value('Company', salary_structure.company, 'default_payroll_payable_account')
|
||||
if not default_payroll_payable_account:
|
||||
frappe.throw(_('Please set "Default Payroll Payable Account" in Company Defaults'))
|
||||
account_currency = frappe.db.get_value('Account', default_payroll_payable_account, 'account_currency')
|
||||
if account_currency != salary_structure.currency:
|
||||
frappe.throw(_("Account currency of Account: {0} is different than what is specified in salary structure: {1}").format(self.default_payroll_payable_account, self.salary_structure))
|
||||
|
||||
assignment = frappe.new_doc("Salary Structure Assignment")
|
||||
assignment.employee = employee
|
||||
assignment.salary_structure = salary_structure.name
|
||||
assignment.company = salary_structure.company
|
||||
assignment.currency = salary_structure.currency
|
||||
assignment.default_payroll_payable_account = default_payroll_payable_account
|
||||
assignment.from_date = from_date
|
||||
assignment.base = base
|
||||
assignment.variable = variable
|
||||
@@ -170,7 +182,8 @@ def make_salary_slip(source_name, target_doc = None, employee = None, as_print =
|
||||
"doctype": "Salary Slip",
|
||||
"field_map": {
|
||||
"total_earning": "gross_pay",
|
||||
"name": "salary_structure"
|
||||
"name": "salary_structure",
|
||||
"currency": "currency"
|
||||
}
|
||||
}
|
||||
}, target_doc, postprocess, ignore_child_tables=True, ignore_permissions=ignore_permissions)
|
||||
@@ -192,3 +205,24 @@ def get_employees(salary_structure):
|
||||
Assign {1} to an Employee to preview Salary Slip").format(salary_structure, salary_structure))
|
||||
|
||||
return list(set([d.employee for d in employees]))
|
||||
|
||||
@frappe.whitelist()
|
||||
@frappe.validate_and_sanitize_search_inputs
|
||||
def get_earning_deduction_components(doctype, txt, searchfield, start, page_len, filters):
|
||||
if len(filters) < 3:
|
||||
return {}
|
||||
|
||||
currency_list = []
|
||||
company_currency = erpnext.get_company_currency(filters['company'])
|
||||
currency_list.append(company_currency)
|
||||
if filters['currency'] != company_currency:
|
||||
currency_list.append(filters['currency'])
|
||||
return frappe.db.sql("""
|
||||
select t1.salary_component
|
||||
from `tabSalary Component` t1, `tabSalary Component Account` t2
|
||||
where t1.salary_component = t2.parent
|
||||
and t1.type = %s
|
||||
and t2.company = %s
|
||||
and t2.account_currency in %s
|
||||
order by salary_component
|
||||
""", (filters['type'], filters['company'], currency_list) )
|
||||
|
||||
@@ -6,9 +6,6 @@ frappe.ui.form.on('Salary Structure Assignment', {
|
||||
frm.set_query("employee", function() {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.employee_query",
|
||||
filters: {
|
||||
company: frm.doc.company
|
||||
}
|
||||
}
|
||||
});
|
||||
frm.set_query("salary_structure", function() {
|
||||
@@ -30,8 +27,21 @@ frappe.ui.form.on('Salary Structure Assignment', {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query("default_payroll_payable_account", function() {
|
||||
return {
|
||||
filters: {
|
||||
"company": frm.doc.company,
|
||||
"root_type": "Liability",
|
||||
"is_group": 0,
|
||||
"account_currency": frm.doc.currency
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
employee: function(frm) {
|
||||
debugger;
|
||||
if(frm.doc.employee){
|
||||
frappe.call({
|
||||
method: "frappe.client.get_value",
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
"employee_name",
|
||||
"department",
|
||||
"company",
|
||||
"default_payroll_payable_account",
|
||||
"column_break_6",
|
||||
"designation",
|
||||
"salary_structure",
|
||||
"from_date",
|
||||
"income_tax_slab",
|
||||
"currency",
|
||||
"section_break_7",
|
||||
"base",
|
||||
"column_break_9",
|
||||
@@ -94,7 +96,7 @@
|
||||
"fieldname": "base",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Base",
|
||||
"options": "Company:company:default_currency"
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_9",
|
||||
@@ -104,7 +106,7 @@
|
||||
"fieldname": "variable",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Variable",
|
||||
"options": "Company:company:default_currency"
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
@@ -120,11 +122,30 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "Income Tax Slab",
|
||||
"options": "Income Tax Slab"
|
||||
},
|
||||
{
|
||||
"depends_on": "salary_structure",
|
||||
"fieldname": "default_payroll_payable_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Default Payroll Payable Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"default": "Company:company:default_currency",
|
||||
"depends_on": "eval:(doc.docstatus==1 || doc.salary_structure)",
|
||||
"fetch_from": "salary_structure.currency",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 19:58:09.964692",
|
||||
"modified": "2020-09-30 17:35:49.922227",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Salary Structure Assignment",
|
||||
|
||||
@@ -13,6 +13,7 @@ class DuplicateAssignment(frappe.ValidationError): pass
|
||||
class SalaryStructureAssignment(Document):
|
||||
def validate(self):
|
||||
self.validate_dates()
|
||||
self.validate_default_payroll_payable_account()
|
||||
|
||||
def validate_dates(self):
|
||||
joining_date, relieving_date = frappe.db.get_value("Employee", self.employee,
|
||||
@@ -31,6 +32,15 @@ class SalaryStructureAssignment(Document):
|
||||
frappe.throw(_("From Date {0} cannot be after employee's relieving Date {1}")
|
||||
.format(self.from_date, relieving_date))
|
||||
|
||||
def validate_default_payroll_payable_account(self):
|
||||
if not self.default_payroll_payable_account:
|
||||
self.default_payroll_payable_account = frappe.db.get_value('Company', self.company, 'default_payroll_payable_account')
|
||||
if not self.default_payroll_payable_account:
|
||||
frappe.throw(_('Please set "Default Payroll Payable Account" in Company Defaults'))
|
||||
account_currency = frappe.db.get_value('Account', self.default_payroll_payable_account, 'account_currency')
|
||||
if account_currency != self.currency:
|
||||
frappe.throw(_("Account currency of Account: {0} is different than what is specified in salary structure: {1}").format(self.default_payroll_payable_account, self.salary_structure))
|
||||
|
||||
def get_assigned_salary_structure(employee, on_date):
|
||||
if not employee or not on_date:
|
||||
return None
|
||||
@@ -43,3 +53,11 @@ def get_assigned_salary_structure(employee, on_date):
|
||||
'on_date': on_date,
|
||||
})
|
||||
return salary_structure[0][0] if salary_structure else None
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_payroll_payable_account_currency(employee):
|
||||
default_payroll_payable_account = frappe.db.get_value('Salary Structure Assignment', {'employee': employee}, 'default_payroll_payable_account')
|
||||
if not default_payroll_payable_account:
|
||||
frappe.throw(_("There is no Salary Structure assigned to {0}. First assign a Salary Stucture.").format(employee))
|
||||
account_currency = frappe.db.get_value('Account', default_payroll_payable_account, 'account_currency')
|
||||
return account_currency
|
||||
@@ -238,31 +238,31 @@ cur_frm.cscript.change_abbr = function() {
|
||||
|
||||
erpnext.company.setup_queries = function(frm) {
|
||||
$.each([
|
||||
["default_bank_account", {"account_type": "Bank"}],
|
||||
["default_cash_account", {"account_type": "Cash"}],
|
||||
["default_receivable_account", {"account_type": "Receivable"}],
|
||||
["default_payable_account", {"account_type": "Payable"}],
|
||||
["default_expense_account", {"root_type": "Expense"}],
|
||||
["default_income_account", {"root_type": "Income"}],
|
||||
["default_payroll_payable_account", {"root_type": "Liability"}],
|
||||
["round_off_account", {"root_type": "Expense"}],
|
||||
["write_off_account", {"root_type": "Expense"}],
|
||||
["discount_allowed_account", {"root_type": "Expense"}],
|
||||
["discount_received_account", {"root_type": "Income"}],
|
||||
["exchange_gain_loss_account", {"root_type": "Expense"}],
|
||||
["unrealized_exchange_gain_loss_account", {"root_type": "Expense"}],
|
||||
["default_bank_account", {"account_type": "Bank", "account_currency": frm.doc.default_currency}],
|
||||
["default_cash_account", {"account_type": "Cash", "account_currency": frm.doc.default_currency}],
|
||||
["default_receivable_account", {"account_type": "Receivable", "account_currency": frm.doc.default_currency}],
|
||||
["default_payable_account", {"account_type": "Payable", "account_currency": frm.doc.default_currency}],
|
||||
["default_expense_account", {"root_type": "Expense", "account_currency": frm.doc.default_currency}],
|
||||
["default_income_account", {"root_type": "Income", "account_currency": frm.doc.default_currency}],
|
||||
["default_payroll_payable_account", {"root_type": "Liability", "account_currency": frm.doc.default_currency}],
|
||||
["round_off_account", {"root_type": "Expense", "account_currency": frm.doc.default_currency}],
|
||||
["write_off_account", {"root_type": "Expense", "account_currency": frm.doc.default_currency}],
|
||||
["discount_allowed_account", {"root_type": "Expense", "account_currency": frm.doc.default_currency}],
|
||||
["discount_received_account", {"root_type": "Income", "account_currency": frm.doc.default_currency}],
|
||||
["exchange_gain_loss_account", {"root_type": "Expense", "account_currency": frm.doc.default_currency}],
|
||||
["unrealized_exchange_gain_loss_account", {"root_type": "Expense", "account_currency": frm.doc.default_currency}],
|
||||
["accumulated_depreciation_account",
|
||||
{"root_type": "Asset", "account_type": "Accumulated Depreciation"}],
|
||||
["depreciation_expense_account", {"root_type": "Expense", "account_type": "Depreciation"}],
|
||||
["disposal_account", {"report_type": "Profit and Loss"}],
|
||||
["default_inventory_account", {"account_type": "Stock"}],
|
||||
{"root_type": "Asset", "account_type": "Accumulated Depreciation", "account_currency": frm.doc.default_currency}],
|
||||
["depreciation_expense_account", {"root_type": "Expense", "account_type": "Depreciation", "account_currency": frm.doc.default_currency}],
|
||||
["disposal_account", {"report_type": "Profit and Loss", "account_currency": frm.doc.default_currency}],
|
||||
["default_inventory_account", {"account_type": "Stock", "account_currency": frm.doc.default_currency}],
|
||||
["cost_center", {}],
|
||||
["round_off_cost_center", {}],
|
||||
["depreciation_cost_center", {}],
|
||||
["default_employee_advance_account", {"root_type": "Asset"}],
|
||||
["expenses_included_in_asset_valuation", {"account_type": "Expenses Included In Asset Valuation"}],
|
||||
["capital_work_in_progress_account", {"account_type": "Capital Work in Progress"}],
|
||||
["asset_received_but_not_billed", {"account_type": "Asset Received But Not Billed"}]
|
||||
["default_employee_advance_account", {"root_type": "Asset", "account_currency": frm.doc.default_currency}],
|
||||
["expenses_included_in_asset_valuation", {"account_type": "Expenses Included In Asset Valuation", "account_currency": frm.doc.default_currency}],
|
||||
["capital_work_in_progress_account", {"account_type": "Capital Work in Progress", "account_currency": frm.doc.default_currency}],
|
||||
["asset_received_but_not_billed", {"account_type": "Asset Received But Not Billed", "account_currency": frm.doc.default_currency}]
|
||||
], function(i, v) {
|
||||
erpnext.company.set_custom_query(frm, v);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user