feat: employee initial work history updated when transfer is performed (#27768)

* feat: employee initial work history updated when transfer is performed

* fix: sider

* fix: remove commit statement

* fix: tests and code formatting

* fix: tests

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
diff --git a/erpnext/hr/doctype/employee_promotion/employee_promotion.py b/erpnext/hr/doctype/employee_promotion/employee_promotion.py
index 164d48b..b051752 100644
--- a/erpnext/hr/doctype/employee_promotion/employee_promotion.py
+++ b/erpnext/hr/doctype/employee_promotion/employee_promotion.py
@@ -9,7 +9,7 @@
 from frappe.model.document import Document
 from frappe.utils import getdate
 
-from erpnext.hr.utils import update_employee, validate_active_employee
+from erpnext.hr.utils import update_employee_work_history, validate_active_employee
 
 
 class EmployeePromotion(Document):
@@ -23,10 +23,10 @@
 
 	def on_submit(self):
 		employee = frappe.get_doc("Employee", self.employee)
-		employee = update_employee(employee, self.promotion_details, date=self.promotion_date)
+		employee = update_employee_work_history(employee, self.promotion_details, date=self.promotion_date)
 		employee.save()
 
 	def on_cancel(self):
 		employee = frappe.get_doc("Employee", self.employee)
-		employee = update_employee(employee, self.promotion_details, cancel=True)
+		employee = update_employee_work_history(employee, self.promotion_details, cancel=True)
 		employee.save()
diff --git a/erpnext/hr/doctype/employee_transfer/employee_transfer.py b/erpnext/hr/doctype/employee_transfer/employee_transfer.py
index b1f6609..29d93f3 100644
--- a/erpnext/hr/doctype/employee_transfer/employee_transfer.py
+++ b/erpnext/hr/doctype/employee_transfer/employee_transfer.py
@@ -9,7 +9,7 @@
 from frappe.model.document import Document
 from frappe.utils import getdate
 
-from erpnext.hr.utils import update_employee
+from erpnext.hr.utils import update_employee_work_history
 
 
 class EmployeeTransfer(Document):
@@ -24,7 +24,7 @@
 			new_employee = frappe.copy_doc(employee)
 			new_employee.name = None
 			new_employee.employee_number = None
-			new_employee = update_employee(new_employee, self.transfer_details, date=self.transfer_date)
+			new_employee = update_employee_work_history(new_employee, self.transfer_details, date=self.transfer_date)
 			if self.new_company and self.company != self.new_company:
 				new_employee.internal_work_history = []
 				new_employee.date_of_joining = self.transfer_date
@@ -39,7 +39,7 @@
 			employee.db_set("relieving_date", self.transfer_date)
 			employee.db_set("status", "Left")
 		else:
-			employee = update_employee(employee, self.transfer_details, date=self.transfer_date)
+			employee = update_employee_work_history(employee, self.transfer_details, date=self.transfer_date)
 			if self.new_company and self.company != self.new_company:
 				employee.company = self.new_company
 				employee.date_of_joining = self.transfer_date
@@ -56,7 +56,7 @@
 			employee.status = "Active"
 			employee.relieving_date = ''
 		else:
-			employee = update_employee(employee, self.transfer_details, cancel=True)
+			employee = update_employee_work_history(employee, self.transfer_details, date=self.transfer_date, cancel=True)
 		if self.new_company != self.company:
 			employee.company = self.company
 		employee.save()
diff --git a/erpnext/hr/doctype/employee_transfer/test_employee_transfer.py b/erpnext/hr/doctype/employee_transfer/test_employee_transfer.py
index ad2f3ad..c0440d0 100644
--- a/erpnext/hr/doctype/employee_transfer/test_employee_transfer.py
+++ b/erpnext/hr/doctype/employee_transfer/test_employee_transfer.py
@@ -4,6 +4,7 @@
 from __future__ import unicode_literals
 
 import unittest
+from datetime import date
 
 import frappe
 from frappe.utils import add_days, getdate
@@ -15,7 +16,12 @@
 	def setUp(self):
 		make_employee("employee2@transfers.com")
 		make_employee("employee3@transfers.com")
-		frappe.db.sql("""delete from `tabEmployee Transfer`""")
+		create_company()
+		create_employee()
+		create_employee_transfer()
+
+	def tearDown(self):
+		frappe.db.rollback()
 
 	def test_submit_before_transfer_date(self):
 		transfer_obj = frappe.get_doc({
@@ -57,3 +63,77 @@
 		self.assertTrue(transfer.new_employee_id)
 		self.assertEqual(frappe.get_value("Employee", transfer.new_employee_id, "status"), "Active")
 		self.assertEqual(frappe.get_value("Employee", transfer.employee, "status"), "Left")
+
+	def test_employee_history(self):
+		name = frappe.get_value("Employee", {"first_name": "John", "company": "Test Company"}, "name")
+		doc = frappe.get_doc("Employee",name)
+		count = 0
+		department = ["Accounts - TC", "Management - TC"]
+		designation = ["Accountant", "Manager"]
+		dt = [getdate("01-10-2021"), date.today()]
+
+		for data in doc.internal_work_history:
+			self.assertEqual(data.department, department[count])
+			self.assertEqual(data.designation, designation[count])
+			self.assertEqual(data.from_date, dt[count])
+			count = count + 1
+
+		data = frappe.db.get_list("Employee Transfer", filters={"employee":name}, fields=["*"])
+		doc = frappe.get_doc("Employee Transfer", data[0]["name"])
+		doc.cancel()
+		employee_doc = frappe.get_doc("Employee",name)
+
+		for data in employee_doc.internal_work_history:
+			self.assertEqual(data.designation, designation[0])
+			self.assertEqual(data.department, department[0])
+			self.assertEqual(data.from_date, dt[0])
+
+def create_employee():
+	doc = frappe.get_doc({
+			"doctype": "Employee",
+			"first_name": "John",
+			"company": "Test Company",
+			"gender": "Male",
+			"date_of_birth": getdate("30-09-1980"),
+			"date_of_joining": getdate("01-10-2021"),
+			"department": "Accounts - TC",
+			"designation": "Accountant"
+	})
+
+	doc.save()
+
+def create_company():
+	exists = frappe.db.exists("Company", "Test Company")
+	if not exists:
+		doc = frappe.get_doc({
+				"doctype": "Company",
+				"company_name": "Test Company",
+				"default_currency": "INR",
+				"country": "India"
+		})
+
+		doc.save()
+
+def create_employee_transfer():
+	doc = frappe.get_doc({
+		"doctype": "Employee Transfer",
+		"employee": frappe.get_value("Employee", {"first_name": "John", "company": "Test Company"}, "name"),
+		"transfer_date": date.today(),
+		"transfer_details": [
+			{
+				"property": "Designation",
+				"current": "Accountant",
+				"new": "Manager",
+				"fieldname": "designation"
+			},
+			{
+				"property": "Department",
+				"current": "Accounts - TC",
+				"new": "Management - TC",
+				"fieldname": "department"
+			}
+		]
+	})
+
+	doc.save()
+	doc.submit()
\ No newline at end of file
diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py
index b6f4cad..0febce1 100644
--- a/erpnext/hr/utils.py
+++ b/erpnext/hr/utils.py
@@ -29,7 +29,15 @@
 	if doc.employee and not doc.employee_name:
 		doc.employee_name = frappe.db.get_value("Employee", doc.employee, "employee_name")
 
-def update_employee(employee, details, date=None, cancel=False):
+def update_employee_work_history(employee, details, date=None, cancel=False):
+	if not employee.internal_work_history and not cancel:
+		employee.append("internal_work_history", {
+			"branch": employee.branch,
+			"designation": employee.designation,
+			"department": employee.department,
+			"from_date": employee.date_of_joining
+		})
+
 	internal_work_history = {}
 	for item in details:
 		field = frappe.get_meta("Employee").get_field(item.fieldname)
@@ -44,11 +52,35 @@
 		setattr(employee, item.fieldname, new_data)
 		if item.fieldname in ["department", "designation", "branch"]:
 			internal_work_history[item.fieldname] = item.new
+
 	if internal_work_history and not cancel:
 		internal_work_history["from_date"] = date
 		employee.append("internal_work_history", internal_work_history)
+
+	if cancel:
+		delete_employee_work_history(details, employee, date)
+
 	return employee
 
+def delete_employee_work_history(details, employee, date):
+	filters = {}
+	for d in details:
+		for history in employee.internal_work_history:
+			if d.property == "Department" and history.department == d.new:
+				department = d.new
+				filters["department"] = department
+			if d.property == "Designation" and history.designation == d.new:
+				designation = d.new
+				filters["designation"] = designation
+			if d.property == "Branch" and history.branch == d.new:
+				branch = d.new
+				filters["branch"] = branch
+			if date and date == history.from_date:
+				filters["from_date"] = date
+	if filters:
+		frappe.db.delete("Employee Internal Work History", filters)
+
+
 @frappe.whitelist()
 def get_employee_fields_label():
 	fields = []