fix: available employee for selection (#25378)
* fix: available employee for selection * fix: available employee for selection fix: available employee for selection
This commit is contained in:
parent
36247faf1a
commit
b6d2106184
@ -151,6 +151,10 @@ frappe.ui.form.on('Payroll Entry', {
|
|||||||
filters['company'] = frm.doc.company;
|
filters['company'] = frm.doc.company;
|
||||||
filters['start_date'] = frm.doc.start_date;
|
filters['start_date'] = frm.doc.start_date;
|
||||||
filters['end_date'] = frm.doc.end_date;
|
filters['end_date'] = frm.doc.end_date;
|
||||||
|
filters['salary_slip_based_on_timesheet'] = frm.doc.salary_slip_based_on_timesheet;
|
||||||
|
filters['payroll_frequency'] = frm.doc.payroll_frequency;
|
||||||
|
filters['payroll_payable_account'] = frm.doc.payroll_payable_account;
|
||||||
|
filters['currency'] = frm.doc.currency;
|
||||||
|
|
||||||
if (frm.doc.department) {
|
if (frm.doc.department) {
|
||||||
filters['department'] = frm.doc.department;
|
filters['department'] = frm.doc.department;
|
||||||
|
@ -52,48 +52,22 @@ class PayrollEntry(Document):
|
|||||||
Returns list of active employees based on selected criteria
|
Returns list of active employees based on selected criteria
|
||||||
and for which salary structure exists
|
and for which salary structure exists
|
||||||
"""
|
"""
|
||||||
cond = self.get_filter_condition()
|
self.check_mandatory()
|
||||||
cond += self.get_joining_relieving_condition()
|
filters = self.make_filters()
|
||||||
|
cond = get_filter_condition(filters)
|
||||||
|
cond += get_joining_relieving_condition(self.start_date, self.end_date)
|
||||||
|
|
||||||
condition = ''
|
condition = ''
|
||||||
if self.payroll_frequency:
|
if self.payroll_frequency:
|
||||||
condition = """and payroll_frequency = '%(payroll_frequency)s'"""% {"payroll_frequency": self.payroll_frequency}
|
condition = """and payroll_frequency = '%(payroll_frequency)s'"""% {"payroll_frequency": self.payroll_frequency}
|
||||||
|
|
||||||
sal_struct = frappe.db.sql_list("""
|
sal_struct = get_sal_struct(self.company, self.currency, self.salary_slip_based_on_timesheet, condition)
|
||||||
select
|
|
||||||
name from `tabSalary Structure`
|
|
||||||
where
|
|
||||||
docstatus = 1 and
|
|
||||||
is_active = 'Yes'
|
|
||||||
and company = %(company)s
|
|
||||||
and currency = %(currency)s and
|
|
||||||
ifnull(salary_slip_based_on_timesheet,0) = %(salary_slip_based_on_timesheet)s
|
|
||||||
{condition}""".format(condition=condition),
|
|
||||||
{"company": self.company, "currency": self.currency, "salary_slip_based_on_timesheet":self.salary_slip_based_on_timesheet})
|
|
||||||
|
|
||||||
if sal_struct:
|
if sal_struct:
|
||||||
cond += "and t2.salary_structure IN %(sal_struct)s "
|
cond += "and t2.salary_structure IN %(sal_struct)s "
|
||||||
cond += "and t2.payroll_payable_account = %(payroll_payable_account)s "
|
cond += "and t2.payroll_payable_account = %(payroll_payable_account)s "
|
||||||
cond += "and %(from_date)s >= t2.from_date"
|
cond += "and %(from_date)s >= t2.from_date"
|
||||||
emp_list = frappe.db.sql("""
|
emp_list = get_emp_list(sal_struct, cond, self.end_date, self.payroll_payable_account)
|
||||||
select
|
emp_list = remove_payrolled_employees(emp_list, self.start_date, self.end_date)
|
||||||
distinct t1.name as employee, t1.employee_name, t1.department, t1.designation
|
|
||||||
from
|
|
||||||
`tabEmployee` t1, `tabSalary Structure Assignment` t2
|
|
||||||
where
|
|
||||||
t1.name = t2.employee
|
|
||||||
and t2.docstatus = 1
|
|
||||||
%s order by t2.from_date desc
|
|
||||||
""" % cond, {"sal_struct": tuple(sal_struct), "from_date": self.end_date, "payroll_payable_account": self.payroll_payable_account}, as_dict=True)
|
|
||||||
|
|
||||||
emp_list = self.remove_payrolled_employees(emp_list)
|
|
||||||
return emp_list
|
|
||||||
|
|
||||||
def remove_payrolled_employees(self, emp_list):
|
|
||||||
for employee_details in emp_list:
|
|
||||||
if frappe.db.exists("Salary Slip", {"employee": employee_details.employee, "start_date": self.start_date, "end_date": self.end_date, "docstatus": 1}):
|
|
||||||
emp_list.remove(employee_details)
|
|
||||||
|
|
||||||
return emp_list
|
return emp_list
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -122,23 +96,6 @@ class PayrollEntry(Document):
|
|||||||
if self.validate_attendance:
|
if self.validate_attendance:
|
||||||
return self.validate_employee_attendance()
|
return self.validate_employee_attendance()
|
||||||
|
|
||||||
def get_filter_condition(self):
|
|
||||||
self.check_mandatory()
|
|
||||||
|
|
||||||
cond = ''
|
|
||||||
for f in ['company', 'branch', 'department', 'designation']:
|
|
||||||
if self.get(f):
|
|
||||||
cond += " and t1." + f + " = " + frappe.db.escape(self.get(f))
|
|
||||||
|
|
||||||
return cond
|
|
||||||
|
|
||||||
def get_joining_relieving_condition(self):
|
|
||||||
cond = """
|
|
||||||
and ifnull(t1.date_of_joining, '0000-00-00') <= '%(end_date)s'
|
|
||||||
and ifnull(t1.relieving_date, '2199-12-31') >= '%(start_date)s'
|
|
||||||
""" % {"start_date": self.start_date, "end_date": self.end_date}
|
|
||||||
return cond
|
|
||||||
|
|
||||||
def check_mandatory(self):
|
def check_mandatory(self):
|
||||||
for fieldname in ['company', 'start_date', 'end_date']:
|
for fieldname in ['company', 'start_date', 'end_date']:
|
||||||
if not self.get(fieldname):
|
if not self.get(fieldname):
|
||||||
@ -451,6 +408,53 @@ class PayrollEntry(Document):
|
|||||||
marked_days = attendances[0][0]
|
marked_days = attendances[0][0]
|
||||||
return marked_days
|
return marked_days
|
||||||
|
|
||||||
|
def get_sal_struct(company, currency, salary_slip_based_on_timesheet, condition):
|
||||||
|
return frappe.db.sql_list("""
|
||||||
|
select
|
||||||
|
name from `tabSalary Structure`
|
||||||
|
where
|
||||||
|
docstatus = 1 and
|
||||||
|
is_active = 'Yes'
|
||||||
|
and company = %(company)s
|
||||||
|
and currency = %(currency)s and
|
||||||
|
ifnull(salary_slip_based_on_timesheet,0) = %(salary_slip_based_on_timesheet)s
|
||||||
|
{condition}""".format(condition=condition),
|
||||||
|
{"company": company, "currency": currency, "salary_slip_based_on_timesheet": salary_slip_based_on_timesheet})
|
||||||
|
|
||||||
|
def get_filter_condition(filters):
|
||||||
|
cond = ''
|
||||||
|
for f in ['company', 'branch', 'department', 'designation']:
|
||||||
|
if filters.get(f):
|
||||||
|
cond += " and t1." + f + " = " + frappe.db.escape(filters.get(f))
|
||||||
|
|
||||||
|
return cond
|
||||||
|
|
||||||
|
def get_joining_relieving_condition(start_date, end_date):
|
||||||
|
cond = """
|
||||||
|
and ifnull(t1.date_of_joining, '0000-00-00') <= '%(end_date)s'
|
||||||
|
and ifnull(t1.relieving_date, '2199-12-31') >= '%(start_date)s'
|
||||||
|
""" % {"start_date": start_date, "end_date": end_date}
|
||||||
|
return cond
|
||||||
|
|
||||||
|
def get_emp_list(sal_struct, cond, end_date, payroll_payable_account):
|
||||||
|
return frappe.db.sql("""
|
||||||
|
select
|
||||||
|
distinct t1.name as employee, t1.employee_name, t1.department, t1.designation
|
||||||
|
from
|
||||||
|
`tabEmployee` t1, `tabSalary Structure Assignment` t2
|
||||||
|
where
|
||||||
|
t1.name = t2.employee
|
||||||
|
and t2.docstatus = 1
|
||||||
|
%s order by t2.from_date desc
|
||||||
|
""" % cond, {"sal_struct": tuple(sal_struct), "from_date": end_date, "payroll_payable_account": payroll_payable_account}, as_dict=True)
|
||||||
|
|
||||||
|
def remove_payrolled_employees(emp_list, start_date, end_date):
|
||||||
|
for employee_details in emp_list:
|
||||||
|
if frappe.db.exists("Salary Slip", {"employee": employee_details.employee, "start_date": start_date, "end_date": end_date, "docstatus": 1}):
|
||||||
|
emp_list.remove(employee_details)
|
||||||
|
|
||||||
|
return emp_list
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_start_end_dates(payroll_frequency, start_date=None, company=None):
|
def get_start_end_dates(payroll_frequency, start_date=None, company=None):
|
||||||
'''Returns dict of start and end dates for given payroll frequency based on start_date'''
|
'''Returns dict of start and end dates for given payroll frequency based on start_date'''
|
||||||
@ -639,39 +643,41 @@ def get_payroll_entries_for_jv(doctype, txt, searchfield, start, page_len, filte
|
|||||||
'start': start, 'page_len': page_len
|
'start': start, 'page_len': page_len
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_employee_with_existing_salary_slip(start_date, end_date, company):
|
def get_employee_list(filters):
|
||||||
return frappe.db.sql_list("""
|
cond = get_filter_condition(filters)
|
||||||
select employee from `tabSalary Slip`
|
cond += get_joining_relieving_condition(filters.start_date, filters.end_date)
|
||||||
where
|
condition = """and payroll_frequency = '%(payroll_frequency)s'"""% {"payroll_frequency": filters.payroll_frequency}
|
||||||
(start_date between %(start_date)s and %(end_date)s
|
sal_struct = get_sal_struct(filters.company, filters.currency, filters.salary_slip_based_on_timesheet, condition)
|
||||||
or
|
if sal_struct:
|
||||||
end_date between %(start_date)s and %(end_date)s
|
cond += "and t2.salary_structure IN %(sal_struct)s "
|
||||||
or
|
cond += "and t2.payroll_payable_account = %(payroll_payable_account)s "
|
||||||
%(start_date)s between start_date and end_date)
|
cond += "and %(from_date)s >= t2.from_date"
|
||||||
and company = %(company)s
|
emp_list = get_emp_list(sal_struct, cond, filters.end_date, filters.payroll_payable_account)
|
||||||
and docstatus = 1
|
emp_list = remove_payrolled_employees(emp_list, filters.start_date, filters.end_date)
|
||||||
""", {'start_date': start_date, 'end_date': end_date, 'company': company})
|
return emp_list
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@frappe.validate_and_sanitize_search_inputs
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
def employee_query(doctype, txt, searchfield, start, page_len, filters):
|
def employee_query(doctype, txt, searchfield, start, page_len, filters):
|
||||||
filters = frappe._dict(filters)
|
filters = frappe._dict(filters)
|
||||||
conditions = []
|
conditions = []
|
||||||
exclude_employees = []
|
include_employees = []
|
||||||
emp_cond = ''
|
emp_cond = ''
|
||||||
if filters.start_date and filters.end_date:
|
if filters.start_date and filters.end_date:
|
||||||
employee_list = get_employee_with_existing_salary_slip(filters.start_date, filters.end_date, filters.company)
|
employee_list = get_employee_list(filters)
|
||||||
emp = filters.get('employees')
|
emp = filters.get('employees')
|
||||||
|
include_employees = [employee.employee for employee in employee_list if employee.employee not in emp]
|
||||||
filters.pop('start_date')
|
filters.pop('start_date')
|
||||||
filters.pop('end_date')
|
filters.pop('end_date')
|
||||||
|
filters.pop('salary_slip_based_on_timesheet')
|
||||||
|
filters.pop('payroll_frequency')
|
||||||
|
filters.pop('payroll_payable_account')
|
||||||
|
filters.pop('currency')
|
||||||
if filters.employees is not None:
|
if filters.employees is not None:
|
||||||
filters.pop('employees')
|
filters.pop('employees')
|
||||||
if employee_list:
|
|
||||||
exclude_employees.extend(employee_list)
|
if include_employees:
|
||||||
if emp:
|
emp_cond += 'and employee in %(include_employees)s'
|
||||||
exclude_employees.extend(emp)
|
|
||||||
if exclude_employees:
|
|
||||||
emp_cond += 'and employee not in %(exclude_employees)s'
|
|
||||||
|
|
||||||
return frappe.db.sql("""select name, employee_name from `tabEmployee`
|
return frappe.db.sql("""select name, employee_name from `tabEmployee`
|
||||||
where status = 'Active'
|
where status = 'Active'
|
||||||
@ -695,4 +701,4 @@ def employee_query(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
'_txt': txt.replace("%", ""),
|
'_txt': txt.replace("%", ""),
|
||||||
'start': start,
|
'start': start,
|
||||||
'page_len': page_len,
|
'page_len': page_len,
|
||||||
'exclude_employees': exclude_employees})
|
'include_employees': include_employees})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user