diff --git a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
index 13ed5b6b94..9aa2ee271a 100644
--- a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
+++ b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
@@ -22,7 +22,5 @@ class BankGuarantee(Document):
@frappe.whitelist()
def get_vouchar_detials(column_list, doctype, docname):
- print (column_list, doctype, docname)
return frappe.db.sql(''' select {columns} from `tab{doctype}` where name=%s'''
.format(columns=", ".join(json.loads(column_list)), doctype=doctype), docname, as_dict=1)[0]
-
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
index 1bff93cb77..d7aa0c0d19 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
@@ -111,10 +111,10 @@
{%= __("Age (Days)") %} |
{% if(report.report_name === "Accounts Receivable" && filters.show_sales_person_in_print) { %}
- {%= __("Reference") %} |
+ {%= __("Reference") %} |
{%= __("Sales Person") %} |
{% } else { %}
- {%= __("Reference") %} |
+ {%= __("Reference") %} |
{% } %}
{% if(!filters.show_pdc_in_print) { %}
{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %} |
@@ -127,7 +127,7 @@
{%= __("Outstanding Amount") %} |
{% if(filters.show_pdc_in_print) { %}
{% if(report.report_name === "Accounts Receivable") { %}
- {%= __("Customer LPO No.") %} |
+ {%= __("Customer LPO No.") %} |
{% } %}
{%= __("PDC/LC Ref") %} |
{%= __("PDC/LC Amount") %} |
diff --git a/erpnext/hr/doctype/additional_salary/additional_salary.js b/erpnext/hr/doctype/additional_salary/additional_salary.js
index a96bb94282..d0f64ab51b 100644
--- a/erpnext/hr/doctype/additional_salary/additional_salary.js
+++ b/erpnext/hr/doctype/additional_salary/additional_salary.js
@@ -3,13 +3,8 @@
frappe.ui.form.on('Additional Salary', {
setup: function(frm) {
- frm.set_query("salary_component", function() {
- return {
- filters: {
- is_additional_component: true
- }
- };
- });
+ frm.add_fetch("salary_component", "deduct_full_tax_on_selected_payroll_date", "deduct_full_tax_on_selected_payroll_date");
+
frm.set_query("employee", function() {
return {
filters: {
diff --git a/erpnext/hr/doctype/additional_salary/additional_salary.json b/erpnext/hr/doctype/additional_salary/additional_salary.json
index 7f9e51b5f9..6768b49e28 100644
--- a/erpnext/hr/doctype/additional_salary/additional_salary.json
+++ b/erpnext/hr/doctype/additional_salary/additional_salary.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
@@ -21,6 +22,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "fetch_if_empty": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -54,6 +56,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "employee",
"fieldtype": "Link",
"hidden": 0,
@@ -87,6 +90,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "salary_component",
"fieldtype": "Link",
"hidden": 0,
@@ -120,6 +124,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -153,6 +158,7 @@
"collapsible": 0,
"columns": 0,
"default": "1",
+ "fetch_if_empty": 0,
"fieldname": "overwrite_salary_structure_amount",
"fieldtype": "Check",
"hidden": 0,
@@ -185,6 +191,40 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "deduct_full_tax_on_selected_payroll_date",
+ "fieldtype": "Check",
+ "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": "Deduct Full Tax on Selected Payroll 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": 0,
+ "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,
+ "fetch_if_empty": 0,
"fieldname": "column_break_5",
"fieldtype": "Column Break",
"hidden": 0,
@@ -217,6 +257,8 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "description": "Date on which this component is applied",
+ "fetch_if_empty": 0,
"fieldname": "payroll_date",
"fieldtype": "Date",
"hidden": 0,
@@ -250,6 +292,7 @@
"collapsible": 0,
"columns": 0,
"fetch_from": "employee.employee_name",
+ "fetch_if_empty": 0,
"fieldname": "employee_name",
"fieldtype": "Data",
"hidden": 0,
@@ -284,6 +327,7 @@
"collapsible": 0,
"columns": 0,
"fetch_from": "employee.department",
+ "fetch_if_empty": 0,
"fieldname": "department",
"fieldtype": "Link",
"hidden": 0,
@@ -317,6 +361,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -350,6 +395,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "salary_slip",
"fieldtype": "Link",
"hidden": 0,
@@ -384,6 +430,7 @@
"collapsible": 0,
"columns": 0,
"fetch_from": "salary_component.type",
+ "fetch_if_empty": 0,
"fieldname": "type",
"fieldtype": "Data",
"hidden": 0,
@@ -417,6 +464,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -453,7 +501,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-08-21 14:44:22.921926",
+ "modified": "2019-05-09 19:53:37.475839",
"modified_by": "Administrator",
"module": "HR",
"name": "Additional Salary",
diff --git a/erpnext/hr/doctype/additional_salary/additional_salary.py b/erpnext/hr/doctype/additional_salary/additional_salary.py
index 043f0df78d..82f2a22e81 100644
--- a/erpnext/hr/doctype/additional_salary/additional_salary.py
+++ b/erpnext/hr/doctype/additional_salary/additional_salary.py
@@ -41,7 +41,8 @@ class AdditionalSalary(Document):
@frappe.whitelist()
def get_additional_salary_component(employee, start_date, end_date):
additional_components = frappe.db.sql("""
- select salary_component, sum(amount) as amount, overwrite_salary_structure_amount from `tabAdditional Salary`
+ select salary_component, sum(amount) as amount, overwrite_salary_structure_amount, deduct_full_tax_on_selected_payroll_date
+ from `tabAdditional Salary`
where employee=%(employee)s
and docstatus = 1
and payroll_date between %(from_date)s and %(to_date)s
@@ -54,16 +55,20 @@ def get_additional_salary_component(employee, start_date, end_date):
}, as_dict=1)
additional_components_list = []
+ component_fields = ["depends_on_payment_days", "salary_component_abbr", "is_tax_applicable", "variable_based_on_taxable_salary", 'type']
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_payment_days", "abbr", "is_tax_applicable", "variable_based_on_taxable_salary", "is_additional_component"]:
- struct_row[field] = component.get(field)
+ struct_row = frappe._dict({'salary_component': d.salary_component})
+ component = frappe.get_all("Salary Component", filters={'name': d.salary_component}, fields=component_fields)
+ if component:
+ struct_row.update(component[0])
- additional_components_list.append({
+ struct_row['deduct_full_tax_on_selected_payroll_date'] = d.deduct_full_tax_on_selected_payroll_date
+ struct_row['is_additional_component'] = 1
+
+ additional_components_list.append(frappe._dict({
'amount': d.amount,
- 'type': component.type,
+ 'type': component[0].type,
'struct_row': struct_row,
- 'overwrite': d.overwrite_salary_structure_amount
- })
+ 'overwrite': d.overwrite_salary_structure_amount,
+ }))
return additional_components_list
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
index 412a08aa9f..e71ce1276b 100644
--- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
+++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
@@ -3,13 +3,18 @@
frappe.ui.form.on('Employee Benefit Application', {
setup: function(frm) {
- frm.set_query("earning_component", "employee_benefits", function() {
- return {
- query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components",
- filters: {date: frm.doc.date, employee: frm.doc.employee}
- };
- });
+ if(!frm.doc.employee || !frm.doc.date) {
+ frappe.throw(__("Please select Employee and Date first"));
+ } else {
+ frm.set_query("earning_component", "employee_benefits", function() {
+ return {
+ query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components",
+ filters: {date: frm.doc.date, employee: frm.doc.employee}
+ };
+ });
+ }
},
+
employee: function(frm) {
var method, args;
if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){
diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
index 701ae2465f..fea4246d64 100644
--- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
+++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
@@ -7,7 +7,7 @@ import frappe
from frappe import _
from frappe.utils import date_diff, getdate, rounded, add_days, cstr, cint, flt
from frappe.model.document import Document
-from erpnext.hr.doctype.payroll_period.payroll_period import get_payroll_period_days
+from erpnext.hr.doctype.payroll_period.payroll_period import get_payroll_period_days, get_period_factor
from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure
from erpnext.hr.utils import get_sal_slip_total_benefit_given, get_holidays_for_employee, get_previous_claimed_amount
@@ -131,7 +131,7 @@ def get_max_benefits_remaining(employee, on_date, payroll_period):
salary_component = frappe.get_doc("Salary Component", sal_struct_row.salary_component)
if salary_component.depends_on_payment_days == 1 and salary_component.pay_against_benefit_claim != 1:
have_depends_on_payment_days = True
- benefit_amount = get_benefit_pro_rata_ratio_amount(sal_struct, salary_component.max_benefit_amount)
+ benefit_amount = get_benefit_amount_based_on_pro_rata(sal_struct, salary_component.max_benefit_amount)
amount_per_day = benefit_amount / payroll_period_days
per_day_amount_total += amount_per_day
@@ -167,16 +167,14 @@ def calculate_lwp(employee, start_date, holidays, working_days):
lwp = cint(leave[0][1]) and (lwp + 0.5) or (lwp + 1)
return lwp
-def get_benefit_component_amount(employee, start_date, end_date, struct_row, sal_struct, period_length, frequency):
- payroll_period, period_factor, actual_payroll_days = get_payroll_period_days(start_date, end_date, employee)
-
+def get_benefit_component_amount(employee, start_date, end_date, salary_component, sal_struct, payroll_frequency, payroll_period):
if not payroll_period:
- frappe.msgprint(_("Start and end dates not in a valid Payroll Period, cannot calculate {0}.")
- .format(struct_row.salary_component))
+ frappe.msgprint(_("Start and end dates not in a valid Payroll Period, cannot calculate {0}")
+ .format(salary_component))
return False
# Considering there is only one application for a year
- benefit_application_name = frappe.db.sql("""
+ benefit_application = frappe.db.sql("""
select name
from `tabEmployee Benefit Application`
where
@@ -185,69 +183,58 @@ def get_benefit_component_amount(employee, start_date, end_date, struct_row, sal
and docstatus = 1
""", {
'employee': employee,
- 'payroll_period': payroll_period
+ 'payroll_period': payroll_period.name
})
- if frappe.db.get_value("Salary Component", struct_row.salary_component, "depends_on_payment_days") != 1:
- if frequency == "Monthly" and actual_payroll_days in range(360, 370):
- period_length = 1
- period_factor = 12
+ current_benefit_amount = 0.0
+ component_max_benefit, depends_on_payment_days = frappe.db.get_value("Salary Component",
+ salary_component, ["max_benefit_amount", "depends_on_payment_days"])
- if period_factor:
- # If there is application for benefit then fetch the amount from the application.
- # else Split the max benefits to the pro-rata components with the ratio of their max_benefit_amount
- if benefit_application_name:
- benefit_application = frappe.get_doc("Employee Benefit Application", benefit_application_name[0][0])
- return get_benefit_amount(benefit_application, struct_row, period_factor, period_length)
+ if benefit_application:
+ benefit_amount = frappe.db.get_value("Employee Benefit Application Detail",
+ {"parent": benefit_application[0][0], "earning_component": salary_component}, "amount")
+ elif component_max_benefit:
+ benefit_amount = get_benefit_amount_based_on_pro_rata(sal_struct, component_max_benefit)
- # TODO: Check if there is benefit claim for employee then pro-rata divide the rest of amount (Late Benefit Application)
- else:
- component_max = frappe.db.get_value("Salary Component", struct_row.salary_component, "max_benefit_amount")
- if component_max:
- benefit_amount = get_benefit_pro_rata_ratio_amount(sal_struct, component_max)
- return get_amount(period_factor, benefit_amount, period_length)
- return False
+ current_benefit_amount = 0
+ if benefit_amount:
+ total_sub_periods = get_period_factor(employee,
+ start_date, end_date, payroll_frequency, payroll_period, depends_on_payment_days)[0]
-def get_benefit_pro_rata_ratio_amount(sal_struct, component_max):
- total_pro_rata_max = 0
+ current_benefit_amount = benefit_amount / total_sub_periods
+
+ return current_benefit_amount
+
+def get_benefit_amount_based_on_pro_rata(sal_struct, component_max_benefit):
+ max_benefits_total = 0
benefit_amount = 0
- for sal_struct_row in sal_struct.get("earnings"):
- pay_against_benefit_claim, max_benefit_amount = frappe.db.get_value("Salary Component",
- sal_struct_row.salary_component, ["pay_against_benefit_claim", "max_benefit_amount"])
- if sal_struct_row.is_flexible_benefit == 1 and pay_against_benefit_claim != 1:
- total_pro_rata_max += max_benefit_amount
- if total_pro_rata_max > 0:
- benefit_amount = component_max * sal_struct.max_benefits / total_pro_rata_max
- if benefit_amount > component_max:
- benefit_amount = component_max
+ for d in sal_struct.get("earnings"):
+ if d.is_flexible_benefit == 1:
+ component = frappe.db.get_value("Salary Component", d.salary_component, ["max_benefit_amount", "pay_against_benefit_claim"], as_dict=1)
+ if not component.pay_against_benefit_claim:
+ max_benefits_total += component.max_benefit_amount
+
+ if max_benefits_total > 0:
+ benefit_amount = sal_struct.max_benefits * component.max_benefit_amount / max_benefits_total
+ if benefit_amount > component_max_benefit:
+ benefit_amount = component_max_benefit
+
return benefit_amount
-def get_benefit_amount(application, struct_row, period_factor, period_length):
- amount = 0
- for employee_benefit in application.employee_benefits:
- if employee_benefit.earning_component == struct_row.salary_component:
- amount += get_amount(period_factor, employee_benefit.amount, period_length)
- return amount if amount > 0 else False
-
-def get_amount(period_factor, amount, period_length):
- amount_per_day = amount / period_factor
- total_amount = amount_per_day * period_length
- return total_amount
def get_earning_components(doctype, txt, searchfield, start, page_len, filters):
if len(filters) < 2:
return {}
- employee = filters['employee']
- date = filters['date']
- salary_structure = get_assigned_salary_structure(employee, date)
+
+ salary_structure = get_assigned_salary_structure(filters['employee'], filters['date'])
if salary_structure:
- query = """select salary_component from `tabSalary Detail` where parent = '{salary_structure}'
- and is_flexible_benefit = 1
- order by name"""
-
- return frappe.db.sql(query.format(**{
- "salary_structure": salary_structure
- }))
-
- return {}
+ return frappe.db.sql("""
+ select salary_component
+ from `tabSalary Detail`
+ where parent = %s and is_flexible_benefit = 1
+ order by name
+ """, salary_structure)
+ else:
+ frappe.throw(_("Salary Structure not found for employee {0} and date {1}")
+ .format(filters['employee'], filters['date']))
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.py b/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.py
index 8be67a866a..3a80b30365 100644
--- a/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.py
+++ b/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.py
@@ -5,9 +5,11 @@
from __future__ import unicode_literals
import frappe
from frappe import _
+from frappe.utils import flt
from frappe.model.document import Document
from erpnext.hr.doctype.employee_benefit_application.employee_benefit_application import get_max_benefits
-from erpnext.hr.utils import get_payroll_period, get_previous_claimed_amount
+from erpnext.hr.utils import get_previous_claimed_amount
+from erpnext.hr.doctype.payroll_period.payroll_period import get_payroll_period
from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure
class EmployeeBenefitClaim(Document):
@@ -97,31 +99,28 @@ def get_benefit_pro_rata_ratio_amount(employee, on_date, sal_struct):
benefit_amount_total += benefit_amount
return benefit_amount_total
-def get_benefit_claim_amount(employee, start_date, end_date, salary_component):
- query = """select claimed_amount from `tabEmployee Benefit Claim`
- where employee=%(employee)s
- and docstatus = 1 and pay_against_benefit_claim = 1
+def get_benefit_claim_amount(employee, start_date, end_date, salary_component=None):
+ query = """
+ select sum(claimed_amount)
+ from `tabEmployee Benefit Claim`
+ where
+ employee=%(employee)s
+ and docstatus = 1
+ and pay_against_benefit_claim = 1
+ and claim_date between %(start_date)s and %(end_date)s
"""
- if not start_date:
- query += "and claim_date <= %(end_date)s"
- else:
- query += "and (claim_date between %(start_date)s and %(end_date)s)"
if salary_component:
- query += "and earning_component = %(earning_component)s"
+ query += " and earning_component = %(earning_component)s"
- benefit_claim_details = frappe.db.sql(query, {
+ claimed_amount = flt(frappe.db.sql(query, {
'employee': employee,
'start_date': start_date,
'end_date': end_date,
'earning_component': salary_component
- }, as_dict = True)
- if benefit_claim_details:
- claimed_amount = 0
- for claim_detail in benefit_claim_details:
- claimed_amount += claim_detail.claimed_amount
- return claimed_amount
- return False
+ })[0][0])
+
+ return claimed_amount
def get_total_benefit_dispensed(employee, sal_struct, sal_slip_start_date, payroll_period):
pro_rata_amount = 0
@@ -140,11 +139,11 @@ def get_total_benefit_dispensed(employee, sal_struct, sal_slip_start_date, payro
else:
pro_rata_amount = get_benefit_pro_rata_ratio_amount(employee, sal_slip_start_date, sal_struct)
- claimed_amount += get_benefit_claim_amount(employee, payroll_period.start_date, payroll_period.end_date, False)
+ claimed_amount += get_benefit_claim_amount(employee, payroll_period.start_date, payroll_period.end_date)
return claimed_amount + pro_rata_amount
-def get_last_payroll_period_benefits(employee, sal_slip_start_date, sal_slip_end_date, current_flexi_amount, payroll_period, sal_struct):
+def get_last_payroll_period_benefits(employee, sal_slip_start_date, sal_slip_end_date, payroll_period, sal_struct):
max_benefits = get_max_benefits(employee, payroll_period.end_date)
if not max_benefits:
max_benefits = 0
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json
index 8891b97a5d..e102ff8d70 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json
@@ -446,6 +446,72 @@
"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,
+ "fetch_if_empty": 0,
+ "fieldname": "other_incomes_section",
+ "fieldtype": "Section Break",
+ "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": "Other Incomes",
+ "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": 0,
+ "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,
+ "fetch_if_empty": 0,
+ "fieldname": "income_from_other_sources",
+ "fieldtype": "Currency",
+ "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": "Income From Other Sources",
+ "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": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
}
],
"has_web_view": 0,
@@ -458,7 +524,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2019-04-25 16:38:05.847925",
+ "modified": "2019-05-11 16:13:50.472670",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Tax Exemption Declaration",
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py
index cbdfcf8ecd..f2bba7afed 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py
@@ -25,7 +25,8 @@ class EmployeeTaxExemptionDeclaration(Document):
filters = {
"employee": self.employee,
"payroll_period": self.payroll_period,
- "name": ["!=", self.name]
+ "name": ["!=", self.name],
+ "docstatus": ["!=", 2]
}
)
if duplicate:
diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json
index 76c09d6c7b..9792bd1db6 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json
@@ -448,6 +448,72 @@
"translatable": 0,
"unique": 0
},
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "other_incomes_section",
+ "fieldtype": "Section Break",
+ "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": "Other Incomes",
+ "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": 0,
+ "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,
+ "fetch_if_empty": 0,
+ "fieldname": "income_from_other_sources",
+ "fieldtype": "Currency",
+ "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": "Income From Other Sources",
+ "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": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@@ -558,7 +624,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2019-04-25 17:06:36.569549",
+ "modified": "2019-05-13 12:17:18.045171",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Tax Exemption Proof Submission",
diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.py b/erpnext/hr/doctype/payroll_entry/payroll_entry.py
index 0961ffc5df..4ce2513bea 100644
--- a/erpnext/hr/doctype/payroll_entry/payroll_entry.py
+++ b/erpnext/hr/doctype/payroll_entry/payroll_entry.py
@@ -543,14 +543,15 @@ def submit_salary_slips_for_employees(payroll_entry, salary_slips, publish_progr
payroll_entry.email_salary_slip(submitted_ss)
- payroll_entry.db_set("salary_slips_submitted", 1)
- payroll_entry.notify_update()
+ payroll_entry.db_set("salary_slips_submitted", 1)
+ payroll_entry.notify_update()
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 some Salary Slips"))
+
def get_payroll_entries_for_jv(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""
select name from `tabPayroll Entry`
diff --git a/erpnext/hr/doctype/payroll_period/payroll_period.py b/erpnext/hr/doctype/payroll_period/payroll_period.py
index 506af99f50..cb4264ba4e 100644
--- a/erpnext/hr/doctype/payroll_period/payroll_period.py
+++ b/erpnext/hr/doctype/payroll_period/payroll_period.py
@@ -5,7 +5,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
-from frappe.utils import date_diff, getdate, formatdate, cint
+from frappe.utils import date_diff, getdate, formatdate, cint, month_diff, flt
from frappe.model.document import Document
from erpnext.hr.utils import get_holidays_for_employee
@@ -48,12 +48,13 @@ class PayrollPeriod(Document):
def get_payroll_period_days(start_date, end_date, employee):
company = frappe.db.get_value("Employee", employee, "company")
payroll_period = frappe.db.sql("""
- select name, start_date, end_date from `tabPayroll Period`
- where company=%(company)s
- and (
- (%(start_date)s between start_date and end_date)
- and (%(end_date)s between start_date and end_date)
- )""", {
+ select name, start_date, end_date
+ from `tabPayroll Period`
+ where
+ company=%(company)s
+ and %(start_date)s between start_date and end_date
+ and %(end_date)s between start_date and end_date
+ """, {
'company': company,
'start_date': start_date,
'end_date': end_date
@@ -67,3 +68,38 @@ def get_payroll_period_days(start_date, end_date, employee):
working_days -= len(holidays)
return payroll_period[0][0], working_days, actual_no_of_days
return False, False, False
+
+def get_payroll_period(from_date, to_date, company):
+ payroll_period = frappe.db.sql("""
+ select name, start_date, end_date
+ from `tabPayroll Period`
+ where start_date<=%s and end_date>= %s and company=%s
+ """, (from_date, to_date, company), as_dict=1)
+
+ return payroll_period[0] if payroll_period else None
+
+def get_period_factor(employee, start_date, end_date, payroll_frequency, payroll_period, depends_on_payment_days=0):
+ # TODO if both deduct checked update the factor to make tax consistent
+ period_start, period_end = payroll_period.start_date, payroll_period.end_date
+ joining_date, relieving_date = frappe.db.get_value("Employee", employee, ["date_of_joining", "relieving_date"])
+
+ if getdate(joining_date) > getdate(period_start):
+ period_start = joining_date
+ if relieving_date and getdate(relieving_date) < getdate(period_end):
+ period_end = relieving_date
+
+ total_sub_periods, remaining_sub_periods = 0.0, 0.0
+
+ if payroll_frequency == "Monthly" and not depends_on_payment_days:
+ total_sub_periods = month_diff(payroll_period.end_date, payroll_period.start_date)
+ remaining_sub_periods = month_diff(period_end, start_date)
+ else:
+ salary_days = date_diff(end_date, start_date) + 1
+
+ days_in_payroll_period = date_diff(payroll_period.end_date, payroll_period.start_date) + 1
+ total_sub_periods = flt(days_in_payroll_period) / flt(salary_days)
+
+ remaining_days_in_payroll_period = date_diff(period_end, start_date) + 1
+ remaining_sub_periods = flt(remaining_days_in_payroll_period) / flt(salary_days)
+
+ return total_sub_periods, remaining_sub_periods
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_component/salary_component.js b/erpnext/hr/doctype/salary_component/salary_component.js
index f6afd5efeb..c455eb3303 100644
--- a/erpnext/hr/doctype/salary_component/salary_component.js
+++ b/erpnext/hr/doctype/salary_component/salary_component.js
@@ -24,14 +24,6 @@ frappe.ui.form.on('Salary Component', {
is_flexible_benefit: function(frm) {
if(frm.doc.is_flexible_benefit){
set_value_for_condition_and_formula(frm);
- frm.set_value("is_additional_component", 0);
- frm.set_value("formula", '');
- frm.set_value("amount", 0);
- }
- },
- is_additional_component: function(frm) {
- if(frm.doc.is_additional_component){
- frm.set_value("is_flexible_benefit", 0);
frm.set_value("formula", '');
frm.set_value("amount", 0);
}
diff --git a/erpnext/hr/doctype/salary_component/salary_component.json b/erpnext/hr/doctype/salary_component/salary_component.json
index 697d224092..ca49ceac00 100644
--- a/erpnext/hr/doctype/salary_component/salary_component.json
+++ b/erpnext/hr/doctype/salary_component/salary_component.json
@@ -115,40 +115,6 @@
"translatable": 0,
"unique": 0
},
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.is_flexible_benefit != 1",
- "fetch_if_empty": 0,
- "fieldname": "is_additional_component",
- "fieldtype": "Check",
- "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": "Is Additional Component",
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@@ -285,6 +251,39 @@
"translatable": 0,
"unique": 0
},
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "deduct_full_tax_on_selected_payroll_date",
+ "fieldtype": "Check",
+ "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": "Deduct Full Tax on Selected Payroll 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": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@@ -424,7 +423,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "depends_on": "eval:doc.type==\"Earning\" && doc.is_additional_component != 1 && doc.statistical_component!=1",
+ "depends_on": "eval:doc.type==\"Earning\" && doc.statistical_component!=1",
"fetch_if_empty": 0,
"fieldname": "flexible_benefits",
"fieldtype": "Section Break",
@@ -458,7 +457,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "depends_on": "eval:doc.is_additional_component != 1",
+ "depends_on": "",
"fetch_if_empty": 0,
"fieldname": "is_flexible_benefit",
"fieldtype": "Check",
@@ -1035,7 +1034,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2019-04-16 19:08:55.323567",
+ "modified": "2019-05-13 12:55:55.424370",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Component",
diff --git a/erpnext/hr/doctype/salary_component/test_records.json b/erpnext/hr/doctype/salary_component/test_records.json
index 69491bed99..7b22b481f3 100644
--- a/erpnext/hr/doctype/salary_component/test_records.json
+++ b/erpnext/hr/doctype/salary_component/test_records.json
@@ -35,7 +35,6 @@
"salary_component": "Leave Encashment",
"type": "Earning",
"is_payable": 1,
- "is_tax_applicable": 1,
- "is_additional_component": 1
+ "is_tax_applicable": 1
}
]
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_component/test_salary_component.py b/erpnext/hr/doctype/salary_component/test_salary_component.py
index c13843aca7..965cc9e9ff 100644
--- a/erpnext/hr/doctype/salary_component/test_salary_component.py
+++ b/erpnext/hr/doctype/salary_component/test_salary_component.py
@@ -19,7 +19,5 @@ def create_salary_component(component_name, **args):
"salary_component": component_name,
"type": args.get("type") or "Earning",
"is_payable": args.get("is_payable") or 1,
- "is_tax_applicable": args.get("is_tax_applicable") or 1,
- "is_additional_component": args.get("is_additional_component") or 1
+ "is_tax_applicable": args.get("is_tax_applicable") or 1
}).insert()
-
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_detail/salary_detail.json b/erpnext/hr/doctype/salary_detail/salary_detail.json
index 8f2649ad21..edf2786821 100644
--- a/erpnext/hr/doctype/salary_detail/salary_detail.json
+++ b/erpnext/hr/doctype/salary_detail/salary_detail.json
@@ -218,41 +218,6 @@
"translatable": 0,
"unique": 0
},
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fetch_from": "salary_component.is_additional_component",
- "fetch_if_empty": 0,
- "fieldname": "is_additional_component",
- "fieldtype": "Check",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Is Additional Component",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "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,
@@ -323,6 +288,39 @@
"translatable": 0,
"unique": 0
},
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "deduct_full_tax_on_selected_payroll_date",
+ "fieldtype": "Check",
+ "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": "Deduct Full Tax on Selected Payroll Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "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,
@@ -566,6 +564,41 @@
"translatable": 0,
"unique": 0
},
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fetch_from": "",
+ "fetch_if_empty": 0,
+ "fieldname": "additional_amount",
+ "fieldtype": "Currency",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Additional Amount",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "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,
@@ -713,7 +746,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2019-04-16 19:09:31.726597",
+ "modified": "2019-05-11 17:33:08.508653",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Detail",
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.js b/erpnext/hr/doctype/salary_slip/salary_slip.js
index 4e9fcce898..f430eeed4e 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.js
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.js
@@ -11,7 +11,7 @@ frappe.ui.form.on("Salary Slip", {
{fieldname: 'salary_component', columns: 6},
{fieldname: 'amount', columns: 4}
];
- })
+ });
frm.fields_dict["timesheets"].grid.get_field("time_sheet").get_query = function(){
return {
@@ -19,31 +19,39 @@ frappe.ui.form.on("Salary Slip", {
employee: frm.doc.employee
}
}
- }
+ };
+
frm.set_query("salary_component", "earnings", function() {
return {
filters: {
type: "earning"
}
}
- })
+ });
+
frm.set_query("salary_component", "deductions", function() {
return {
filters: {
type: "deduction"
}
}
- })
+ });
+
+ frm.set_query("employee", function() {
+ return{
+ query: "erpnext.controllers.queries.employee_query"
+ }
+ });
},
- start_date: function(frm, dt, dn){
+ start_date: function(frm){
if(frm.doc.start_date){
frm.trigger("set_end_date");
}
},
- end_date: function(frm, dt, dn) {
- get_emp_and_leave_details(frm.doc, dt, dn);
+ end_date: function(frm) {
+ frm.events.get_emp_and_leave_details(frm);
},
set_end_date: function(frm){
@@ -70,43 +78,54 @@ frappe.ui.form.on("Salary Slip", {
refresh: function(frm) {
frm.trigger("toggle_fields")
- frm.trigger("toggle_reqd_fields")
- var salary_detail_fields = ["formula", "abbr", "statistical_component", "is_tax_applicable",
- "is_flexible_benefit", "variable_based_on_taxable_salary", "is_additional_component"]
+
+ var salary_detail_fields = ["formula", "abbr", "statistical_component", "variable_based_on_taxable_salary"];
cur_frm.fields_dict['earnings'].grid.set_column_disp(salary_detail_fields,false);
cur_frm.fields_dict['deductions'].grid.set_column_disp(salary_detail_fields,false);
},
- salary_slip_based_on_timesheet: function(frm, dt, dn) {
+ salary_slip_based_on_timesheet: function(frm) {
frm.trigger("toggle_fields");
- get_emp_and_leave_details(frm.doc, dt, dn);
+ frm.events.get_emp_and_leave_details(frm);
},
- payroll_frequency: function(frm, dt, dn) {
+ payroll_frequency: function(frm) {
frm.trigger("toggle_fields");
frm.set_value('end_date', '');
},
- employee: function(frm, dt, dn) {
- get_emp_and_leave_details(frm.doc, dt, dn);
+ employee: function(frm) {
+ frm.events.get_emp_and_leave_details(frm);
+ },
+
+ leave_without_pay: function(frm){
+ if (frm.doc.employee && frm.doc.start_date && frm.doc.end_date) {
+ return frappe.call({
+ method: 'process_salary_based_on_leave',
+ doc: frm.doc,
+ args: {"lwp": frm.doc.leave_without_pay},
+ callback: function(r, rt) {
+ frm.refresh();
+ }
+ });
+ }
},
toggle_fields: function(frm) {
- frm.toggle_display(['hourly_wages', 'timesheets'],
- cint(frm.doc.salary_slip_based_on_timesheet)==1);
+ frm.toggle_display(['hourly_wages', 'timesheets'], cint(frm.doc.salary_slip_based_on_timesheet)===1);
frm.toggle_display(['payment_days', 'total_working_days', 'leave_without_pay'],
frm.doc.payroll_frequency!="");
- }
-
-})
-
-frappe.ui.form.on('Salary Detail', {
- earnings_remove: function(frm, dt, dn) {
- calculate_all(frm.doc, dt, dn);
},
- deductions_remove: function(frm, dt, dn) {
- calculate_all(frm.doc, dt, dn);
+
+ get_emp_and_leave_details: function(frm) {
+ return frappe.call({
+ method: 'get_emp_and_leave_details',
+ doc: frm.doc,
+ callback: function(r, rt) {
+ frm.refresh();
+ }
+ });
}
})
@@ -119,133 +138,29 @@ frappe.ui.form.on('Salary Slip Timesheet', {
}
});
-// Get leave details
-//---------------------------------------------------------------------
-var get_emp_and_leave_details = function(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){
- if (doc.employee && doc.start_date && doc.end_date) {
- return $c_obj(doc, 'get_leave_details', {"lwp": doc.leave_without_pay}, function(r, rt) {
- var doc = locals[dt][dn];
- cur_frm.refresh();
- calculate_all(doc, dt, dn);
- });
- }
-}
-
-var calculate_all = function(doc, dt, dn) {
- calculate_earning_total(doc, dt, dn);
- calculate_ded_total(doc, dt, dn);
- calculate_net_pay(doc, dt, dn);
-}
-
-cur_frm.cscript.amount = function(doc,dt,dn){
- var child = locals[dt][dn];
- if(!doc.salary_structure){
- frappe.model.set_value(dt,dn, "default_amount", child.amount)
- }
- calculate_all(doc, dt, dn);
-}
-
-cur_frm.cscript.depends_on_payment_days = function(doc,dt,dn){
- calculate_earning_total(doc, dt, dn, true);
- calculate_ded_total(doc, dt, dn, true);
- calculate_net_pay(doc, dt, dn);
- refresh_many(['amount','gross_pay', 'rounded_total', 'net_pay', 'loan_repayment']);
-};
-
-// Calculate earning total
-// ------------------------------------------------------------------------
-var calculate_earning_total = function(doc, dt, dn, reset_amount) {
-
- var tbl = doc.earnings || [];
- var total_earn = 0;
- for(var i = 0; i < tbl.length; i++){
- if(cint(tbl[i].depends_on_payment_days) == 1) {
- tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days) /
- cint(doc.total_working_days)*100)/100;
- } else if(reset_amount && tbl[i].default_amount) {
- tbl[i].amount = tbl[i].default_amount;
- }
- if(!tbl[i].do_not_include_in_total) {
- total_earn += flt(tbl[i].amount);
-
- }
- }
- doc.gross_pay = total_earn;
- refresh_many(['earnings', 'amount','gross_pay']);
-
-}
-
-// Calculate deduction total
-// ------------------------------------------------------------------------
-var calculate_ded_total = function(doc, dt, dn, reset_amount) {
- var tbl = doc.deductions || [];
- var total_ded = 0;
- for(var i = 0; i < tbl.length; i++){
- if(cint(tbl[i].depends_on_payment_days) == 1) {
- tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days)/cint(doc.total_working_days)*100)/100;
- } else if(reset_amount && tbl[i].default_amount) {
- tbl[i].amount = tbl[i].default_amount;
- }
- if(!tbl[i].do_not_include_in_total) {
- total_ded += flt(tbl[i].amount);
- }
- }
- doc.total_deduction = total_ded;
- refresh_many(['deductions', 'total_deduction']);
-}
-
-var calculate_net_pay = function(doc, dt, dn) {
- doc.net_pay = flt(doc.gross_pay) - flt(doc.total_deduction);
- doc.rounded_total = Math.round(doc.net_pay);
- refresh_many(['net_pay', 'rounded_total']);
-}
-
-cur_frm.cscript.validate = function(doc, dt, dn) {
- calculate_all(doc, dt, dn);
-}
-
-cur_frm.fields_dict.employee.get_query = function(doc,cdt,cdn) {
- return{
- query: "erpnext.controllers.queries.employee_query"
- }
-}
-
// calculate total working hours, earnings based on hourly wages and totals
-// ------------------------------------------------------------------------
var total_work_hours = function(frm, dt, dn) {
- frm.set_value('total_working_hours', 0);
-
+ var total_working_hours = 0.0;
$.each(frm.doc["timesheets"] || [], function(i, timesheet) {
- frm.doc.total_working_hours += timesheet.working_hours;
+ total_working_hours += timesheet.working_hours;
});
- frm.refresh_field('total_working_hours');
+ frm.set_value('total_working_hours', total_working_hours);
var wages_amount = frm.doc.total_working_hours * frm.doc.hour_rate;
frappe.db.get_value('Salary Structure', {'name': frm.doc.salary_structure}, 'salary_component', (r) => {
- frm.set_value('gross_pay', 0);
-
+ var gross_pay = 0.0;
$.each(frm.doc["earnings"], function(i, earning) {
if (earning.salary_component == r.salary_component) {
earning.amount = wages_amount;
frm.refresh_fields('earnings');
}
- frm.doc.gross_pay += earning.amount;
+ gross_pay += earning.amount;
});
+ frm.set_value('gross_pay', gross_pay);
- frm.refresh_field('gross_pay');
- calculate_net_pay(frm.doc, dt, dn);
+ frm.doc.net_pay = flt(frm.doc.gross_pay) - flt(frm.doc.total_deduction);
+ frm.doc.rounded_total = Math.round(frm.doc.net_pay);
+ refresh_many(['net_pay', 'rounded_total']);
});
}
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.json b/erpnext/hr/doctype/salary_slip/salary_slip.json
index c9a5d87281..681b008d02 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.json
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.json
@@ -1,1984 +1,1955 @@
{
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
- "creation": "2013-01-10 16:34:15",
- "custom": 0,
- "default_print_format": "",
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2013-01-10 16:34:15",
+ "custom": 0,
+ "default_print_format": "",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 0,
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Today",
- "fieldname": "posting_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Posting 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,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Today",
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Posting 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,
+ "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": "employee",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Employee",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "employee",
- "oldfieldtype": "Link",
- "options": "Employee",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "employee",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Employee",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "employee",
+ "oldfieldtype": "Link",
+ "options": "Employee",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 1,
+ "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,
- "fetch_from": "employee.employee_name",
- "fieldname": "employee_name",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Employee Name",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "employee_name",
- "oldfieldtype": "Data",
- "options": "",
- "permlevel": 0,
- "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,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "employee.employee_name",
+ "fieldname": "employee_name",
+ "fieldtype": "Read Only",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Employee Name",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "employee_name",
+ "oldfieldtype": "Data",
+ "options": "",
+ "permlevel": 0,
+ "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,
+ "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,
- "fetch_from": "employee.department",
- "fieldname": "department",
- "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": 1,
- "label": "Department",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "department",
- "oldfieldtype": "Link",
- "options": "Department",
- "permlevel": 0,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "employee.department",
+ "fieldname": "department",
+ "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": 1,
+ "label": "Department",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "department",
+ "oldfieldtype": "Link",
+ "options": "Department",
+ "permlevel": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.designation",
- "fetch_from": "employee.designation",
- "fieldname": "designation",
- "fieldtype": "Read Only",
- "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": "Designation",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "designation",
- "oldfieldtype": "Link",
- "options": "",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.designation",
+ "fetch_from": "employee.designation",
+ "fieldname": "designation",
+ "fieldtype": "Read Only",
+ "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": "Designation",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "designation",
+ "oldfieldtype": "Link",
+ "options": "",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "employee.branch",
- "fieldname": "branch",
- "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": 1,
- "label": "Branch",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "branch",
- "oldfieldtype": "Link",
- "options": "Branch",
- "permlevel": 0,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "employee.branch",
+ "fieldname": "branch",
+ "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": 1,
+ "label": "Branch",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "branch",
+ "oldfieldtype": "Link",
+ "options": "Branch",
+ "permlevel": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break1",
- "fieldtype": "Column Break",
- "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,
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "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,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break1",
+ "fieldtype": "Column Break",
+ "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,
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Column Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "50%"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "status",
- "fieldtype": "Select",
- "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": "Status",
- "length": 0,
- "no_copy": 0,
- "options": "Draft\nSubmitted\nCancelled",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "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": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Draft\nSubmitted\nCancelled",
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "journal_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": "Journal Entry",
- "length": 0,
- "no_copy": 0,
- "options": "Journal 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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "journal_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": "Journal Entry",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Journal 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,
- "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,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 1,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 1,
+ "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": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "letter_head",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Letter Head",
- "length": 0,
- "no_copy": 0,
- "options": "Letter Head",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "letter_head",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Letter Head",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Letter Head",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_10",
- "fieldtype": "Section Break",
- "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,
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_10",
+ "fieldtype": "Section Break",
+ "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,
+ "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": 0,
+ "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,
- "depends_on": "",
- "fieldname": "salary_slip_based_on_timesheet",
- "fieldtype": "Check",
- "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 Based on Timesheet",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "salary_slip_based_on_timesheet",
+ "fieldtype": "Check",
+ "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 Based on Timesheet",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "start_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": "Start 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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fieldname": "start_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": "Start 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": 0,
+ "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,
- "default": "",
- "depends_on": "",
- "fieldname": "end_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": "End 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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "depends_on": "",
+ "fieldname": "end_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": "End 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": 0,
+ "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": "column_break_15",
- "fieldtype": "Column Break",
- "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,
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_15",
+ "fieldtype": "Column Break",
+ "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,
+ "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": 0,
+ "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,
- "depends_on": "",
- "fieldname": "salary_structure",
- "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 Structure",
- "length": 0,
- "no_copy": 0,
- "options": "Salary Structure",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "salary_structure",
+ "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 Structure",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Salary Structure",
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "depends_on": "eval:(!doc.salary_slip_based_on_timesheet)",
- "fieldname": "payroll_frequency",
- "fieldtype": "Select",
- "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 Frequency",
- "length": 0,
- "no_copy": 0,
- "options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "depends_on": "eval:(!doc.salary_slip_based_on_timesheet)",
+ "fieldname": "payroll_frequency",
+ "fieldtype": "Select",
+ "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 Frequency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "total_working_days",
- "fieldtype": "Float",
- "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": "Working Days",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "total_days_in_month",
- "oldfieldtype": "Int",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "total_working_days",
+ "fieldtype": "Float",
+ "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": "Working Days",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "total_days_in_month",
+ "oldfieldtype": "Int",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "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,
- "depends_on": "",
- "fieldname": "leave_without_pay",
- "fieldtype": "Float",
- "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": "Leave Without Pay",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "leave_without_pay",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "leave_without_pay",
+ "fieldtype": "Float",
+ "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": "Leave Without Pay",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "leave_without_pay",
+ "oldfieldtype": "Currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "payment_days",
- "fieldtype": "Float",
- "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": "Payment Days",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "payment_days",
- "oldfieldtype": "Float",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "payment_days",
+ "fieldtype": "Float",
+ "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": "Payment Days",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "payment_days",
+ "oldfieldtype": "Float",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "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,
- "depends_on": "",
- "fieldname": "hourly_wages",
- "fieldtype": "Section Break",
- "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": "",
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "hourly_wages",
+ "fieldtype": "Section Break",
+ "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": "",
+ "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": 0,
+ "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,
- "depends_on": "",
- "fieldname": "timesheets",
- "fieldtype": "Table",
- "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 Timesheet",
- "length": 0,
- "no_copy": 0,
- "options": "Salary Slip Timesheet",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "timesheets",
+ "fieldtype": "Table",
+ "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 Timesheet",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Salary Slip Timesheet",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_20",
- "fieldtype": "Column Break",
- "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,
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_20",
+ "fieldtype": "Column Break",
+ "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,
+ "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": 0,
+ "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": "total_working_hours",
- "fieldtype": "Float",
- "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": "Total Working Hours",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 1,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "total_working_hours",
+ "fieldtype": "Float",
+ "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": "Total Working Hours",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 1,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "hour_rate",
- "fieldtype": "Currency",
- "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": "Hour Rate",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 1,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "hour_rate",
+ "fieldtype": "Currency",
+ "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": "Hour Rate",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 1,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "section_break_26",
- "fieldtype": "Section Break",
- "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": "",
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "section_break_26",
+ "fieldtype": "Section Break",
+ "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": "",
+ "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": 0,
+ "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": "bank_name",
- "fieldtype": "Data",
- "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": "Bank Name",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "bank_name",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "bank_name",
+ "fieldtype": "Data",
+ "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": "Bank Name",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "bank_name",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "bank_account_no",
- "fieldtype": "Data",
- "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": "Bank Account No.",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "bank_account_no",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "bank_account_no",
+ "fieldtype": "Data",
+ "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": "Bank Account No.",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "bank_account_no",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_01",
- "fieldtype": "Column Break",
- "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,
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_32",
+ "fieldtype": "Section Break",
+ "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,
+ "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": 0,
+ "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": "amended_from",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Amended From",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "amended_from",
- "oldfieldtype": "Data",
- "options": "Salary Slip",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "deduct_tax_for_unclaimed_employee_benefits",
+ "fieldtype": "Check",
+ "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": "Deduct Tax For Unclaimed Employee Benefits",
+ "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": 0,
+ "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": "section_break_32",
- "fieldtype": "Section Break",
- "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,
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "deduct_tax_for_unsubmitted_tax_exemption_proof",
+ "fieldtype": "Check",
+ "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": "Deduct Tax For Unsubmitted Tax Exemption Proof",
+ "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": 0,
+ "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": "deduct_tax_for_unclaimed_employee_benefits",
- "fieldtype": "Check",
- "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": "Deduct Tax For Unclaimed Employee Benefits",
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "earning_deduction",
+ "fieldtype": "Section Break",
+ "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": "Earning & Deduction",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Section Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "deduct_tax_for_unsubmitted_tax_exemption_proof",
- "fieldtype": "Check",
- "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": "Deduct Tax For Unsubmitted Tax Exemption Proof",
- "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": 0,
- "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": "earning_deduction",
- "fieldtype": "Section Break",
- "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": "Earning & Deduction",
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Section Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "earning",
- "fieldtype": "Column Break",
- "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": "Earning",
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "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,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "earning",
+ "fieldtype": "Column Break",
+ "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": "Earning",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Column Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "50%"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "earnings",
- "fieldtype": "Table",
- "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": "Earnings",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "earning_details",
- "oldfieldtype": "Table",
- "options": "Salary Detail",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "earnings",
+ "fieldtype": "Table",
+ "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": "Earnings",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "earning_details",
+ "oldfieldtype": "Table",
+ "options": "Salary Detail",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "deduction",
- "fieldtype": "Column Break",
- "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": "Deduction",
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "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,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "deduction",
+ "fieldtype": "Column Break",
+ "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": "Deduction",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Column Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "50%"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "deductions",
- "fieldtype": "Table",
- "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": "Deductions",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "deduction_details",
- "oldfieldtype": "Table",
- "options": "Salary Detail",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "deductions",
+ "fieldtype": "Table",
+ "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": "Deductions",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "deduction_details",
+ "oldfieldtype": "Table",
+ "options": "Salary Detail",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "totals",
- "fieldtype": "Section Break",
- "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": "",
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Section Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "totals",
+ "fieldtype": "Section Break",
+ "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": "",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Section Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "gross_pay",
- "fieldtype": "Currency",
- "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": "Gross Pay",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "gross_pay",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "gross_pay",
+ "fieldtype": "Currency",
+ "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": "Gross Pay",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "gross_pay",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_25",
- "fieldtype": "Column Break",
- "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,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_25",
+ "fieldtype": "Column Break",
+ "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,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "total_deduction",
- "fieldtype": "Currency",
- "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": "Total Deduction",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "total_deduction",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "total_deduction",
+ "fieldtype": "Currency",
+ "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": "Total Deduction",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "total_deduction",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "total_loan_repayment",
- "fieldname": "loan_repayment",
- "fieldtype": "Section Break",
- "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": "Loan repayment",
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "total_loan_repayment",
+ "fieldname": "loan_repayment",
+ "fieldtype": "Section Break",
+ "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": "Loan repayment",
+ "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": 0,
+ "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": "loans",
- "fieldtype": "Table",
- "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": "Employee Loan",
- "length": 0,
- "no_copy": 0,
- "options": "Salary Slip Loan",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "loans",
+ "fieldtype": "Table",
+ "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": "Employee Loan",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Salary Slip Loan",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_43",
- "fieldtype": "Section Break",
- "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,
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_43",
+ "fieldtype": "Section Break",
+ "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,
+ "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": 0,
+ "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,
- "default": "0",
- "fieldname": "total_principal_amount",
- "fieldtype": "Currency",
- "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": "Total Principal Amount",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "fieldname": "total_principal_amount",
+ "fieldtype": "Currency",
+ "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": "Total Principal Amount",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "total_interest_amount",
- "fieldtype": "Currency",
- "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": "Total Interest Amount",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "fieldname": "total_interest_amount",
+ "fieldtype": "Currency",
+ "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": "Total Interest Amount",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_45",
- "fieldtype": "Column Break",
- "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,
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_45",
+ "fieldtype": "Column Break",
+ "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,
+ "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": 0,
+ "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,
- "default": "0",
- "fieldname": "total_loan_repayment",
- "fieldtype": "Currency",
- "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": "Total Loan Repayment",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "fieldname": "total_loan_repayment",
+ "fieldtype": "Currency",
+ "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": "Total Loan Repayment",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "net_pay_info",
- "fieldtype": "Section Break",
- "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": "net pay info",
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "net_pay_info",
+ "fieldtype": "Section Break",
+ "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": "net pay info",
+ "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": 0,
+ "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,
- "description": "Gross Pay - Total Deduction - Loan Repayment",
- "fieldname": "net_pay",
- "fieldtype": "Currency",
- "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": "Net Pay",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "net_pay",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "Gross Pay - Total Deduction - Loan Repayment",
+ "fieldname": "net_pay",
+ "fieldtype": "Currency",
+ "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": "Net Pay",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "net_pay",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_53",
- "fieldtype": "Column Break",
- "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,
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_53",
+ "fieldtype": "Column Break",
+ "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,
+ "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": 0,
+ "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": 1,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "rounded_total",
- "fieldtype": "Currency",
- "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": "Rounded Total",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "rounded_total",
+ "fieldtype": "Currency",
+ "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": "Rounded Total",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_55",
- "fieldtype": "Section Break",
- "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,
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_55",
+ "fieldtype": "Section Break",
+ "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,
+ "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": 0,
+ "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,
- "description": "Net Pay (in words) will be visible once you save the Salary Slip.",
- "fieldname": "total_in_words",
- "fieldtype": "Data",
- "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": "Total in words",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "net_pay_in_words",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "Net Pay (in words) will be visible once you save the Salary Slip.",
+ "fieldname": "total_in_words",
+ "fieldtype": "Data",
+ "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": "Total in words",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "net_pay_in_words",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "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,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Amended From",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "amended_from",
+ "oldfieldtype": "Data",
+ "options": "Salary Slip",
+ "permlevel": 0,
+ "print_hide": 1,
+ "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
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "fa fa-file-text",
- "idx": 9,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2019-02-18 18:54:36.161027",
- "modified_by": "Administrator",
- "module": "HR",
- "name": "Salary Slip",
- "owner": "Administrator",
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "icon": "fa fa-file-text",
+ "idx": 9,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 1,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2019-05-13 13:10:14.524119",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Salary Slip",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "HR User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 0,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "HR User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
"write": 1
- },
+ },
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "HR Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "HR Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 0,
- "role": "Employee",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 0,
+ "role": "Employee",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "timeline_field": "employee",
- "title_field": "employee_name",
- "track_changes": 0,
- "track_seen": 0,
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "timeline_field": "employee",
+ "title_field": "employee_name",
+ "track_changes": 0,
+ "track_seen": 0,
"track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 5f6ddfc8fc..125a8ae27c 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe, erpnext
-import datetime
+import datetime, math
from frappe.utils import add_days, cint, cstr, flt, getdate, rounded, date_diff, money_in_words, getdate
from frappe.model.naming import make_autoname
@@ -14,7 +14,7 @@ from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee
from erpnext.utilities.transaction_base import TransactionBase
from frappe.utils.background_jobs import enqueue
from erpnext.hr.doctype.additional_salary.additional_salary import get_additional_salary_component
-from erpnext.hr.utils import get_payroll_period
+from erpnext.hr.doctype.payroll_period.payroll_period import get_period_factor, get_payroll_period
from erpnext.hr.doctype.employee_benefit_application.employee_benefit_application import get_benefit_component_amount
from erpnext.hr.doctype.employee_benefit_claim.employee_benefit_claim import get_benefit_claim_amount, get_last_payroll_period_benefits
@@ -47,7 +47,6 @@ class SalarySlip(TransactionBase):
else:
self.get_leave_details(lwp = self.leave_without_pay)
- # if self.salary_slip_based_on_timesheet or not self.net_pay:
self.calculate_net_pay()
company_currency = erpnext.get_company_currency(self.company)
@@ -59,148 +58,57 @@ class SalarySlip(TransactionBase):
frappe.msgprint(_("Total working hours should not be greater than max working hours {0}").
format(max_working_hours), alert=True)
+ def on_submit(self):
+ if self.net_pay < 0:
+ frappe.throw(_("Net Pay cannot be less than 0"))
+ 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 get_status(self):
+ if self.docstatus == 0:
+ status = "Draft"
+ elif self.docstatus == 1:
+ status = "Submitted"
+ elif self.docstatus == 2:
+ status = "Cancelled"
+ return status
+
def validate_dates(self):
if date_diff(self.end_date, self.start_date) < 0:
frappe.throw(_("To date cannot be before From date"))
- def calculate_component_amounts(self):
- if not getattr(self, '_salary_structure_doc', None):
- self._salary_structure_doc = frappe.get_doc('Salary Structure', self.salary_structure)
-
- data = self.get_data_for_eval()
-
- for key in ('earnings', 'deductions'):
- for struct_row in self._salary_structure_doc.get(key):
- amount = self.eval_condition_and_formula(struct_row, data)
- if amount and struct_row.statistical_component == 0:
- self.update_component_row(struct_row, amount, key)
-
- if key=="earnings" and struct_row.is_flexible_benefit == 1:
- self.add_employee_flexi_benefits(struct_row)
-
- additional_components = get_additional_salary_component(self.employee, self.start_date, self.end_date)
- if additional_components:
- for additional_component in additional_components:
- additional_component = frappe._dict(additional_component)
- amount = additional_component.amount
- overwrite = additional_component.overwrite
- key = "earnings"
- if additional_component.type == "Deduction":
- key = "deductions"
- self.update_component_row(frappe._dict(additional_component.struct_row), amount, key, overwrite=overwrite)
-
- self.get_last_payroll_period_benefit()
-
- # Calculate variable_based_on_taxable_salary after all components updated in salary slip
- for struct_row in self._salary_structure_doc.get("deductions"):
- if struct_row.variable_based_on_taxable_salary == 1 and not struct_row.formula and not struct_row.amount:
- tax_detail = self.calculate_variable_based_on_taxable_salary(struct_row.salary_component)
- if tax_detail and tax_detail[1]:
- self.update_component_row(frappe._dict(tax_detail[0]), tax_detail[1], "deductions", tax_detail[2], tax_detail[3])
-
- def get_last_payroll_period_benefit(self):
- payroll_period = get_payroll_period(self.start_date, self.end_date, self.company)
- if payroll_period:
- # Check for last payroll period
- if (getdate(payroll_period.end_date) <= getdate(self.end_date)):
- current_flexi_amount = 0
- for d in self.get("earnings"):
- if d.is_flexible_benefit == 1:
- current_flexi_amount += d.amount
- last_benefits = get_last_payroll_period_benefits(self.employee, self.start_date, self.end_date,
- current_flexi_amount, payroll_period, self._salary_structure_doc)
- if last_benefits:
- for last_benefit in last_benefits:
- last_benefit = frappe._dict(last_benefit)
- amount = last_benefit.amount
- self.update_component_row(frappe._dict(last_benefit.struct_row), amount, "earnings")
-
- def add_employee_flexi_benefits(self, struct_row):
- if frappe.db.get_value("Salary Component", struct_row.salary_component, "pay_against_benefit_claim") != 1:
- benefit_component_amount = get_benefit_component_amount(self.employee, self.start_date, self.end_date, \
- struct_row, self._salary_structure_doc, self.total_working_days, self.payroll_frequency)
- if benefit_component_amount:
- self.update_component_row(struct_row, benefit_component_amount, "earnings")
+ def check_existing(self):
+ if not self.salary_slip_based_on_timesheet:
+ ret_exist = frappe.db.sql("""select name from `tabSalary Slip`
+ where start_date = %s and end_date = %s and docstatus != 2
+ and employee = %s and name != %s""",
+ (self.start_date, self.end_date, self.employee, self.name))
+ if ret_exist:
+ self.employee = ''
+ frappe.throw(_("Salary Slip of employee {0} already created for this period").format(self.employee))
else:
- benefit_claim_amount = get_benefit_claim_amount(self.employee, self.start_date, self.end_date, struct_row.salary_component)
- if benefit_claim_amount:
- self.update_component_row(struct_row, benefit_claim_amount, "earnings")
+ for data in self.timesheets:
+ if frappe.db.get_value('Timesheet', data.time_sheet, 'status') == 'Payrolled':
+ frappe.throw(_("Salary Slip of employee {0} already created for time sheet {1}").format(self.employee, data.time_sheet))
- def update_component_row(self, struct_row, amount, key, benefit_tax=None, additional_tax=None, overwrite=1):
- component_row = None
- for d in self.get(key):
- if d.salary_component == struct_row.salary_component:
- component_row = d
-
- if not component_row:
- self.append(key, {
- 'amount': amount,
- 'default_amount': amount,
- 'depends_on_payment_days' : struct_row.depends_on_payment_days,
- 'salary_component' : struct_row.salary_component,
- 'abbr' : struct_row.abbr,
- 'do_not_include_in_total' : struct_row.do_not_include_in_total,
- 'is_tax_applicable': struct_row.is_tax_applicable,
- 'is_flexible_benefit': struct_row.is_flexible_benefit,
- 'variable_based_on_taxable_salary': struct_row.variable_based_on_taxable_salary,
- 'is_additional_component': struct_row.is_additional_component,
- 'tax_on_flexible_benefit': benefit_tax,
- 'tax_on_additional_salary': additional_tax
- })
- else:
- if not overwrite:
- amount += struct_row.get("default_amount", 0)
-
- component_row.default_amount = amount
- component_row.amount = amount
-
- component_row.tax_on_flexible_benefit = benefit_tax
- component_row.tax_on_additional_salary = additional_tax
-
- def eval_condition_and_formula(self, d, data):
- try:
- condition = d.condition.strip() if d.condition else None
- if condition:
- if not frappe.safe_eval(condition, self.whitelisted_globals, data):
- return None
- amount = d.amount
- if d.amount_based_on_formula:
- formula = d.formula.strip() if d.formula else None
- if formula:
- amount = rounded(frappe.safe_eval(formula, self.whitelisted_globals, data))
- if amount:
- data[d.abbr] = amount
-
- return amount
-
- except NameError as err:
- frappe.throw(_("Name error: {0}".format(err)))
- except SyntaxError as err:
- frappe.throw(_("Syntax error in formula or condition: {0}".format(err)))
- except Exception as e:
- frappe.throw(_("Error in formula or condition: {0}".format(e)))
- raise
-
- def get_data_for_eval(self):
- '''Returns data for evaluating formula'''
- data = frappe._dict()
-
- data.update(frappe.get_doc("Salary Structure Assignment",
- {"employee": self.employee, "salary_structure": self.salary_structure}).as_dict())
-
- data.update(frappe.get_doc("Employee", self.employee).as_dict())
- data.update(self.as_dict())
-
- # set values for components
- salary_components = frappe.get_all("Salary Component", fields=["salary_component_abbr"])
- for sc in salary_components:
- 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
+ def get_date_details(self):
+ if not self.end_date:
+ date_details = get_start_end_dates(self.payroll_frequency, self.start_date or self.posting_date)
+ self.start_date = date_details.start_date
+ self.end_date = date_details.end_date
def get_emp_and_leave_details(self):
'''First time, load all the components from salary structure'''
@@ -235,12 +143,6 @@ class SalarySlip(TransactionBase):
'working_hours': data.total_hours
})
- def get_date_details(self):
- if not self.end_date:
- date_details = get_start_end_dates(self.payroll_frequency, self.start_date or self.posting_date)
- self.start_date = date_details.start_date
- self.end_date = date_details.end_date
-
def check_sal_struct(self, joining_date, relieving_date):
cond = """and sa.employee=%(employee)s and (sa.from_date <= %(start_date)s or
sa.from_date <= %(end_date)s or sa.from_date <= %(joining_date)s)"""
@@ -279,43 +181,18 @@ class SalarySlip(TransactionBase):
make_salary_slip(self._salary_structure_doc.name, self)
- def process_salary_structure(self):
- '''Calculate salary after salary structure details have been updated'''
- if not self.salary_slip_based_on_timesheet:
- self.get_date_details()
- self.pull_emp_details()
- self.get_leave_details()
- self.calculate_net_pay()
-
- def add_earning_for_hourly_wages(self, doc, salary_component, amount):
- row_exists = False
- for row in doc.earnings:
- if row.salary_component == salary_component:
- row.amount = amount
- row_exists = True
- break
-
- if not row_exists:
- wages_row = {
- "salary_component": salary_component,
- "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):
- emp = frappe.db.get_value("Employee", self.employee, ["bank_name", "bank_ac_no"], as_dict=1)
- if emp:
- self.bank_name = emp.bank_name
- self.bank_account_no = emp.bank_ac_no
-
- def get_leave_details(self, joining_date=None, relieving_date=None, lwp=None):
+ def get_leave_details(self, joining_date=None, relieving_date=None, lwp=None, for_preview=0):
if not joining_date:
joining_date, relieving_date = frappe.db.get_value("Employee", self.employee,
["date_of_joining", "relieving_date"])
- holidays = self.get_holidays_for_employee(self.start_date, self.end_date)
working_days = date_diff(self.end_date, self.start_date) + 1
+ if for_preview:
+ self.total_working_days = working_days
+ self.payment_days = working_days
+ return
+
+ holidays = self.get_holidays_for_employee(self.start_date, self.end_date)
actual_lwp = self.calculate_lwp(holidays, working_days)
if not cint(frappe.db.get_value("HR Settings", None, "include_holidays_in_total_working_days")):
working_days -= len(holidays)
@@ -392,21 +269,425 @@ class SalarySlip(TransactionBase):
lwp = cint(leave[0][1]) and (lwp + 0.5) or (lwp + 1)
return lwp
- def check_existing(self):
- if not self.salary_slip_based_on_timesheet:
- ret_exist = frappe.db.sql("""select name from `tabSalary Slip`
- where start_date = %s and end_date = %s and docstatus != 2
- and employee = %s and name != %s""",
- (self.start_date, self.end_date, self.employee, self.name))
- if ret_exist:
- self.employee = ''
- frappe.throw(_("Salary Slip of employee {0} already created for this period").format(self.employee))
- else:
- for data in self.timesheets:
- if frappe.db.get_value('Timesheet', data.time_sheet, 'status') == 'Payrolled':
- frappe.throw(_("Salary Slip of employee {0} already created for time sheet {1}").format(self.employee, data.time_sheet))
+ def add_earning_for_hourly_wages(self, doc, salary_component, amount):
+ row_exists = False
+ for row in doc.earnings:
+ if row.salary_component == salary_component:
+ row.amount = amount
+ row_exists = True
+ break
- def sum_components(self, component_type, total_field, precision):
+ if not row_exists:
+ wages_row = {
+ "salary_component": salary_component,
+ "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 calculate_net_pay(self):
+ if self.salary_structure:
+ self.calculate_component_amounts()
+
+ self.gross_pay = self.get_component_totals("earnings")
+ self.total_deduction = self.get_component_totals("deductions")
+
+ self.set_loan_repayment()
+
+ self.net_pay = 0
+ if self.total_working_days:
+ self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
+
+ self.rounded_total = rounded(self.net_pay)
+
+ if self.net_pay < 0:
+ frappe.throw(_("Net Pay cannnot be negative"))
+
+ def calculate_component_amounts(self):
+ if not getattr(self, '_salary_structure_doc', None):
+ self._salary_structure_doc = frappe.get_doc('Salary Structure', self.salary_structure)
+
+ payroll_period = get_payroll_period(self.start_date, self.end_date, self.company)
+
+ self.add_structure_components()
+ self.add_employee_benefits(payroll_period)
+ self.add_additional_salary_components()
+ self.add_tax_components(payroll_period)
+
+ def add_structure_components(self):
+ data = self.get_data_for_eval()
+ for key in ('earnings', 'deductions'):
+ for struct_row in self._salary_structure_doc.get(key):
+ amount = self.eval_condition_and_formula(struct_row, data)
+ if amount and struct_row.statistical_component == 0:
+ self.update_component_row(struct_row, amount, key)
+
+ def get_data_for_eval(self):
+ '''Returns data for evaluating formula'''
+ data = frappe._dict()
+
+ data.update(frappe.get_doc("Salary Structure Assignment",
+ {"employee": self.employee, "salary_structure": self.salary_structure}).as_dict())
+
+ data.update(frappe.get_doc("Employee", self.employee).as_dict())
+ data.update(self.as_dict())
+
+ # set values for components
+ salary_components = frappe.get_all("Salary Component", fields=["salary_component_abbr"])
+ for sc in salary_components:
+ 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
+
+ def eval_condition_and_formula(self, d, data):
+ try:
+ condition = d.condition.strip() if d.condition else None
+ if condition:
+ if not frappe.safe_eval(condition, self.whitelisted_globals, data):
+ return None
+ amount = d.amount
+ if d.amount_based_on_formula:
+ formula = d.formula.strip() if d.formula else None
+ if formula:
+ amount = flt(frappe.safe_eval(formula, self.whitelisted_globals, data), d.precision("amount"))
+ if amount:
+ data[d.abbr] = amount
+
+ return amount
+
+ except NameError as err:
+ frappe.throw(_("Name error: {0}".format(err)))
+ except SyntaxError as err:
+ frappe.throw(_("Syntax error in formula or condition: {0}".format(err)))
+ except Exception as e:
+ frappe.throw(_("Error in formula or condition: {0}".format(e)))
+ raise
+
+ def add_employee_benefits(self, payroll_period):
+ for struct_row in self._salary_structure_doc.get("earnings"):
+ if struct_row.is_flexible_benefit == 1:
+ if frappe.db.get_value("Salary Component", struct_row.salary_component, "pay_against_benefit_claim") != 1:
+ benefit_component_amount = get_benefit_component_amount(self.employee, self.start_date, self.end_date,
+ struct_row.salary_component, self._salary_structure_doc, self.payroll_frequency, payroll_period)
+ if benefit_component_amount:
+ self.update_component_row(struct_row, benefit_component_amount, "earnings")
+ else:
+ benefit_claim_amount = get_benefit_claim_amount(self.employee, self.start_date, self.end_date, struct_row.salary_component)
+ if benefit_claim_amount:
+ self.update_component_row(struct_row, benefit_claim_amount, "earnings")
+
+ self.adjust_benefits_in_last_payroll_period(payroll_period)
+
+ def adjust_benefits_in_last_payroll_period(self, payroll_period):
+ if payroll_period:
+ if (getdate(payroll_period.end_date) <= getdate(self.end_date)):
+ last_benefits = get_last_payroll_period_benefits(self.employee, self.start_date, self.end_date,
+ payroll_period, self._salary_structure_doc)
+ if last_benefits:
+ for last_benefit in last_benefits:
+ last_benefit = frappe._dict(last_benefit)
+ amount = last_benefit.amount
+ self.update_component_row(frappe._dict(last_benefit.struct_row), amount, "earnings")
+
+ def add_additional_salary_components(self):
+ additional_components = get_additional_salary_component(self.employee, self.start_date, self.end_date)
+ if additional_components:
+ for additional_component in additional_components:
+ amount = additional_component.amount
+ overwrite = additional_component.overwrite
+ key = "earnings" if additional_component.type == "Earning" else "deductions"
+ self.update_component_row(frappe._dict(additional_component.struct_row), amount, key, overwrite=overwrite)
+
+ def add_tax_components(self, payroll_period):
+ # Calculate variable_based_on_taxable_salary after all components updated in salary slip
+ struct_tax_components = [d.salary_component for d in self._salary_structure_doc.get("deductions")
+ if d.variable_based_on_taxable_salary == 1 and not d.formula and not d.amount]
+
+ if not struct_tax_components:
+ struct_tax_components = [d.name for d in
+ frappe.get_all("Salary Component", filters={"variable_based_on_taxable_salary": 1})]
+
+ for d in struct_tax_components:
+ tax_amount = self.calculate_variable_based_on_taxable_salary(d, payroll_period)
+ tax_row = self.get_salary_slip_row(d)
+ self.update_component_row(tax_row, tax_amount, "deductions")
+
+ def update_component_row(self, struct_row, amount, key, overwrite=1):
+ component_row = None
+ for d in self.get(key):
+ if d.salary_component == struct_row.salary_component:
+ component_row = d
+
+ if not component_row:
+ if amount:
+ self.append(key, {
+ 'amount': amount,
+ 'default_amount': amount if not struct_row.get("is_additional_component") else 0,
+ 'depends_on_payment_days' : struct_row.depends_on_payment_days,
+ 'salary_component' : struct_row.salary_component,
+ 'abbr' : struct_row.abbr,
+ 'do_not_include_in_total' : struct_row.do_not_include_in_total,
+ 'is_tax_applicable': struct_row.is_tax_applicable,
+ 'is_flexible_benefit': struct_row.is_flexible_benefit,
+ 'variable_based_on_taxable_salary': struct_row.variable_based_on_taxable_salary,
+ 'deduct_full_tax_on_selected_payroll_date': struct_row.deduct_full_tax_on_selected_payroll_date,
+ 'additional_amount': amount if struct_row.get("is_additional_component") else 0
+ })
+ else:
+ if struct_row.get("is_additional_component"):
+ if overwrite:
+ component_row.additional_amount = amount - component_row.get("default_amount", 0)
+ else:
+ component_row.additional_amount = amount
+
+ if not overwrite:
+ amount += component_row.default_amount
+
+ component_row.amount = amount
+ component_row.deduct_full_tax_on_selected_payroll_date = struct_row.deduct_full_tax_on_selected_payroll_date
+
+ def calculate_variable_based_on_taxable_salary(self, tax_component, payroll_period):
+ if not payroll_period:
+ frappe.msgprint(_("Start and end dates not in a valid Payroll Period, cannot calculate {0}.")
+ .format(tax_component))
+ return
+
+ # Deduct taxes forcefully for unsubmitted tax exemption proof and unclaimed benefits in the last period
+ if payroll_period.end_date <= getdate(self.end_date):
+ self.deduct_tax_for_unsubmitted_tax_exemption_proof = 1
+ self.deduct_tax_for_unclaimed_employee_benefits = 1
+
+ return self.calculate_variable_tax(payroll_period, tax_component)
+
+ def calculate_variable_tax(self, payroll_period, tax_component):
+ # get remaining numbers of sub-period (period for which one salary is processed)
+ remaining_sub_periods = get_period_factor(self.employee,
+ self.start_date, self.end_date, self.payroll_frequency, payroll_period)[1]
+
+ # get taxable_earnings, paid_taxes for previous period
+ previous_taxable_earnings = self.get_taxable_earnings_for_prev_period(payroll_period.start_date, self.start_date)
+ previous_total_paid_taxes = self.get_tax_paid_in_period(payroll_period.start_date, self.start_date, tax_component)
+
+ # get taxable_earnings for current period (all days)
+ current_taxable_earnings = self.get_taxable_earnings()
+ future_structured_taxable_earnings = current_taxable_earnings.taxable_earnings * (math.ceil(remaining_sub_periods) - 1)
+
+ # get taxable_earnings, addition_earnings for current actual payment days
+ self.set_component_amounts_based_on_payment_days()
+ current_taxable_earnings_for_payment_days = self.get_taxable_earnings()
+ current_structured_taxable_earnings = current_taxable_earnings_for_payment_days.taxable_earnings
+ current_additional_earnings = current_taxable_earnings_for_payment_days.additional_income
+ current_additional_earnings_with_full_tax = current_taxable_earnings_for_payment_days.additional_income_with_full_tax
+
+ # Get taxable unclaimed benefits
+ unclaimed_taxable_benefits = 0
+ if self.deduct_tax_for_unclaimed_employee_benefits:
+ unclaimed_taxable_benefits = self.calculate_unclaimed_taxable_benefits(payroll_period)
+ unclaimed_taxable_benefits += current_taxable_earnings_for_payment_days.flexi_benefits
+
+ # Total exemption amount based on tax exemption declaration
+ total_exemption_amount, other_incomes = self.get_total_exemption_amount_and_other_incomes(payroll_period)
+
+ # Total taxable earnings including additional and other incomes
+ total_taxable_earnings = previous_taxable_earnings + current_structured_taxable_earnings + future_structured_taxable_earnings \
+ + current_additional_earnings + other_incomes + unclaimed_taxable_benefits - total_exemption_amount
+
+ # Total taxable earnings without additional earnings with full tax
+ total_taxable_earnings_without_full_tax_addl_components = total_taxable_earnings - current_additional_earnings_with_full_tax
+
+ # Structured tax amount
+ total_structured_tax_amount = self.calculate_tax_by_tax_slab(payroll_period, total_taxable_earnings_without_full_tax_addl_components)
+
+ current_structured_tax_amount = (total_structured_tax_amount - previous_total_paid_taxes) / remaining_sub_periods
+
+ # Total taxable earnings with additional earnings with full tax
+ full_tax_on_additional_earnings = 0.0
+ if current_additional_earnings_with_full_tax:
+ total_tax_amount = self.calculate_tax_by_tax_slab(payroll_period, total_taxable_earnings)
+ full_tax_on_additional_earnings = total_tax_amount - total_structured_tax_amount
+
+ current_tax_amount = current_structured_tax_amount + full_tax_on_additional_earnings
+ if flt(current_tax_amount) < 0:
+ current_tax_amount = 0
+
+ return current_tax_amount
+
+ def get_taxable_earnings_for_prev_period(self, start_date, end_date):
+ taxable_earnings = frappe.db.sql("""
+ select sum(sd.amount)
+ from
+ `tabSalary Detail` sd join `tabSalary Slip` ss on sd.parent=ss.name
+ where
+ sd.parentfield='earnings'
+ and sd.is_tax_applicable=1
+ and is_flexible_benefit=0
+ and ss.docstatus=1
+ and ss.employee=%(employee)s
+ and ss.start_date between %(from_date)s and %(to_date)s
+ and ss.end_date between %(from_date)s and %(to_date)s
+ """, {
+ "employee": self.employee,
+ "from_date": start_date,
+ "to_date": end_date
+ })
+ return flt(taxable_earnings[0][0]) if taxable_earnings else 0
+
+ def get_tax_paid_in_period(self, start_date, end_date, tax_component):
+ # find total_tax_paid, tax paid for benefit, additional_salary
+ total_tax_paid = flt(frappe.db.sql("""
+ select
+ sum(sd.amount)
+ from
+ `tabSalary Detail` sd join `tabSalary Slip` ss on sd.parent=ss.name
+ where
+ sd.parentfield='deductions'
+ and sd.salary_component=%(salary_component)s
+ and sd.variable_based_on_taxable_salary=1
+ and ss.docstatus=1
+ and ss.employee=%(employee)s
+ and ss.start_date between %(from_date)s and %(to_date)s
+ and ss.end_date between %(from_date)s and %(to_date)s
+ """, {
+ "salary_component": tax_component,
+ "employee": self.employee,
+ "from_date": start_date,
+ "to_date": end_date
+ })[0][0])
+
+ return total_tax_paid
+
+ def get_taxable_earnings(self, only_flexi=0):
+ taxable_earnings = 0
+ additional_income = 0
+ additional_income_with_full_tax = 0
+ flexi_benefits = 0
+
+ for earning in self.earnings:
+ if earning.is_tax_applicable:
+ if flt(earning.additional_amount):
+ taxable_earnings += (earning.amount - earning.additional_amount)
+ additional_income += earning.additional_amount
+ if earning.deduct_full_tax_on_selected_payroll_date:
+ additional_income_with_full_tax += earning.additional_amount
+ continue
+
+ if earning.is_flexible_benefit:
+ flexi_benefits += earning.amount
+ else:
+ taxable_earnings += earning.amount
+
+ return frappe._dict({
+ "taxable_earnings": taxable_earnings,
+ "additional_income": additional_income,
+ "additional_income_with_full_tax": additional_income_with_full_tax,
+ "flexi_benefits": flexi_benefits
+ })
+
+ def calculate_unclaimed_taxable_benefits(self, payroll_period):
+ # get total sum of benefits paid
+ total_benefits_paid = flt(frappe.db.sql("""
+ select sum(sd.amount)
+ from `tabSalary Detail` sd join `tabSalary Slip` ss on sd.parent=ss.name
+ where
+ sd.parentfield='earnings'
+ and sd.is_tax_applicable=1
+ and is_flexible_benefit=1
+ and ss.docstatus=1
+ and ss.employee=%(employee)s
+ and ss.start_date between %(start_date)s and %(end_date)s
+ and ss.end_date between %(start_date)s and %(end_date)s
+ """, {
+ "employee": self.employee,
+ "start_date": payroll_period.start_date,
+ "end_date": self.start_date
+ })[0][0])
+
+ # get total benefits claimed
+ total_benefits_claimed = flt(frappe.db.sql("""
+ select sum(claimed_amount)
+ from `tabEmployee Benefit Claim`
+ where
+ docstatus=1
+ and employee=%s
+ and claim_date between %s and %s
+ """, (self.employee, payroll_period.start_date, self.end_date))[0][0])
+
+ return total_benefits_paid - total_benefits_claimed
+
+ def get_total_exemption_amount_and_other_incomes(self, payroll_period):
+ total_exemption_amount, other_incomes = 0, 0
+ if self.deduct_tax_for_unsubmitted_tax_exemption_proof:
+ exemption_proof = frappe.db.get_value("Employee Tax Exemption Proof Submission",
+ {"employee": self.employee, "payroll_period": payroll_period.name, "docstatus": 1},
+ ["exemption_amount", "income_from_other_sources"])
+ if exemption_proof:
+ total_exemption_amount, other_incomes = exemption_proof
+ else:
+ declaration = frappe.db.get_value("Employee Tax Exemption Declaration",
+ {"employee": self.employee, "payroll_period": payroll_period.name, "docstatus": 1},
+ ["total_exemption_amount", "income_from_other_sources"])
+ if declaration:
+ total_exemption_amount, other_incomes = declaration
+
+ return total_exemption_amount, other_incomes
+
+ def calculate_tax_by_tax_slab(self, payroll_period, annual_taxable_earning):
+ payroll_period_obj = frappe.get_doc("Payroll Period", payroll_period)
+ annual_taxable_earning -= flt(payroll_period_obj.standard_tax_exemption_amount)
+ data = self.get_data_for_eval()
+ data.update({"annual_taxable_earning": annual_taxable_earning})
+ taxable_amount = 0
+ for slab in payroll_period_obj.taxable_salary_slabs:
+ if slab.condition and not self.eval_tax_slab_condition(slab.condition, data):
+ continue
+ if not slab.to_amount and annual_taxable_earning > slab.from_amount:
+ taxable_amount += (annual_taxable_earning - slab.from_amount) * slab.percent_deduction *.01
+ continue
+ if annual_taxable_earning > slab.from_amount and annual_taxable_earning < slab.to_amount:
+ taxable_amount += (annual_taxable_earning - slab.from_amount) * slab.percent_deduction *.01
+ elif annual_taxable_earning > slab.from_amount and annual_taxable_earning > slab.to_amount:
+ taxable_amount += (slab.to_amount - slab.from_amount) * slab.percent_deduction * .01
+ return taxable_amount
+
+ def eval_tax_slab_condition(self, condition, data):
+ try:
+ condition = condition.strip()
+ if condition:
+ return frappe.safe_eval(condition, self.whitelisted_globals, data)
+ except NameError as err:
+ frappe.throw(_("Name error: {0}".format(err)))
+ except SyntaxError as err:
+ frappe.throw(_("Syntax error in condition: {0}".format(err)))
+ except Exception as e:
+ frappe.throw(_("Error in formula or condition: {0}".format(e)))
+ raise
+
+ def get_salary_slip_row(self, salary_component):
+ component = frappe.get_doc("Salary Component", salary_component)
+ # Data for update_component_row
+ struct_row = frappe._dict()
+ struct_row['depends_on_payment_days'] = component.depends_on_payment_days
+ struct_row['salary_component'] = component.name
+ struct_row['abbr'] = component.salary_component_abbr
+ struct_row['do_not_include_in_total'] = component.do_not_include_in_total
+ struct_row['is_tax_applicable'] = component.is_tax_applicable
+ struct_row['is_flexible_benefit'] = component.is_flexible_benefit
+ struct_row['variable_based_on_taxable_salary'] = component.variable_based_on_taxable_salary
+ return struct_row
+
+ def get_component_totals(self, component_type):
+ total = 0.0
+ for d in self.get(component_type):
+ if not d.do_not_include_in_total:
+ d.amount = flt(d.amount, d.precision("amount"))
+ total += d.amount
+ return total
+
+ def set_component_amounts_based_on_payment_days(self):
joining_date, relieving_date = frappe.db.get_value("Employee", self.employee,
["date_of_joining", "relieving_date"])
@@ -416,51 +697,24 @@ class SalarySlip(TransactionBase):
if not joining_date:
frappe.throw(_("Please set the Date Of Joining for employee {0}").format(frappe.bold(self.employee_name)))
- for d in self.get(component_type):
- if (self.salary_structure and
- cint(d.depends_on_payment_days) and cint(self.total_working_days) and
- (not
- self.salary_slip_based_on_timesheet or
- getdate(self.start_date) < joining_date or
- getdate(self.end_date) > relieving_date
- )):
+ for component_type in ("earnings", "deductions"):
+ for d in self.get(component_type):
+ if (self.salary_structure and
+ cint(d.depends_on_payment_days) and cint(self.total_working_days) 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, precision) * flt(self.payment_days)
- / cint(self.total_working_days)), self.precision("amount", component_type)
- )
+ d.amount = flt(
+ (flt(d.default_amount + d.additional_amount) * flt(self.payment_days)
+ / cint(self.total_working_days))
+ , d.precision("amount"))
- elif not self.payment_days and not self.salary_slip_based_on_timesheet and \
- cint(d.depends_on_payment_days):
- d.amount = 0
- elif not d.amount:
- d.amount = d.default_amount
- if not d.do_not_include_in_total:
- self.set(total_field, self.get(total_field) + flt(d.amount, precision))
-
- def calculate_net_pay(self):
- if self.salary_structure:
- self.calculate_component_amounts()
-
- disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
- precision = frappe.defaults.get_global_default("currency_precision")
- self.total_deduction = 0
- self.gross_pay = 0
-
- self.sum_components('earnings', 'gross_pay', precision)
- self.sum_components('deductions', 'total_deduction', precision)
-
- self.set_loan_repayment()
-
- self.net_pay = 0
- if self.total_working_days:
- self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
-
- self.rounded_total = rounded(self.net_pay,
- self.precision("net_pay") if disable_rounded_total else 0)
-
- if self.net_pay < 0:
- frappe.throw(_("Net Pay cannnot be negative"))
+ elif not self.payment_days and not self.salary_slip_based_on_timesheet and cint(d.depends_on_payment_days):
+ d.amount = 0
+ elif not d.amount:
+ d.amount = d.default_amount + d.additional_amount
def set_loan_repayment(self):
self.set('loans', [])
@@ -492,25 +746,6 @@ class SalarySlip(TransactionBase):
l.repay_from_salary = 1 and l.docstatus = 1 and l.applicant = %s""",
(self.start_date, self.end_date, self.employee), as_dict=True) or []
- def on_submit(self):
- if self.net_pay < 0:
- frappe.throw(_("Net Pay cannot be less than 0"))
- 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("""
@@ -559,289 +794,24 @@ class SalarySlip(TransactionBase):
status = self.get_status()
self.db_set("status", status)
- def get_status(self):
- if self.docstatus == 0:
- status = "Draft"
- elif self.docstatus == 1:
- status = "Submitted"
- elif self.docstatus == 2:
- status = "Cancelled"
- return status
- def calculate_variable_based_on_taxable_salary(self, tax_component):
- payroll_period = get_payroll_period(self.start_date, self.end_date, self.company)
- if not payroll_period:
- frappe.msgprint(_("Start and end dates not in a valid Payroll Period, cannot calculate {0}.")
- .format(tax_component))
- return False
- if payroll_period.end_date <= getdate(self.end_date):
- if not self.deduct_tax_for_unsubmitted_tax_exemption_proof or not\
- self.deduct_tax_for_unclaimed_employee_benefits:
- frappe.throw(_("You have to Deduct Tax for Unsubmitted Tax Exemption Proof and Unclaimed \
- Employee Benefits in the last Salary Slip of Payroll Period"))
- # calc prorata tax to be applied
- return self.calculate_variable_tax(tax_component, payroll_period)
+ def process_salary_structure(self, for_preview=0):
+ '''Calculate salary after salary structure details have been updated'''
+ if not self.salary_slip_based_on_timesheet:
+ self.get_date_details()
+ self.pull_emp_details()
+ self.get_leave_details(for_preview=for_preview)
+ self.calculate_net_pay()
- def calculate_variable_tax(self, tax_component, payroll_period):
- annual_taxable_earning, period_factor = 0, 0
- pro_rata_tax_paid, additional_tax_paid, benefit_tax_paid = 0.0, 0.0, 0.0
- unclaimed_earning, unclaimed_benefit, additional_income = 0.0, 0.0, 0.0
+ def pull_emp_details(self):
+ emp = frappe.db.get_value("Employee", self.employee, ["bank_name", "bank_ac_no"], as_dict=1)
+ if emp:
+ self.bank_name = emp.bank_name
+ self.bank_account_no = emp.bank_ac_no
- # get taxable_earning, additional_income in this slip
- taxable_earning = self.get_taxable_earnings()
- if self.deduct_tax_for_unclaimed_employee_benefits:
- # get all untaxed benefits till date, pass amount to be taxed by later methods
- unclaimed_benefit = self.calculate_unclaimed_taxable_benefit(payroll_period)
- # flexi's excluded from monthly tax, add flexis in this slip to unclaimed_benefit
- unclaimed_benefit += self.get_taxable_earnings(only_flexi=True)["taxable_earning"]
- if self.deduct_tax_for_unsubmitted_tax_exemption_proof:
- # do not consider exemption, calc tax to be paid for the period till date
- # considering prorata taxes paid and proofs submitted
- unclaimed_earning = self.calculate_unclaimed_taxable_earning(payroll_period, tax_component)
- earning_in_period = taxable_earning["taxable_earning"] + unclaimed_earning
- period_factor = self.get_period_factor(payroll_period.start_date, payroll_period.end_date,
- payroll_period.start_date, self.end_date)
- annual_taxable_earning = earning_in_period * period_factor
- additional_income += self.get_total_additional_income(payroll_period.start_date)
- else:
- # consider exemption declaration, find annual_earning by monthly taxable salary
- period_factor = self.get_period_factor(payroll_period.start_date, payroll_period.end_date)
- annual_earning = taxable_earning["taxable_earning"] * period_factor
- exemption_amount = 0
- if frappe.db.exists("Employee Tax Exemption Declaration", {"employee": self.employee,
- "payroll_period": payroll_period.name, "docstatus": 1}):
- exemption_amount = frappe.db.get_value("Employee Tax Exemption Declaration",
- {"employee": self.employee, "payroll_period": payroll_period.name, "docstatus": 1},
- "total_exemption_amount")
- annual_taxable_earning = annual_earning - exemption_amount
-
- if self.deduct_tax_for_unclaimed_employee_benefits or self.deduct_tax_for_unsubmitted_tax_exemption_proof:
- tax_detail = self.get_tax_paid_in_period(payroll_period, tax_component)
- if tax_detail:
- pro_rata_tax_paid = tax_detail["total_tax_paid"] - tax_detail["additional_tax"] - tax_detail["benefit_tax"]
- additional_tax_paid = tax_detail["additional_tax"]
- benefit_tax_paid = tax_detail["benefit_tax"]
-
- # add any additional income in this slip
- additional_income += taxable_earning["additional_income"]
- args = {
- "payroll_period": payroll_period.name,
- "tax_component": tax_component,
- "period_factor": period_factor,
- "annual_taxable_earning": annual_taxable_earning,
- "additional_income": additional_income,
- "unclaimed_benefit": unclaimed_benefit,
- "pro_rata_tax_paid": pro_rata_tax_paid,
- "benefit_tax_paid": benefit_tax_paid,
- "additional_tax_paid": additional_tax_paid
- }
- return self.calculate_tax(args)
-
- def calculate_unclaimed_taxable_benefit(self, payroll_period):
- total_benefit, total_benefit_claim = 0, 0
-
- # get total sum of benefits paid
- sum_benefit = frappe.db.sql("""select sum(sd.amount) from `tabSalary Detail` sd join
- `tabSalary Slip` ss on sd.parent=ss.name where sd.parentfield='earnings'
- and sd.is_tax_applicable=1 and is_flexible_benefit=1 and ss.docstatus=1
- and ss.employee='{0}' and ss.start_date between '{1}' and '{2}' and
- ss.end_date between '{1}' and '{2}'""".format(self.employee,
- payroll_period.start_date, self.start_date))
- if sum_benefit and sum_benefit[0][0]:
- total_benefit = sum_benefit[0][0]
-
- # get total benefits claimed
- sum_benefit_claim = frappe.db.sql("""select sum(claimed_amount) from
- `tabEmployee Benefit Claim` where docstatus=1 and employee='{0}' and claim_date
- between '{1}' and '{2}'""".format(self.employee, payroll_period.start_date, self.end_date))
- if sum_benefit_claim and sum_benefit_claim[0][0]:
- total_benefit_claim = sum_benefit_claim[0][0]
- return total_benefit - total_benefit_claim
-
- def calculate_unclaimed_taxable_earning(self, payroll_period, tax_component):
- total_taxable_earning, total_exemption_amount = 0, 0
- # calc total taxable amount in period
- sum_taxable_earning = frappe.db.sql("""select sum(sd.amount) from `tabSalary Detail` sd join
- `tabSalary Slip` ss on sd.parent=ss.name where sd.parentfield='earnings'
- and sd.is_tax_applicable=1 and is_additional_component=0 and is_flexible_benefit=0
- and ss.docstatus=1 and ss.employee='{0}' and ss.start_date between '{1}' and '{2}'
- and ss.end_date between '{1}' and '{2}'""".format(self.employee,
- payroll_period.start_date, self.start_date))
- if sum_taxable_earning and sum_taxable_earning[0][0]:
- total_taxable_earning = sum_taxable_earning[0][0]
-
- # add up total Proof Submission
- sum_exemption = frappe.db.sql("""select sum(exemption_amount) from
- `tabEmployee Tax Exemption Proof Submission` where docstatus=1 and employee='{0}' and
- payroll_period='{1}' and submission_date between '{2}' and '{3}'""".format(self.employee,
- payroll_period.name, payroll_period.start_date, self.end_date))
- if sum_exemption and sum_exemption[0][0]:
- total_exemption_amount = sum_exemption[0][0]
- total_taxable_earning -= total_exemption_amount
- return total_taxable_earning
-
- def get_total_additional_income(self, from_date):
- sum_additional_earning = frappe.db.sql("""
- select sum(sd.amount)
- from
- `tabSalary Detail` sd join `tabSalary Slip` ss on sd.parent=ss.name
- where
- sd.parentfield='earnings'
- and sd.is_tax_applicable=1 and is_additional_component=1
- and is_flexible_benefit=0 and ss.docstatus=1
- and ss.employee=%(employee)s
- and ss.start_date between %(from_date)s and %(to_date)s
- and ss.end_date between %(from_date)s and %(to_date)s
- """, {
- "employee": self.employee,
- "from_date": from_date,
- "to_date": self.start_date
- })
- return flt(sum_additional_earning[0][0]) if sum_additional_earning else 0
-
- def get_tax_paid_in_period(self, payroll_period, tax_component, only_total=False):
- # find total_tax_paid, tax paid for benefit, additional_salary
- sum_tax_paid = frappe.db.sql("""
- select
- sum(sd.amount), sum(tax_on_flexible_benefit), sum(tax_on_additional_salary)
- from
- `tabSalary Detail` sd join `tabSalary Slip` ss on sd.parent=ss.name
- where
- sd.parentfield='deductions' and sd.salary_component=%(salary_component)s
- and sd.variable_based_on_taxable_salary=1
- and ss.docstatus=1 and ss.employee=%(employee)s
- and ss.start_date between %(from_date)s and %(to_date)s
- and ss.end_date between %(from_date)s and %(to_date)s
- """, {
- "salary_component": tax_component,
- "employee": self.employee,
- "from_date": payroll_period.start_date,
- "to_date": self.start_date
- })
- if sum_tax_paid and sum_tax_paid[0][0]:
- return {
- 'total_tax_paid': sum_tax_paid[0][0],
- 'benefit_tax':sum_tax_paid[0][1],
- 'additional_tax': sum_tax_paid[0][2]
- }
-
- def get_taxable_earnings(self, include_flexi=0, only_flexi=0):
- taxable_earning = 0
- additional_income = 0
- for earning in self.earnings:
- if earning.is_tax_applicable:
- if earning.is_additional_component:
- additional_income += earning.amount
- continue
- if only_flexi:
- if earning.is_flexible_benefit:
- taxable_earning += earning.amount
- continue
- if include_flexi or not earning.is_flexible_benefit:
- taxable_earning += earning.amount
- return {
- "taxable_earning": taxable_earning,
- "additional_income": additional_income
- }
-
- def calculate_tax(self, args):
- tax_amount, benefit_tax, additional_tax = 0, 0, 0
- annual_taxable_earning = args.get("annual_taxable_earning")
- benefit_to_tax = args.get("unclaimed_benefit")
- additional_income = args.get("additional_income")
-
- # Get tax calc by period
- annual_tax = self.calculate_tax_by_tax_slab(args.get("payroll_period"), annual_taxable_earning)
-
- # Calc prorata tax
- tax_amount = annual_tax / args.get("period_factor")
-
- # Benefit is a part of Salary Structure, add the tax diff, update annual_tax
- if benefit_to_tax > 0:
- annual_taxable_earning += benefit_to_tax
- annual_tax_with_benefit_income = self.calculate_tax_by_tax_slab(
- args.get("payroll_period"), annual_taxable_earning)
- benefit_tax = annual_tax_with_benefit_income - annual_tax - args.get("benefit_tax_paid")
- tax_amount += benefit_tax
- annual_tax = annual_tax_with_benefit_income
-
- # find the annual tax diff caused by additional_income, add to tax_amount
- if additional_income > 0:
- annual_tax_with_additional_income = self.calculate_tax_by_tax_slab(
- args.get("payroll_period"), annual_taxable_earning + additional_income)
- additional_tax = annual_tax_with_additional_income - annual_tax - args.get("additional_tax_paid")
- tax_amount += additional_tax
- # less paid taxes
- if args.get("pro_rata_tax_paid"):
- tax_amount -= args.get("pro_rata_tax_paid")
- tax_amount = rounded(tax_amount)
- struct_row = self.get_salary_slip_row(args.get("tax_component"))
- return [struct_row, tax_amount, benefit_tax, additional_tax]
-
- def calculate_tax_by_tax_slab(self, payroll_period, annual_taxable_earning):
- payroll_period_obj = frappe.get_doc("Payroll Period", payroll_period)
- annual_taxable_earning -= flt(payroll_period_obj.standard_tax_exemption_amount)
- data = self.get_data_for_eval()
- data.update({"annual_taxable_earning": annual_taxable_earning})
-
- taxable_amount = 0
- for slab in payroll_period_obj.taxable_salary_slabs:
- if slab.condition and not self.eval_tax_slab_condition(slab.condition, data):
- continue
- if not slab.to_amount and annual_taxable_earning > slab.from_amount:
- taxable_amount += (annual_taxable_earning - slab.from_amount) * slab.percent_deduction *.01
- continue
- if annual_taxable_earning > slab.from_amount and annual_taxable_earning < slab.to_amount:
- taxable_amount += (annual_taxable_earning - slab.from_amount) * slab.percent_deduction *.01
- elif annual_taxable_earning > slab.from_amount and annual_taxable_earning > slab.to_amount:
- taxable_amount += (slab.to_amount - slab.from_amount) * slab.percent_deduction * .01
- return taxable_amount
-
- def eval_tax_slab_condition(self, condition, data):
- try:
- condition = condition.strip()
- if condition:
- return frappe.safe_eval(condition, self.whitelisted_globals, data)
- except NameError as err:
- frappe.throw(_("Name error: {0}".format(err)))
- except SyntaxError as err:
- frappe.throw(_("Syntax error in condition: {0}".format(err)))
- except Exception as e:
- frappe.throw(_("Error in formula or condition: {0}".format(e)))
- raise
-
- def get_period_factor(self, period_start, period_end, start_date=None, end_date=None):
- # TODO if both deduct checked update the factor to make tax consistent
- joining_date, relieving_date = frappe.db.get_value("Employee", self.employee, ["date_of_joining", "relieving_date"])
- if getdate(joining_date) > getdate(period_start):
- period_start = joining_date
- if relieving_date and getdate(relieving_date) < getdate(period_end):
- period_end = relieving_date
-
- payroll_days = date_diff(period_end, period_start) + 1
- if start_date and end_date:
- salary_days = date_diff(end_date, start_date) + 1
- return flt(payroll_days)/flt(salary_days)
-
- # if period configured for a year and monthly frequency return 12 to make tax calc consistent
- if 360 <= payroll_days <= 370 and self.payroll_frequency == "Monthly":
- return 12
-
- salary_days = date_diff(self.end_date, self.start_date) + 1
- return flt(payroll_days)/flt(salary_days)
-
- def get_salary_slip_row(self, salary_component):
- component = frappe.get_doc("Salary Component", salary_component)
- # Data for update_component_row
- struct_row = {}
- struct_row['depends_on_payment_days'] = component.depends_on_payment_days
- struct_row['salary_component'] = component.name
- struct_row['abbr'] = component.salary_component_abbr
- struct_row['do_not_include_in_total'] = component.do_not_include_in_total
- struct_row['is_tax_applicable'] = component.is_tax_applicable
- struct_row['is_flexible_benefit'] = component.is_flexible_benefit
- struct_row['variable_based_on_taxable_salary'] = component.variable_based_on_taxable_salary
- return struct_row
+ def process_salary_based_on_leave(self, lwp=0):
+ self.get_leave_details(lwp=lwp)
+ self.calculate_net_pay()
def unlink_ref_doc_from_salary_slip(ref_no):
linked_ss = frappe.db.sql_list("""select name from `tabSalary Slip`
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
index 75c1e420b8..b7e0782001 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
@@ -45,12 +45,12 @@ class TestSalarySlip(unittest.TestCase):
self.assertEqual(ss.total_working_days, no_of_days[0])
self.assertEqual(ss.payment_days, no_of_days[0])
- self.assertEqual(ss.earnings[0].amount, 25000)
+ self.assertEqual(ss.earnings[0].amount, 50000)
self.assertEqual(ss.earnings[1].amount, 3000)
self.assertEqual(ss.deductions[0].amount, 5000)
self.assertEqual(ss.deductions[1].amount, 5000)
- self.assertEqual(ss.gross_pay, 40500)
- self.assertEqual(ss.net_pay, 29918)
+ self.assertEqual(ss.gross_pay, 78000)
+ self.assertEqual(ss.net_pay, 67418.0)
def test_salary_slip_with_holidays_excluded(self):
no_of_days = self.get_no_of_days()
@@ -64,13 +64,13 @@ class TestSalarySlip(unittest.TestCase):
self.assertEqual(ss.total_working_days, no_of_days[0] - no_of_days[1])
self.assertEqual(ss.payment_days, no_of_days[0] - no_of_days[1])
- self.assertEqual(ss.earnings[0].amount, 25000)
- self.assertEqual(ss.earnings[0].default_amount, 25000)
+ self.assertEqual(ss.earnings[0].amount, 50000)
+ self.assertEqual(ss.earnings[0].default_amount, 50000)
self.assertEqual(ss.earnings[1].amount, 3000)
self.assertEqual(ss.deductions[0].amount, 5000)
self.assertEqual(ss.deductions[1].amount, 5000)
- self.assertEqual(ss.gross_pay, 40500)
- self.assertEqual(ss.net_pay, 29918)
+ self.assertEqual(ss.gross_pay, 78000)
+ self.assertEqual(ss.net_pay, 67418.0)
def test_payment_days(self):
no_of_days = self.get_no_of_days()
@@ -211,7 +211,7 @@ class TestSalarySlip(unittest.TestCase):
tax_paid = get_tax_paid_in_period(employee)
# total taxable income 586000, 250000 @ 5%, 86000 @ 20% ie. 12500 + 17200
- annual_tax = 29700
+ annual_tax = 113567.79
try:
self.assertEqual(tax_paid, annual_tax)
except AssertionError:
@@ -250,7 +250,7 @@ class TestSalarySlip(unittest.TestCase):
# total taxable income 416000, 166000 @ 5% ie. 8300
try:
- self.assertEqual(tax_paid, 8300)
+ self.assertEqual(tax_paid, 88607.79)
except AssertionError:
print("\nSalary Slip - Tax calculation failed on following case\n", data, "\n")
raise
@@ -265,7 +265,7 @@ class TestSalarySlip(unittest.TestCase):
# total taxable income 566000, 250000 @ 5%, 66000 @ 20%, 12500 + 13200
tax_paid = get_tax_paid_in_period(employee)
try:
- self.assertEqual(tax_paid, 25700)
+ self.assertEqual(tax_paid, 121211.48)
except AssertionError:
print("\nSalary Slip - Tax calculation failed on following case\n", data, "\n")
raise
@@ -365,7 +365,7 @@ def make_earning_salary_component(setup=False, test_tax=False):
"salary_component": 'Basic Salary',
"abbr":'BS',
"condition": 'base > 10000',
- "formula": 'base*.5',
+ "formula": 'base',
"type": "Earning",
"amount_based_on_formula": 1
},
@@ -386,7 +386,6 @@ def make_earning_salary_component(setup=False, test_tax=False):
{
"salary_component": "Leave Encashment",
"abbr": 'LE',
- "is_additional_component": 1,
"type": "Earning"
}
]
@@ -398,7 +397,8 @@ def make_earning_salary_component(setup=False, test_tax=False):
"is_flexible_benefit": 1,
"type": "Earning",
"pay_against_benefit_claim": 1,
- "max_benefit_amount": 100000
+ "max_benefit_amount": 100000,
+ "depends_on_payment_days": 0
},
{
"salary_component": "Medical Allowance",
@@ -409,9 +409,8 @@ def make_earning_salary_component(setup=False, test_tax=False):
"max_benefit_amount": 15000
},
{
- "salary_component": "Perfomance Bonus",
+ "salary_component": "Performance Bonus",
"abbr": 'B',
- "is_additional_component": 1,
"type": "Earning"
}
])
@@ -442,7 +441,8 @@ def make_deduction_salary_component(setup=False, test_tax=False):
"abbr":'T',
"formula": 'base*.1',
"type": "Deduction",
- "amount_based_on_formula": 1
+ "amount_based_on_formula": 1,
+ "depends_on_payment_days": 0
}
]
if not test_tax:
@@ -512,21 +512,23 @@ def create_tax_slab(payroll_period):
{
"from_amount": 250000,
"to_amount": 500000,
- "percent_deduction": 5
+ "percent_deduction": 5.2,
+ "condition": "annual_taxable_earning > 500000"
},
{
- "from_amount": 500000,
+ "from_amount": 500001,
"to_amount": 1000000,
- "percent_deduction": 20
+ "percent_deduction": 20.8
},
{
- "from_amount": 1000000,
- "percent_deduction": 30
+ "from_amount": 1000001,
+ "percent_deduction": 31.2
}
]
payroll_period.taxable_salary_slabs = []
for item in data:
payroll_period.append("taxable_salary_slabs", item)
+ payroll_period.standard_tax_exemption_amount = 52500
payroll_period.save()
def create_salary_slips_for_payroll_period(employee, salary_structure, payroll_period, deduct_random=True):
@@ -559,7 +561,7 @@ def create_additional_salary(employee, payroll_period, amount):
"doctype": "Additional Salary",
"employee": employee,
"company": erpnext.get_default_company(),
- "salary_component": "Perfomance Bonus",
+ "salary_component": "Performance Bonus",
"payroll_date": salary_date,
"amount": amount,
"type": "Earning"
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.js b/erpnext/hr/doctype/salary_structure/salary_structure.js
index e3f37e7105..d56320a073 100755
--- a/erpnext/hr/doctype/salary_structure/salary_structure.js
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.js
@@ -147,7 +147,8 @@ frappe.ui.form.on('Salary Structure', {
source_name: frm.doc.name,
employee: values.employee,
as_print: 1,
- print_format: print_format
+ print_format: print_format,
+ for_preview: 1
},
callback: function(r) {
var new_window = window.open();
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.py b/erpnext/hr/doctype/salary_structure/salary_structure.py
index 3431d3d4a8..f7d712d3f1 100644
--- a/erpnext/hr/doctype/salary_structure/salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.py
@@ -137,7 +137,7 @@ def get_existing_assignments(employees, salary_structure,from_date):
return salary_structures_assignments
@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, for_preview=0):
def postprocess(source, target):
if employee:
employee_details = frappe.db.get_value("Employee", employee,
@@ -147,7 +147,7 @@ def make_salary_slip(source_name, target_doc = None, employee = None, as_print =
target.branch = employee_details.branch
target.designation = employee_details.designation
target.department = employee_details.department
- target.run_method('process_salary_structure')
+ target.run_method('process_salary_structure', for_preview=for_preview)
doc = get_mapped_doc("Salary Structure", source_name, {
"Salary Structure": {
diff --git a/erpnext/hr/doctype/salary_structure/test_salary_structure.py b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
index 1a660d90ec..848c3df57a 100644
--- a/erpnext/hr/doctype/salary_structure/test_salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
@@ -39,18 +39,19 @@ class TestSalaryStructure(unittest.TestCase):
holiday_list.save()
def test_amount_totals(self):
+ frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee_2@salary.com"})
if not sal_slip:
sal_slip = make_employee_salary_slip("test_employee_2@salary.com", "Monthly", "Salary Structure Sample")
self.assertEqual(sal_slip.get("salary_structure"), 'Salary Structure Sample')
- self.assertEqual(sal_slip.get("earnings")[0].amount, 25000)
+ self.assertEqual(sal_slip.get("earnings")[0].amount, 50000)
self.assertEqual(sal_slip.get("earnings")[1].amount, 3000)
- self.assertEqual(sal_slip.get("earnings")[2].amount, 12500)
- self.assertEqual(sal_slip.get("gross_pay"), 40500)
+ self.assertEqual(sal_slip.get("earnings")[2].amount, 25000)
+ self.assertEqual(sal_slip.get("gross_pay"), 78000)
self.assertEqual(sal_slip.get("deductions")[0].amount, 5000)
self.assertEqual(sal_slip.get("deductions")[1].amount, 5000)
self.assertEqual(sal_slip.get("total_deduction"), 10000)
- self.assertEqual(sal_slip.get("net_pay"), 30500)
+ self.assertEqual(sal_slip.get("net_pay"), 68000)
def test_whitespaces_in_formula_conditions_fields(self):
salary_structure = make_salary_structure("Salary Structure Sample", "Monthly", dont_submit=True)
diff --git a/erpnext/hr/report/salary_register/salary_register.py b/erpnext/hr/report/salary_register/salary_register.py
index 869ca23139..be4b501c6e 100644
--- a/erpnext/hr/report/salary_register/salary_register.py
+++ b/erpnext/hr/report/salary_register/salary_register.py
@@ -35,6 +35,8 @@ def execute(filters=None):
for d in ded_types:
row.append(ss_ded_map.get(ss.name, {}).get(d))
+ row.append(ss.total_loan_repayment)
+
row += [ss.total_deduction, ss.net_pay]
data.append(row)
@@ -67,7 +69,7 @@ def get_columns(salary_slips):
columns = columns + [(e + ":Currency:120") for e in salary_components[_("Earning")]] + \
[_("Gross Pay") + ":Currency:120"] + [(d + ":Currency:120") for d in salary_components[_("Deduction")]] + \
- [_("Total Deduction") + ":Currency:120", _("Net Pay") + ":Currency:120"]
+ [_("Loan Repayment") + ":Currency:120", _("Total Deduction") + ":Currency:120", _("Net Pay") + ":Currency:120"]
return columns, salary_components[_("Earning")], salary_components[_("Deduction")]
diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py
index a600e75884..7357fd0cc1 100644
--- a/erpnext/hr/utils.py
+++ b/erpnext/hr/utils.py
@@ -126,9 +126,9 @@ def get_employee_fields_label():
fields = []
for df in frappe.get_meta("Employee").get("fields"):
if df.fieldname in ["salutation", "user_id", "employee_number", "employment_type",
- "holiday_list", "branch", "department", "designation", "grade",
- "notice_number_of_days", "reports_to", "leave_policy", "company_email"]:
- fields.append({"value": df.fieldname, "label": df.label})
+ "holiday_list", "branch", "department", "designation", "grade",
+ "notice_number_of_days", "reports_to", "leave_policy", "company_email"]:
+ fields.append({"value": df.fieldname, "label": df.label})
return fields
@frappe.whitelist()
@@ -263,12 +263,6 @@ def get_leave_period(from_date, to_date, company):
if leave_period:
return leave_period
-def get_payroll_period(from_date, to_date, company):
- payroll_period = frappe.db.sql("""select name, start_date, end_date from
- `tabPayroll Period`
- where start_date<=%s and end_date>= %s and company=%s""", (from_date, to_date, company), as_dict=1)
- return payroll_period[0] if payroll_period else None
-
def allocate_earned_leaves():
'''Allocate earned leaves to Employees'''
e_leave_types = frappe.get_all("Leave Type",
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index f413a8ed4d..fc2fc9658f 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -146,11 +146,9 @@ def calculate_annual_eligible_hra_exemption(doc):
hra_component = frappe.get_cached_value('Company', doc.company, "hra_component")
if not (basic_component and hra_component):
frappe.throw(_("Please mention Basic and HRA component in Company"))
-
annual_exemption, monthly_exemption, hra_amount = 0, 0, 0
if hra_component and basic_component:
assignment = get_salary_assignment(doc.employee, nowdate())
-
if assignment:
hra_component_exists = frappe.db.exists("Salary Detail", {
"parent": assignment.salary_structure,
@@ -158,18 +156,19 @@ def calculate_annual_eligible_hra_exemption(doc):
"parentfield": "earnings",
"parenttype": "Salary Structure"
})
+
if hra_component_exists:
basic_amount, hra_amount = get_component_amt_from_salary_slip(doc.employee,
assignment.salary_structure, basic_component, hra_component)
if hra_amount:
if doc.monthly_house_rent:
annual_exemption = calculate_hra_exemption(assignment.salary_structure,
- basic_amount, hra_amount, doc.monthly_house_rent,
- doc.rented_in_metro_city)
+ basic_amount, hra_amount, doc.monthly_house_rent, doc.rented_in_metro_city)
if annual_exemption > 0:
monthly_exemption = annual_exemption / 12
else:
annual_exemption = 0
+
elif doc.docstatus == 1:
frappe.throw(_("Salary Structure must be submitted before submission of Tax Ememption Declaration"))
@@ -180,7 +179,7 @@ def calculate_annual_eligible_hra_exemption(doc):
})
def get_component_amt_from_salary_slip(employee, salary_structure, basic_component, hra_component):
- salary_slip = make_salary_slip(salary_structure, employee=employee)
+ salary_slip = make_salary_slip(salary_structure, employee=employee, for_preview=1)
basic_amt, hra_amt = 0, 0
for earning in salary_slip.earnings:
if earning.salary_component == basic_component:
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 4ac11c07e5..1e6056ec86 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -11,11 +11,6 @@ frappe.ui.form.on("Company", {
filters: {"type": "Earning"}
}
});
- frm.set_query("arrear_component", function(){
- return {
- filters: {"is_additional_component": 1}
- }
- });
frm.set_query("parent_company", function() {
return {