From 447f0e495a56335d3b7e3b508736ae2289498600 Mon Sep 17 00:00:00 2001 From: Ranjith Date: Wed, 16 May 2018 12:13:46 +0530 Subject: [PATCH 1/7] remove duplicate fields --- .../salary_component/salary_component.json | 318 +----------------- 1 file changed, 2 insertions(+), 316 deletions(-) diff --git a/erpnext/hr/doctype/salary_component/salary_component.json b/erpnext/hr/doctype/salary_component/salary_component.json index f08b1d7a0b..5bb69c7cad 100644 --- a/erpnext/hr/doctype/salary_component/salary_component.json +++ b/erpnext/hr/doctype/salary_component/salary_component.json @@ -893,320 +893,6 @@ "translatable": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "help", - "fieldtype": "HTML", - "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": "Help", - "length": 0, - "no_copy": 0, - "options": "

Help

\n\n

Notes:

\n\n
    \n
  1. Use field base for using base salary of the Employee
  2. \n
  3. Use Salary Component abbreviations in conditions and formulas. BS = Basic Salary
  4. \n
  5. Use field name for employee details in conditions and formulas. Employment Type = employment_typeBranch = branch
  6. \n
  7. Use field name from Salary Slip in conditions and formulas. Payment Days = payment_daysLeave without pay = leave_without_pay
  8. \n
  9. Direct Amount can also be entered based on Condtion. See example 3
\n\n

Examples

\n
    \n
  1. Calculating Basic Salary based on base\n
    Condition: base < 10000
    \n
    Formula: base * .2
  2. \n
  3. Calculating HRA based on Basic SalaryBS \n
    Condition: BS > 2000
    \n
    Formula: BS * .1
  4. \n
  5. Calculating TDS based on Employment Typeemployment_type \n
    Condition: employment_type==\"Intern\"
    \n
    Amount: 1000
  6. \n
", - "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_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "condition_and_formula", - "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": "Condition and Formula", - "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_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "condition", - "fieldtype": "Code", - "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": "Condition", - "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_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "If selected, the value specified or calculated in this component will not contribute to the earnings or deductions. However, it's value can be referenced by other components that can be added or deducted. ", - "fieldname": "statistical_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": "Statistical 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_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "depends_on_lwp", - "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": "Depends on Leave Without Pay", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "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_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "do_not_include_in_total", - "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": "Do not include in total", - "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_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "1", - "fieldname": "amount_based_on_formula", - "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": "Amount based on formula", - "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_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.amount_based_on_formula!==0", - "fieldname": "formula", - "fieldtype": "Code", - "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": "Formula", - "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_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.amount_based_on_formula!==1", - "fieldname": "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": "Amount", - "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_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_28", - "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_on_submit": 0, @@ -1251,7 +937,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-05-09 17:35:11.073733", + "modified": "2018-05-16 12:13:12.831051", "modified_by": "Administrator", "module": "HR", "name": "Salary Component", @@ -1286,4 +972,4 @@ "sort_order": "DESC", "track_changes": 0, "track_seen": 0 -} +} \ No newline at end of file From db120fb0bc7d2fe4ab6358cb9b0734b061411a07 Mon Sep 17 00:00:00 2001 From: Ranjith Date: Wed, 16 May 2018 12:17:16 +0530 Subject: [PATCH 2/7] Salary Component - fields is_tax_applicable, is_payable --- .../salary_component/salary_component.json | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/salary_component/salary_component.json b/erpnext/hr/doctype/salary_component/salary_component.json index 5bb69c7cad..cf85af4a76 100644 --- a/erpnext/hr/doctype/salary_component/salary_component.json +++ b/erpnext/hr/doctype/salary_component/salary_component.json @@ -108,6 +108,70 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.type==\"Earning\"", + "fieldname": "is_tax_applicable", + "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 Tax Applicable", + "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_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "1", + "fieldname": "is_payable", + "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 Payable", + "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_on_submit": 0, @@ -554,6 +618,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "depends_on": "is_payable", "fieldname": "section_break_5", "fieldtype": "Section Break", "hidden": 0, @@ -937,7 +1002,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-05-16 12:13:12.831051", + "modified": "2018-05-16 12:15:43.117948", "modified_by": "Administrator", "module": "HR", "name": "Salary Component", From 4bbf705e58be1acc3591ca324b29281d61fa7c7f Mon Sep 17 00:00:00 2001 From: Ranjith Date: Wed, 16 May 2018 12:17:57 +0530 Subject: [PATCH 3/7] fix intendation --- erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py | 3 +-- erpnext/accounts/utils.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 9599d1f53f..08e3d10fd8 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -750,7 +750,7 @@ class PurchaseInvoice(BuyingController): self.db_set('on_hold', 0) self.db_set('release_date', None) - def set_tax_withholding(self): + def set_tax_withholding(self): """ 1. Get TDS Configurations against Supplier """ @@ -812,4 +812,3 @@ def block_invoice(name, hold_comment): def make_inter_company_sales_invoice(source_name, target_doc=None): from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_invoice return make_inter_company_invoice("Purchase Invoice", source_name, target_doc) - diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 8c86887186..a33f867d12 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -602,7 +602,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None): invoice = 'Sales Invoice' if erpnext.get_party_account_type(party_type) == 'Receivable' else 'Purchase Invoice' held_invoices = get_held_invoices(party_type, party) - invoice_list = frappe.db.sql(""" + invoice_list = frappe.db.sql(""" select voucher_no, voucher_type, posting_date, ifnull(sum({dr_or_cr}), 0) as invoice_amount, ( From 29e0ed3da13c1f8bff58f06d3e39a05675268280 Mon Sep 17 00:00:00 2001 From: Ranjith Date: Wed, 16 May 2018 19:10:35 +0530 Subject: [PATCH 4/7] Exemption Declaration - field total_amount --- .../employee_tax_exemption_declaration.json | 33 ++++++++++++++++++- .../employee_tax_exemption_declaration.py | 3 ++ 2 files changed, 35 insertions(+), 1 deletion(-) 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 9dee848029..c5691f72ee 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 @@ -139,6 +139,37 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "total_exemption_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 Exemption Amount", + "length": 0, + "no_copy": 0, + "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_on_submit": 0, @@ -243,7 +274,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-05-15 16:16:46.075493", + "modified": "2018-05-16 19:03:57.624215", "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 52746d4cff..22e1638751 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 @@ -19,3 +19,6 @@ class EmployeeTaxExemptionDeclaration(Document): "docstatus": 1}): frappe.throw(_("Tax Declaration of {0} for period {1} already submitted.")\ .format(self.employee, self.payroll_period), frappe.DocstatusTransitionError) + self.total_exemption_amount = 0 + for item in self.declarations: + self.total_exemption_amount += item.amount From c6b2575a9cecc86fc848ea78e9358afe252ccb39 Mon Sep 17 00:00:00 2001 From: Ranjith Date: Wed, 16 May 2018 22:59:21 +0530 Subject: [PATCH 5/7] fields in salary detail, copy data from salary component on change --- .../doctype/salary_detail/salary_detail.json | 109 +++++++++++++++++- .../salary_structure/salary_structure.js | 17 +-- 2 files changed, 118 insertions(+), 8 deletions(-) diff --git a/erpnext/hr/doctype/salary_detail/salary_detail.json b/erpnext/hr/doctype/salary_detail/salary_detail.json index 01d02779b7..862728afb7 100644 --- a/erpnext/hr/doctype/salary_detail/salary_detail.json +++ b/erpnext/hr/doctype/salary_detail/salary_detail.json @@ -40,6 +40,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -72,6 +73,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -101,6 +103,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -132,6 +135,100 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "is_tax_applicable", + "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 Tax Applicable", + "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_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "is_flexible_benefit", + "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 Flexible Benefit", + "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_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "variable_based_on_taxable_salary", + "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": "Variable Based On Taxable Salary", + "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 }, { @@ -161,6 +258,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -192,6 +290,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -225,6 +324,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -258,6 +358,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -290,6 +391,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -321,6 +423,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -351,6 +454,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -383,6 +487,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -413,6 +518,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -445,6 +551,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 } ], @@ -458,7 +565,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2017-10-02 13:57:22.769751", + "modified": "2018-05-16 22:42:59.974450", "modified_by": "Administrator", "module": "HR", "name": "Salary Detail", diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.js b/erpnext/hr/doctype/salary_structure/salary_structure.js index ca92234461..8fd51d990f 100755 --- a/erpnext/hr/doctype/salary_structure/salary_structure.js +++ b/erpnext/hr/doctype/salary_structure/salary_structure.js @@ -201,17 +201,20 @@ frappe.ui.form.on('Salary Detail', { callback: function(data) { if(data.message){ var result = data.message; - frappe.model.set_value(cdt, cdn, 'condition',result.condition); - frappe.model.set_value(cdt, cdn, 'amount_based_on_formula',result.amount_based_on_formula); + frappe.model.set_value(cdt, cdn, 'condition', result.condition); + frappe.model.set_value(cdt, cdn, 'amount_based_on_formula', result.amount_based_on_formula); if(result.amount_based_on_formula == 1){ - frappe.model.set_value(cdt, cdn, 'formula',result.formula); + frappe.model.set_value(cdt, cdn, 'formula', result.formula); } else{ - frappe.model.set_value(cdt, cdn, 'amount',result.amount); + frappe.model.set_value(cdt, cdn, 'amount', result.amount); } - frappe.model.set_value(cdt, cdn, 'statistical_component',result.statistical_component); - frappe.model.set_value(cdt, cdn, 'depends_on_lwp',result.depends_on_lwp); - frappe.model.set_value(cdt, cdn, 'do_not_include_in_total',result.do_not_include_in_total); + frappe.model.set_value(cdt, cdn, 'statistical_component', result.statistical_component); + frappe.model.set_value(cdt, cdn, 'depends_on_lwp', result.depends_on_lwp); + frappe.model.set_value(cdt, cdn, 'do_not_include_in_total', result.do_not_include_in_total); + frappe.model.set_value(cdt, cdn, 'variable_based_on_taxable_salary', result.variable_based_on_taxable_salary); + frappe.model.set_value(cdt, cdn, 'is_tax_applicable', result.is_tax_applicable); + frappe.model.set_value(cdt, cdn, 'is_flexible_benefit', result.is_flexible_benefit); refresh_field("earnings"); refresh_field("deductions"); } From b485b1ef804deadfe1ed2c6eb3d36deb8c0095b8 Mon Sep 17 00:00:00 2001 From: Ranjith Date: Wed, 16 May 2018 23:01:40 +0530 Subject: [PATCH 6/7] Salary Slip calc tax, except for flexi benefits --- .../salary_component/salary_component.py | 11 +++- erpnext/hr/doctype/salary_slip/salary_slip.py | 51 +++++++++++++++++++ .../taxable_salary_slab.json | 4 +- erpnext/hr/utils.py | 7 +++ 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/erpnext/hr/doctype/salary_component/salary_component.py b/erpnext/hr/doctype/salary_component/salary_component.py index 9108f31f9b..beffaec21f 100644 --- a/erpnext/hr/doctype/salary_component/salary_component.py +++ b/erpnext/hr/doctype/salary_component/salary_component.py @@ -18,4 +18,13 @@ class SalaryComponent(Document): self.salary_component_abbr = self.salary_component_abbr.strip() self.salary_component_abbr = append_number_if_name_exists('Salary Component', self.salary_component_abbr, - 'salary_component_abbr', separator='_', filters={"name": ["!=", self.name]}) \ No newline at end of file + 'salary_component_abbr', separator='_', filters={"name": ["!=", self.name]}) + + def calculate_tax(self, annual_earning): + taxable_amount = 0 + for slab in self.taxable_salary_slabs: + if annual_earning > slab.from_amount and annual_earning < slab.to_amount: + taxable_amount += (annual_earning - slab.from_amount) * slab.percent_deduction *.01 + elif annual_earning > slab.from_amount and annual_earning > slab.to_amount: + taxable_amount += (slab.to_amount - slab.from_amount) * slab.percent_deduction * .01 + return taxable_amount diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py index 984a78c75f..ba8cc0235d 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.py +++ b/erpnext/hr/doctype/salary_slip/salary_slip.py @@ -13,6 +13,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_component.additional_salary_component import get_additional_salary_component +from erpnext.hr.utils import get_payroll_period class SalarySlip(TransactionBase): def autoname(self): @@ -58,6 +59,10 @@ class SalarySlip(TransactionBase): 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=="deductions" and struct_row.variable_based_on_taxable_salary: + tax_row, amount = self.calculate_pro_rata_tax(struct_row.salary_component) + if tax_row and amount: + self.update_component_row(frappe._dict(tax_row), amount, key) additional_components = get_additional_salary_component(self.employee, self.start_date, self.end_date) if additional_components: @@ -464,6 +469,52 @@ class SalarySlip(TransactionBase): status = "Cancelled" return status + def calculate_pro_rata_tax(self, salary_component): + # Calculate total tax payable earnings + tax_applicable_components = [] + for earning in self._salary_structure_doc.earnings: + #all tax applicable earnings which are not flexi + if earning.is_tax_applicable and not earning.is_flexible_benefit: + tax_applicable_components.append(earning.salary_component) + total_taxable_earning = 0 + for earning in self.earnings: + if earning.salary_component in tax_applicable_components: + total_taxable_earning += earning.amount + + # Get payroll period, prorata frequency + days = date_diff(self.end_date, self.start_date) + 1 + payroll_period = get_payroll_period(self.start_date, self.end_date, self.company) + if not payroll_period: + frappe.throw(_("Start and end dates not in a valid Payroll Period")) + total_days = date_diff(payroll_period.end_date, payroll_period.start_date) + 1 + prorata_frequency = flt(total_days)/flt(days) + annual_earning = total_taxable_earning * prorata_frequency + + # Calculate total exemption declaration + exemption_amount = 0 + if frappe.db.exists("Employee Tax Exemption Declaration", {"employee": self.employee, + "payroll_period": payroll_period.parent, "docstatus": 1}): + exemption_amount = frappe.db.get_value("Employee Tax Exemption Declaration", + {"employee": self.employee, "payroll_period": "2018", "docstatus": 1}, #fix period + "total_exemption_amount") + annual_earning = annual_earning - exemption_amount + + # Get tax calc by component + component = frappe.get_doc("Salary Component", salary_component) + annual_tax = component.calculate_tax(annual_earning) + + # Calc prorata tax + pro_rata_tax = annual_tax/prorata_frequency + + # Data for update_component_row + struct_row = {} + struct_row['depends_on_lwp'] = 0 + struct_row['salary_component'] = component.name + struct_row['abbr'] = component.salary_component_abbr + struct_row['do_not_include_in_total'] = 0 + + return struct_row, pro_rata_tax + def unlink_ref_doc_from_salary_slip(ref_no): linked_ss = frappe.db.sql_list("""select name from `tabSalary Slip` where journal_entry=%s and docstatus < 2""", (ref_no)) diff --git a/erpnext/hr/doctype/taxable_salary_slab/taxable_salary_slab.json b/erpnext/hr/doctype/taxable_salary_slab/taxable_salary_slab.json index bd0ec6be31..8e6c1d86ae 100644 --- a/erpnext/hr/doctype/taxable_salary_slab/taxable_salary_slab.json +++ b/erpnext/hr/doctype/taxable_salary_slab/taxable_salary_slab.json @@ -50,7 +50,7 @@ "collapsible": 0, "columns": 0, "fieldname": "to_amount", - "fieldtype": "Data", + "fieldtype": "Currency", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -147,7 +147,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-04-13 20:09:36.675987", + "modified": "2018-05-16 18:18:23.802576", "modified_by": "Administrator", "module": "HR", "name": "Taxable Salary Slab", diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py index df720c4cc6..315368dbab 100644 --- a/erpnext/hr/utils.py +++ b/erpnext/hr/utils.py @@ -234,3 +234,10 @@ 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 pd.parent, pd.start_date, pd.end_date from + `tabPayroll Period Date` pd join `tabPayroll Period` pp on + pd.parent=pp.name where pd.start_date<=%s and pd.end_date>= %s + and pp.company=%s""", (from_date, to_date, company), as_dict=1) + return payroll_period[0] if payroll_period else None From 58363e6bbd769e145cc5a27765a56eff6a2cf76c Mon Sep 17 00:00:00 2001 From: Ranjith Date: Thu, 17 May 2018 10:00:33 +0530 Subject: [PATCH 7/7] get_payroll_period return name, fix hard coded leave period --- erpnext/hr/doctype/salary_slip/salary_slip.py | 4 ++-- erpnext/hr/utils.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py index ba8cc0235d..53e6aa437e 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.py +++ b/erpnext/hr/doctype/salary_slip/salary_slip.py @@ -493,9 +493,9 @@ class SalarySlip(TransactionBase): # Calculate total exemption declaration exemption_amount = 0 if frappe.db.exists("Employee Tax Exemption Declaration", {"employee": self.employee, - "payroll_period": payroll_period.parent, "docstatus": 1}): + "payroll_period": payroll_period.name, "docstatus": 1}): exemption_amount = frappe.db.get_value("Employee Tax Exemption Declaration", - {"employee": self.employee, "payroll_period": "2018", "docstatus": 1}, #fix period + {"employee": self.employee, "payroll_period": payroll_period.name, "docstatus": 1}, #fix period "total_exemption_amount") annual_earning = annual_earning - exemption_amount diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py index 315368dbab..20fe666d2b 100644 --- a/erpnext/hr/utils.py +++ b/erpnext/hr/utils.py @@ -236,7 +236,7 @@ def get_leave_period(from_date, to_date, company): return leave_period def get_payroll_period(from_date, to_date, company): - payroll_period = frappe.db.sql("""select pd.parent, pd.start_date, pd.end_date from + payroll_period = frappe.db.sql("""select pp.name, pd.start_date, pd.end_date from `tabPayroll Period Date` pd join `tabPayroll Period` pp on pd.parent=pp.name where pd.start_date<=%s and pd.end_date>= %s and pp.company=%s""", (from_date, to_date, company), as_dict=1)