feat: reverse linking and multiple additonal salaries in salary slip
diff --git a/erpnext/hr/doctype/additional_salary/additional_salary.py b/erpnext/hr/doctype/additional_salary/additional_salary.py
index d8f7444..4076ffe 100644
--- a/erpnext/hr/doctype/additional_salary/additional_salary.py
+++ b/erpnext/hr/doctype/additional_salary/additional_salary.py
@@ -9,6 +9,13 @@
from frappe.utils import getdate, date_diff
class AdditionalSalary(Document):
+
+ def on_submit(self):
+ if self.ref_doctype == "Employee Advance" and self.ref_docname:
+ emp_adv = frappe.get_doc(self.ref_doctype, self.ref_docname)
+ emp_adv.return_amount = self.amount
+ emp_adv.save()
+
def before_insert(self):
if frappe.db.exists("Additional Salary", {"employee": self.employee, "salary_component": self.salary_component,
"amount": self.amount, "payroll_date": self.payroll_date, "company": self.company, "docstatus": 1}):
@@ -49,8 +56,8 @@
@frappe.whitelist()
def get_additional_salary_component(employee, start_date, end_date, component_type):
- additional_components = frappe.db.sql("""
- select name, salary_component, amount, overwrite_salary_structure_amount, deduct_full_tax_on_selected_payroll_date
+ additional_salaries = frappe.db.sql("""
+ select name, salary_component, type, amount, overwrite_salary_structure_amount, deduct_full_tax_on_selected_payroll_date
from `tabAdditional Salary`
where employee=%(employee)s
and docstatus = 1
@@ -60,7 +67,7 @@
from_date <= %(to_date)s and to_date >= %(to_date)s
)
and type = %(component_type)s
- order by salary_component, overwrite_salary_structure_amount
+ order by salary_component, overwrite_salary_structure_amount DESC
""", {
'employee': employee,
'from_date': start_date,
@@ -68,26 +75,38 @@
'component_type': "Earning" if component_type == "earnings" else "Deduction"
}, as_dict=1)
- additional_components_list = []
- existing_salary_components = []
+ existing_salary_components= []
+ salary_components_details = {}
+ additional_salary_details = []
+
+ overwrites_components = [ele.salary_component for ele in additional_salaries if ele.overwrite_salary_structure_amount == 1]
+
component_fields = ["depends_on_payment_days", "salary_component_abbr", "is_tax_applicable", "variable_based_on_taxable_salary", 'type']
- for d in additional_components:
- if d.salary_component in existing_salary_components:
- frappe.throw(_('Multiple additional Salary is created for Salary Component {0}'.format(d.salary_component)))
- struct_row = frappe._dict({'salary_component': d.salary_component})
- component = frappe.get_all("Salary Component", filters={'name': d.salary_component}, fields=component_fields)
- if component:
- struct_row.update(component[0])
+ for d in additional_salaries:
- struct_row['deduct_full_tax_on_selected_payroll_date'] = d.deduct_full_tax_on_selected_payroll_date
- struct_row['is_additional_component'] = 1
- struct_row['additional_salary'] = d.name
+ if d.salary_component not in existing_salary_components:
+ component = frappe.get_all("Salary Component", filters={'name': d.salary_component}, fields=component_fields)
+ struct_row = frappe._dict({'salary_component': d.salary_component})
+ if component:
+ struct_row.update(component[0])
- additional_components_list.append(frappe._dict({
- 'amount': d.amount,
- 'type': component[0].type,
- 'struct_row': struct_row,
- 'overwrite': d.overwrite_salary_structure_amount,
- }))
+ struct_row['deduct_full_tax_on_selected_payroll_date'] = d.deduct_full_tax_on_selected_payroll_date
+ struct_row['is_additional_component'] = 1
+
+ salary_components_details[d.salary_component] = struct_row
+
+
+ if overwrites_components.count(d.salary_component) > 1:
+ frappe.throw(_("Multiple Additional Salaries with overwrite property exist for Salary Component: {0} between {1} and {2}.".format(d.salary_component, start_date, end_date)), title=_("Error"))
+ else:
+ additional_salary_details.append({
+ 'name': d.name,
+ 'component': d.salary_component,
+ 'amount': d.amount,
+ 'type': d.type,
+ 'overwrite': d.overwrite_salary_structure_amount,
+ })
+
existing_salary_components.append(d.salary_component)
- return additional_components_list
\ No newline at end of file
+
+ return salary_components_details, additional_salary_details
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.json b/erpnext/hr/doctype/employee_advance/employee_advance.json
index 1ab2356..8c5ce42 100644
--- a/erpnext/hr/doctype/employee_advance/employee_advance.json
+++ b/erpnext/hr/doctype/employee_advance/employee_advance.json
@@ -165,6 +165,7 @@
"options": "Mode of Payment"
},
{
+ "allow_on_submit": 1,
"fieldname": "return_amount",
"fieldtype": "Currency",
"label": "Returned Amount",
@@ -180,7 +181,7 @@
],
"is_submittable": 1,
"links": [],
- "modified": "2020-03-05 16:31:50.417539",
+ "modified": "2020-03-06 15:11:33.747535",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Advance",
diff --git a/erpnext/hr/doctype/employee_incentive/employee_incentive.py b/erpnext/hr/doctype/employee_incentive/employee_incentive.py
index 1cc52e1..44763fc 100644
--- a/erpnext/hr/doctype/employee_incentive/employee_incentive.py
+++ b/erpnext/hr/doctype/employee_incentive/employee_incentive.py
@@ -9,27 +9,13 @@
class EmployeeIncentive(Document):
def on_submit(self):
company = frappe.db.get_value('Employee', self.employee, 'company')
- additional_salary = frappe.db.exists('Additional Salary', {
- 'employee': self.employee,
- 'ref_doctype': self.doctype,
- 'ref_docname': self.name,
- 'salary_component': self.salary_component,
- 'payroll_date': self.payroll_date,
- 'company': company,
- 'docstatus': ["!=", 2]
- })
- if not additional_salary:
- additional_salary = frappe.new_doc('Additional Salary')
- additional_salary.employee = self.employee
- additional_salary.salary_component = self.salary_component
- additional_salary.amount = self.incentive_amount
- additional_salary.payroll_date = self.payroll_date
- additional_salary.company = company
- additional_salary.ref_doctype = self.doctype
- additional_salary.ref_docname = self.name
- additional_salary.submit()
- else:
- incentive_added = frappe.db.get_value('Additional Salary', additional_salary, 'amount') + self.incentive_amount
- frappe.db.set_value('Additional Salary', additional_salary, {'amount', incentive_added})
-
+ additional_salary = frappe.new_doc('Additional Salary')
+ additional_salary.employee = self.employee
+ additional_salary.salary_component = self.salary_component
+ additional_salary.amount = self.incentive_amount
+ additional_salary.payroll_date = self.payroll_date
+ additional_salary.company = company
+ additional_salary.ref_doctype = self.doctype
+ additional_salary.ref_docname = self.name
+ additional_salary.submit()
diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.py b/erpnext/hr/doctype/leave_encashment/leave_encashment.py
index ad2cc02..56f2f4c 100644
--- a/erpnext/hr/doctype/leave_encashment/leave_encashment.py
+++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.py
@@ -31,13 +31,16 @@
additional_salary = frappe.new_doc("Additional Salary")
additional_salary.company = frappe.get_value("Employee", self.employee, "company")
additional_salary.employee = self.employee
- additional_salary.salary_component = frappe.get_value("Leave Type", self.leave_type, "earning_component")
+ 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)))
+ additional_salary.salary_component = earning_component
additional_salary.payroll_date = self.encashment_date
additional_salary.amount = self.encashment_amount
+ additional_salary.ref_doctype = self.doctype
+ additional_salary.ref_docname = self.name
additional_salary.submit()
- self.db_set("additional_salary", additional_salary.name)
-
# Set encashed leaves in Allocation
frappe.db.set_value("Leave Allocation", self.leave_allocation, "total_leaves_encashed",
frappe.db.get_value('Leave Allocation', self.leave_allocation, 'total_leaves_encashed') + self.encashable_days)
@@ -119,4 +122,4 @@
leave_type=allocation.leave_type,
encashment_date=allocation.to_date
))
- leave_encashment.insert(ignore_permissions=True)
+ leave_encashment.insert(ignore_permissions=True)
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index ac55c67..1d19427 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -74,7 +74,6 @@
def on_cancel(self):
self.set_status()
self.update_status()
- self.update_salary_slip_in_additional_salary()
self.cancel_loan_repayment_entry()
def on_trash(self):
@@ -405,14 +404,15 @@
self.update_component_row(frappe._dict(last_benefit.struct_row), amount, "earnings")
def add_additional_salary_components(self, component_type):
- additional_components = get_additional_salary_component(self.employee,
+ salary_components_details, additional_salary_details = get_additional_salary_component(self.employee,
self.start_date, self.end_date, component_type)
- if additional_components:
- for additional_component in additional_components:
- amount = additional_component.amount
- overwrite = additional_component.overwrite
- self.update_component_row(frappe._dict(additional_component.struct_row), amount,
- component_type, overwrite=overwrite)
+ if salary_components_details and additional_salary_details:
+ for additional_salary in additional_salary_details:
+ additional_salary =frappe._dict(additional_salary)
+ amount = additional_salary.amount
+ overwrite = additional_salary.overwrite
+ self.update_component_row(frappe._dict(salary_components_details[additional_salary.component]), amount,
+ component_type, overwrite=overwrite, additional_salary=additional_salary.name)
def add_tax_components(self, payroll_period):
# Calculate variable_based_on_taxable_salary after all components updated in salary slip
@@ -432,21 +432,20 @@
tax_row = self.get_salary_slip_row(d)
self.update_component_row(tax_row, tax_amount, "deductions")
- def update_component_row(self, struct_row, amount, key, overwrite=1):
+ def update_component_row(self, struct_row, amount, key, overwrite=1, additional_salary = ''):
component_row = None
for d in self.get(key):
if d.salary_component == struct_row.salary_component:
component_row = d
-
- if not component_row:
+ if not component_row or (struct_row.get("is_additional_component") and not overwrite):
if amount:
self.append(key, {
'amount': amount,
- 'additional_salary': '' if not struct_row.get("additional_salary") else struct_row.get("additional_salary"),
'default_amount': amount if not struct_row.get("is_additional_component") else 0,
'depends_on_payment_days' : struct_row.depends_on_payment_days,
'salary_component' : struct_row.salary_component,
'abbr' : struct_row.abbr,
+ 'additional_salary': additional_salary,
'do_not_include_in_total' : struct_row.do_not_include_in_total,
'is_tax_applicable': struct_row.is_tax_applicable,
'is_flexible_benefit': struct_row.is_flexible_benefit,
@@ -458,6 +457,7 @@
if struct_row.get("is_additional_component"):
if overwrite:
component_row.additional_amount = amount - component_row.get("default_amount", 0)
+ component_row.additional_salary = additional_salary
else:
component_row.additional_amount = amount
@@ -878,4 +878,4 @@
def generate_password_for_pdf(policy_template, employee):
employee = frappe.get_doc("Employee", employee)
- return policy_template.format(**employee.as_dict())
+ return policy_template.format(**employee.as_dict())
\ No newline at end of file