refactor: trigger generate schedule when any change made in items table (#29874)

* refactor: trigger generate schedule when any change made in items table

* chore: added serial validation on server side

* test: serials updated in schedules after save

* fix: schedule not generating after updating some fields

* feat: generate_schedule is triggered on_save when items table is changed

* test: updated tests to check other field changes on save

* chore: removed serial validation function for schedules table and added no_of_visits validation function

* test: updated for manually deleted schedele rows

* refactor: updated validate_items_table_change to return bool

* test: updated test_schedule_with_serials to cover validate_items_table_change

* fix: linting
This commit is contained in:
Noah Jacob 2022-04-12 15:30:49 +05:30 committed by GitHub
parent 60fb71bd2a
commit 8261b2bb4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 21 deletions

View File

@ -140,26 +140,6 @@ erpnext.maintenance.MaintenanceSchedule = class MaintenanceSchedule extends frap
}
}
start_date(doc, cdt, cdn) {
this.set_no_of_visits(doc, cdt, cdn);
}
end_date(doc, cdt, cdn) {
this.set_no_of_visits(doc, cdt, cdn);
}
periodicity(doc, cdt, cdn) {
this.set_no_of_visits(doc, cdt, cdn);
}
set_no_of_visits(doc, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
let me = this;
if (item.start_date && item.periodicity) {
me.frm.call('validate_end_date_visits');
}
}
};
extend_cscript(cur_frm.cscript, new erpnext.maintenance.MaintenanceSchedule({frm: cur_frm}));

View File

@ -213,6 +213,26 @@ class MaintenanceSchedule(TransactionBase):
if chk:
throw(_("Maintenance Schedule {0} exists against {1}").format(chk[0][0], d.sales_order))
def validate_items_table_change(self):
doc_before_save = self.get_doc_before_save()
if not doc_before_save:
return
for prev_item, item in zip(doc_before_save.items, self.items):
fields = [
"item_code",
"start_date",
"end_date",
"periodicity",
"sales_person",
"no_of_visits",
"serial_no",
]
for field in fields:
b_doc = prev_item.as_dict()
doc = item.as_dict()
if cstr(b_doc[field]) != cstr(doc[field]):
return True
def validate_no_of_visits(self):
return len(self.schedules) != sum(d.no_of_visits for d in self.items)
@ -221,7 +241,7 @@ class MaintenanceSchedule(TransactionBase):
self.validate_maintenance_detail()
self.validate_dates_with_periodicity()
self.validate_sales_order()
if not self.schedules or self.validate_no_of_visits():
if not self.schedules or self.validate_items_table_change() or self.validate_no_of_visits():
self.generate_schedule()
def on_update(self):

View File

@ -123,6 +123,36 @@ class TestMaintenanceSchedule(unittest.TestCase):
frappe.db.rollback()
def test_schedule_with_serials(self):
# Checks whether serials are automatically updated when changing in items table.
# Also checks if other fields trigger generate schdeule if changed in items table.
item_code = "_Test Serial Item"
make_serial_item_with_serial(item_code)
ms = make_maintenance_schedule(item_code=item_code, serial_no="TEST001, TEST002")
ms.save()
# Before Save
self.assertEqual(ms.schedules[0].serial_no, "TEST001, TEST002")
self.assertEqual(ms.schedules[0].sales_person, "Sales Team")
self.assertEqual(len(ms.schedules), 4)
self.assertFalse(ms.validate_items_table_change())
# After Save
ms.items[0].serial_no = "TEST001"
ms.items[0].sales_person = "_Test Sales Person"
ms.items[0].no_of_visits = 2
self.assertTrue(ms.validate_items_table_change())
ms.save()
self.assertEqual(ms.schedules[0].serial_no, "TEST001")
self.assertEqual(ms.schedules[0].sales_person, "_Test Sales Person")
self.assertEqual(len(ms.schedules), 2)
# When user manually deleted a row from schedules table.
ms.schedules.pop()
self.assertEqual(len(ms.schedules), 1)
ms.save()
self.assertEqual(len(ms.schedules), 2)
frappe.db.rollback()
def make_serial_item_with_serial(item_code):
serial_item_doc = create_item(item_code, is_stock_item=1)