Fixed conflict

This commit is contained in:
Nabin Hait 2018-07-30 11:09:05 +05:30
parent b2e0f649d2
commit 04d5412754
8 changed files with 185 additions and 172 deletions

View File

@ -60,7 +60,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Company",
"length": 0,
@ -94,7 +94,7 @@
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"in_standard_filter": 1,
"label": "Employee",
"length": 0,
"no_copy": 0,
@ -107,7 +107,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
@ -127,7 +127,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Employee Name",
"length": 0,
@ -161,7 +161,7 @@
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"in_standard_filter": 1,
"label": "Salary Component",
"length": 0,
"no_copy": 0,
@ -174,7 +174,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
@ -251,7 +251,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "from_date",
"fieldname": "payroll_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
@ -260,7 +260,7 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "From Date",
"label": "Payroll Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -271,39 +271,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "to_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "To Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
@ -322,7 +290,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Amount",
"length": 0,
@ -374,6 +342,39 @@
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "salary_slip",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Salary Slip",
"length": 0,
"no_copy": 0,
"options": "Salary Slip",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@ -417,7 +418,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-07-26 12:05:16.337082",
"modified": "2018-07-28 17:50:25.725444",
"modified_by": "Administrator",
"module": "HR",
"name": "Additional Salary",
@ -471,5 +472,6 @@
"sort_order": "DESC",
"title_field": "employee",
"track_changes": 1,
"track_seen": 0
"track_seen": 0,
"track_views": 0
}

View File

@ -17,11 +17,9 @@ class AdditionalSalary(Document):
def validate_dates(self):
date_of_joining, relieving_date = frappe.db.get_value("Employee", self.employee,
["date_of_joining", "relieving_date"])
if getdate(self.from_date) > getdate(self.to_date):
frappe.throw(_("To date can not be less than from date"))
elif date_of_joining and getdate(self.from_date) < getdate(date_of_joining):
frappe.throw(_("From date can not be less than employee's joining date"))
elif relieving_date and getdate(self.to_date) > getdate(relieving_date):
if date_of_joining and getdate(self.payroll_date) < getdate(date_of_joining):
frappe.throw(_("Payroll date can not be less than employee's joining date"))
elif relieving_date and getdate(self.payroll_date) > getdate(relieving_date):
frappe.throw(_("To date can not greater than employee's relieving date"))
def get_amount(self, sal_start_date, sal_end_date):
@ -39,46 +37,27 @@ class AdditionalSalary(Document):
@frappe.whitelist()
def get_additional_salary_component(employee, start_date, end_date):
additional_components = frappe.db.sql("""
select name from `tabAdditional Salary`
where employee=%(employee)s
and docstatus = 1
and (
(%(from_date)s between from_date and to_date)
or (%(to_date)s between from_date and to_date)
or (from_date between %(from_date)s and %(to_date)s)
)""", {
select salary_component, sum(amount) as amount from `tabAdditional Salary`
where employee=%(employee)s
and docstatus = 1
and payroll_date between %(from_date)s and %(to_date)s
group by salary_component
""", {
'employee': employee,
'from_date': start_date,
'to_date': end_date
})
}, as_dict=1)
if additional_components:
additional_components_array = []
for additional_component in additional_components:
additional_component_obj = frappe.get_doc("Additional Salary", additional_component[0])
amount = additional_component_obj.get_amount(start_date, end_date)
salary_component = frappe.get_doc("Salary Component", additional_component_obj.salary_component)
added = False
for added_component in additional_components_array:
if added_component["struct_row"]["salary_component"] == salary_component.name:
added_component["amount"] += amount
added = True
if added:
continue
struct_row = {}
additional_components_dict = {}
struct_row['depends_on_lwp'] = salary_component.depends_on_lwp
struct_row['salary_component'] = salary_component.name
struct_row['abbr'] = salary_component.salary_component_abbr
struct_row['do_not_include_in_total'] = salary_component.do_not_include_in_total
struct_row['is_tax_applicable'] = salary_component.is_tax_applicable
struct_row['variable_based_on_taxable_salary'] = salary_component.variable_based_on_taxable_salary
struct_row['is_additional_component'] = salary_component.is_additional_component
additional_components_dict['amount'] = amount
additional_components_dict['struct_row'] = struct_row
additional_components_dict['type'] = salary_component.type
additional_components_array.append(additional_components_dict)
additional_components_list = []
for d in additional_components:
component = frappe.get_doc("Salary Component", d.salary_component)
struct_row = {'salary_component': d.salary_component}
for field in ["depends_on_lwp", "abbr", "is_tax_applicable", "variable_based_on_taxable_salary", "is_additional_component"]:
struct_row[field] = component.get(field)
if len(additional_components_array) > 0:
return additional_components_array
return False
additional_components_list.append({
'amount': d.amount,
'type': component.type,
'struct_row': struct_row
})
return additional_components_list

View File

@ -30,8 +30,7 @@ class LeaveEncashment(Document):
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")
additional_salary.from_date = self.encashment_date
additional_salary.to_date = self.encashment_date
additional_salary.payroll_date = self.encashment_date
additional_salary.amount = self.encashment_amount
additional_salary.submit()

View File

@ -12,7 +12,6 @@ from erpnext.accounts.utils import get_fiscal_year
from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee
class PayrollEntry(Document):
def on_submit(self):
self.create_salary_slips()
@ -97,41 +96,25 @@ class PayrollEntry(Document):
Creates salary slip for selected employees if already not created
"""
self.check_permission('write')
self.created = 1;
emp_list = self.get_emp_list()
ss_list = []
self.created = 1
emp_list = [d.employee for d in self.get_emp_list()]
if emp_list:
for emp in emp_list:
if not frappe.db.sql("""select
name from `tabSalary Slip`
where
docstatus!= 2 and
employee = %s and
start_date >= %s and
end_date <= %s and
company = %s
""", (emp['employee'], self.start_date, self.end_date, self.company)):
ss = frappe.get_doc({
"doctype": "Salary Slip",
"salary_slip_based_on_timesheet": self.salary_slip_based_on_timesheet,
"payroll_frequency": self.payroll_frequency,
"start_date": self.start_date,
"end_date": self.end_date,
"employee": emp['employee'],
"employee_name": frappe.get_value("Employee", {"name":emp['employee']}, "employee_name"),
"company": self.company,
"posting_date": self.posting_date,
"deduct_tax_for_unclaimed_employee_benefits": self.deduct_tax_for_unclaimed_employee_benefits,
"deduct_tax_for_unsubmitted_tax_exemption_proof": self.deduct_tax_for_unsubmitted_tax_exemption_proof
})
ss.insert()
ss_dict = {}
ss_dict["Employee Name"] = ss.employee_name
ss_dict["Total Pay"] = fmt_money(ss.rounded_total,currency = frappe.defaults.get_global_default("currency"))
ss_dict["Salary Slip"] = format_as_links(ss.name)[0]
ss_list.append(ss_dict)
return create_log(ss_list)
args = frappe._dict({
"salary_slip_based_on_timesheet": self.salary_slip_based_on_timesheet,
"payroll_frequency": self.payroll_frequency,
"start_date": self.start_date,
"end_date": self.end_date,
"company": self.company,
"posting_date": self.posting_date,
"deduct_tax_for_unclaimed_employee_benefits": self.deduct_tax_for_unclaimed_employee_benefits,
"deduct_tax_for_unsubmitted_tax_exemption_proof": self.deduct_tax_for_unsubmitted_tax_exemption_proof,
"payroll_entry": self.payroll_entry
})
if len(emp_list) > 50:
frappe.enqueue(create_salary_slips_for_employees, timeout=600, employees=emp_list, args=args)
else:
create_salary_slips_for_employees(emp_list, args, publish_progress=False)
def get_sal_slip_list(self, ss_status, as_dict=False):
"""
Returns list of salary slips based on selected criteria
@ -151,9 +134,6 @@ class PayrollEntry(Document):
"""
self.check_permission('write')
# self.create_salary_slips()
jv_name = ""
ss_list = self.get_sal_slip_list(ss_status=0)
submitted_ss = []
not_submitted_ss = []
@ -175,14 +155,15 @@ class PayrollEntry(Document):
except frappe.ValidationError:
not_submitted_ss.append(ss_dict)
if submitted_ss:
jv_name = self.make_accrual_jv_entry()
self.make_accrual_jv_entry()
frappe.msgprint(_("Salary Slip submitted for period from {0} to {1}")
.format(ss_obj.start_date, ss_obj.end_date))
self.email_salary_slip(submitted_ss)
return create_submit_log(submitted_ss, not_submitted_ss, jv_name)
return create_submit_log(submitted_ss, not_submitted_ss)
def email_salary_slip(self, submitted_ss):
if frappe.db.get_single_value("HR Settings", "email_salary_slip_to_employee"):
@ -509,28 +490,16 @@ def get_month_details(year, month):
else:
frappe.throw(_("Fiscal Year {0} not found").format(year))
@frappe.whitelist()
def create_log(ss_list):
if not ss_list:
frappe.throw(
_("There's no employee for the given criteria. Check that Salary Slips have not already been created."),
title='Error'
)
return ss_list
def format_as_links(salary_slip):
return ['<a href="#Form/Salary Slip/{0}">{0}</a>'.format(salary_slip)]
def create_submit_log(submitted_ss, not_submitted_ss, jv_name):
def create_submit_log(submitted_ss, not_submitted_ss):
if not submitted_ss and not not_submitted_ss:
frappe.msgprint(_("No salary slip found to submit for the above selected criteria OR salary slip already submitted"))
if not_submitted_ss:
frappe.msgprint(_("Could not submit any Salary Slip <br>\
frappe.msgprint(_("Could not submit some Salary Slips <br>\
Possible reasons: <br>\
1. Net pay is less than 0. <br>\
2. Company Email Address specified in employee master is not valid. <br>"))
@ -584,3 +553,26 @@ def payroll_entry_has_bank_entries(name):
response['submitted'] = 1 if bank_entries else 0
return response
def create_salary_slips_for_employees(employees, args, publish_progress=True):
salary_slips_exists_for = get_existing_salary_slips(employees, args)
count=0
for emp in employees:
if emp not in salary_slips_exists_for:
ss = frappe.new_doc("Salary Slip")
ss.employee = emp
ss.update(args)
ss.insert()
count+=1
if publish_progress:
frappe.publish_progress(count*100/len(set(employees) - set(salary_slips_exists_for)),
title = _("Creating Salary Slips..."))
def get_existing_salary_slips(employees, args):
return frappe.db.sql_list("""
select distinct employee from `tabSalary Slip`
where docstatus!= 2 and company = %s
and start_date >= %s and end_date <= %s
and employee in (%s)
""" % ('%s', '%s', '%s', ', '.join(['%s']*len(employees))),
[args.company, args.start_date, args.end_date] + employees)

View File

@ -39,10 +39,13 @@ frappe.ui.form.on("Salary Slip", {
start_date: function(frm, dt, dn){
if(frm.doc.start_date){
frm.trigger("set_end_date");
get_emp_and_leave_details(frm.doc, dt, dn);
}
},
end_date: function(frm, dt, dn) {
get_emp_and_leave_details(frm.doc, dt, dn);
},
set_end_date: function(frm){
frappe.call({
method: 'erpnext.hr.doctype.payroll_entry.payroll_entry.get_end_date',
@ -82,8 +85,6 @@ frappe.ui.form.on("Salary Slip", {
payroll_frequency: function(frm, dt, dn) {
frm.trigger("toggle_fields");
frm.set_value('end_date', '');
frm.set_value('start_date', '');
get_emp_and_leave_details(frm.doc, dt, dn);
},
employee: function(frm, dt, dn) {
@ -121,21 +122,14 @@ frappe.ui.form.on('Salary Slip Timesheet', {
// Get leave details
//---------------------------------------------------------------------
var get_emp_and_leave_details = function(doc, dt, dn) {
if(!doc.start_date){
return frappe.call({
method: 'get_emp_and_leave_details',
doc: locals[dt][dn],
callback: function(r, rt) {
cur_frm.refresh();
calculate_all(doc, dt, dn);
}
});
}
}
cur_frm.cscript.employee = function(doc,dt,dn){
doc.salary_structure = ''
get_emp_and_leave_details(doc, dt, dn);
return frappe.call({
method: 'get_emp_and_leave_details',
doc: locals[dt][dn],
callback: function(r, rt) {
cur_frm.refresh();
calculate_all(doc, dt, dn);
}
});
}
cur_frm.cscript.leave_without_pay = function(doc,dt,dn){

View File

@ -318,6 +318,39 @@
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "payroll_entry",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payroll Entry",
"length": 0,
"no_copy": 0,
"options": "Payroll Entry",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@ -1872,7 +1905,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-06-28 12:18:50.538159",
"modified": "2018-07-27 19:23:35.587516",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Slip",

View File

@ -241,10 +241,14 @@ class SalarySlip(TransactionBase):
if self.payroll_frequency:
cond += """and ss.payroll_frequency = '%(payroll_frequency)s'""" % {"payroll_frequency": self.payroll_frequency}
st_name = frappe.db.sql("""select sa.salary_structure from `tabSalary Structure Assignment` sa
join `tabSalary Structure` ss where sa.salary_structure=ss.name
and sa.docstatus = 1 and ss.docstatus = 1 and ss.is_active ='Yes' %s
order by sa.from_date desc limit 1 """ %cond, {'employee': self.employee, 'start_date': self.start_date,
st_name = frappe.db.sql("""
select sa.salary_structure
from `tabSalary Structure Assignment` sa join `tabSalary Structure` ss
where sa.salary_structure=ss.name
and sa.docstatus = 1 and ss.docstatus = 1 and ss.is_active ='Yes' %s
order by sa.from_date desc
limit 1
""" %cond, {'employee': self.employee, 'start_date': self.start_date,
'end_date': self.end_date, 'joining_date': joining_date})
if st_name:
@ -480,17 +484,26 @@ class SalarySlip(TransactionBase):
else:
self.set_status()
self.update_status(self.name)
self.update_salary_slip_in_additional_salary()
if (frappe.db.get_single_value("HR Settings", "email_salary_slip_to_employee")) and not frappe.flags.via_payroll_entry:
self.email_salary_slip()
def on_cancel(self):
self.set_status()
self.update_status()
self.update_salary_slip_in_additional_salary()
def on_trash(self):
from frappe.model.naming import revert_series_if_last
revert_series_if_last(self.series, self.name)
def update_salary_slip_in_additional_salary(self):
salary_slip = self.name if self.docstatus==1 else None
frappe.db.sql("""
update `tabAdditional Salary` set salary_slip=%s
where employee=%s and payroll_date between %s and %s and docstatus=1
""", (salary_slip, self.employee, self.start_date, self.end_date))
def email_salary_slip(self):
receiver = frappe.db.get_value("Employee", self.employee, "prefered_email")

View File

@ -28,7 +28,7 @@
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"in_standard_filter": 1,
"label": "Employee",
"length": 0,
"no_copy": 0,
@ -41,7 +41,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
@ -129,7 +129,7 @@
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"in_standard_filter": 1,
"label": "Salary Structure",
"length": 0,
"no_copy": 0,
@ -142,7 +142,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
@ -412,7 +412,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-06-22 14:54:05.494234",
"modified": "2018-07-27 16:23:17.490097",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Structure Assignment",
@ -485,5 +485,6 @@
"sort_order": "DESC",
"title_field": "employee_name",
"track_changes": 1,
"track_seen": 0
"track_seen": 0,
"track_views": 0
}