Hi,
We are trying to implement the following in Salary Structure but are unable to do the same since the MIN or MAX function is not defined in global_defaults and I am getting the below error:
Traceback (most recent call last):
File "/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/salary_slip/salary_slip.py", line 170, in eval_condition_and_formula
amount = frappe.safe_eval(formula, self.whitelisted_globals, data)
File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 1512, in safe_eval
return eval(code, eval_globals, eval_locals)
File "<string>", line 1, in <module>
NameError: name 'min' is not defined
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/frappe/frappe-bench/apps/frappe/frappe/desk/form/save.py", line 22, in savedocs
doc.save()
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 260, in save
return self._save(*args, **kwargs)
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 296, in _save
self.run_before_save_methods()
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 876, in run_before_save_methods
self.run_method("validate")
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 772, in run_method
out = Document.hook(fn)(self, *args, **kwargs)
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 1048, in composer
return composed(self, method, *args, **kwargs)
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 1031, in runner
add_to_return_value(self, fn(self, *args, **kwargs))
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 766, in <lambda>
fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
File "/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/salary_slip/salary_slip.py", line 51, in validate
self.calculate_net_pay()
File "/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/salary_slip/salary_slip.py", line 443, in calculate_net_pay
self.calculate_component_amounts()
File "/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/salary_slip/salary_slip.py", line 74, in calculate_component_amounts
amount = self.eval_condition_and_formula(struct_row, data)
File "/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/salary_slip/salary_slip.py", line 177, in eval_condition_and_formula
frappe.throw(_("Name error: {0}".format(err)))
File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 355, in throw
msgprint(msg, raise_exception=exc, title=title, indicator='red')
File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 341, in msgprint
_raise_exception()
File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 314, in _raise_exception
raise raise_exception(msg)
frappe.exceptions.ValidationError: Name error: name 'min' is not defined
request.js:321:6
Traceback (most recent call last):
File "/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/salary_slip/salary_slip.py", line 170, in eval_condition_and_formula
amount = frappe.safe_eval(formula, self.whitelisted_globals, data)
File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 1512, in safe_eval
return eval(code, eval_globals, eval_locals)
File "<string>", line 1, in <module>
NameError: name 'min' is not defined
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/frappe/frappe-bench/apps/frappe/frappe/app.py", line 61, in application
response = frappe.handler.handle()
File "/home/frappe/frappe-bench/apps/frappe/frappe/handler.py", line 21, in handle
data = execute_cmd(cmd)
File "/home/frappe/frappe-bench/apps/frappe/frappe/handler.py", line 56, in execute_cmd
return frappe.call(method, **frappe.form_dict)
File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 1030, in call
return fn(*args, **newargs)
File "/home/frappe/frappe-bench/apps/frappe/frappe/desk/form/save.py", line 22, in savedocs
doc.save()
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 260, in save
return self._save(*args, **kwargs)
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 296, in _save
self.run_before_save_methods()
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 876, in run_before_save_methods
self.run_method("validate")
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 772, in run_method
out = Document.hook(fn)(self, *args, **kwargs)
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 1048, in composer
return composed(self, method, *args, **kwargs)
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 1031, in runner
add_to_return_value(self, fn(self, *args, **kwargs))
File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 766, in <lambda>
fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
File "/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/salary_slip/salary_slip.py", line 51, in validate
self.calculate_net_pay()
File "/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/salary_slip/salary_slip.py", line 443, in calculate_net_pay
self.calculate_component_amounts()
File "/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/salary_slip/salary_slip.py", line 74, in calculate_component_amounts
amount = self.eval_condition_and_formula(struct_row, data)
File "/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/salary_slip/salary_slip.py", line 177, in eval_condition_and_formula
frappe.throw(_("Name error: {0}".format(err)))
File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 355, in throw
msgprint(msg, raise_exception=exc, title=title, indicator='red')
File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 341, in msgprint
_raise_exception()
File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 314, in _raise_exception
raise raise_exception(msg)
frappe.exceptions.ValidationError: Name error: name 'min' is not defined
Why do we need the MIN or MAX funtion, here is the use case:
- We need to calculate EPF (Employees Provident Fund), which is calculated as (Basic Salary + HRA + Other Allowances) * 12% but its limited to a maximum amount of 1800/-. Now when I try to put a condition and calculate the EPF which means if I put a condition BS + HRA + OA <= 15000 then EPF = (HRA+BS+OA) * 12%, this works fine but in case when the condition is above 15000/- then we have set the value at 1800/- there is the calculation gets wrong if an employee is absent.
Now above formula would give the error as explained above but if we want to calculate the value for above 15000 then the below condition is being used which is giving wrong values:
Now the problem with the amount is as below:
In the below example
BS = 15750 + OA = 5250/-
So basically if the person comes on all days in a month then EPF would be 15750 + 5250 = 21000 * 12% = 2520 but since its greater than 1800/- then EPF amount would be 1800/-
Now in the below case the person was absent for 1 day so the salary would be 15225 + 5075 = 20300 and EPF = 20300 * 12% = 2436/- but since its also greater than 1800/- then EPF is again 1800/- but in our system the EPF is getting calculated as 1740/-
The above calculation of 1740/- is happening since 20300/- is greater than 15k as per the condition and then it gives it an amount of 1800/- and since there is one absent the amount 1800 * 29/30 = 1740/- which is WRONG and hence we need MIN and MAX functions to be allowed in SALARY STRUCTURES.