Multiple Salary Fixes
This commit is contained in:
parent
52daaca885
commit
37a57813fa
@ -49,13 +49,13 @@ class SalarySlip(TransactionBase):
|
|||||||
self._salary_structure_doc = frappe.get_doc('Salary Structure', self.salary_structure)
|
self._salary_structure_doc = frappe.get_doc('Salary Structure', self.salary_structure)
|
||||||
|
|
||||||
data = self.get_data_for_eval()
|
data = self.get_data_for_eval()
|
||||||
|
|
||||||
for key in ('earnings', 'deductions'):
|
for key in ('earnings', 'deductions'):
|
||||||
for struct_row in self._salary_structure_doc.get(key):
|
for struct_row in self._salary_structure_doc.get(key):
|
||||||
amount = self.eval_condition_and_formula(struct_row, data)
|
amount = self.eval_condition_and_formula(struct_row, data)
|
||||||
if amount:
|
if amount:
|
||||||
self.update_component_row(struct_row, amount, key)
|
self.update_component_row(struct_row, amount, key)
|
||||||
|
|
||||||
|
|
||||||
def update_component_row(self, struct_row, amount, key):
|
def update_component_row(self, struct_row, amount, key):
|
||||||
component_row = None
|
component_row = None
|
||||||
for d in self.get(key):
|
for d in self.get(key):
|
||||||
@ -83,6 +83,7 @@ class SalarySlip(TransactionBase):
|
|||||||
amount = eval(d.formula, None, data)
|
amount = eval(d.formula, None, data)
|
||||||
if amount:
|
if amount:
|
||||||
data[d.abbr] = amount
|
data[d.abbr] = amount
|
||||||
|
|
||||||
return amount
|
return amount
|
||||||
|
|
||||||
except NameError as err:
|
except NameError as err:
|
||||||
@ -97,8 +98,6 @@ class SalarySlip(TransactionBase):
|
|||||||
'''Returns data for evaluating formula'''
|
'''Returns data for evaluating formula'''
|
||||||
data = frappe._dict()
|
data = frappe._dict()
|
||||||
|
|
||||||
for d in self._salary_structure_doc.employees:
|
|
||||||
if d.employee == self.employee:
|
|
||||||
data.update(frappe.get_doc("Salary Structure Employee", {"employee": self.employee}).as_dict())
|
data.update(frappe.get_doc("Salary Structure Employee", {"employee": self.employee}).as_dict())
|
||||||
|
|
||||||
data.update(frappe.get_doc("Employee", self.employee).as_dict())
|
data.update(frappe.get_doc("Employee", self.employee).as_dict())
|
||||||
@ -106,8 +105,13 @@ class SalarySlip(TransactionBase):
|
|||||||
|
|
||||||
# set values for components
|
# set values for components
|
||||||
salary_components = frappe.get_all("Salary Component", fields=["salary_component_abbr"])
|
salary_components = frappe.get_all("Salary Component", fields=["salary_component_abbr"])
|
||||||
for salary_component in salary_components:
|
for sc in salary_components:
|
||||||
data[salary_component.salary_component_abbr] = 0
|
data.setdefault(sc.salary_component_abbr, 0)
|
||||||
|
|
||||||
|
for key in ('earnings', 'deductions'):
|
||||||
|
for d in self.get(key):
|
||||||
|
data[d.abbr] = d.amount
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
@ -173,13 +177,16 @@ class SalarySlip(TransactionBase):
|
|||||||
|
|
||||||
def pull_sal_struct(self):
|
def pull_sal_struct(self):
|
||||||
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
|
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
|
||||||
make_salary_slip(self._salary_structure_doc.name, self)
|
|
||||||
|
|
||||||
if self.salary_slip_based_on_timesheet:
|
if self.salary_slip_based_on_timesheet:
|
||||||
self.salary_structure = self._salary_structure_doc.name
|
self.salary_structure = self._salary_structure_doc.name
|
||||||
self.hour_rate = self._salary_structure_doc.hour_rate
|
self.hour_rate = self._salary_structure_doc.hour_rate
|
||||||
self.total_working_hours = sum([d.working_hours or 0.0 for d in self.timesheets]) or 0.0
|
self.total_working_hours = sum([d.working_hours or 0.0 for d in self.timesheets]) or 0.0
|
||||||
self.add_earning_for_hourly_wages(self._salary_structure_doc.salary_component)
|
wages_amount = self.hour_rate * self.total_working_hours
|
||||||
|
|
||||||
|
self.add_earning_for_hourly_wages(self, self._salary_structure_doc.salary_component, wages_amount)
|
||||||
|
|
||||||
|
make_salary_slip(self._salary_structure_doc.name, self)
|
||||||
|
|
||||||
def process_salary_structure(self):
|
def process_salary_structure(self):
|
||||||
'''Calculate salary after salary structure details have been updated'''
|
'''Calculate salary after salary structure details have been updated'''
|
||||||
@ -188,18 +195,21 @@ class SalarySlip(TransactionBase):
|
|||||||
self.get_leave_details()
|
self.get_leave_details()
|
||||||
self.calculate_net_pay()
|
self.calculate_net_pay()
|
||||||
|
|
||||||
def add_earning_for_hourly_wages(self, salary_component):
|
def add_earning_for_hourly_wages(self, doc, salary_component, amount):
|
||||||
default_type = False
|
row_exists = False
|
||||||
for data in self.earnings:
|
for row in doc.earnings:
|
||||||
if data.salary_component == salary_component:
|
if row.salary_component == salary_component:
|
||||||
data.amount = self.hour_rate * self.total_working_hours
|
row.amount = amount
|
||||||
default_type = True
|
row_exists = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if not default_type:
|
if not row_exists:
|
||||||
earnings = self.append('earnings', {})
|
wages_row = {
|
||||||
earnings.salary_component = salary_component
|
"salary_component": salary_component,
|
||||||
earnings.amount = self.hour_rate * self.total_working_hours
|
"abbr": frappe.db.get_value("Salary Component", salary_component, "salary_component_abbr"),
|
||||||
|
"amount": self.hour_rate * self.total_working_hours
|
||||||
|
}
|
||||||
|
doc.append('earnings', wages_row)
|
||||||
|
|
||||||
def pull_emp_details(self):
|
def pull_emp_details(self):
|
||||||
emp = frappe.db.get_value("Employee", self.employee, ["bank_name", "bank_ac_no"], as_dict=1)
|
emp = frappe.db.get_value("Employee", self.employee, ["bank_name", "bank_ac_no"], as_dict=1)
|
||||||
@ -307,8 +317,15 @@ class SalarySlip(TransactionBase):
|
|||||||
frappe.throw(_("Salary Slip of employee {0} already created for time sheet {1}").format(self.employee, data.time_sheet))
|
frappe.throw(_("Salary Slip of employee {0} already created for time sheet {1}").format(self.employee, data.time_sheet))
|
||||||
|
|
||||||
def sum_components(self, component_type, total_field):
|
def sum_components(self, component_type, total_field):
|
||||||
|
joining_date, relieving_date = frappe.db.get_value("Employee", self.employee,
|
||||||
|
["date_of_joining", "relieving_date"])
|
||||||
|
if not relieving_date:
|
||||||
|
relieving_date = getdate(self.end_date)
|
||||||
|
|
||||||
for d in self.get(component_type):
|
for d in self.get(component_type):
|
||||||
if cint(d.depends_on_lwp) == 1 and not self.salary_slip_based_on_timesheet:
|
if ((cint(d.depends_on_lwp) == 1 and not self.salary_slip_based_on_timesheet) or\
|
||||||
|
getdate(self.start_date) < joining_date or getdate(self.end_date) > relieving_date):
|
||||||
|
|
||||||
d.amount = rounded((flt(d.default_amount) * flt(self.payment_days)
|
d.amount = rounded((flt(d.default_amount) * flt(self.payment_days)
|
||||||
/ cint(self.total_working_days)), self.precision("amount", component_type))
|
/ cint(self.total_working_days)), self.precision("amount", component_type))
|
||||||
elif not self.payment_days and not self.salary_slip_based_on_timesheet:
|
elif not self.payment_days and not self.salary_slip_based_on_timesheet:
|
||||||
|
@ -16,7 +16,7 @@ class SalaryStructure(Document):
|
|||||||
self.validate_amount()
|
self.validate_amount()
|
||||||
for e in self.get('employees'):
|
for e in self.get('employees'):
|
||||||
set_employee_name(e)
|
set_employee_name(e)
|
||||||
self.validate_joining_date()
|
self.validate_date()
|
||||||
|
|
||||||
def get_ss_values(self,employee):
|
def get_ss_values(self,employee):
|
||||||
basic_info = frappe.db.sql("""select bank_name, bank_ac_no
|
basic_info = frappe.db.sql("""select bank_name, bank_ac_no
|
||||||
@ -29,12 +29,37 @@ class SalaryStructure(Document):
|
|||||||
if flt(self.net_pay) < 0 and self.salary_slip_based_on_timesheet:
|
if flt(self.net_pay) < 0 and self.salary_slip_based_on_timesheet:
|
||||||
frappe.throw(_("Net pay cannot be negative"))
|
frappe.throw(_("Net pay cannot be negative"))
|
||||||
|
|
||||||
def validate_joining_date(self):
|
def validate_date(self):
|
||||||
for e in self.get('employees'):
|
for employee in self.get('employees'):
|
||||||
joining_date = getdate(frappe.db.get_value("Employee", e.employee, "date_of_joining"))
|
joining_date, relieving_date = frappe.db.get_value("Employee", employee.employee,
|
||||||
if e.from_date and getdate(e.from_date) < joining_date:
|
["date_of_joining", "relieving_date"])
|
||||||
|
if employee.from_date and getdate(employee.from_date) < joining_date:
|
||||||
frappe.throw(_("From Date {0} for Employee {1} cannot be before employee's joining Date {2}")
|
frappe.throw(_("From Date {0} for Employee {1} cannot be before employee's joining Date {2}")
|
||||||
.format(e.from_date, e.employee, joining_date))
|
.format(employee.from_date, employee.employee, joining_date))
|
||||||
|
|
||||||
|
st_name = frappe.db.sql("""select parent from `tabSalary Structure Employee`
|
||||||
|
where
|
||||||
|
employee=%(employee)s
|
||||||
|
and (
|
||||||
|
(%(from_date)s between from_date and ifnull(to_date, '2199-12-31'))
|
||||||
|
or (%(to_date)s between from_date and ifnull(to_date, '2199-12-31'))
|
||||||
|
or (from_date between %(from_date)s and %(to_date)s)
|
||||||
|
)
|
||||||
|
and (
|
||||||
|
exists (select name from `tabSalary Structure`
|
||||||
|
where name = `tabSalary Structure Employee`.parent and is_active = 'Yes')
|
||||||
|
)
|
||||||
|
and parent != %(salary_struct)s""",
|
||||||
|
{
|
||||||
|
'employee': employee.employee,
|
||||||
|
'from_date': employee.from_date,
|
||||||
|
'to_date': (employee.to_date or '2199-12-31'),
|
||||||
|
'salary_struct': self.name
|
||||||
|
})
|
||||||
|
|
||||||
|
if st_name:
|
||||||
|
frappe.throw(_("Active Salary Structure {0} found for employee {1} for the given dates")
|
||||||
|
.format(st_name[0][0], employee.employee))
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_salary_slip(source_name, target_doc = None, employee = None, as_print = False, print_format = None):
|
def make_salary_slip(source_name, target_doc = None, employee = None, as_print = False, print_format = None):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user