fix: employee advance return through multiple additional salaries (#27438)
* fix: employee advance return through multiple additional salaries * test: test repay unclaimed amount from salary * fix: sorting in imports
This commit is contained in:
		
							parent
							
								
									c7ceb37b63
								
							
						
					
					
						commit
						b98740b44a
					
				| @ -73,7 +73,7 @@ frappe.ui.form.on('Employee Advance', { | |||||||
| 					frm.trigger('make_return_entry'); | 					frm.trigger('make_return_entry'); | ||||||
| 				}, __('Create')); | 				}, __('Create')); | ||||||
| 			} else if (frm.doc.repay_unclaimed_amount_from_salary == 1 && frappe.model.can_create("Additional Salary")) { | 			} else if (frm.doc.repay_unclaimed_amount_from_salary == 1 && frappe.model.can_create("Additional Salary")) { | ||||||
| 				frm.add_custom_button(__("Deduction from salary"), function() { | 				frm.add_custom_button(__("Deduction from Salary"), function() { | ||||||
| 					frm.events.make_deduction_via_additional_salary(frm); | 					frm.events.make_deduction_via_additional_salary(frm); | ||||||
| 				}, __('Create')); | 				}, __('Create')); | ||||||
| 			} | 			} | ||||||
|  | |||||||
| @ -170,7 +170,7 @@ | |||||||
|    "default": "0", |    "default": "0", | ||||||
|    "fieldname": "repay_unclaimed_amount_from_salary", |    "fieldname": "repay_unclaimed_amount_from_salary", | ||||||
|    "fieldtype": "Check", |    "fieldtype": "Check", | ||||||
|    "label": "Repay unclaimed amount from salary" |    "label": "Repay Unclaimed Amount from Salary" | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|    "depends_on": "eval:cur_frm.doc.employee", |    "depends_on": "eval:cur_frm.doc.employee", | ||||||
| @ -200,10 +200,11 @@ | |||||||
|  ], |  ], | ||||||
|  "is_submittable": 1, |  "is_submittable": 1, | ||||||
|  "links": [], |  "links": [], | ||||||
|  "modified": "2021-03-31 22:31:53.746659", |  "modified": "2021-09-11 18:38:38.617478", | ||||||
|  "modified_by": "Administrator", |  "modified_by": "Administrator", | ||||||
|  "module": "HR", |  "module": "HR", | ||||||
|  "name": "Employee Advance", |  "name": "Employee Advance", | ||||||
|  |  "naming_rule": "By \"Naming Series\" field", | ||||||
|  "owner": "Administrator", |  "owner": "Administrator", | ||||||
|  "permissions": [ |  "permissions": [ | ||||||
|   { |   { | ||||||
|  | |||||||
| @ -172,7 +172,10 @@ def get_paying_amount_paying_exchange_rate(payment_account, doc): | |||||||
| @frappe.whitelist() | @frappe.whitelist() | ||||||
| def create_return_through_additional_salary(doc): | def create_return_through_additional_salary(doc): | ||||||
| 	import json | 	import json | ||||||
| 	doc = frappe._dict(json.loads(doc)) | 
 | ||||||
|  | 	if isinstance(doc, str): | ||||||
|  | 		doc = frappe._dict(json.loads(doc)) | ||||||
|  | 
 | ||||||
| 	additional_salary = frappe.new_doc('Additional Salary') | 	additional_salary = frappe.new_doc('Additional Salary') | ||||||
| 	additional_salary.employee = doc.employee | 	additional_salary.employee = doc.employee | ||||||
| 	additional_salary.currency = doc.currency | 	additional_salary.currency = doc.currency | ||||||
|  | |||||||
| @ -12,8 +12,11 @@ import erpnext | |||||||
| from erpnext.hr.doctype.employee.test_employee import make_employee | from erpnext.hr.doctype.employee.test_employee import make_employee | ||||||
| from erpnext.hr.doctype.employee_advance.employee_advance import ( | from erpnext.hr.doctype.employee_advance.employee_advance import ( | ||||||
| 	EmployeeAdvanceOverPayment, | 	EmployeeAdvanceOverPayment, | ||||||
|  | 	create_return_through_additional_salary, | ||||||
| 	make_bank_entry, | 	make_bank_entry, | ||||||
| ) | ) | ||||||
|  | from erpnext.payroll.doctype.salary_component.test_salary_component import create_salary_component | ||||||
|  | from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestEmployeeAdvance(unittest.TestCase): | class TestEmployeeAdvance(unittest.TestCase): | ||||||
| @ -33,6 +36,46 @@ class TestEmployeeAdvance(unittest.TestCase): | |||||||
| 		journal_entry1 = make_payment_entry(advance) | 		journal_entry1 = make_payment_entry(advance) | ||||||
| 		self.assertRaises(EmployeeAdvanceOverPayment, journal_entry1.submit) | 		self.assertRaises(EmployeeAdvanceOverPayment, journal_entry1.submit) | ||||||
| 
 | 
 | ||||||
|  | 	def test_repay_unclaimed_amount_from_salary(self): | ||||||
|  | 		employee_name = make_employee("_T@employe.advance") | ||||||
|  | 		advance = make_employee_advance(employee_name, {"repay_unclaimed_amount_from_salary": 1}) | ||||||
|  | 
 | ||||||
|  | 		args = {"type": "Deduction"} | ||||||
|  | 		create_salary_component("Advance Salary - Deduction", **args) | ||||||
|  | 		make_salary_structure("Test Additional Salary for Advance Return", "Monthly", employee=employee_name) | ||||||
|  | 
 | ||||||
|  | 		# additional salary for 700 first | ||||||
|  | 		advance.reload() | ||||||
|  | 		additional_salary = create_return_through_additional_salary(advance) | ||||||
|  | 		additional_salary.salary_component = "Advance Salary - Deduction" | ||||||
|  | 		additional_salary.payroll_date = nowdate() | ||||||
|  | 		additional_salary.amount = 700 | ||||||
|  | 		additional_salary.insert() | ||||||
|  | 		additional_salary.submit() | ||||||
|  | 
 | ||||||
|  | 		advance.reload() | ||||||
|  | 		self.assertEqual(advance.return_amount, 700) | ||||||
|  | 
 | ||||||
|  | 		# additional salary for remaining 300 | ||||||
|  | 		additional_salary = create_return_through_additional_salary(advance) | ||||||
|  | 		additional_salary.salary_component = "Advance Salary - Deduction" | ||||||
|  | 		additional_salary.payroll_date = nowdate() | ||||||
|  | 		additional_salary.amount = 300 | ||||||
|  | 		additional_salary.insert() | ||||||
|  | 		additional_salary.submit() | ||||||
|  | 
 | ||||||
|  | 		advance.reload() | ||||||
|  | 		self.assertEqual(advance.return_amount, 1000) | ||||||
|  | 
 | ||||||
|  | 		# update advance return amount on additional salary cancellation | ||||||
|  | 		additional_salary.cancel() | ||||||
|  | 		advance.reload() | ||||||
|  | 		self.assertEqual(advance.return_amount, 700) | ||||||
|  | 
 | ||||||
|  | 	def tearDown(self): | ||||||
|  | 		frappe.db.rollback() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def make_payment_entry(advance): | def make_payment_entry(advance): | ||||||
| 	journal_entry = frappe.get_doc(make_bank_entry("Employee Advance", advance.name)) | 	journal_entry = frappe.get_doc(make_bank_entry("Employee Advance", advance.name)) | ||||||
| 	journal_entry.cheque_no = "123123" | 	journal_entry.cheque_no = "123123" | ||||||
| @ -41,7 +84,7 @@ def make_payment_entry(advance): | |||||||
| 
 | 
 | ||||||
| 	return journal_entry | 	return journal_entry | ||||||
| 
 | 
 | ||||||
| def make_employee_advance(employee_name): | def make_employee_advance(employee_name, args=None): | ||||||
| 	doc = frappe.new_doc("Employee Advance") | 	doc = frappe.new_doc("Employee Advance") | ||||||
| 	doc.employee = employee_name | 	doc.employee = employee_name | ||||||
| 	doc.company  = "_Test company" | 	doc.company  = "_Test company" | ||||||
| @ -51,6 +94,10 @@ def make_employee_advance(employee_name): | |||||||
| 	doc.advance_amount = 1000 | 	doc.advance_amount = 1000 | ||||||
| 	doc.posting_date = nowdate() | 	doc.posting_date = nowdate() | ||||||
| 	doc.advance_account = "_Test Employee Advance - _TC" | 	doc.advance_account = "_Test Employee Advance - _TC" | ||||||
|  | 
 | ||||||
|  | 	if args: | ||||||
|  | 		doc.update(args) | ||||||
|  | 
 | ||||||
| 	doc.insert() | 	doc.insert() | ||||||
| 	doc.submit() | 	doc.submit() | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -14,12 +14,11 @@ from erpnext.hr.utils import validate_active_employee | |||||||
| 
 | 
 | ||||||
| class AdditionalSalary(Document): | class AdditionalSalary(Document): | ||||||
| 	def on_submit(self): | 	def on_submit(self): | ||||||
| 		if self.ref_doctype == "Employee Advance" and self.ref_docname: | 		self.update_return_amount_in_employee_advance() | ||||||
| 			frappe.db.set_value("Employee Advance", self.ref_docname, "return_amount", self.amount) |  | ||||||
| 
 |  | ||||||
| 		self.update_employee_referral() | 		self.update_employee_referral() | ||||||
| 
 | 
 | ||||||
| 	def on_cancel(self): | 	def on_cancel(self): | ||||||
|  | 		self.update_return_amount_in_employee_advance() | ||||||
| 		self.update_employee_referral(cancel=True) | 		self.update_employee_referral(cancel=True) | ||||||
| 
 | 
 | ||||||
| 	def validate(self): | 	def validate(self): | ||||||
| @ -98,6 +97,17 @@ class AdditionalSalary(Document): | |||||||
| 				frappe.throw(_("Additional Salary for referral bonus can only be created against Employee Referral with status {0}").format( | 				frappe.throw(_("Additional Salary for referral bonus can only be created against Employee Referral with status {0}").format( | ||||||
| 					frappe.bold("Accepted"))) | 					frappe.bold("Accepted"))) | ||||||
| 
 | 
 | ||||||
|  | 	def update_return_amount_in_employee_advance(self): | ||||||
|  | 		if self.ref_doctype == "Employee Advance" and self.ref_docname: | ||||||
|  | 			return_amount = frappe.db.get_value("Employee Advance", self.ref_docname, "return_amount") | ||||||
|  | 
 | ||||||
|  | 			if self.docstatus == 2: | ||||||
|  | 				return_amount -= self.amount | ||||||
|  | 			else: | ||||||
|  | 				return_amount += self.amount | ||||||
|  | 
 | ||||||
|  | 			frappe.db.set_value("Employee Advance", self.ref_docname, "return_amount", return_amount) | ||||||
|  | 
 | ||||||
| 	def update_employee_referral(self, cancel=False): | 	def update_employee_referral(self, cancel=False): | ||||||
| 		if self.ref_doctype == "Employee Referral": | 		if self.ref_doctype == "Employee Referral": | ||||||
| 			status = "Unpaid" if cancel else "Paid" | 			status = "Unpaid" if cancel else "Paid" | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user