mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-15 04:45:09 +00:00
fix: refactor and added conditions
This commit is contained in:
@@ -912,7 +912,8 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
||||
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":
|
||||
total_amount = ref_doc.advance_amount
|
||||
total_amount = ref_doc.advance_amount
|
||||
if party_account_currency != company_currency:
|
||||
exchange_rate = ref_doc.get("exchange_rate")
|
||||
if not total_amount:
|
||||
if party_account_currency == company_currency:
|
||||
@@ -934,7 +935,7 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
||||
outstanding_amount = flt(ref_doc.get("total_sanctioned_amount")) + flt(ref_doc.get("total_taxes_and_charges"))\
|
||||
- flt(ref_doc.get("total_amount_reimbursed")) - flt(ref_doc.get("total_advance_amount"))
|
||||
elif reference_doctype == "Employee Advance":
|
||||
outstanding_amount = ref_doc.advance_amount - flt(ref_doc.paid_amount)
|
||||
outstanding_amount = (flt(ref_doc.advance_amount) - flt(ref_doc.paid_amount))
|
||||
else:
|
||||
outstanding_amount = flt(total_amount) - flt(ref_doc.advance_paid)
|
||||
else:
|
||||
@@ -957,70 +958,14 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
|
||||
frappe.throw(_("Can only make payment against unbilled {0}").format(dt))
|
||||
|
||||
if dt in ("Sales Invoice", "Sales Order", "Dunning"):
|
||||
party_type = "Customer"
|
||||
elif dt in ("Purchase Invoice", "Purchase Order"):
|
||||
party_type = "Supplier"
|
||||
elif dt in ("Expense Claim", "Employee Advance"):
|
||||
party_type = "Employee"
|
||||
elif dt in ("Fees"):
|
||||
party_type = "Student"
|
||||
|
||||
# party account
|
||||
if dt == "Sales Invoice":
|
||||
party_account = get_party_account_based_on_invoice_discounting(dn) or doc.debit_to
|
||||
elif dt == "Purchase Invoice":
|
||||
party_account = doc.credit_to
|
||||
elif dt == "Fees":
|
||||
party_account = doc.receivable_account
|
||||
elif dt == "Employee Advance":
|
||||
party_account = doc.advance_account
|
||||
elif dt == "Expense Claim":
|
||||
party_account = doc.payable_account
|
||||
else:
|
||||
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
||||
|
||||
if dt not in ("Sales Invoice", "Purchase Invoice"):
|
||||
party_account_currency = get_account_currency(party_account)
|
||||
else:
|
||||
party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)
|
||||
|
||||
# payment type
|
||||
if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees", "Dunning") and doc.outstanding_amount > 0)) \
|
||||
or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
|
||||
payment_type = "Receive"
|
||||
else:
|
||||
payment_type = "Pay"
|
||||
|
||||
# amounts
|
||||
grand_total = outstanding_amount = 0
|
||||
if party_amount:
|
||||
grand_total = outstanding_amount = party_amount
|
||||
elif dt in ("Sales Invoice", "Purchase Invoice"):
|
||||
if party_account_currency == doc.company_currency:
|
||||
grand_total = doc.base_rounded_total or doc.base_grand_total
|
||||
else:
|
||||
grand_total = doc.rounded_total or doc.grand_total
|
||||
outstanding_amount = doc.outstanding_amount
|
||||
elif dt in ("Expense Claim"):
|
||||
grand_total = doc.total_sanctioned_amount + doc.total_taxes_and_charges
|
||||
outstanding_amount = doc.grand_total \
|
||||
- doc.total_amount_reimbursed
|
||||
elif dt == "Employee Advance":
|
||||
grand_total = doc.advance_amount
|
||||
outstanding_amount = flt(doc.advance_amount) - flt(doc.paid_amount)
|
||||
elif dt == "Fees":
|
||||
grand_total = doc.grand_total
|
||||
outstanding_amount = doc.outstanding_amount
|
||||
elif dt == "Dunning":
|
||||
grand_total = doc.grand_total
|
||||
outstanding_amount = doc.grand_total
|
||||
else:
|
||||
if party_account_currency == doc.company_currency:
|
||||
grand_total = flt(doc.get("base_rounded_total") or doc.base_grand_total)
|
||||
else:
|
||||
grand_total = flt(doc.get("rounded_total") or doc.grand_total)
|
||||
outstanding_amount = grand_total - flt(doc.advance_paid)
|
||||
party_type = set_party_type(dt)
|
||||
party_account = set_party_account(dt, doc, party_type)
|
||||
exchange_rate = 1
|
||||
party_account_currency = set_party_account_currency(dt, party_account, doc)
|
||||
if party_account_currency != doc.currency:
|
||||
exchange_rate = doc.get('exchange_rate', 1)
|
||||
payment_type = set_payment_type(dt, doc)
|
||||
grand_total, outstanding_amount = set_grand_total_and_outstanding_amount(party_amount, dt, party_account_currency, doc, exchange_rate)
|
||||
|
||||
# bank or cash
|
||||
bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"),
|
||||
@@ -1030,22 +975,7 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
bank = get_default_bank_cash_account(doc.company, "Cash", mode_of_payment=doc.get("mode_of_payment"),
|
||||
account=bank_account)
|
||||
|
||||
paid_amount = received_amount = 0
|
||||
if party_account_currency == bank.account_currency:
|
||||
paid_amount = received_amount = abs(outstanding_amount)
|
||||
elif payment_type == "Receive":
|
||||
paid_amount = abs(outstanding_amount)
|
||||
if bank_amount:
|
||||
received_amount = bank_amount
|
||||
else:
|
||||
received_amount = paid_amount * doc.get('conversion_rate', 1)
|
||||
else:
|
||||
received_amount = abs(outstanding_amount)
|
||||
if bank_amount:
|
||||
paid_amount = bank_amount
|
||||
else:
|
||||
# if party account currency and bank currency is different then populate paid amount as well
|
||||
paid_amount = received_amount * doc.get('conversion_rate', 1)
|
||||
paid_amount, received_amount = set_paid_amount_and_received_amount(dt, party_account_currency, bank, outstanding_amount, payment_type, bank_amount, doc)
|
||||
|
||||
pe = frappe.new_doc("Payment Entry")
|
||||
pe.payment_type = payment_type
|
||||
@@ -1121,6 +1051,101 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
pe.set_amounts()
|
||||
return pe
|
||||
|
||||
def set_party_type(dt):
|
||||
if dt in ("Sales Invoice", "Sales Order", "Dunning"):
|
||||
party_type = "Customer"
|
||||
elif dt in ("Purchase Invoice", "Purchase Order"):
|
||||
party_type = "Supplier"
|
||||
elif dt in ("Expense Claim", "Employee Advance"):
|
||||
party_type = "Employee"
|
||||
elif dt in ("Fees"):
|
||||
party_type = "Student"
|
||||
return party_type
|
||||
|
||||
def set_party_account(dt, doc, party_type):
|
||||
if dt == "Sales Invoice":
|
||||
party_account = get_party_account_based_on_invoice_discounting(dn) or doc.debit_to
|
||||
elif dt == "Purchase Invoice":
|
||||
party_account = doc.credit_to
|
||||
elif dt == "Fees":
|
||||
party_account = doc.receivable_account
|
||||
elif dt == "Employee Advance":
|
||||
party_account = doc.advance_account
|
||||
elif dt == "Expense Claim":
|
||||
party_account = doc.payable_account
|
||||
else:
|
||||
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
||||
return party_account
|
||||
|
||||
def set_party_account_currency(dt, party_account, doc):
|
||||
if dt not in ("Sales Invoice", "Purchase Invoice"):
|
||||
party_account_currency = get_account_currency(party_account)
|
||||
else:
|
||||
party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)
|
||||
return party_account_currency
|
||||
|
||||
def set_payment_type(dt, doc):
|
||||
if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees", "Dunning") and doc.outstanding_amount > 0)) \
|
||||
or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
|
||||
payment_type = "Receive"
|
||||
else:
|
||||
payment_type = "Pay"
|
||||
return payment_type
|
||||
|
||||
def set_grand_total_and_outstanding_amount(party_amount, dt, party_account_currency, doc, exchange_rate):
|
||||
grand_total = outstanding_amount = 0
|
||||
if party_amount:
|
||||
grand_total = outstanding_amount = party_amount
|
||||
elif dt in ("Sales Invoice", "Purchase Invoice"):
|
||||
if party_account_currency == doc.company_currency:
|
||||
grand_total = doc.base_rounded_total or doc.base_grand_total
|
||||
else:
|
||||
grand_total = doc.rounded_total or doc.grand_total
|
||||
outstanding_amount = doc.outstanding_amount
|
||||
elif dt in ("Expense Claim"):
|
||||
grand_total = doc.total_sanctioned_amount + doc.total_taxes_and_charges
|
||||
outstanding_amount = doc.grand_total \
|
||||
- doc.total_amount_reimbursed
|
||||
elif dt == "Employee Advance":
|
||||
grand_total = flt(doc.advance_amount) * flt(exchange_rate)
|
||||
outstanding_amount = (flt(doc.advance_amount) - flt(doc.paid_amount)) * flt(exchange_rate)
|
||||
elif dt == "Fees":
|
||||
grand_total = doc.grand_total
|
||||
outstanding_amount = doc.outstanding_amount
|
||||
elif dt == "Dunning":
|
||||
grand_total = doc.grand_total
|
||||
outstanding_amount = doc.grand_total
|
||||
else:
|
||||
if party_account_currency == doc.company_currency:
|
||||
grand_total = flt(doc.get("base_rounded_total") or doc.base_grand_total)
|
||||
else:
|
||||
grand_total = flt(doc.get("rounded_total") or doc.grand_total)
|
||||
outstanding_amount = grand_total - flt(doc.advance_paid)
|
||||
return grand_total, outstanding_amount
|
||||
|
||||
def set_paid_amount_and_received_amount(dt, party_account_currency, bank, outstanding_amount, payment_type, bank_amount, doc):
|
||||
paid_amount = received_amount = 0
|
||||
if party_account_currency == bank.account_currency:
|
||||
paid_amount = received_amount = abs(outstanding_amount)
|
||||
elif payment_type == "Receive":
|
||||
paid_amount = abs(outstanding_amount)
|
||||
if bank_amount:
|
||||
received_amount = bank_amount
|
||||
else:
|
||||
received_amount = paid_amount * doc.get('conversion_rate', 1)
|
||||
if dt == "Employee Advance":
|
||||
received_amount = paid_amount * doc.get('exchange_rate', 1)
|
||||
else:
|
||||
received_amount = abs(outstanding_amount)
|
||||
if bank_amount:
|
||||
paid_amount = bank_amount
|
||||
else:
|
||||
# if party account currency and bank currency is different then populate paid amount as well
|
||||
paid_amount = received_amount * doc.get('conversion_rate', 1)
|
||||
if dt == "Employee Advance":
|
||||
paid_amount = received_amount * doc.get('exchange_rate', 1)
|
||||
return paid_amount, received_amount
|
||||
|
||||
def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
|
||||
references = []
|
||||
for payment_term in payment_schedule:
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"company",
|
||||
"default_account",
|
||||
"account_currency"
|
||||
"account"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -19,24 +18,16 @@
|
||||
},
|
||||
{
|
||||
"description": "Default Bank / Cash account will be automatically updated in Salary Journal Entry when this mode is selected.",
|
||||
"fieldname": "default_account",
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Default Account",
|
||||
"label": "Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"fetch_from": "default_account.account_currency",
|
||||
"fieldname": "account_currency",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Account Currency",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-09-30 13:50:06.809353",
|
||||
"modified": "2020-10-18 17:57:57.110257",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Salary Component Account",
|
||||
|
||||
@@ -18,12 +18,13 @@ frappe.ui.form.on('Employee Advance', {
|
||||
if (!frm.doc.employee) {
|
||||
frappe.msgprint(__("Please select employee first"))
|
||||
}
|
||||
var company_currency = erpnext.get_currency(frm.doc.company);
|
||||
return {
|
||||
filters: {
|
||||
"root_type": "Asset",
|
||||
"is_group": 0,
|
||||
"company": frm.doc.company,
|
||||
"account_currency": frm.doc.currency,
|
||||
"account_currency": ["in",[frm.doc.currency, company_currency]],
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -142,33 +143,39 @@ frappe.ui.form.on('Employee Advance', {
|
||||
|
||||
employee: function (frm) {
|
||||
if (frm.doc.employee) {
|
||||
frappe.call({
|
||||
method: "erpnext.hr.doctype.employee_advance.employee_advance.get_pending_amount",
|
||||
args: {
|
||||
"employee": frm.doc.employee,
|
||||
"posting_date": frm.doc.posting_date
|
||||
},
|
||||
callback: function(r) {
|
||||
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()
|
||||
}
|
||||
}
|
||||
});
|
||||
frm.trigger('get_pending_amount');
|
||||
frm.trigger('get_employee_currency');
|
||||
}
|
||||
},
|
||||
|
||||
get_pending_amount: function(frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.hr.doctype.employee_advance.employee_advance.get_pending_amount",
|
||||
args: {
|
||||
"employee": frm.doc.employee,
|
||||
"posting_date": frm.doc.posting_date
|
||||
},
|
||||
callback: function(r) {
|
||||
frm.set_value("pending_amount",r.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
get_employee_currency: function(frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_employee_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('currency', r.message);
|
||||
frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
currency: function(frm) {
|
||||
var from_currency = frm.doc.currency;
|
||||
if (!frm.doc.company) {
|
||||
@@ -177,26 +184,15 @@ frappe.ui.form.on('Employee Advance', {
|
||||
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 {
|
||||
if(from_currency == company_currency) {
|
||||
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();
|
||||
} else {
|
||||
frm.set_value("exchange_rate", '');
|
||||
frm.set_df_property('exchange_rate', 'hidden', 0);
|
||||
frm.set_df_property("exchange_rate", "description", "1 " + frm.doc.currency + " = [?] " + company_currency);
|
||||
}
|
||||
frm.refresh_fields();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -197,13 +197,12 @@
|
||||
"label": "Exchange Rate",
|
||||
"precision": "9",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-09-30 19:05:42.364629",
|
||||
"modified": "2020-10-22 03:48:09.386149",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Employee Advance",
|
||||
|
||||
@@ -19,7 +19,6 @@ class EmployeeAdvance(Document):
|
||||
|
||||
def validate(self):
|
||||
self.set_status()
|
||||
# self.validate_employee_advance_account()
|
||||
|
||||
def on_cancel(self):
|
||||
self.ignore_linked_doctypes = ('GL Entry')
|
||||
@@ -38,32 +37,42 @@ 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 set_total_advance_paid(self):
|
||||
paid_amount = frappe.db.sql("""
|
||||
select ifnull(sum(debit_in_account_currency), 0) as paid_amount
|
||||
paid_amount = 0
|
||||
return_amount = 0
|
||||
|
||||
paid_amount_data = frappe.db.sql("""
|
||||
select debit_in_account_currency as paid_amount, account
|
||||
from `tabGL Entry`
|
||||
where against_voucher_type = 'Employee Advance'
|
||||
and against_voucher = %s
|
||||
and party_type = 'Employee'
|
||||
and party = %s
|
||||
""", (self.name, self.employee), as_dict=1)[0].paid_amount
|
||||
""", (self.name, self.employee), as_dict=1)
|
||||
|
||||
return_amount = frappe.db.sql("""
|
||||
select name, ifnull(sum(credit_in_account_currency), 0) as return_amount
|
||||
return_amount_data = frappe.db.sql("""
|
||||
select credit_in_account_currency as return_amount, account
|
||||
from `tabGL Entry`
|
||||
where against_voucher_type = 'Employee Advance'
|
||||
and voucher_type != 'Expense Claim'
|
||||
and against_voucher = %s
|
||||
and party_type = 'Employee'
|
||||
and party = %s
|
||||
""", (self.name, self.employee), as_dict=1)[0].return_amount
|
||||
""", (self.name, self.employee), as_dict=1)
|
||||
|
||||
for pmd in paid_amount_data:
|
||||
account_currency = frappe.db.get_value('Account', pmd.account, 'account_currency')
|
||||
if account_currency != self.currency:
|
||||
paid_amount += flt(pmd.paid_amount) / flt(self.exchange_rate)
|
||||
else:
|
||||
paid_amount += flt(pmd.paid_amount)
|
||||
|
||||
for rmd in return_amount_data:
|
||||
account_currency = frappe.db.get_value('Account', rmd.account, 'account_currency')
|
||||
if account_currency != self.currency:
|
||||
return_amount += flt(rmd.paid_amount) / flt(self.exchange_rate)
|
||||
else:
|
||||
return_amount += flt(rmd.paid_amount)
|
||||
|
||||
if flt(paid_amount) > self.advance_amount:
|
||||
frappe.throw(_("Row {0}# Paid Amount cannot be greater than requested advance amount"),
|
||||
@@ -109,24 +118,26 @@ def make_bank_entry(dt, dn):
|
||||
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)
|
||||
|
||||
advance_account_currency = frappe.db.get_value('Account', doc.advance_account, 'account_currency')
|
||||
|
||||
if advance_account_currency != doc.currency:
|
||||
advance_amount = flt(doc.advance_amount) * flt(doc.exchange_rate)
|
||||
advance_exchange_rate = 1
|
||||
else:
|
||||
advance_amount = doc.advance_amount
|
||||
advance_exchange_rate = doc.exchange_rate
|
||||
|
||||
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)
|
||||
paying_amount = flt(doc.advance_amount) * flt(doc.exchange_rate)
|
||||
paying_exchange_rate = 1
|
||||
else:
|
||||
paying_amount = doc.advance_amount
|
||||
paying_exchange_rate = 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)
|
||||
multi_currency = 0
|
||||
if advance_account_currency != payment_account.account_currency:
|
||||
multi_currency = 1
|
||||
|
||||
je = frappe.new_doc("Journal Entry")
|
||||
je.posting_date = nowdate()
|
||||
@@ -137,9 +148,9 @@ def make_bank_entry(dt, dn):
|
||||
|
||||
je.append("accounts", {
|
||||
"account": doc.advance_account,
|
||||
"account_currency": doc.currency,
|
||||
"exchange_rate": doc.exchange_rate,
|
||||
"debit_in_account_currency": flt(doc.advance_amount),
|
||||
"account_currency": advance_account_currency,
|
||||
"exchange_rate": flt(advance_exchange_rate),
|
||||
"debit_in_account_currency": flt(advance_amount),
|
||||
"reference_type": "Employee Advance",
|
||||
"reference_name": doc.name,
|
||||
"party_type": "Employee",
|
||||
@@ -151,9 +162,10 @@ 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": credit_in_account_currency,
|
||||
"credit_in_account_currency": flt(paying_amount),
|
||||
"account_currency": payment_account.account_currency,
|
||||
"account_type": payment_account.account_type
|
||||
"account_type": payment_account.account_type,
|
||||
"exchange_rate": flt(paying_exchange_rate)
|
||||
})
|
||||
|
||||
return je.as_dict()
|
||||
@@ -177,22 +189,28 @@ def make_return_entry(employee, company, employee_advance_name, return_amount,
|
||||
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)
|
||||
|
||||
advance_account_currency = frappe.db.get_value('Account', advance_account, 'account_currency')
|
||||
|
||||
employee_advance_doc = frappe.get_doc("Employee Advance", employee_advance_name)
|
||||
multi_currency = 0
|
||||
exchange_rate = 1
|
||||
|
||||
if advance_account_currency != employee_advance_doc.currency:
|
||||
advance_amount = flt(return_amount) * flt(employee_advance_doc.exchange_rate)
|
||||
advance_exchange_rate = 1
|
||||
else:
|
||||
advance_amount = return_amount
|
||||
advance_exchange_rate = employee_advance_doc.exchange_rate
|
||||
|
||||
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
|
||||
returning_amount = flt(return_amount) * flt(employee_advance_doc.exchange_rate)
|
||||
returning_exchange_rate = 1
|
||||
else:
|
||||
returning_amount = return_amount
|
||||
returning_exchange_rate = employee_advance_doc.exchange_rate
|
||||
|
||||
multi_currency = 0
|
||||
if advance_account_currency != return_account.account_currency:
|
||||
multi_currency = 1
|
||||
|
||||
mode_of_payment_type = ''
|
||||
if mode_of_payment:
|
||||
@@ -211,9 +229,9 @@ def make_return_entry(employee, company, employee_advance_name, return_amount,
|
||||
|
||||
je.append('accounts', {
|
||||
'account': advance_account,
|
||||
'credit_in_account_currency': return_amount,
|
||||
'account_currency': employee_advance_doc.currency,
|
||||
'exchange_rate': exchange_rate,
|
||||
'credit_in_account_currency': advance_amount,
|
||||
'account_currency': advance_account_currency,
|
||||
'exchange_rate': advance_exchange_rate,
|
||||
'reference_type': 'Employee Advance',
|
||||
'reference_name': employee_advance_name,
|
||||
'party_type': 'Employee',
|
||||
@@ -223,9 +241,10 @@ def make_return_entry(employee, company, employee_advance_name, return_amount,
|
||||
|
||||
je.append("accounts", {
|
||||
"account": return_account.account,
|
||||
"debit_in_account_currency": flt(return_amount) * exchange_rate,
|
||||
"debit_in_account_currency": returning_amount,
|
||||
"account_currency": return_account.account_currency,
|
||||
"account_type": return_account.account_type
|
||||
"account_type": return_account.account_type,
|
||||
"exchange_rate": returning_exchange_rate
|
||||
})
|
||||
|
||||
return je.as_dict()
|
||||
|
||||
@@ -23,6 +23,7 @@ frappe.ui.form.on('Leave Encashment', {
|
||||
},
|
||||
employee: function(frm) {
|
||||
frm.trigger("get_leave_details_for_encashment");
|
||||
frm.trigger('get_employee_currency');
|
||||
},
|
||||
leave_type: function(frm) {
|
||||
frm.trigger("get_leave_details_for_encashment");
|
||||
@@ -37,21 +38,23 @@ 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();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
get_employee_currency: function(frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_employee_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('currency', r.message);
|
||||
frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -130,9 +130,9 @@
|
||||
},
|
||||
{
|
||||
"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,
|
||||
@@ -146,7 +146,7 @@
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-09-24 19:21:56.856605",
|
||||
"modified": "2020-10-20 17:44:14.590652",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Leave Encashment",
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
"disbursed_amount",
|
||||
"column_break_11",
|
||||
"maximum_loan_amount",
|
||||
"is_term_loan",
|
||||
"repayment_method",
|
||||
"repayment_periods",
|
||||
"monthly_repayment_amount",
|
||||
"repayment_start_date",
|
||||
"is_term_loan",
|
||||
"account_info",
|
||||
"mode_of_payment",
|
||||
"payment_account",
|
||||
@@ -334,7 +334,7 @@
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-08-01 12:36:11.255233",
|
||||
"modified": "2020-10-21 13:30:51.709754",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Loan Management",
|
||||
"name": "Loan",
|
||||
|
||||
@@ -12,6 +12,8 @@ from erpnext.controllers.accounts_controller import AccountsController
|
||||
|
||||
class Loan(AccountsController):
|
||||
def validate(self):
|
||||
if self.applicant_type == 'Employee':
|
||||
validate_employe_currency_with_company_currency(self.applicant, self.company)
|
||||
self.set_loan_amount()
|
||||
self.validate_loan_amount()
|
||||
self.set_missing_fields()
|
||||
@@ -274,5 +276,14 @@ def create_loan_security_unpledge(unpledge_map, loan, company, applicant_type, a
|
||||
|
||||
return unpledge_request
|
||||
|
||||
|
||||
|
||||
def validate_employe_currency_with_company_currency(applicant, company):
|
||||
from erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment import get_employee_currency
|
||||
if not applicant:
|
||||
frappe.throw(_("Please select Applicant"))
|
||||
if not company:
|
||||
frappe.throw(_("Please select Company"))
|
||||
employee_currency = get_employee_currency(applicant)
|
||||
company_currency = erpnext.get_company_currency(company)
|
||||
if employee_currency != company_currency:
|
||||
frappe.throw(_("Currency in salary structure for employee {0} should be in {1}")
|
||||
.format(applicant, company_currency))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, math
|
||||
import frappe, math, erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import flt, rounded, cint
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
@@ -16,6 +16,9 @@ from six import string_types
|
||||
|
||||
class LoanApplication(Document):
|
||||
def validate(self):
|
||||
if self.applicant_type == 'Employee':
|
||||
from erpnext.loan_management.doctype.loan.loan import validate_employe_currency_with_company_currency
|
||||
validate_employe_currency_with_company_currency(self.applicant, self.company)
|
||||
self.set_pledge_amount()
|
||||
self.set_loan_amount()
|
||||
self.validate_loan_amount()
|
||||
|
||||
@@ -12,6 +12,9 @@ from erpnext.loan_management.doctype.loan_security_price.loan_security_price imp
|
||||
|
||||
class LoanSecurityPledge(Document):
|
||||
def validate(self):
|
||||
if self.applicant_type == 'Employee':
|
||||
from erpnext.loan_management.doctype.loan.loan import validate_employe_currency_with_company_currency
|
||||
validate_employe_currency_with_company_currency(self.applicant, self.company)
|
||||
self.set_pledge_amount()
|
||||
self.validate_duplicate_securities()
|
||||
self.validate_loan_security_type()
|
||||
|
||||
@@ -13,6 +13,9 @@ from erpnext.loan_management.doctype.loan_security_price.loan_security_price imp
|
||||
|
||||
class LoanSecurityUnpledge(Document):
|
||||
def validate(self):
|
||||
if self.applicant_type == 'Employee':
|
||||
from erpnext.loan_management.doctype.loan.loan import validate_employe_currency_with_company_currency
|
||||
validate_employe_currency_with_company_currency(self.applicant, self.company)
|
||||
self.validate_duplicate_securities()
|
||||
self.validate_unpledge_qty()
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ from frappe.model.document import Document
|
||||
|
||||
class SanctionedLoanAmount(Document):
|
||||
def validate(self):
|
||||
if self.applicant_type == 'Employee':
|
||||
from erpnext.loan_management.doctype.loan.loan import validate_employe_currency_with_company_currency
|
||||
validate_employe_currency_with_company_currency(self.applicant, self.company)
|
||||
sanctioned_doc = frappe.db.exists('Sanctioned Loan Amount', {'applicant': self.applicant, 'company': self.company})
|
||||
|
||||
if sanctioned_doc and sanctioned_doc != self.name:
|
||||
|
||||
@@ -23,37 +23,44 @@ frappe.ui.form.on('Additional Salary', {
|
||||
},
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
frm.trigger('set_company');
|
||||
frm.trigger('get_employee_currency');
|
||||
} else {
|
||||
frm.set_value("company", null);
|
||||
}
|
||||
},
|
||||
|
||||
set_company: function(frm) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
get_employee_currency: function(frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_employee_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('currency', r.message);
|
||||
frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -164,9 +164,9 @@
|
||||
},
|
||||
{
|
||||
"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,
|
||||
@@ -176,7 +176,7 @@
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-09-24 12:55:51.660506",
|
||||
"modified": "2020-10-20 17:51:13.419716",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Additional Salary",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
frappe.ui.form.on('Employee Benefit Application', {
|
||||
employee: function(frm) {
|
||||
frm.trigger('get_employee_currency');
|
||||
frm.trigger('set_earning_component');
|
||||
var method, args;
|
||||
if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){
|
||||
@@ -36,9 +37,12 @@ frappe.ui.form.on('Employee Benefit Application', {
|
||||
filters: {date: frm.doc.date, employee: frm.doc.employee}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
get_employee_currency: function(frm) {
|
||||
if (frm.doc.employee) {
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_payroll_payable_account_currency",
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_employee_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
@@ -70,7 +74,6 @@ frappe.ui.form.on('Employee Benefit Application', {
|
||||
});
|
||||
|
||||
var get_max_benefits=function(frm, method, args) {
|
||||
debugger;
|
||||
frappe.call({
|
||||
method: method,
|
||||
args: args,
|
||||
|
||||
@@ -14,7 +14,7 @@ frappe.ui.form.on('Employee Benefit Claim', {
|
||||
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",
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_employee_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
|
||||
@@ -22,37 +22,44 @@ frappe.ui.form.on('Employee Incentive', {
|
||||
},
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
frm.trigger('set_company');
|
||||
frm.trigger('get_employee_currency');
|
||||
} else {
|
||||
frm.set_value("company", null);
|
||||
}
|
||||
},
|
||||
|
||||
set_company: function(frm) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
get_employee_currency: function(frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_employee_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('currency', r.message);
|
||||
frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -79,7 +79,6 @@
|
||||
"depends_on": "eval:(doc.docstatus==1 || doc.employee)",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"print_hide": 1,
|
||||
@@ -96,7 +95,7 @@
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-09-30 17:59:57.754477",
|
||||
"modified": "2020-10-20 17:22:16.468042",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Employee Incentive",
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"column_break_2",
|
||||
"payroll_period",
|
||||
"company",
|
||||
"currency",
|
||||
"amended_from",
|
||||
"section_break_8",
|
||||
"declarations",
|
||||
@@ -92,6 +93,7 @@
|
||||
"fieldname": "total_declared_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Declared Amount",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -102,12 +104,22 @@
|
||||
"fieldname": "total_exemption_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Exemption Amount",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "Company:company:default_currency",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"print_hide": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 22:49:43.829892",
|
||||
"modified": "2020-10-20 16:42:24.493761",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Employee Tax Exemption Declaration",
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Maximum Exempted Amount",
|
||||
"options": "currency",
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
@@ -43,12 +44,13 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Declared Amount",
|
||||
"options": "currency",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 23:41:03.638739",
|
||||
"modified": "2020-10-20 16:43:09.606265",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Employee Tax Exemption Declaration Category",
|
||||
|
||||
@@ -54,5 +54,9 @@ frappe.ui.form.on('Employee Tax Exemption Proof Submission', {
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
currency: function(frm) {
|
||||
frm.refresh_fields();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"employee",
|
||||
"employee_name",
|
||||
"department",
|
||||
"currency",
|
||||
"column_break_2",
|
||||
"submission_date",
|
||||
"payroll_period",
|
||||
@@ -97,6 +98,7 @@
|
||||
"fieldname": "total_actual_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Actual Amount",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -107,6 +109,7 @@
|
||||
"fieldname": "exemption_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Exemption Amount",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -126,11 +129,20 @@
|
||||
"options": "Employee Tax Exemption Proof Submission",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "Company:company:default_currency",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"print_hide": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 22:53:10.412321",
|
||||
"modified": "2020-10-20 16:47:03.410020",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Employee Tax Exemption Proof Submission",
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Maximum Exemption Amount",
|
||||
"options": "currency",
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
@@ -48,12 +49,13 @@
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Actual Amount"
|
||||
"label": "Actual Amount",
|
||||
"options": "currency"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 23:37:08.265600",
|
||||
"modified": "2020-10-20 16:47:31.480870",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Employee Tax Exemption Proof Submission Detail",
|
||||
|
||||
@@ -2,5 +2,7 @@
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Income Tax Slab', {
|
||||
|
||||
currency: function(frm) {
|
||||
frm.refresh_fields();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
"effective_from",
|
||||
"company",
|
||||
"column_break_3",
|
||||
"allow_tax_exemption",
|
||||
"currency",
|
||||
"standard_tax_exemption_amount",
|
||||
"allow_tax_exemption",
|
||||
"disabled",
|
||||
"amended_from",
|
||||
"taxable_salary_slabs_section",
|
||||
@@ -70,7 +71,7 @@
|
||||
"fieldname": "standard_tax_exemption_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Standard Tax Exemption Amount",
|
||||
"options": "Company:company:default_currency"
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
@@ -90,11 +91,20 @@
|
||||
"fieldtype": "Table",
|
||||
"label": "Other Taxes and Charges",
|
||||
"options": "Income Tax Slab Other Charges"
|
||||
},
|
||||
{
|
||||
"default": "Company:company:default_currency",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"print_hide": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 20:27:13.425084",
|
||||
"modified": "2020-10-19 13:54:24.728075",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Income Tax Slab",
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Min Taxable Income",
|
||||
"options": "Company:company:default_currency"
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_7",
|
||||
@@ -57,12 +57,12 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Max Taxable Income",
|
||||
"options": "Company:company:default_currency"
|
||||
"options": "currency"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 23:33:17.931912",
|
||||
"modified": "2020-10-19 13:45:12.850090",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Income Tax Slab Other Charges",
|
||||
|
||||
@@ -24,7 +24,6 @@ frappe.ui.form.on('Payroll Entry', {
|
||||
"company": frm.doc.company,
|
||||
"root_type": "Liability",
|
||||
"is_group": 0,
|
||||
"account_currency": frm.doc.currency
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -151,7 +150,6 @@ frappe.ui.form.on('Payroll Entry', {
|
||||
},
|
||||
|
||||
currency: function (frm) {
|
||||
debugger;
|
||||
if (!frm.doc.company) {
|
||||
var company_currency = erpnext.get_currency(frappe.defaults.get_default("Company"));
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
"depends_on": "company",
|
||||
"fieldname": "default_payroll_payable_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Default Payroll Payable Account",
|
||||
"label": "Payroll Payable Account",
|
||||
"options": "Account",
|
||||
"reqd": 1
|
||||
}
|
||||
@@ -290,7 +290,7 @@
|
||||
"icon": "fa fa-cog",
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-09-30 12:47:45.729777",
|
||||
"modified": "2020-10-22 01:57:27.226066",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Payroll Entry",
|
||||
|
||||
@@ -125,7 +125,8 @@ class PayrollEntry(Document):
|
||||
"posting_date": self.posting_date,
|
||||
"deduct_tax_for_unclaimed_employee_benefits": self.deduct_tax_for_unclaimed_employee_benefits,
|
||||
"deduct_tax_for_unsubmitted_tax_exemption_proof": self.deduct_tax_for_unsubmitted_tax_exemption_proof,
|
||||
"payroll_entry": self.name
|
||||
"payroll_entry": self.name,
|
||||
"exchange_rate": self.exchange_rate
|
||||
})
|
||||
if len(emp_list) > 30:
|
||||
frappe.enqueue(create_salary_slips_for_employees, timeout=600, employees=emp_list, args=args)
|
||||
@@ -205,21 +206,10 @@ class PayrollEntry(Document):
|
||||
account_dict[(account, key[1])] = account_dict.get((account, key[1]), 0) + amount
|
||||
return account_dict
|
||||
|
||||
def get_default_payroll_payable_account(self):
|
||||
payroll_payable_account = frappe.get_cached_value('Company',
|
||||
{"company_name": self.company}, "default_payroll_payable_account")
|
||||
|
||||
if not payroll_payable_account:
|
||||
frappe.throw(_("Please set Default Payroll Payable Account in Company {0}")
|
||||
.format(self.company))
|
||||
|
||||
return payroll_payable_account
|
||||
|
||||
def make_accrual_jv_entry(self):
|
||||
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.default_payroll_payable_account
|
||||
jv_name = ""
|
||||
precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")
|
||||
@@ -329,7 +319,6 @@ 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.default_payroll_payable_account
|
||||
precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")
|
||||
|
||||
@@ -528,6 +517,25 @@ def create_salary_slips_for_employees(employees, args, publish_progress=True):
|
||||
if publish_progress:
|
||||
frappe.publish_progress(count*100/len(set(employees) - set(salary_slips_exists_for)),
|
||||
title = _("Creating Salary Slips..."))
|
||||
else:
|
||||
salary_slip_name = frappe.db.sql(
|
||||
'''SELECT
|
||||
name
|
||||
FROM
|
||||
`tabSalary Slip`
|
||||
WHERE
|
||||
company=%s
|
||||
AND
|
||||
start_date >= %s
|
||||
AND
|
||||
end_date <= %s
|
||||
AND
|
||||
employee = %s
|
||||
''', (args.company, args.start_date, args.end_date, emp), as_dict=True)
|
||||
|
||||
salary_slip_doc = frappe.get_doc('Salary Slip', salary_slip_name[0].name)
|
||||
salary_slip_doc.exchange_rate = args.exchange_rate
|
||||
salary_slip_doc.set_base_amounts_after_exchange_rate_change()
|
||||
|
||||
payroll_entry = frappe.get_doc("Payroll Entry", args.payroll_entry)
|
||||
payroll_entry.db_set("salary_slips_created", 1)
|
||||
|
||||
@@ -18,5 +18,22 @@ frappe.ui.form.on('Retention Bonus', {
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
employee: function(frm) {
|
||||
if (frm.doc.employee) {
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_employee_currency",
|
||||
args: {
|
||||
employee: frm.doc.employee,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('currency', r.message);
|
||||
frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
"column_break_6",
|
||||
"employee_name",
|
||||
"department",
|
||||
"date_of_joining"
|
||||
"date_of_joining",
|
||||
"currency"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -46,6 +47,7 @@
|
||||
"fieldname": "bonus_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Bonus Amount",
|
||||
"options": "currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -89,11 +91,22 @@
|
||||
"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",
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 22:42:05.251951",
|
||||
"modified": "2020-10-20 17:27:47.003134",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Retention Bonus",
|
||||
@@ -151,7 +164,6 @@
|
||||
"share": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
|
||||
@@ -73,42 +73,67 @@ frappe.ui.form.on("Salary Slip", {
|
||||
var company = locals[':Company'][frm.doc.company];
|
||||
if(!frm.doc.letter_head && company.default_letter_head) {
|
||||
frm.set_value('letter_head', company.default_letter_head);
|
||||
}
|
||||
};
|
||||
frm.trigger("set_dynamic_labels")
|
||||
},
|
||||
|
||||
currency: function(frm) {
|
||||
calculate_totals(frm.doc);
|
||||
calculate_totals(frm);
|
||||
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");
|
||||
|
||||
var company_currency = frm.doc.company? erpnext.get_currency(frm.doc.company): frappe.defaults.get_default("currency");
|
||||
// frm.events.set_exchange_rate(frm, company_currency);
|
||||
if (frm.doc.currency && company_currency!=frm.doc.currency) {
|
||||
frm.events.hide_loan_section(frm);
|
||||
}
|
||||
frm.events.change_form_labels(frm, company_currency);
|
||||
frm.events.change_grid_labels(frm, company_currency);
|
||||
frm.refresh_fields();
|
||||
},
|
||||
|
||||
exchange_rate: function(frm) {
|
||||
calculate_totals(frm);
|
||||
},
|
||||
|
||||
hide_loan_section: function(frm) {
|
||||
frm.set_df_property('section_break_43', 'hidden', 1);
|
||||
},
|
||||
|
||||
change_form_labels: function(frm, company_currency) {
|
||||
frm.set_currency_labels(["base_hour_rate", "base_gross_pay", "base_total_deduction",
|
||||
"base_net_pay", "base_rounded_total", "base_total_in_words"],
|
||||
company_currency);
|
||||
|
||||
frm.set_currency_labels(["hour_rate", "gross_pay", "total_deduction", "net_pay", "rounded_total", "total_in_words"],
|
||||
frm.doc.currency);
|
||||
|
||||
cur_frm.set_df_property("exchange_rate", "description", "1 " + frm.doc.currency
|
||||
+ " = [?] " + company_currency);
|
||||
|
||||
// toggle fields
|
||||
frm.toggle_display(["exchange_rate", "base_hour_rate", "base_gross_pay", "base_total_deduction",
|
||||
"base_net_pay", "base_rounded_total", "base_total_in_words"],
|
||||
frm.doc.currency != company_currency);
|
||||
},
|
||||
|
||||
change_grid_labels: function(frm, company_currency) {
|
||||
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");
|
||||
},
|
||||
|
||||
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);
|
||||
frm.fields_dict['earnings'].grid.set_column_disp(salary_detail_fields,false);
|
||||
frm.fields_dict['deductions'].grid.set_column_disp(salary_detail_fields,false);
|
||||
calculate_totals(frm);
|
||||
frm.trigger("set_dynamic_labels")
|
||||
},
|
||||
|
||||
salary_slip_based_on_timesheet: function(frm) {
|
||||
@@ -145,104 +170,56 @@ 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,
|
||||
callback: function(r, rt) {
|
||||
frm.refresh();
|
||||
if (r.message){
|
||||
frm.fields_dict.absent_days.set_description("Unmarked Days is treated as "+ r.message +". You can can change this in " + frappe.utils.get_form_link("Payroll Settings", "Payroll Settings", true));
|
||||
if (frm.doc.employee) {
|
||||
return frappe.call({
|
||||
method: 'get_emp_and_working_day_details',
|
||||
doc: frm.doc,
|
||||
callback: function(r) {
|
||||
if (r.message){
|
||||
frm.fields_dict.absent_days.set_description("Unmarked Days is treated as "+ r.message +". You can can change this in " + frappe.utils.get_form_link("Payroll Settings", "Payroll Settings", true));
|
||||
}
|
||||
frm.refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on('Salary Slip Timesheet', {
|
||||
time_sheet: function(frm, dt, dn) {
|
||||
total_work_hours(frm, dt, dn);
|
||||
time_sheet: function(frm) {
|
||||
calculate_totals(frm);
|
||||
},
|
||||
timesheets_remove: function(frm, dt, dn) {
|
||||
total_work_hours(frm, dt, dn);
|
||||
timesheets_remove: function(frm) {
|
||||
calculate_totals(frm);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
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;
|
||||
});
|
||||
frm.set_value('total_working_hours', total_working_hours);
|
||||
|
||||
var wages_amount = frm.doc.total_working_hours * frm.doc.hour_rate;
|
||||
|
||||
frappe.db.get_value('Salary Structure', {'name': frm.doc.salary_structure}, 'salary_component', (r) => {
|
||||
var gross_pay = 0.0;
|
||||
$.each(frm.doc["earnings"], function(i, earning) {
|
||||
if (earning.salary_component == r.salary_component) {
|
||||
earning.amount = wages_amount;
|
||||
frm.refresh_fields('earnings');
|
||||
}
|
||||
gross_pay += earning.amount;
|
||||
});
|
||||
frm.set_value('gross_pay', gross_pay);
|
||||
|
||||
frm.doc.net_pay = flt(frm.doc.gross_pay) - flt(frm.doc.total_deduction);
|
||||
frm.doc.rounded_total = Math.round(frm.doc.net_pay);
|
||||
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);
|
||||
var calculate_totals = function(frm) {
|
||||
if (frm.doc.earnings || frm.doc.deductions) {
|
||||
frappe.call({
|
||||
method: "set_totals",
|
||||
doc: frm.doc,
|
||||
callback: function(r) {
|
||||
frm.refresh_fields()
|
||||
}
|
||||
})
|
||||
}
|
||||
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);
|
||||
calculate_totals(frm);
|
||||
},
|
||||
|
||||
earnings_remove: function(frm) {
|
||||
calculate_totals(frm.doc);
|
||||
calculate_totals(frm);
|
||||
},
|
||||
|
||||
deductions_remove: function(frm) {
|
||||
calculate_totals(frm.doc);
|
||||
calculate_totals(frm);
|
||||
},
|
||||
|
||||
salary_component: function(frm, cdt, cdn) {
|
||||
debugger;
|
||||
var child = locals[cdt][cdn];
|
||||
if(child.salary_component){
|
||||
frappe.call({
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"payroll_entry",
|
||||
"company",
|
||||
"currency",
|
||||
"exchange_rate",
|
||||
"letter_head",
|
||||
"section_break_10",
|
||||
"start_date",
|
||||
@@ -39,6 +40,7 @@
|
||||
"column_break_20",
|
||||
"total_working_hours",
|
||||
"hour_rate",
|
||||
"base_hour_rate",
|
||||
"section_break_26",
|
||||
"bank_name",
|
||||
"bank_account_no",
|
||||
@@ -53,8 +55,10 @@
|
||||
"deductions",
|
||||
"totals",
|
||||
"gross_pay",
|
||||
"base_gross_pay",
|
||||
"column_break_25",
|
||||
"total_deduction",
|
||||
"base_total_deduction",
|
||||
"loan_repayment",
|
||||
"loans",
|
||||
"section_break_43",
|
||||
@@ -64,10 +68,14 @@
|
||||
"total_loan_repayment",
|
||||
"net_pay_info",
|
||||
"net_pay",
|
||||
"base_net_pay",
|
||||
"column_break_53",
|
||||
"rounded_total",
|
||||
"base_rounded_total",
|
||||
"section_break_55",
|
||||
"total_in_words",
|
||||
"column_break_69",
|
||||
"base_total_in_words",
|
||||
"section_break_75",
|
||||
"amended_from"
|
||||
],
|
||||
@@ -374,6 +382,7 @@
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.docstatus != 0",
|
||||
"fieldname": "section_break_43",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
@@ -411,7 +420,6 @@
|
||||
"label": "net pay info"
|
||||
},
|
||||
{
|
||||
"description": "Gross Pay - Total Deduction - Loan Repayment",
|
||||
"fieldname": "net_pay",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Net Pay",
|
||||
@@ -505,7 +513,6 @@
|
||||
"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",
|
||||
@@ -515,13 +522,69 @@
|
||||
{
|
||||
"fieldname": "section_break_75",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "base_hour_rate",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Hour Rate (Company Currency)",
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide_if_no_value": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "base_gross_pay",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Gross Pay (Company Currency)",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "1.0",
|
||||
"fieldname": "exchange_rate",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 1,
|
||||
"label": "Exchange Rate",
|
||||
"print_hide": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "base_total_deduction",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Deduction (Company Currency)",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "base_net_pay",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Net Pay (Company Currency)",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"bold": 1,
|
||||
"fieldname": "base_rounded_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rounded Total (Company Currency)",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "base_total_in_words",
|
||||
"fieldtype": "Data",
|
||||
"label": "Total in words (Company Currency)",
|
||||
"length": 240,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_69",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-file-text",
|
||||
"idx": 9,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-09-30 17:31:21.909671",
|
||||
"modified": "2020-10-21 23:02:59.400249",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Salary Slip",
|
||||
|
||||
@@ -50,16 +50,20 @@ class SalarySlip(TransactionBase):
|
||||
|
||||
self.calculate_net_pay()
|
||||
|
||||
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, 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")
|
||||
if self.salary_slip_based_on_timesheet and (self.total_working_hours > int(max_working_hours)):
|
||||
frappe.msgprint(_("Total working hours should not be greater than max working hours {0}").
|
||||
format(max_working_hours), alert=True)
|
||||
|
||||
def set_net_total_in_words(self):
|
||||
doc_currency = self.currency
|
||||
company_currency = erpnext.get_company_currency(self.company)
|
||||
total = self.net_pay if self.is_rounding_total_disabled() else self.rounded_total
|
||||
base_total = self.base_net_pay if self.is_rounding_total_disabled() else self.base_rounded_total
|
||||
self.total_in_words = money_in_words(total, doc_currency)
|
||||
self.base_total_in_words = money_in_words(base_total, company_currency)
|
||||
|
||||
def on_submit(self):
|
||||
if self.net_pay < 0:
|
||||
frappe.throw(_("Net Pay cannot be less than 0"))
|
||||
@@ -182,6 +186,7 @@ class SalarySlip(TransactionBase):
|
||||
if self.salary_slip_based_on_timesheet:
|
||||
self.salary_structure = self._salary_structure_doc.name
|
||||
self.hour_rate = self._salary_structure_doc.hour_rate
|
||||
self.base_hour_rate = flt(self.hour_rate) * flt(self.exchange_rate)
|
||||
self.total_working_hours = sum([d.working_hours or 0.0 for d in self.timesheets]) or 0.0
|
||||
wages_amount = self.hour_rate * self.total_working_hours
|
||||
|
||||
@@ -391,15 +396,45 @@ class SalarySlip(TransactionBase):
|
||||
if self.salary_structure:
|
||||
self.calculate_component_amounts("earnings")
|
||||
self.gross_pay = self.get_component_totals("earnings")
|
||||
self.base_gross_pay = flt(self.gross_pay) * flt(self.exchange_rate)
|
||||
|
||||
if self.salary_structure:
|
||||
self.calculate_component_amounts("deductions")
|
||||
self.total_deduction = self.get_component_totals("deductions")
|
||||
self.base_total_deduction = flt(self.total_deduction) * flt(self.exchange_rate)
|
||||
|
||||
self.set_loan_repayment()
|
||||
|
||||
self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
|
||||
self.rounded_total = rounded(self.net_pay)
|
||||
self.base_net_pay = flt(self.net_pay) * flt(self.exchange_rate)
|
||||
self.base_rounded_total = rounded(self.base_net_pay)
|
||||
if self.hour_rate:
|
||||
self.base_hour_rate = flt(self.hour_rate) * flt(self.exchange_rate)
|
||||
self.set_net_total_in_words()
|
||||
|
||||
def set_base_amounts_after_exchange_rate_change(self):
|
||||
self.db_set("exchange_rate", self.exchange_rate)
|
||||
base_gross_pay = flt(self.gross_pay) * flt(self.exchange_rate)
|
||||
self.db_set("base_gross_pay", base_gross_pay)
|
||||
base_total_deduction = flt(self.total_deduction) * flt(self.exchange_rate)
|
||||
self.db_set("base_total_deduction", base_total_deduction)
|
||||
base_net_pay = flt(self.net_pay) * flt(self.exchange_rate)
|
||||
self.db_set("base_net_pay", base_net_pay)
|
||||
base_rounded_total = rounded(self.base_net_pay)
|
||||
self.db_set("base_rounded_total", base_rounded_total)
|
||||
if self.hour_rate:
|
||||
base_hour_rate = flt(self.hour_rate) * flt(self.exchange_rate)
|
||||
self.db_set("base_hour_rate", base_hour_rate)
|
||||
doc_currency = self.currency
|
||||
company_currency = erpnext.get_company_currency(self.company)
|
||||
base_total = base_net_pay if self.is_rounding_total_disabled() else base_rounded_total
|
||||
base_total_in_words = money_in_words(base_total, company_currency)
|
||||
self.db_set("base_total_in_words", base_total_in_words)
|
||||
self.db_set("docstatus", 0)
|
||||
frappe.db.commit()
|
||||
self.docstatus = 0
|
||||
self.set_status()
|
||||
|
||||
def calculate_component_amounts(self, component_type):
|
||||
if not getattr(self, '_salary_structure_doc', None):
|
||||
@@ -1047,6 +1082,50 @@ class SalarySlip(TransactionBase):
|
||||
self.get_working_days_details(lwp=self.leave_without_pay)
|
||||
self.calculate_net_pay()
|
||||
|
||||
def set_totals(self):
|
||||
self.gross_pay = 0
|
||||
if self.salary_slip_based_on_timesheet == 1:
|
||||
self.calculate_total_for_salary_slip_based_on_timesheet()
|
||||
else:
|
||||
self.total_deduction = 0
|
||||
if self.earnings:
|
||||
for earning in self.earnings:
|
||||
self.gross_pay += flt(earning.amount)
|
||||
if self.deductions:
|
||||
for deduction in self.deductions:
|
||||
self.total_deduction += flt(deduction.amount)
|
||||
self.base_gross_pay = flt(self.gross_pay) * flt(self.exchange_rate)
|
||||
self.base_total_deduction = flt(self.total_deduction) * flt(self.exchange_rate)
|
||||
self.net_pay = flt(self.gross_pay) - flt(self.total_deduction) - flt(self.total_loan_repayment)
|
||||
self.rounded_total = rounded(self.net_pay)
|
||||
self.base_net_pay = flt(self.net_pay) * flt(self.exchange_rate)
|
||||
self.base_rounded_total = rounded(self.base_net_pay)
|
||||
self.set_net_total_in_words()
|
||||
|
||||
return
|
||||
|
||||
#calculate total working hours, earnings based on hourly wages and totals
|
||||
def calculate_total_for_salary_slip_based_on_timesheet(self):
|
||||
if self.timesheets:
|
||||
for timesheet in self.timesheets:
|
||||
if timesheet.working_hours:
|
||||
self.total_working_hours += timesheet.working_hours
|
||||
|
||||
wages_amount = self.total_working_hours * self.hour_rate
|
||||
self.base_hour_rate = flt(self.hour_rate) * flt(self.exchange_rate)
|
||||
salary_component = frappe.db.get_value('Salary Structure', {'name': self.salary_structure}, 'salary_component')
|
||||
if self.earnings:
|
||||
for i, earning in enumerate(self.earnings):
|
||||
if earning.salary_component == salary_component:
|
||||
self.earnings[i].amount = wages_amount
|
||||
self.gross_pay += self.earnings[i].amount
|
||||
self.base_gross_pay = flt(self.gross_pay) * flt(self.exchange_rate)
|
||||
self.base_total_deduction = flt(self.total_deduction) * flt(self.exchange_rate)
|
||||
self.net_pay = flt(self.gross_pay) - flt(self.total_deduction)
|
||||
self.rounded_total = rounded(self.net_pay)
|
||||
self.base_net_pay = flt(self.net_pay) * flt(self.exchange_rate)
|
||||
self.base_rounded_total = rounded(self.base_net_pay)
|
||||
|
||||
def unlink_ref_doc_from_salary_slip(ref_no):
|
||||
linked_ss = frappe.db.sql_list("""select name from `tabSalary Slip`
|
||||
where journal_entry=%s and docstatus < 2""", (ref_no))
|
||||
|
||||
@@ -79,16 +79,9 @@ frappe.ui.form.on('Salary Structure', {
|
||||
},
|
||||
|
||||
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");
|
||||
|
||||
@@ -255,7 +248,6 @@ cur_frm.cscript.amount = function(doc, cdt, cdn){
|
||||
};
|
||||
|
||||
var calculate_totals = function(doc) {
|
||||
debugger;
|
||||
var tbl1 = doc.earnings || [];
|
||||
var tbl2 = doc.deductions || [];
|
||||
|
||||
|
||||
@@ -23,25 +23,26 @@ frappe.ui.form.on('Salary Structure Assignment', {
|
||||
filters: {
|
||||
company: frm.doc.company,
|
||||
docstatus: 1,
|
||||
disabled: 0
|
||||
disabled: 0,
|
||||
currency: frm.doc.currency
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query("default_payroll_payable_account", function() {
|
||||
var company_currency = erpnext.get_currency(frm.doc.company);
|
||||
return {
|
||||
filters: {
|
||||
"company": frm.doc.company,
|
||||
"root_type": "Liability",
|
||||
"is_group": 0,
|
||||
"account_currency": frm.doc.currency
|
||||
"account_currency": ["in",[frm.doc.currency, company_currency]],
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
employee: function(frm) {
|
||||
debugger;
|
||||
if(frm.doc.employee){
|
||||
frappe.call({
|
||||
method: "frappe.client.get_value",
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
"depends_on": "salary_structure",
|
||||
"fieldname": "default_payroll_payable_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Default Payroll Payable Account",
|
||||
"label": "Payroll Payable Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
@@ -145,7 +145,7 @@
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-09-30 17:35:49.922227",
|
||||
"modified": "2020-10-21 22:43:55.208492",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Salary Structure Assignment",
|
||||
|
||||
@@ -13,7 +13,6 @@ 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,
|
||||
@@ -32,15 +31,6 @@ 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
|
||||
@@ -55,9 +45,8 @@ def get_assigned_salary_structure(employee, 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:
|
||||
def get_employee_currency(employee):
|
||||
employee_currency = frappe.db.get_value('Salary Structure Assignment', {'employee': employee}, 'currency')
|
||||
if not employee_currency:
|
||||
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
|
||||
return employee_currency
|
||||
@@ -19,13 +19,15 @@
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "From Amount",
|
||||
"options": "currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "to_amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "To Amount"
|
||||
"label": "To Amount",
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
@@ -53,7 +55,7 @@
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 18:16:07.596493",
|
||||
"modified": "2020-10-19 13:44:39.549337",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Taxable Salary Slab",
|
||||
|
||||
@@ -8,34 +8,47 @@ frappe.query_reports["Salary Register"] = {
|
||||
"label": __("From"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.datetime.add_months(frappe.datetime.get_today(),-1),
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
"fieldname":"to_date",
|
||||
"label": __("To"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.datetime.get_today(),
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"options": "Currency",
|
||||
"label": __("Currency"),
|
||||
"default": erpnext.get_currency(frappe.defaults.get_default("Company")),
|
||||
"width": "50px"
|
||||
},
|
||||
{
|
||||
"fieldname":"employee",
|
||||
"label": __("Employee"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Employee"
|
||||
"options": "Employee",
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
"fieldname":"company",
|
||||
"label": __("Company"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"default": frappe.defaults.get_user_default("Company")
|
||||
"default": frappe.defaults.get_user_default("Company"),
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
"fieldname":"docstatus",
|
||||
"label":__("Document Status"),
|
||||
"fieldtype":"Select",
|
||||
"options":["Draft", "Submitted", "Cancelled"],
|
||||
"default":"Submitted"
|
||||
"default":"Submitted",
|
||||
"width": "100px"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,18 +2,24 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
from frappe.utils import flt
|
||||
from frappe import _
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
salary_slips = get_salary_slips(filters)
|
||||
currency = None
|
||||
company_currency = None
|
||||
if filters.get('currency'):
|
||||
currency = filters.get('currency')
|
||||
if filters.get("company"):
|
||||
company_currency = erpnext.get_company_currency(filters.get("company"))
|
||||
salary_slips = get_salary_slips(filters, company_currency)
|
||||
if not salary_slips: return [], []
|
||||
|
||||
columns, earning_types, ded_types = get_columns(salary_slips)
|
||||
ss_earning_map = get_ss_earning_map(salary_slips)
|
||||
ss_ded_map = get_ss_ded_map(salary_slips)
|
||||
ss_earning_map = get_ss_earning_map(salary_slips, currency, company_currency)
|
||||
ss_ded_map = get_ss_ded_map(salary_slips,currency, company_currency)
|
||||
doj_map = get_employee_doj_map()
|
||||
|
||||
data = []
|
||||
@@ -30,14 +36,20 @@ def execute(filters=None):
|
||||
for e in earning_types:
|
||||
row.append(ss_earning_map.get(ss.name, {}).get(e))
|
||||
|
||||
row += [ss.gross_pay]
|
||||
if currency == company_currency:
|
||||
row += [flt(ss.gross_pay) * flt(ss.exchange_rate)]
|
||||
else:
|
||||
row += [ss.gross_pay]
|
||||
|
||||
for d in ded_types:
|
||||
row.append(ss_ded_map.get(ss.name, {}).get(d))
|
||||
|
||||
row.append(ss.total_loan_repayment)
|
||||
|
||||
row += [ss.total_deduction, ss.net_pay]
|
||||
if currency == company_currency:
|
||||
row += [flt(ss.total_deduction) * flt(ss.exchange_rate), flt(ss.net_pay) * flt(ss.exchange_rate)]
|
||||
else:
|
||||
row += [ss.total_deduction, ss.net_pay]
|
||||
|
||||
data.append(row)
|
||||
|
||||
@@ -73,15 +85,15 @@ def get_columns(salary_slips):
|
||||
|
||||
return columns, salary_components[_("Earning")], salary_components[_("Deduction")]
|
||||
|
||||
def get_salary_slips(filters):
|
||||
def get_salary_slips(filters, company_currency):
|
||||
filters.update({"from_date": filters.get("from_date"), "to_date":filters.get("to_date")})
|
||||
conditions, filters = get_conditions(filters)
|
||||
conditions, filters = get_conditions(filters, company_currency)
|
||||
salary_slips = frappe.db.sql("""select * from `tabSalary Slip` where %s
|
||||
order by employee""" % conditions, filters, as_dict=1)
|
||||
|
||||
return salary_slips or []
|
||||
|
||||
def get_conditions(filters):
|
||||
def get_conditions(filters, company_currency):
|
||||
conditions = ""
|
||||
doc_status = {"Draft": 0, "Submitted": 1, "Cancelled": 2}
|
||||
|
||||
@@ -92,6 +104,8 @@ def get_conditions(filters):
|
||||
if filters.get("to_date"): conditions += " and end_date <= %(to_date)s"
|
||||
if filters.get("company"): conditions += " and company = %(company)s"
|
||||
if filters.get("employee"): conditions += " and employee = %(employee)s"
|
||||
if filters.get("currency") and filters.get("currency") != company_currency:
|
||||
conditions += " and currency = %(currency)s"
|
||||
|
||||
return conditions, filters
|
||||
|
||||
@@ -103,26 +117,32 @@ def get_employee_doj_map():
|
||||
FROM `tabEmployee`
|
||||
"""))
|
||||
|
||||
def get_ss_earning_map(salary_slips):
|
||||
ss_earnings = frappe.db.sql("""select parent, salary_component, amount
|
||||
from `tabSalary Detail` where parent in (%s)""" %
|
||||
def get_ss_earning_map(salary_slips, currency, company_currency):
|
||||
ss_earnings = frappe.db.sql("""select sd.parent, sd.salary_component, sd.amount, ss.exchange_rate, ss.name
|
||||
from `tabSalary Detail` sd, `tabSalary Slip` ss where sd.parent=ss.name and sd.parent in (%s)""" %
|
||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
|
||||
|
||||
ss_earning_map = {}
|
||||
for d in ss_earnings:
|
||||
ss_earning_map.setdefault(d.parent, frappe._dict()).setdefault(d.salary_component, [])
|
||||
ss_earning_map[d.parent][d.salary_component] = flt(d.amount)
|
||||
if currency == company_currency:
|
||||
ss_earning_map[d.parent][d.salary_component] = flt(d.amount) * flt(d.exchange_rate if d.exchange_rate else 1)
|
||||
else:
|
||||
ss_earning_map[d.parent][d.salary_component] = flt(d.amount)
|
||||
|
||||
return ss_earning_map
|
||||
|
||||
def get_ss_ded_map(salary_slips):
|
||||
ss_deductions = frappe.db.sql("""select parent, salary_component, amount
|
||||
from `tabSalary Detail` where parent in (%s)""" %
|
||||
def get_ss_ded_map(salary_slips, currency, company_currency):
|
||||
ss_deductions = frappe.db.sql("""select sd.parent, sd.salary_component, sd.amount, ss.exchange_rate, ss.name
|
||||
from `tabSalary Detail` sd, `tabSalary Slip` ss where sd.parent=ss.name and sd.parent in (%s)""" %
|
||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
|
||||
|
||||
ss_ded_map = {}
|
||||
for d in ss_deductions:
|
||||
ss_ded_map.setdefault(d.parent, frappe._dict()).setdefault(d.salary_component, [])
|
||||
ss_ded_map[d.parent][d.salary_component] = flt(d.amount)
|
||||
if currency == company_currency:
|
||||
ss_ded_map[d.parent][d.salary_component] = flt(d.amount) * flt(d.exchange_rate if d.exchange_rate else 1)
|
||||
else:
|
||||
ss_ded_map[d.parent][d.salary_component] = flt(d.amount)
|
||||
|
||||
return ss_ded_map
|
||||
|
||||
Reference in New Issue
Block a user