mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-09 00:01:18 +00:00
feat: Additon of leave details in Salary Slip
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
"daily_wages_fraction_for_half_day",
|
||||
"email_salary_slip_to_employee",
|
||||
"encrypt_salary_slips_in_emails",
|
||||
"show_leave_balances_in_salary_slip",
|
||||
"password_policy"
|
||||
],
|
||||
"fields": [
|
||||
@@ -23,58 +24,44 @@
|
||||
"fieldname": "payroll_based_on",
|
||||
"fieldtype": "Select",
|
||||
"label": "Calculate Payroll Working Days Based On",
|
||||
"options": "Leave\nAttendance",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "Leave\nAttendance"
|
||||
},
|
||||
{
|
||||
"fieldname": "max_working_hours_against_timesheet",
|
||||
"fieldtype": "Float",
|
||||
"label": "Max working hours against Timesheet",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"label": "Max working hours against Timesheet"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "If checked, Total no. of Working Days will include holidays, and this will reduce the value of Salary Per Day",
|
||||
"fieldname": "include_holidays_in_total_working_days",
|
||||
"fieldtype": "Check",
|
||||
"label": "Include holidays in Total no. of Working Days",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"label": "Include holidays in Total no. of Working Days"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "If checked, hides and disables Rounded Total field in Salary Slips",
|
||||
"fieldname": "disable_rounded_total",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disable Rounded Total",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"label": "Disable Rounded Total"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "0.5",
|
||||
"description": "The fraction of daily wages to be paid for half-day attendance",
|
||||
"fieldname": "daily_wages_fraction_for_half_day",
|
||||
"fieldtype": "Float",
|
||||
"label": "Fraction of Daily Salary for Half Day",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"label": "Fraction of Daily Salary for Half Day"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"description": "Emails salary slip to employee based on preferred email selected in Employee",
|
||||
"fieldname": "email_salary_slip_to_employee",
|
||||
"fieldtype": "Check",
|
||||
"label": "Email Salary Slip to Employee",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"label": "Email Salary Slip to Employee"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
@@ -82,9 +69,7 @@
|
||||
"description": "The salary slip emailed to the employee will be password protected, the password will be generated based on the password policy.",
|
||||
"fieldname": "encrypt_salary_slips_in_emails",
|
||||
"fieldtype": "Check",
|
||||
"label": "Encrypt Salary Slips in Emails",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"label": "Encrypt Salary Slips in Emails"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.encrypt_salary_slips_in_emails == 1",
|
||||
@@ -92,24 +77,27 @@
|
||||
"fieldname": "password_policy",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Password Policy",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"label": "Password Policy"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.payroll_based_on == 'Attendance'",
|
||||
"fieldname": "consider_unmarked_attendance_as",
|
||||
"fieldtype": "Select",
|
||||
"label": "Consider Unmarked Attendance As",
|
||||
"options": "Present\nAbsent",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "Present\nAbsent"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "show_leave_balances_in_salary_slip",
|
||||
"fieldtype": "Check",
|
||||
"label": "Show Leave Balances in Salary Slip"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-cog",
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-22 17:00:58.408030",
|
||||
"modified": "2021-02-19 11:07:55.873991",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Payroll Settings",
|
||||
|
||||
@@ -76,6 +76,8 @@
|
||||
"total_in_words",
|
||||
"column_break_69",
|
||||
"base_total_in_words",
|
||||
"leave_details_section",
|
||||
"leave_details",
|
||||
"section_break_75",
|
||||
"amended_from"
|
||||
],
|
||||
@@ -578,13 +580,55 @@
|
||||
{
|
||||
"fieldname": "column_break_69",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"description": "Total salary booked for this employee from the beginning of the year (payroll period or fiscal year) up to the current salary slip's end date.",
|
||||
"fieldname": "year_to_date",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Year To Date",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"description": "Total salary booked for this employee from the beginning of the month up to the current salary slip's end date.",
|
||||
"fieldname": "month_to_date",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Month To Date",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "base_year_to_date",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Year To Date(Company Currency)",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "base_month_to_date",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Month To Date(Company Currency)",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "leave_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Leave Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "leave_details",
|
||||
"fieldtype": "Table",
|
||||
"label": "Leave Details",
|
||||
"options": "Salary Slip Leave",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-file-text",
|
||||
"idx": 9,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-10-21 23:02:59.400249",
|
||||
"modified": "2021-02-19 11:48:05.383945",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Salary Slip",
|
||||
|
||||
@@ -18,6 +18,8 @@ from erpnext.payroll.doctype.payroll_period.payroll_period import get_period_fac
|
||||
from erpnext.payroll.doctype.employee_benefit_application.employee_benefit_application import get_benefit_component_amount
|
||||
from erpnext.payroll.doctype.employee_benefit_claim.employee_benefit_claim import get_benefit_claim_amount, get_last_payroll_period_benefits
|
||||
from erpnext.loan_management.doctype.loan_repayment.loan_repayment import calculate_amounts, create_repayment_entry
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from six import iteritems
|
||||
|
||||
class SalarySlip(TransactionBase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -49,6 +51,10 @@ class SalarySlip(TransactionBase):
|
||||
self.get_working_days_details(lwp = self.leave_without_pay)
|
||||
|
||||
self.calculate_net_pay()
|
||||
self.compute_year_to_date()
|
||||
self.compute_month_to_date()
|
||||
self.compute_component_wise_year_to_date()
|
||||
self.add_leave_balances()
|
||||
|
||||
if frappe.db.get_single_value("Payroll Settings", "max_working_hours_against_timesheet"):
|
||||
max_working_hours = frappe.db.get_single_value("Payroll Settings", "max_working_hours_against_timesheet")
|
||||
@@ -1125,6 +1131,98 @@ class SalarySlip(TransactionBase):
|
||||
self.gross_pay += self.earnings[i].amount
|
||||
self.net_pay = flt(self.gross_pay) - flt(self.total_deduction)
|
||||
|
||||
def compute_year_to_date(self):
|
||||
year_to_date = 0
|
||||
period_start_date, period_end_date = self.get_year_to_date_period()
|
||||
|
||||
salary_slip_sum = frappe.get_list('Salary Slip',
|
||||
fields = ['sum(net_pay) as sum'],
|
||||
filters = {'employee_name' : self.employee_name,
|
||||
'start_date' : ['>=', period_start_date],
|
||||
'end_date' : ['<', period_end_date],
|
||||
'name': ['!=', self.name],
|
||||
'docstatus': 1
|
||||
})
|
||||
|
||||
year_to_date = flt(salary_slip_sum[0].sum) if salary_slip_sum else 0.0
|
||||
|
||||
year_to_date += self.net_pay
|
||||
self.year_to_date = year_to_date
|
||||
|
||||
def compute_month_to_date(self):
|
||||
month_to_date = 0
|
||||
first_day_of_the_month = get_first_day(self.start_date)
|
||||
salary_slip_sum = frappe.get_list('Salary Slip',
|
||||
fields = ['sum(net_pay) as sum'],
|
||||
filters = {'employee_name' : self.employee_name,
|
||||
'start_date' : ['>=', first_day_of_the_month],
|
||||
'end_date' : ['<', self.start_date],
|
||||
'name': ['!=', self.name],
|
||||
'docstatus': 1
|
||||
})
|
||||
|
||||
month_to_date = flt(salary_slip_sum[0].sum) if salary_slip_sum else 0.0
|
||||
|
||||
month_to_date += self.net_pay
|
||||
self.month_to_date = month_to_date
|
||||
|
||||
def compute_component_wise_year_to_date(self):
|
||||
period_start_date, period_end_date = self.get_year_to_date_period()
|
||||
|
||||
for key in ('earnings', 'deductions'):
|
||||
for component in self.get(key):
|
||||
year_to_date = 0
|
||||
component_sum = frappe.db.sql("""
|
||||
SELECT sum(detail.amount) as sum
|
||||
FROM `tabSalary Detail` as detail
|
||||
INNER JOIN `tabSalary Slip` as salary_slip
|
||||
ON detail.parent = salary_slip.name
|
||||
WHERE
|
||||
salary_slip.employee_name = %(employee_name)s
|
||||
AND detail.salary_component = %(component)s
|
||||
AND salary_slip.start_date >= %(period_start_date)s
|
||||
AND salary_slip.end_date < %(period_end_date)s
|
||||
AND salary_slip.name != %(docname)s
|
||||
AND salary_slip.docstatus = 1""",
|
||||
{'employee_name': self.employee_name, 'component': component.salary_component, 'period_start_date': period_start_date,
|
||||
'period_end_date': period_end_date, 'docname': self.name}
|
||||
)
|
||||
|
||||
year_to_date = flt(component_sum[0][0]) if component_sum else 0.0
|
||||
year_to_date += component.amount
|
||||
component.year_to_date = year_to_date
|
||||
|
||||
def get_year_to_date_period(self):
|
||||
payroll_period = get_payroll_period(self.start_date, self.end_date, self.company)
|
||||
|
||||
if payroll_period:
|
||||
period_start_date = payroll_period.start_date
|
||||
period_end_date = payroll_period.end_date
|
||||
else:
|
||||
# get dates based on fiscal year if no payroll period exists
|
||||
fiscal_year = get_fiscal_year(date=self.start_date, company=self.company, as_dict=1)
|
||||
period_start_date = fiscal_year.year_start_date
|
||||
period_end_date = fiscal_year.year_end_date
|
||||
|
||||
return period_start_date, period_end_date
|
||||
|
||||
def add_leave_balances(self):
|
||||
self.set('leave_details', [])
|
||||
|
||||
if frappe.db.get_single_value('Payroll Settings', 'show_leave_balances_in_salary_slip'):
|
||||
from erpnext.hr.doctype.leave_application.leave_application import get_leave_details
|
||||
leave_details = get_leave_details(self.employee, self.end_date)
|
||||
|
||||
for leave_type, leave_values in iteritems(leave_details['leave_allocation']):
|
||||
self.append('leave_details', {
|
||||
'leave_type': leave_type,
|
||||
'total_allocated_leaves': flt(leave_values.get('total_leaves')),
|
||||
'expired_leaves': flt(leave_values.get('expired_leaves')),
|
||||
'used_leaves': flt(leave_values.get('leaves_taken')),
|
||||
'pending_leaves': flt(leave_values.get('pending_leaves')),
|
||||
'available_leaves': flt(leave_values.get('remaining_leaves'))
|
||||
})
|
||||
|
||||
def unlink_ref_doc_from_salary_slip(ref_no):
|
||||
linked_ss = frappe.db.sql_list("""select name from `tabSalary Slip`
|
||||
where journal_entry=%s and docstatus < 2""", (ref_no))
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2021-02-19 11:45:18.173417",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"leave_type",
|
||||
"total_allocated_leaves",
|
||||
"expired_leaves",
|
||||
"used_leaves",
|
||||
"pending_leaves",
|
||||
"available_leaves"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "leave_type",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Leave Type",
|
||||
"no_copy": 1,
|
||||
"options": "Leave Type",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "total_allocated_leaves",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Total Allocated Leaves",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "expired_leaves",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Expired Leaves",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "used_leaves",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Used Leaves",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pending_leaves",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Pending Leaves",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "available_leaves",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Available Leaves",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-02-19 10:47:48.546724",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Salary Slip Leave",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class SalarySlipLeave(Document):
|
||||
pass
|
||||
@@ -212,8 +212,7 @@
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Represents Company",
|
||||
"options": "Company",
|
||||
"unique": 1
|
||||
"options": "Company"
|
||||
},
|
||||
{
|
||||
"depends_on": "represents_company",
|
||||
@@ -500,7 +499,7 @@
|
||||
"image_field": "image",
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-01-27 12:54:57.258959",
|
||||
"modified": "2021-01-28 12:54:57.258959",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Customer",
|
||||
|
||||
Reference in New Issue
Block a user