Merge pull request #6413 from KanchanChauhan/salaryslip-docfield-in-condition
Salary Slip fields in Condition and Formula
diff --git a/erpnext/hr/doctype/salary_detail/salary_detail.json b/erpnext/hr/doctype/salary_detail/salary_detail.json
index 3bb621b..99c705a 100644
--- a/erpnext/hr/doctype/salary_detail/salary_detail.json
+++ b/erpnext/hr/doctype/salary_detail/salary_detail.json
@@ -300,7 +300,7 @@
"label": "Condition and Formula Help",
"length": 0,
"no_copy": 0,
- "options": "<h3>Condition and Formula Help</h3>\n\n<p>Notes:</p>\n\n<ol>\n<li>Use field <code>base</code> for using base salary of the Employee</li>\n<li>Use Salary Component abbreviations in conditions and formulas. <code>BS = Basic Salary</code></li>\n<li>Use field name for employee details in conditions and formulas. <code>Employment Type = employment_type</code><code>Branch = branch</code></li>\n<li>Direct Amount can also be entered based on Condtion. See example 3</li></ol>\n\n<h4>Examples</h4>\n<ol>\n<li>Calculating Basic Salary based on <code>base</code>\n<pre><code>Condition: base < 10000</code></pre>\n<pre><code>Formula: base * .2</code></pre></li>\n<li>Calculating HRA based on Basic Salary<code>BS</code> \n<pre><code>Condition: BS > 2000</code></pre>\n<pre><code>Formula: BS * .1</code></pre></li>\n<li>Calculating TDS based on Employment Type<code>employment_type</code> \n<pre><code>Condition: employment_type==\"Intern\"</code></pre>\n<pre><code>Amount: 1000</code></pre></li>\n</ol>",
+ "options": "<h3>Condition and Formula Help</h3>\n\n<p>Notes:</p>\n\n<ol>\n<li>Use field <code>base</code> for using base salary of the Employee</li>\n<li>Use Salary Component abbreviations in conditions and formulas. <code>BS = Basic Salary</code></li>\n<li>Use field name for employee details in conditions and formulas. <code>Employment Type = employment_type</code><code>Branch = branch</code></li>\n<li>Use field name from Salary Slip in conditions and formulas. <code>Payment Days = payment_days</code><code>Leave without pay = leave_without_pay</code></li>\n<li>Direct Amount can also be entered based on Condtion. See example 3</li></ol>\n\n<h4>Examples</h4>\n<ol>\n<li>Calculating Basic Salary based on <code>base</code>\n<pre><code>Condition: base < 10000</code></pre>\n<pre><code>Formula: base * .2</code></pre></li>\n<li>Calculating HRA based on Basic Salary<code>BS</code> \n<pre><code>Condition: BS > 2000</code></pre>\n<pre><code>Formula: BS * .1</code></pre></li>\n<li>Calculating TDS based on Employment Type<code>employment_type</code> \n<pre><code>Condition: employment_type==\"Intern\"</code></pre>\n<pre><code>Amount: 1000</code></pre></li>\n</ol>",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -323,7 +323,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-08-23 15:26:07.754570",
+ "modified": "2016-09-20 05:29:26.373992",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Detail",
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 1918f92..dbbdf7f 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -31,7 +31,7 @@
self.get_leave_details(lwp = self.leave_without_pay)
# if self.salary_slip_based_on_timesheet or not self.net_pay:
- # self.calculate_net_pay()
+ self.calculate_net_pay()
company_currency = get_company_currency(self.company)
self.total_in_words = money_in_words(self.rounded_total, company_currency)
@@ -52,15 +52,27 @@
data = self.get_data_for_eval()
for key in ('earnings', 'deductions'):
- for d in self._salary_structure_doc.get(key):
- amount = self.eval_condition_and_formula(d, data)
- if amount:
- self.append(key, {
- 'amount': amount,
- 'default_amount': amount,
- 'depends_on_lwp' : d.depends_on_lwp,
- 'salary_component' : d.salary_component
- })
+ for struct_row in self._salary_structure_doc.get(key):
+ amount = self.eval_condition_and_formula(struct_row, data)
+ if amount:
+ self.update_component_row(struct_row, amount, key)
+
+
+ def update_component_row(self, struct_row, amount, key):
+ component_row = None
+ for d in self.get(key):
+ if d.salary_component == struct_row.salary_component:
+ component_row = d
+
+ if not component_row:
+ self.append(key, {
+ 'amount': amount,
+ 'default_amount': amount,
+ 'depends_on_lwp' : struct_row.depends_on_lwp,
+ 'salary_component' : struct_row.salary_component
+ })
+ else:
+ component_row.amount = amount
def eval_condition_and_formula(self, d, data):
try:
@@ -74,6 +86,7 @@
amount = eval(d.formula, None, data)
data[d.abbr] = amount
+
return amount
except NameError as err:
frappe.throw(_("Name error: {0}".format(err)))
@@ -92,6 +105,7 @@
data.base, data.variable = d.base, d.variable
data.update(frappe.get_doc("Employee", self.employee).as_dict())
+ data.update(self.as_dict())
# set values for components
salary_components = frappe.get_all("Salary Component", fields=["salary_component_abbr"])
@@ -351,4 +365,4 @@
timesheet.salary_slip = salary_slip
timesheet.flags.ignore_validate_update_after_submit = True
timesheet.set_status()
- timesheet.save()
\ No newline at end of file
+ timesheet.save()