feat: Training Event Status Update and Validations (#26698)
* fix: training event employee status not updated on feedback submission * feat: update attendees status on training event status update * test: Training Event and Feedback * chore: remove unused import
This commit is contained in:
parent
a9a24051c9
commit
bf75ea70fb
@ -11,21 +11,34 @@ from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_
|
|||||||
class TestTrainingEvent(unittest.TestCase):
|
class TestTrainingEvent(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
create_training_program("Basic Training")
|
create_training_program("Basic Training")
|
||||||
self.employee = make_employee("robert_loan@trainig.com")
|
employee = make_employee("robert_loan@trainig.com")
|
||||||
self.employee2 = make_employee("suzie.tan@trainig.com")
|
employee2 = make_employee("suzie.tan@trainig.com")
|
||||||
|
self.attendees = [
|
||||||
|
{"employee": employee},
|
||||||
|
{"employee": employee2}
|
||||||
|
]
|
||||||
|
|
||||||
|
def test_training_event_status_update(self):
|
||||||
|
training_event = create_training_event(self.attendees)
|
||||||
|
training_event.submit()
|
||||||
|
|
||||||
|
training_event.event_status = "Completed"
|
||||||
|
training_event.save()
|
||||||
|
training_event.reload()
|
||||||
|
|
||||||
|
for entry in training_event.employees:
|
||||||
|
self.assertEqual(entry.status, "Completed")
|
||||||
|
|
||||||
|
training_event.event_status = "Scheduled"
|
||||||
|
training_event.save()
|
||||||
|
training_event.reload()
|
||||||
|
|
||||||
|
for entry in training_event.employees:
|
||||||
|
self.assertEqual(entry.status, "Open")
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
frappe.db.rollback()
|
||||||
|
|
||||||
def test_create_training_event(self):
|
|
||||||
if not frappe.db.get_value("Training Event", "Basic Training Event"):
|
|
||||||
frappe.get_doc({
|
|
||||||
"doctype": "Training Event",
|
|
||||||
"event_name": "Basic Training Event",
|
|
||||||
"training_program": "Basic Training",
|
|
||||||
"location": "Union Square",
|
|
||||||
"start_time": add_days(today(), 5),
|
|
||||||
"end_time": add_days(today(), 6),
|
|
||||||
"introduction": "Welcome to the Basic Training Event",
|
|
||||||
"employees": get_attendees(self.employee, self.employee2)
|
|
||||||
}).insert()
|
|
||||||
|
|
||||||
def create_training_program(training_program):
|
def create_training_program(training_program):
|
||||||
if not frappe.db.get_value("Training Program", training_program):
|
if not frappe.db.get_value("Training Program", training_program):
|
||||||
@ -35,8 +48,14 @@ def create_training_program(training_program):
|
|||||||
"description": training_program
|
"description": training_program
|
||||||
}).insert()
|
}).insert()
|
||||||
|
|
||||||
def get_attendees(employee, employee2):
|
def create_training_event(attendees):
|
||||||
return [
|
return frappe.get_doc({
|
||||||
{"employee": employee},
|
"doctype": "Training Event",
|
||||||
{"employee": employee2}
|
"event_name": "Basic Training Event",
|
||||||
]
|
"training_program": "Basic Training",
|
||||||
|
"location": "Union Square",
|
||||||
|
"start_time": add_days(today(), 5),
|
||||||
|
"end_time": add_days(today(), 6),
|
||||||
|
"introduction": "Welcome to the Basic Training Event",
|
||||||
|
"employees": attendees
|
||||||
|
}).insert()
|
@ -14,10 +14,25 @@ class TrainingEvent(Document):
|
|||||||
self.set_employee_emails()
|
self.set_employee_emails()
|
||||||
self.validate_period()
|
self.validate_period()
|
||||||
|
|
||||||
|
def on_update_after_submit(self):
|
||||||
|
self.set_status_for_attendees()
|
||||||
|
|
||||||
def set_employee_emails(self):
|
def set_employee_emails(self):
|
||||||
self.employee_emails = ', '.join(get_employee_emails([d.employee
|
self.employee_emails = ', '.join(get_employee_emails([d.employee
|
||||||
for d in self.employees]))
|
for d in self.employees]))
|
||||||
|
|
||||||
def validate_period(self):
|
def validate_period(self):
|
||||||
if time_diff_in_seconds(self.end_time, self.start_time) <= 0:
|
if time_diff_in_seconds(self.end_time, self.start_time) <= 0:
|
||||||
frappe.throw(_('End time cannot be before start time'))
|
frappe.throw(_('End time cannot be before start time'))
|
||||||
|
|
||||||
|
def set_status_for_attendees(self):
|
||||||
|
if self.event_status == 'Completed':
|
||||||
|
for employee in self.employees:
|
||||||
|
if employee.attendance == 'Present' and employee.status != 'Feedback Submitted':
|
||||||
|
employee.status = 'Completed'
|
||||||
|
|
||||||
|
elif self.event_status == 'Scheduled':
|
||||||
|
for employee in self.employees:
|
||||||
|
employee.status = 'Open'
|
||||||
|
|
||||||
|
self.db_update_all()
|
||||||
|
@ -5,8 +5,63 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import unittest
|
import unittest
|
||||||
|
from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_employee
|
||||||
# test_records = frappe.get_test_records('Training Feedback')
|
from erpnext.hr.doctype.training_event.test_training_event import create_training_program, create_training_event
|
||||||
|
|
||||||
class TestTrainingFeedback(unittest.TestCase):
|
class TestTrainingFeedback(unittest.TestCase):
|
||||||
pass
|
def setUp(self):
|
||||||
|
create_training_program("Basic Training")
|
||||||
|
self.employee = make_employee("robert_loan@trainig.com")
|
||||||
|
self.employee2 = make_employee("suzie.tan@trainig.com")
|
||||||
|
self.attendees = [{"employee": self.employee}]
|
||||||
|
|
||||||
|
def test_employee_validations_for_feedback(self):
|
||||||
|
training_event = create_training_event(self.attendees)
|
||||||
|
training_event.submit()
|
||||||
|
|
||||||
|
training_event.event_status = "Completed"
|
||||||
|
training_event.save()
|
||||||
|
training_event.reload()
|
||||||
|
|
||||||
|
# should not allow creating feedback since employee2 was not part of the event
|
||||||
|
feedback = create_training_feedback(training_event.name, self.employee2)
|
||||||
|
self.assertRaises(frappe.ValidationError, feedback.save)
|
||||||
|
|
||||||
|
# cannot record feedback for absent employee
|
||||||
|
employee = frappe.db.get_value("Training Event Employee", {
|
||||||
|
"parent": training_event.name,
|
||||||
|
"employee": self.employee
|
||||||
|
}, "name")
|
||||||
|
|
||||||
|
frappe.db.set_value("Training Event Employee", employee, "attendance", "Absent")
|
||||||
|
feedback = create_training_feedback(training_event.name, self.employee)
|
||||||
|
self.assertRaises(frappe.ValidationError, feedback.save)
|
||||||
|
|
||||||
|
def test_training_feedback_status(self):
|
||||||
|
training_event = create_training_event(self.attendees)
|
||||||
|
training_event.submit()
|
||||||
|
|
||||||
|
training_event.event_status = "Completed"
|
||||||
|
training_event.save()
|
||||||
|
training_event.reload()
|
||||||
|
|
||||||
|
feedback = create_training_feedback(training_event.name, self.employee)
|
||||||
|
feedback.submit()
|
||||||
|
|
||||||
|
status = frappe.db.get_value("Training Event Employee", {
|
||||||
|
"parent": training_event.name,
|
||||||
|
"employee": self.employee
|
||||||
|
}, "status")
|
||||||
|
|
||||||
|
self.assertEqual(status, "Feedback Submitted")
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
frappe.db.rollback()
|
||||||
|
|
||||||
|
|
||||||
|
def create_training_feedback(event, employee):
|
||||||
|
return frappe.get_doc({
|
||||||
|
"doctype": "Training Feedback",
|
||||||
|
"training_event": event,
|
||||||
|
"employee": employee,
|
||||||
|
"feedback": "Test"
|
||||||
|
})
|
@ -11,15 +11,35 @@ class TrainingFeedback(Document):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
training_event = frappe.get_doc("Training Event", self.training_event)
|
training_event = frappe.get_doc("Training Event", self.training_event)
|
||||||
if training_event.docstatus != 1:
|
if training_event.docstatus != 1:
|
||||||
frappe.throw(_('{0} must be submitted').format(_('Training Event')))
|
frappe.throw(_("{0} must be submitted").format(_("Training Event")))
|
||||||
|
|
||||||
|
emp_event_details = frappe.db.get_value("Training Event Employee", {
|
||||||
|
"parent": self.training_event,
|
||||||
|
"employee": self.employee
|
||||||
|
}, ["name", "attendance"], as_dict=True)
|
||||||
|
|
||||||
|
if not emp_event_details:
|
||||||
|
frappe.throw(_("Employee {0} not found in Training Event Participants.").format(
|
||||||
|
frappe.bold(self.employee_name)))
|
||||||
|
|
||||||
|
if emp_event_details.attendance == "Absent":
|
||||||
|
frappe.throw(_("Feedback cannot be recorded for an absent Employee."))
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
training_event = frappe.get_doc("Training Event", self.training_event)
|
employee = frappe.db.get_value("Training Event Employee", {
|
||||||
event_status = None
|
"parent": self.training_event,
|
||||||
for e in training_event.employees:
|
"employee": self.employee
|
||||||
if e.employee == self.employee:
|
})
|
||||||
event_status = 'Feedback Submitted'
|
|
||||||
break
|
if employee:
|
||||||
|
frappe.db.set_value("Training Event Employee", employee, "status", "Feedback Submitted")
|
||||||
|
|
||||||
|
def on_cancel(self):
|
||||||
|
employee = frappe.db.get_value("Training Event Employee", {
|
||||||
|
"parent": self.training_event,
|
||||||
|
"employee": self.employee
|
||||||
|
})
|
||||||
|
|
||||||
|
if employee:
|
||||||
|
frappe.db.set_value("Training Event Employee", employee, "status", "Completed")
|
||||||
|
|
||||||
if event_status:
|
|
||||||
frappe.db.set_value("Training Event", self.training_event, "event_status", event_status)
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user