diff --git a/erpnext/patches/v13_0/setup_gratuity_rule_for_india_and_uae.py b/erpnext/patches/v13_0/setup_gratuity_rule_for_india_and_uae.py index 93cadf576cb..2dd064ebcac 100644 --- a/erpnext/patches/v13_0/setup_gratuity_rule_for_india_and_uae.py +++ b/erpnext/patches/v13_0/setup_gratuity_rule_for_india_and_uae.py @@ -9,10 +9,9 @@ def execute(): frappe.reload_doc('payroll', 'doctype', 'gratuity_rule') frappe.reload_doc('payroll', 'doctype', 'gratuity_rule_slab') frappe.reload_doc('payroll', 'doctype', 'gratuity_applicable_component') - region = erpnext.get_region() - if region == "India": + if frappe.db.exists("company", {"country": "India"}): from erpnext.regional.india.setup import create_gratuity_rule create_gratuity_rule() - elif region == "United Arab Emirates": + if frappe.db.exists("company", {"country": "United Arab Emirates"}): from erpnext.regional.united_arab_emirates.setup import create_gratuity_rule create_gratuity_rule() \ No newline at end of file diff --git a/erpnext/payroll/doctype/gratuity/gratuity.js b/erpnext/payroll/doctype/gratuity/gratuity.js index d6e93af5244..dfdf08bdea0 100644 --- a/erpnext/payroll/doctype/gratuity/gratuity.js +++ b/erpnext/payroll/doctype/gratuity/gratuity.js @@ -2,24 +2,7 @@ // For license information, please see license.txt frappe.ui.form.on('Gratuity', { - refresh: function(frm){ - if(frm.doc.docstatus === 1 && frm.doc.pay_via_salary_slip === 0 && frm.doc.status === "Unpaid") { - frm.add_custom_button(__("Make Payment Entry"), function() { - return frappe.call({ - method: 'erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry', - args: { - "dt": cur_frm.doc.doctype, - "dn": cur_frm.doc.name - }, - callback: function(r) { - var doclist = frappe.model.sync(r.message); - frappe.set_route("Form", doclist[0].doctype, doclist[0].name); - } - }); - }); - } - }, - onload: function(frm){ + setup: function(frm){ frm.set_query('salary_component', function() { return { filters: { @@ -30,13 +13,30 @@ frappe.ui.form.on('Gratuity', { frm.set_query("expense_account", function() { return { filters: { - "root_type": "Asset", + "root_type": "Expense", "is_group": 0, "company": frm.doc.company } }; }); }, + refresh: function(frm){ + if(frm.doc.docstatus === 1 && frm.doc.pay_via_salary_slip === 0 && frm.doc.status === "Unpaid") { + frm.add_custom_button(__("Create Payment Entry"), function() { + return frappe.call({ + method: 'erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry', + args: { + "dt": frm.doc.doctype, + "dn": frm.doc.name + }, + callback: function(r) { + var doclist = frappe.model.sync(r.message); + frappe.set_route("Form", doclist[0].doctype, doclist[0].name); + } + }); + }); + } + }, employee: function(frm) { frm.events.calculate_work_experience_and_amount(frm); }, diff --git a/erpnext/payroll/doctype/gratuity/gratuity.json b/erpnext/payroll/doctype/gratuity/gratuity.json index b8122dfb894..b81ae588eaa 100644 --- a/erpnext/payroll/doctype/gratuity/gratuity.json +++ b/erpnext/payroll/doctype/gratuity/gratuity.json @@ -175,9 +175,10 @@ "read_only": 1 } ], + "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2020-08-14 11:59:15.499548", + "modified": "2020-10-27 14:04:41.886934", "modified_by": "Administrator", "module": "Payroll", "name": "Gratuity", @@ -191,7 +192,19 @@ "print": 1, "read": 1, "report": 1, - "role": "System Manager", + "role": "HR Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR User", "share": 1, "write": 1 } diff --git a/erpnext/payroll/doctype/gratuity/gratuity.py b/erpnext/payroll/doctype/gratuity/gratuity.py index 815e24d6e4b..e6c519a482f 100644 --- a/erpnext/payroll/doctype/gratuity/gratuity.py +++ b/erpnext/payroll/doctype/gratuity/gratuity.py @@ -9,7 +9,6 @@ from frappe.model.document import Document from frappe.utils import flt, get_datetime, get_link_to_form from math import floor -from frappe.utils import get_datetime class Gratuity(Document): def validate(self): data = calculate_work_experience_and_amount(self.employee, self.gratuity_rule) @@ -22,6 +21,9 @@ class Gratuity(Document): self.status = "Paid" def on_submit(self): + create_additional_salary() + + def create_additional_salary(self): if self.pay_via_salary_slip: additional_salary = frappe.new_doc('Additional Salary') additional_salary.employee = self.employee @@ -170,7 +172,7 @@ def get_total_applicable_component_amount(employee, applicable_earnings_componen fields=["amount"]) total_applicable_components_amount = 0 if not len(component_and_amounts): - frappe.throw("No Applicable Component is present in last month salary slip") + frappe.throw(_("No Applicable Component is present in last month salary slip")) for data in component_and_amounts: total_applicable_components_amount += data.amount @@ -180,10 +182,17 @@ def get_gratuity_rule_slabs(gratuity_rule): return frappe.get_all("Gratuity Rule Slab", filters= {'parent': gratuity_rule}, fields = ["*"], order_by="idx") def get_salary_structure(employee): - return frappe.get_list("Salary Structure Assignment", filters = {"employee": employee, 'docstatus': 1}, fields=["from_date", "salary_structure"], order_by = "from_date desc")[0].salary_structure + return frappe.get_list("Salary Structure Assignment", filters = { + "employee": employee, 'docstatus': 1 + }, + fields=["from_date", "salary_structure"], + order_by = "from_date desc")[0].salary_structure def get_last_salary_slip(employee): - return frappe.get_list("Salary Slip", filters = {"employee": employee, 'docstatus': 1}, order_by = "start_date desc")[0].name + return frappe.get_list("Salary Slip", filters = { + "employee": employee, 'docstatus': 1 + }, + order_by = "start_date desc")[0].name diff --git a/erpnext/payroll/doctype/gratuity/test_gratuity.py b/erpnext/payroll/doctype/gratuity/test_gratuity.py index fb2488cf85e..680ecbcfc1b 100644 --- a/erpnext/payroll/doctype/gratuity/test_gratuity.py +++ b/erpnext/payroll/doctype/gratuity/test_gratuity.py @@ -13,12 +13,10 @@ from frappe.utils import getdate, add_days, get_datetime, flt class TestGratuity(unittest.TestCase): - def setUp(self): frappe.db.sql("DELETE FROM `tabgratuity`") frappe.db.sql("DELETE FROM `tabAdditional Salary` WHERE ref_doctype = 'Gratuity'") - def test_check_gratuity_amount_based_on_current_slab_and_additional_salary_creation(self): employee, sal_slip = create_employee_and_get_last_salary_slip() rule = frappe.db.exists("Gratuity Rule", "Rule Under Unlimited Contract on termination (UAE)") @@ -33,15 +31,15 @@ class TestGratuity(unittest.TestCase): rule.save() rule.reload() - gra = frappe.new_doc("Gratuity") - gra.employee = employee - gra.posting_date = getdate() - gra.gratuity_rule = rule.name - gra.pay_via_salary_slip = 1 - gra.salary_component = "Performance Bonus" - gra.payroll_date = getdate() - gra.save() - gra.submit() + gratuity = frappe.new_doc("Gratuity") + gratuity.employee = employee + gratuity.posting_date = getdate() + gratuity.gratuity_rule = rule.name + gratuity.pay_via_salary_slip = 1 + gratuity.salary_component = "Performance Bonus" + gratuity.payroll_date = getdate() + gratuity.save() + gratuity.submit() #work experience calculation date_of_joining, relieving_date = frappe.db.get_value('Employee', employee, ['date_of_joining', 'relieving_date']) @@ -49,11 +47,11 @@ class TestGratuity(unittest.TestCase): experience = employee_total_workings_days/rule.total_working_days_per_year - gra.reload() + gratuity.reload() from math import floor - self.assertEqual(floor(experience), gra.current_work_experience) + self.assertEqual(floor(experience), gratuity.current_work_experience) #amount Calculation 6 component_amount = frappe.get_list("Salary Detail", @@ -68,15 +66,13 @@ class TestGratuity(unittest.TestCase): ''' 5 - 0 fraction is 1 ''' gratuity_amount = component_amount[0].amount * experience - gra.reload() + gratuity.reload() - self.assertEqual(flt(gratuity_amount, 2), flt(gra.amount, 2)) + self.assertEqual(flt(gratuity_amount, 2), flt(gratuity.amount, 2)) #additional salary creation (Pay via salary slip) - self.assertTrue(frappe.db.exists("Additional Salary", {"ref_docname": gra.name})) - self.assertEqual(gra.status, "Paid") - - + self.assertTrue(frappe.db.exists("Additional Salary", {"ref_docname": gratuity.name})) + self.assertEqual(gratuity.status, "Paid") def test_check_gratuity_amount_based_on_all_previous_slabs(self): employee, sal_slip = create_employee_and_get_last_salary_slip() @@ -102,17 +98,17 @@ class TestGratuity(unittest.TestCase): mof.save() - gra = frappe.new_doc("Gratuity") - gra.employee = employee - gra.posting_date = getdate() - gra.gratuity_rule = rule.name - gra.pay_via_salary_slip = 0 - gra.payroll_date = getdate() - gra.expense_account = "Payment Account - _TC" - gra.mode_of_payment = "Cheque" + gratuity = frappe.new_doc("Gratuity") + gratuity.employee = employee + gratuity.posting_date = getdate() + gratuity.gratuity_rule = rule.name + gratuity.pay_via_salary_slip = 0 + gratuity.payroll_date = getdate() + gratuity.expense_account = "Payment Account - _TC" + gratuity.mode_of_payment = "Cheque" - gra.save() - gra.submit() + gratuity.save() + gratuity.submit() #work experience calculation date_of_joining, relieving_date = frappe.db.get_value('Employee', employee, ['date_of_joining', 'relieving_date']) @@ -120,11 +116,11 @@ class TestGratuity(unittest.TestCase): experience = employee_total_workings_days/rule.total_working_days_per_year - gra.reload() + gratuity.reload() from math import floor - self.assertEqual(floor(experience), gra.current_work_experience) + self.assertEqual(floor(experience), gratuity.current_work_experience) #amount Calculation 6 component_amount = frappe.get_list("Salary Detail", @@ -145,25 +141,29 @@ class TestGratuity(unittest.TestCase): gratuity_amount = ((0 * 1) + (4 * 0.7) + (1 * 1)) * component_amount[0].amount - gra.reload() + gratuity.reload() - self.assertEqual(flt(gratuity_amount, 2), flt(gra.amount, 2)) - self.assertEqual(gra.status, "Unpaid") + self.assertEqual(flt(gratuity_amount, 2), flt(gratuity.amount, 2)) + self.assertEqual(gratuity.status, "Unpaid") from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry - pay_entry = get_payment_entry("Gratuity", gra.name) + pay_entry = get_payment_entry("Gratuity", gratuity.name) pay_entry.reference_no = "123467" pay_entry.reference_date = getdate() pay_entry.save() pay_entry.submit() - gra.reload() + gratuity.reload() - self.assertEqual(gra.status, "Paid") - self.assertEqual(gra.paid_amount, flt(gra.amount, 2)) + self.assertEqual(gratuity.status, "Paid") + self.assertEqual(gratuity.paid_amount, flt(gratuity.amount, 2)) + + def tearDown(self): + frappe.db.sql("DELETE FROM `tabgratuity`") + frappe.db.sql("DELETE FROM `tabAdditional Salary` WHERE ref_doctype = 'Gratuity'") def create_employee_and_get_last_salary_slip(): employee = make_employee("test_employee@salary.com") diff --git a/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.js b/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.js index 69099bb39d5..9e9f3e204bc 100644 --- a/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.js +++ b/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.js @@ -25,7 +25,7 @@ frappe.ui.form.on('Gratuity Rule Slab', { gratuity_rule_slabs_add(frm, cdt, cdn) { let row = locals[cdt][cdn]; - let array_idx = row.idx - 1 + let array_idx = row.idx - 1; if(array_idx > 0){ row.from_year = cur_frm.doc.gratuity_rule_slabs[array_idx-1].to_year; frm.refresh(); diff --git a/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.json b/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.json index 18053ba88e7..7d24e41f485 100644 --- a/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.json +++ b/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.json @@ -75,8 +75,9 @@ "label": "Minimum Year for Gratuity" } ], + "index_web_pages_for_search": 1, "links": [], - "modified": "2020-08-17 14:17:02.594665", + "modified": "2020-10-27 14:04:31.617621", "modified_by": "Administrator", "module": "Payroll", "name": "Gratuity Rule", @@ -90,7 +91,19 @@ "print": 1, "read": 1, "report": 1, - "role": "All", + "role": "HR Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR User", "share": 1, "write": 1 }