mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-01 11:19:09 +00:00
style: format code with black
This commit is contained in:
@@ -16,17 +16,17 @@ class MaintenanceSchedule(TransactionBase):
|
||||
def generate_schedule(self):
|
||||
if self.docstatus != 0:
|
||||
return
|
||||
self.set('schedules', [])
|
||||
self.set("schedules", [])
|
||||
count = 1
|
||||
for d in self.get('items'):
|
||||
for d in self.get("items"):
|
||||
self.validate_maintenance_detail()
|
||||
s_list = []
|
||||
s_list = self.create_schedule_list(d.start_date, d.end_date, d.no_of_visits, d.sales_person)
|
||||
for i in range(d.no_of_visits):
|
||||
child = self.append('schedules')
|
||||
child = self.append("schedules")
|
||||
child.item_code = d.item_code
|
||||
child.item_name = d.item_name
|
||||
child.scheduled_date = s_list[i].strftime('%Y-%m-%d')
|
||||
child.scheduled_date = s_list[i].strftime("%Y-%m-%d")
|
||||
if d.serial_no:
|
||||
child.serial_no = d.serial_no
|
||||
child.idx = count
|
||||
@@ -37,18 +37,14 @@ class MaintenanceSchedule(TransactionBase):
|
||||
|
||||
@frappe.whitelist()
|
||||
def validate_end_date_visits(self):
|
||||
days_in_period = {
|
||||
"Weekly": 7,
|
||||
"Monthly": 30,
|
||||
"Quarterly": 91,
|
||||
"Half Yearly": 182,
|
||||
"Yearly": 365
|
||||
}
|
||||
days_in_period = {"Weekly": 7, "Monthly": 30, "Quarterly": 91, "Half Yearly": 182, "Yearly": 365}
|
||||
for item in self.items:
|
||||
if item.periodicity and item.periodicity != "Random" and item.start_date:
|
||||
if not item.end_date:
|
||||
if item.no_of_visits:
|
||||
item.end_date = add_days(item.start_date, item.no_of_visits * days_in_period[item.periodicity])
|
||||
item.end_date = add_days(
|
||||
item.start_date, item.no_of_visits * days_in_period[item.periodicity]
|
||||
)
|
||||
else:
|
||||
item.end_date = add_days(item.start_date, days_in_period[item.periodicity])
|
||||
|
||||
@@ -61,20 +57,23 @@ class MaintenanceSchedule(TransactionBase):
|
||||
item.no_of_visits = cint(diff / days_in_period[item.periodicity])
|
||||
|
||||
elif item.no_of_visits > no_of_visits:
|
||||
item.end_date = add_days(item.start_date, item.no_of_visits * days_in_period[item.periodicity])
|
||||
item.end_date = add_days(
|
||||
item.start_date, item.no_of_visits * days_in_period[item.periodicity]
|
||||
)
|
||||
|
||||
elif item.no_of_visits < no_of_visits:
|
||||
item.end_date = add_days(item.start_date, item.no_of_visits * days_in_period[item.periodicity])
|
||||
|
||||
item.end_date = add_days(
|
||||
item.start_date, item.no_of_visits * days_in_period[item.periodicity]
|
||||
)
|
||||
|
||||
def on_submit(self):
|
||||
if not self.get('schedules'):
|
||||
if not self.get("schedules"):
|
||||
throw(_("Please click on 'Generate Schedule' to get schedule"))
|
||||
self.check_serial_no_added()
|
||||
self.validate_schedule()
|
||||
|
||||
email_map = {}
|
||||
for d in self.get('items'):
|
||||
for d in self.get("items"):
|
||||
if d.serial_no:
|
||||
serial_nos = get_valid_serial_nos(d.serial_no)
|
||||
self.validate_serial_no(d.item_code, serial_nos, d.start_date)
|
||||
@@ -90,29 +89,37 @@ class MaintenanceSchedule(TransactionBase):
|
||||
|
||||
if no_email_sp:
|
||||
frappe.msgprint(
|
||||
_("Setting Events to {0}, since the Employee attached to the below Sales Persons does not have a User ID{1}").format(
|
||||
self.owner, "<br>" + "<br>".join(no_email_sp)
|
||||
)
|
||||
_(
|
||||
"Setting Events to {0}, since the Employee attached to the below Sales Persons does not have a User ID{1}"
|
||||
).format(self.owner, "<br>" + "<br>".join(no_email_sp))
|
||||
)
|
||||
|
||||
scheduled_date = frappe.db.sql("""select scheduled_date from
|
||||
scheduled_date = frappe.db.sql(
|
||||
"""select scheduled_date from
|
||||
`tabMaintenance Schedule Detail` where sales_person=%s and item_code=%s and
|
||||
parent=%s""", (d.sales_person, d.item_code, self.name), as_dict=1)
|
||||
parent=%s""",
|
||||
(d.sales_person, d.item_code, self.name),
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
for key in scheduled_date:
|
||||
description =frappe._("Reference: {0}, Item Code: {1} and Customer: {2}").format(self.name, d.item_code, self.customer)
|
||||
event = frappe.get_doc({
|
||||
"doctype": "Event",
|
||||
"owner": email_map.get(d.sales_person, self.owner),
|
||||
"subject": description,
|
||||
"description": description,
|
||||
"starts_on": cstr(key["scheduled_date"]) + " 10:00:00",
|
||||
"event_type": "Private",
|
||||
})
|
||||
description = frappe._("Reference: {0}, Item Code: {1} and Customer: {2}").format(
|
||||
self.name, d.item_code, self.customer
|
||||
)
|
||||
event = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Event",
|
||||
"owner": email_map.get(d.sales_person, self.owner),
|
||||
"subject": description,
|
||||
"description": description,
|
||||
"starts_on": cstr(key["scheduled_date"]) + " 10:00:00",
|
||||
"event_type": "Private",
|
||||
}
|
||||
)
|
||||
event.add_participant(self.doctype, self.name)
|
||||
event.insert(ignore_permissions=1)
|
||||
|
||||
frappe.db.set(self, 'status', 'Submitted')
|
||||
frappe.db.set(self, "status", "Submitted")
|
||||
|
||||
def create_schedule_list(self, start_date, end_date, no_of_visit, sales_person):
|
||||
schedule_list = []
|
||||
@@ -121,11 +128,12 @@ class MaintenanceSchedule(TransactionBase):
|
||||
add_by = date_diff / no_of_visit
|
||||
|
||||
for visit in range(cint(no_of_visit)):
|
||||
if (getdate(start_date_copy) < getdate(end_date)):
|
||||
if getdate(start_date_copy) < getdate(end_date):
|
||||
start_date_copy = add_days(start_date_copy, add_by)
|
||||
if len(schedule_list) < no_of_visit:
|
||||
schedule_date = self.validate_schedule_date_for_holiday_list(getdate(start_date_copy),
|
||||
sales_person)
|
||||
schedule_date = self.validate_schedule_date_for_holiday_list(
|
||||
getdate(start_date_copy), sales_person
|
||||
)
|
||||
if schedule_date > getdate(end_date):
|
||||
schedule_date = getdate(end_date)
|
||||
schedule_list.append(schedule_date)
|
||||
@@ -139,9 +147,11 @@ class MaintenanceSchedule(TransactionBase):
|
||||
if employee:
|
||||
holiday_list = get_holiday_list_for_employee(employee)
|
||||
else:
|
||||
holiday_list = frappe.get_cached_value('Company', self.company, "default_holiday_list")
|
||||
holiday_list = frappe.get_cached_value("Company", self.company, "default_holiday_list")
|
||||
|
||||
holidays = frappe.db.sql_list('''select holiday_date from `tabHoliday` where parent=%s''', holiday_list)
|
||||
holidays = frappe.db.sql_list(
|
||||
"""select holiday_date from `tabHoliday` where parent=%s""", holiday_list
|
||||
)
|
||||
|
||||
if not validated and holidays:
|
||||
|
||||
@@ -157,25 +167,28 @@ class MaintenanceSchedule(TransactionBase):
|
||||
|
||||
def validate_dates_with_periodicity(self):
|
||||
for d in self.get("items"):
|
||||
if d.start_date and d.end_date and d.periodicity and d.periodicity!="Random":
|
||||
if d.start_date and d.end_date and d.periodicity and d.periodicity != "Random":
|
||||
date_diff = (getdate(d.end_date) - getdate(d.start_date)).days + 1
|
||||
days_in_period = {
|
||||
"Weekly": 7,
|
||||
"Monthly": 30,
|
||||
"Quarterly": 90,
|
||||
"Half Yearly": 180,
|
||||
"Yearly": 365
|
||||
"Yearly": 365,
|
||||
}
|
||||
|
||||
if date_diff < days_in_period[d.periodicity]:
|
||||
throw(_("Row {0}: To set {1} periodicity, difference between from and to date must be greater than or equal to {2}")
|
||||
.format(d.idx, d.periodicity, days_in_period[d.periodicity]))
|
||||
throw(
|
||||
_(
|
||||
"Row {0}: To set {1} periodicity, difference between from and to date must be greater than or equal to {2}"
|
||||
).format(d.idx, d.periodicity, days_in_period[d.periodicity])
|
||||
)
|
||||
|
||||
def validate_maintenance_detail(self):
|
||||
if not self.get('items'):
|
||||
if not self.get("items"):
|
||||
throw(_("Please enter Maintaince Details first"))
|
||||
|
||||
for d in self.get('items'):
|
||||
for d in self.get("items"):
|
||||
if not d.item_code:
|
||||
throw(_("Please select item code"))
|
||||
elif not d.start_date or not d.end_date:
|
||||
@@ -189,11 +202,14 @@ class MaintenanceSchedule(TransactionBase):
|
||||
throw(_("Start date should be less than end date for Item {0}").format(d.item_code))
|
||||
|
||||
def validate_sales_order(self):
|
||||
for d in self.get('items'):
|
||||
for d in self.get("items"):
|
||||
if d.sales_order:
|
||||
chk = frappe.db.sql("""select ms.name from `tabMaintenance Schedule` ms,
|
||||
chk = frappe.db.sql(
|
||||
"""select ms.name from `tabMaintenance Schedule` ms,
|
||||
`tabMaintenance Schedule Item` msi where msi.parent=ms.name and
|
||||
msi.sales_order=%s and ms.docstatus=1""", d.sales_order)
|
||||
msi.sales_order=%s and ms.docstatus=1""",
|
||||
d.sales_order,
|
||||
)
|
||||
if chk:
|
||||
throw(_("Maintenance Schedule {0} exists against {1}").format(chk[0][0], d.sales_order))
|
||||
|
||||
@@ -209,7 +225,7 @@ class MaintenanceSchedule(TransactionBase):
|
||||
self.generate_schedule()
|
||||
|
||||
def on_update(self):
|
||||
frappe.db.set(self, 'status', 'Draft')
|
||||
frappe.db.set(self, "status", "Draft")
|
||||
|
||||
def update_amc_date(self, serial_nos, amc_expiry_date=None):
|
||||
for serial_no in serial_nos:
|
||||
@@ -219,65 +235,96 @@ class MaintenanceSchedule(TransactionBase):
|
||||
|
||||
def validate_serial_no(self, item_code, serial_nos, amc_start_date):
|
||||
for serial_no in serial_nos:
|
||||
sr_details = frappe.db.get_value("Serial No", serial_no,
|
||||
["warranty_expiry_date", "amc_expiry_date", "warehouse", "delivery_date", "item_code"], as_dict=1)
|
||||
sr_details = frappe.db.get_value(
|
||||
"Serial No",
|
||||
serial_no,
|
||||
["warranty_expiry_date", "amc_expiry_date", "warehouse", "delivery_date", "item_code"],
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
if not sr_details:
|
||||
frappe.throw(_("Serial No {0} not found").format(serial_no))
|
||||
|
||||
if sr_details.get("item_code") != item_code:
|
||||
frappe.throw(_("Serial No {0} does not belong to Item {1}")
|
||||
.format(frappe.bold(serial_no), frappe.bold(item_code)), title="Invalid")
|
||||
frappe.throw(
|
||||
_("Serial No {0} does not belong to Item {1}").format(
|
||||
frappe.bold(serial_no), frappe.bold(item_code)
|
||||
),
|
||||
title="Invalid",
|
||||
)
|
||||
|
||||
if sr_details.warranty_expiry_date \
|
||||
and getdate(sr_details.warranty_expiry_date) >= getdate(amc_start_date):
|
||||
throw(_("Serial No {0} is under warranty upto {1}")
|
||||
.format(serial_no, sr_details.warranty_expiry_date))
|
||||
if sr_details.warranty_expiry_date and getdate(sr_details.warranty_expiry_date) >= getdate(
|
||||
amc_start_date
|
||||
):
|
||||
throw(
|
||||
_("Serial No {0} is under warranty upto {1}").format(
|
||||
serial_no, sr_details.warranty_expiry_date
|
||||
)
|
||||
)
|
||||
|
||||
if sr_details.amc_expiry_date and getdate(sr_details.amc_expiry_date) >= getdate(amc_start_date):
|
||||
throw(_("Serial No {0} is under maintenance contract upto {1}")
|
||||
.format(serial_no, sr_details.amc_expiry_date))
|
||||
if sr_details.amc_expiry_date and getdate(sr_details.amc_expiry_date) >= getdate(
|
||||
amc_start_date
|
||||
):
|
||||
throw(
|
||||
_("Serial No {0} is under maintenance contract upto {1}").format(
|
||||
serial_no, sr_details.amc_expiry_date
|
||||
)
|
||||
)
|
||||
|
||||
if not sr_details.warehouse and sr_details.delivery_date and \
|
||||
getdate(sr_details.delivery_date) >= getdate(amc_start_date):
|
||||
throw(_("Maintenance start date can not be before delivery date for Serial No {0}")
|
||||
.format(serial_no))
|
||||
if (
|
||||
not sr_details.warehouse
|
||||
and sr_details.delivery_date
|
||||
and getdate(sr_details.delivery_date) >= getdate(amc_start_date)
|
||||
):
|
||||
throw(
|
||||
_("Maintenance start date can not be before delivery date for Serial No {0}").format(
|
||||
serial_no
|
||||
)
|
||||
)
|
||||
|
||||
def validate_schedule(self):
|
||||
item_lst1 =[]
|
||||
item_lst2 =[]
|
||||
for d in self.get('items'):
|
||||
item_lst1 = []
|
||||
item_lst2 = []
|
||||
for d in self.get("items"):
|
||||
if d.item_code not in item_lst1:
|
||||
item_lst1.append(d.item_code)
|
||||
|
||||
for m in self.get('schedules'):
|
||||
for m in self.get("schedules"):
|
||||
if m.item_code not in item_lst2:
|
||||
item_lst2.append(m.item_code)
|
||||
|
||||
if len(item_lst1) != len(item_lst2):
|
||||
throw(_("Maintenance Schedule is not generated for all the items. Please click on 'Generate Schedule'"))
|
||||
throw(
|
||||
_(
|
||||
"Maintenance Schedule is not generated for all the items. Please click on 'Generate Schedule'"
|
||||
)
|
||||
)
|
||||
else:
|
||||
for x in item_lst1:
|
||||
if x not in item_lst2:
|
||||
throw(_("Please click on 'Generate Schedule'"))
|
||||
|
||||
def check_serial_no_added(self):
|
||||
serial_present =[]
|
||||
for d in self.get('items'):
|
||||
serial_present = []
|
||||
for d in self.get("items"):
|
||||
if d.serial_no:
|
||||
serial_present.append(d.item_code)
|
||||
|
||||
for m in self.get('schedules'):
|
||||
for m in self.get("schedules"):
|
||||
if serial_present:
|
||||
if m.item_code in serial_present and not m.serial_no:
|
||||
throw(_("Please click on 'Generate Schedule' to fetch Serial No added for Item {0}").format(m.item_code))
|
||||
throw(
|
||||
_("Please click on 'Generate Schedule' to fetch Serial No added for Item {0}").format(
|
||||
m.item_code
|
||||
)
|
||||
)
|
||||
|
||||
def on_cancel(self):
|
||||
for d in self.get('items'):
|
||||
for d in self.get("items"):
|
||||
if d.serial_no:
|
||||
serial_nos = get_valid_serial_nos(d.serial_no)
|
||||
self.update_amc_date(serial_nos)
|
||||
frappe.db.set(self, 'status', 'Cancelled')
|
||||
frappe.db.set(self, "status", "Cancelled")
|
||||
delete_events(self.doctype, self.name)
|
||||
|
||||
def on_trash(self):
|
||||
@@ -301,23 +348,26 @@ class MaintenanceSchedule(TransactionBase):
|
||||
return items
|
||||
elif data_type == "id":
|
||||
for schedule in self.schedules:
|
||||
if schedule.item_name == item_name and s_date == formatdate(schedule.scheduled_date, "dd-mm-yyyy"):
|
||||
if schedule.item_name == item_name and s_date == formatdate(
|
||||
schedule.scheduled_date, "dd-mm-yyyy"
|
||||
):
|
||||
return schedule.name
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_serial_nos_from_schedule(item_code, schedule=None):
|
||||
serial_nos = []
|
||||
if schedule:
|
||||
serial_nos = frappe.db.get_value('Maintenance Schedule Item', {
|
||||
'parent': schedule,
|
||||
'item_code': item_code
|
||||
}, 'serial_no')
|
||||
serial_nos = frappe.db.get_value(
|
||||
"Maintenance Schedule Item", {"parent": schedule, "item_code": item_code}, "serial_no"
|
||||
)
|
||||
|
||||
if serial_nos:
|
||||
serial_nos = get_serial_nos(serial_nos)
|
||||
|
||||
return serial_nos
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_maintenance_visit(source_name, target_doc=None, item_name=None, s_id=None):
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
@@ -331,27 +381,26 @@ def make_maintenance_visit(source_name, target_doc=None, item_name=None, s_id=No
|
||||
if len(serial_nos) == 1:
|
||||
target.serial_no = serial_nos[0]
|
||||
else:
|
||||
target.serial_no = ''
|
||||
target.serial_no = ""
|
||||
|
||||
doclist = get_mapped_doc("Maintenance Schedule", source_name, {
|
||||
"Maintenance Schedule": {
|
||||
"doctype": "Maintenance Visit",
|
||||
"field_map": {
|
||||
"name": "maintenance_schedule"
|
||||
doclist = get_mapped_doc(
|
||||
"Maintenance Schedule",
|
||||
source_name,
|
||||
{
|
||||
"Maintenance Schedule": {
|
||||
"doctype": "Maintenance Visit",
|
||||
"field_map": {"name": "maintenance_schedule"},
|
||||
"validation": {"docstatus": ["=", 1]},
|
||||
"postprocess": update_status_and_detail,
|
||||
},
|
||||
"validation": {
|
||||
"docstatus": ["=", 1]
|
||||
"Maintenance Schedule Item": {
|
||||
"doctype": "Maintenance Visit Purpose",
|
||||
"condition": lambda doc: doc.item_name == item_name,
|
||||
"field_map": {"sales_person": "service_person"},
|
||||
"postprocess": update_serial,
|
||||
},
|
||||
"postprocess": update_status_and_detail
|
||||
},
|
||||
"Maintenance Schedule Item": {
|
||||
"doctype": "Maintenance Visit Purpose",
|
||||
"condition": lambda doc: doc.item_name == item_name,
|
||||
"field_map": {
|
||||
"sales_person": "service_person"
|
||||
},
|
||||
"postprocess": update_serial
|
||||
}
|
||||
}, target_doc)
|
||||
target_doc,
|
||||
)
|
||||
|
||||
return doclist
|
||||
|
||||
@@ -16,6 +16,7 @@ from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_i
|
||||
|
||||
# test_records = frappe.get_test_records('Maintenance Schedule')
|
||||
|
||||
|
||||
class TestMaintenanceSchedule(unittest.TestCase):
|
||||
def test_events_should_be_created_and_deleted(self):
|
||||
ms = make_maintenance_schedule()
|
||||
@@ -42,15 +43,15 @@ class TestMaintenanceSchedule(unittest.TestCase):
|
||||
expected_end_date = add_days(i.start_date, i.no_of_visits * 7)
|
||||
self.assertEqual(i.end_date, expected_end_date)
|
||||
|
||||
items = ms.get_pending_data(data_type = "items")
|
||||
items = items.split('\n')
|
||||
items = ms.get_pending_data(data_type="items")
|
||||
items = items.split("\n")
|
||||
items.pop(0)
|
||||
expected_items = ['_Test Item']
|
||||
expected_items = ["_Test Item"]
|
||||
self.assertTrue(items, expected_items)
|
||||
|
||||
# "dates" contains all generated schedule dates
|
||||
dates = ms.get_pending_data(data_type = "date", item_name = i.item_name)
|
||||
dates = dates.split('\n')
|
||||
dates = ms.get_pending_data(data_type="date", item_name=i.item_name)
|
||||
dates = dates.split("\n")
|
||||
dates.pop(0)
|
||||
expected_dates.append(formatdate(add_days(i.start_date, 7), "dd-MM-yyyy"))
|
||||
expected_dates.append(formatdate(add_days(i.start_date, 14), "dd-MM-yyyy"))
|
||||
@@ -59,33 +60,38 @@ class TestMaintenanceSchedule(unittest.TestCase):
|
||||
self.assertEqual(dates, expected_dates)
|
||||
|
||||
ms.submit()
|
||||
s_id = ms.get_pending_data(data_type = "id", item_name = i.item_name, s_date = expected_dates[1])
|
||||
s_id = ms.get_pending_data(data_type="id", item_name=i.item_name, s_date=expected_dates[1])
|
||||
|
||||
# Check if item is mapped in visit.
|
||||
test_map_visit = make_maintenance_visit(source_name = ms.name, item_name = "_Test Item", s_id = s_id)
|
||||
test_map_visit = make_maintenance_visit(source_name=ms.name, item_name="_Test Item", s_id=s_id)
|
||||
self.assertEqual(len(test_map_visit.purposes), 1)
|
||||
self.assertEqual(test_map_visit.purposes[0].item_name, "_Test Item")
|
||||
|
||||
visit = frappe.new_doc('Maintenance Visit')
|
||||
visit = frappe.new_doc("Maintenance Visit")
|
||||
visit = test_map_visit
|
||||
visit.maintenance_schedule = ms.name
|
||||
visit.maintenance_schedule_detail = s_id
|
||||
visit.completion_status = "Partially Completed"
|
||||
visit.set('purposes', [{
|
||||
'item_code': i.item_code,
|
||||
'description': "test",
|
||||
'work_done': "test",
|
||||
'service_person': "Sales Team",
|
||||
}])
|
||||
visit.set(
|
||||
"purposes",
|
||||
[
|
||||
{
|
||||
"item_code": i.item_code,
|
||||
"description": "test",
|
||||
"work_done": "test",
|
||||
"service_person": "Sales Team",
|
||||
}
|
||||
],
|
||||
)
|
||||
visit.save()
|
||||
visit.submit()
|
||||
ms = frappe.get_doc('Maintenance Schedule', ms.name)
|
||||
ms = frappe.get_doc("Maintenance Schedule", ms.name)
|
||||
|
||||
#checks if visit status is back updated in schedule
|
||||
# checks if visit status is back updated in schedule
|
||||
self.assertTrue(ms.schedules[1].completion_status, "Partially Completed")
|
||||
self.assertEqual(format_date(visit.mntc_date), format_date(ms.schedules[1].actual_date))
|
||||
|
||||
#checks if visit status is updated on cancel
|
||||
# checks if visit status is updated on cancel
|
||||
visit.cancel()
|
||||
ms.reload()
|
||||
self.assertTrue(ms.schedules[1].completion_status, "Pending")
|
||||
@@ -117,22 +123,24 @@ class TestMaintenanceSchedule(unittest.TestCase):
|
||||
|
||||
frappe.db.rollback()
|
||||
|
||||
|
||||
def make_serial_item_with_serial(item_code):
|
||||
serial_item_doc = create_item(item_code, is_stock_item=1)
|
||||
if not serial_item_doc.has_serial_no or not serial_item_doc.serial_no_series:
|
||||
serial_item_doc.has_serial_no = 1
|
||||
serial_item_doc.serial_no_series = "TEST.###"
|
||||
serial_item_doc.save(ignore_permissions=True)
|
||||
active_serials = frappe.db.get_all('Serial No', {"status": "Active", "item_code": item_code})
|
||||
active_serials = frappe.db.get_all("Serial No", {"status": "Active", "item_code": item_code})
|
||||
if len(active_serials) < 2:
|
||||
make_serialized_item(item_code=item_code)
|
||||
|
||||
|
||||
def get_events(ms):
|
||||
return frappe.get_all("Event Participants", filters={
|
||||
"reference_doctype": ms.doctype,
|
||||
"reference_docname": ms.name,
|
||||
"parenttype": "Event"
|
||||
})
|
||||
return frappe.get_all(
|
||||
"Event Participants",
|
||||
filters={"reference_doctype": ms.doctype, "reference_docname": ms.name, "parenttype": "Event"},
|
||||
)
|
||||
|
||||
|
||||
def make_maintenance_schedule(**args):
|
||||
ms = frappe.new_doc("Maintenance Schedule")
|
||||
@@ -140,14 +148,17 @@ def make_maintenance_schedule(**args):
|
||||
ms.customer = "_Test Customer"
|
||||
ms.transaction_date = today()
|
||||
|
||||
ms.append("items", {
|
||||
"item_code": args.get("item_code") or "_Test Item",
|
||||
"start_date": today(),
|
||||
"periodicity": "Weekly",
|
||||
"no_of_visits": 4,
|
||||
"serial_no": args.get("serial_no"),
|
||||
"sales_person": "Sales Team",
|
||||
})
|
||||
ms.append(
|
||||
"items",
|
||||
{
|
||||
"item_code": args.get("item_code") or "_Test Item",
|
||||
"start_date": today(),
|
||||
"periodicity": "Weekly",
|
||||
"no_of_visits": 4,
|
||||
"serial_no": args.get("serial_no"),
|
||||
"sales_person": "Sales Team",
|
||||
},
|
||||
)
|
||||
ms.insert(ignore_permissions=True)
|
||||
|
||||
return ms
|
||||
|
||||
@@ -14,7 +14,7 @@ class MaintenanceVisit(TransactionBase):
|
||||
return _("To {0}").format(self.customer_name)
|
||||
|
||||
def validate_serial_no(self):
|
||||
for d in self.get('purposes'):
|
||||
for d in self.get("purposes"):
|
||||
if d.serial_no and not frappe.db.exists("Serial No", d.serial_no):
|
||||
frappe.throw(_("Serial No {0} does not exist").format(d.serial_no))
|
||||
|
||||
@@ -24,13 +24,19 @@ class MaintenanceVisit(TransactionBase):
|
||||
|
||||
def validate_maintenance_date(self):
|
||||
if self.maintenance_type == "Scheduled" and self.maintenance_schedule_detail:
|
||||
item_ref = frappe.db.get_value('Maintenance Schedule Detail', self.maintenance_schedule_detail, 'item_reference')
|
||||
item_ref = frappe.db.get_value(
|
||||
"Maintenance Schedule Detail", self.maintenance_schedule_detail, "item_reference"
|
||||
)
|
||||
if item_ref:
|
||||
start_date, end_date = frappe.db.get_value('Maintenance Schedule Item', item_ref, ['start_date', 'end_date'])
|
||||
if get_datetime(self.mntc_date) < get_datetime(start_date) or get_datetime(self.mntc_date) > get_datetime(end_date):
|
||||
frappe.throw(_("Date must be between {0} and {1}")
|
||||
.format(format_date(start_date), format_date(end_date)))
|
||||
|
||||
start_date, end_date = frappe.db.get_value(
|
||||
"Maintenance Schedule Item", item_ref, ["start_date", "end_date"]
|
||||
)
|
||||
if get_datetime(self.mntc_date) < get_datetime(start_date) or get_datetime(
|
||||
self.mntc_date
|
||||
) > get_datetime(end_date):
|
||||
frappe.throw(
|
||||
_("Date must be between {0} and {1}").format(format_date(start_date), format_date(end_date))
|
||||
)
|
||||
|
||||
def validate(self):
|
||||
self.validate_serial_no()
|
||||
@@ -44,73 +50,87 @@ class MaintenanceVisit(TransactionBase):
|
||||
status = self.completion_status
|
||||
actual_date = self.mntc_date
|
||||
if self.maintenance_schedule_detail:
|
||||
frappe.db.set_value('Maintenance Schedule Detail', self.maintenance_schedule_detail, 'completion_status', status)
|
||||
frappe.db.set_value('Maintenance Schedule Detail', self.maintenance_schedule_detail, 'actual_date', actual_date)
|
||||
frappe.db.set_value(
|
||||
"Maintenance Schedule Detail", self.maintenance_schedule_detail, "completion_status", status
|
||||
)
|
||||
frappe.db.set_value(
|
||||
"Maintenance Schedule Detail", self.maintenance_schedule_detail, "actual_date", actual_date
|
||||
)
|
||||
|
||||
def update_customer_issue(self, flag):
|
||||
if not self.maintenance_schedule:
|
||||
for d in self.get('purposes'):
|
||||
if d.prevdoc_docname and d.prevdoc_doctype == 'Warranty Claim' :
|
||||
if flag==1:
|
||||
for d in self.get("purposes"):
|
||||
if d.prevdoc_docname and d.prevdoc_doctype == "Warranty Claim":
|
||||
if flag == 1:
|
||||
mntc_date = self.mntc_date
|
||||
service_person = d.service_person
|
||||
work_done = d.work_done
|
||||
status = "Open"
|
||||
if self.completion_status == 'Fully Completed':
|
||||
status = 'Closed'
|
||||
elif self.completion_status == 'Partially Completed':
|
||||
status = 'Work In Progress'
|
||||
if self.completion_status == "Fully Completed":
|
||||
status = "Closed"
|
||||
elif self.completion_status == "Partially Completed":
|
||||
status = "Work In Progress"
|
||||
else:
|
||||
nm = frappe.db.sql("select t1.name, t1.mntc_date, t2.service_person, t2.work_done from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.completion_status = 'Partially Completed' and t2.prevdoc_docname = %s and t1.name!=%s and t1.docstatus = 1 order by t1.name desc limit 1", (d.prevdoc_docname, self.name))
|
||||
nm = frappe.db.sql(
|
||||
"select t1.name, t1.mntc_date, t2.service_person, t2.work_done from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.completion_status = 'Partially Completed' and t2.prevdoc_docname = %s and t1.name!=%s and t1.docstatus = 1 order by t1.name desc limit 1",
|
||||
(d.prevdoc_docname, self.name),
|
||||
)
|
||||
|
||||
if nm:
|
||||
status = 'Work In Progress'
|
||||
mntc_date = nm and nm[0][1] or ''
|
||||
service_person = nm and nm[0][2] or ''
|
||||
work_done = nm and nm[0][3] or ''
|
||||
status = "Work In Progress"
|
||||
mntc_date = nm and nm[0][1] or ""
|
||||
service_person = nm and nm[0][2] or ""
|
||||
work_done = nm and nm[0][3] or ""
|
||||
else:
|
||||
status = 'Open'
|
||||
status = "Open"
|
||||
mntc_date = None
|
||||
service_person = None
|
||||
work_done = None
|
||||
|
||||
wc_doc = frappe.get_doc('Warranty Claim', d.prevdoc_docname)
|
||||
wc_doc.update({
|
||||
'resolution_date': mntc_date,
|
||||
'resolved_by': service_person,
|
||||
'resolution_details': work_done,
|
||||
'status': status
|
||||
})
|
||||
wc_doc = frappe.get_doc("Warranty Claim", d.prevdoc_docname)
|
||||
wc_doc.update(
|
||||
{
|
||||
"resolution_date": mntc_date,
|
||||
"resolved_by": service_person,
|
||||
"resolution_details": work_done,
|
||||
"status": status,
|
||||
}
|
||||
)
|
||||
|
||||
wc_doc.db_update()
|
||||
|
||||
def check_if_last_visit(self):
|
||||
"""check if last maintenance visit against same sales order/ Warranty Claim"""
|
||||
check_for_docname = None
|
||||
for d in self.get('purposes'):
|
||||
for d in self.get("purposes"):
|
||||
if d.prevdoc_docname:
|
||||
check_for_docname = d.prevdoc_docname
|
||||
#check_for_doctype = d.prevdoc_doctype
|
||||
# check_for_doctype = d.prevdoc_doctype
|
||||
|
||||
if check_for_docname:
|
||||
check = frappe.db.sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.name!=%s and t2.prevdoc_docname=%s and t1.docstatus = 1 and (t1.mntc_date > %s or (t1.mntc_date = %s and t1.mntc_time > %s))", (self.name, check_for_docname, self.mntc_date, self.mntc_date, self.mntc_time))
|
||||
check = frappe.db.sql(
|
||||
"select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.name!=%s and t2.prevdoc_docname=%s and t1.docstatus = 1 and (t1.mntc_date > %s or (t1.mntc_date = %s and t1.mntc_time > %s))",
|
||||
(self.name, check_for_docname, self.mntc_date, self.mntc_date, self.mntc_time),
|
||||
)
|
||||
|
||||
if check:
|
||||
check_lst = [x[0] for x in check]
|
||||
check_lst =','.join(check_lst)
|
||||
frappe.throw(_("Cancel Material Visits {0} before cancelling this Maintenance Visit").format(check_lst))
|
||||
check_lst = ",".join(check_lst)
|
||||
frappe.throw(
|
||||
_("Cancel Material Visits {0} before cancelling this Maintenance Visit").format(check_lst)
|
||||
)
|
||||
raise Exception
|
||||
else:
|
||||
self.update_customer_issue(0)
|
||||
|
||||
def on_submit(self):
|
||||
self.update_customer_issue(1)
|
||||
frappe.db.set(self, 'status', 'Submitted')
|
||||
frappe.db.set(self, "status", "Submitted")
|
||||
self.update_status_and_actual_date()
|
||||
|
||||
def on_cancel(self):
|
||||
self.check_if_last_visit()
|
||||
frappe.db.set(self, 'status', 'Cancelled')
|
||||
frappe.db.set(self, "status", "Cancelled")
|
||||
self.update_status_and_actual_date(cancel=True)
|
||||
|
||||
def on_update(self):
|
||||
|
||||
@@ -8,9 +8,11 @@ from frappe.utils.data import today
|
||||
|
||||
# test_records = frappe.get_test_records('Maintenance Visit')
|
||||
|
||||
|
||||
class TestMaintenanceVisit(unittest.TestCase):
|
||||
pass
|
||||
|
||||
|
||||
def make_maintenance_visit():
|
||||
mv = frappe.new_doc("Maintenance Visit")
|
||||
mv.company = "_Test Company"
|
||||
@@ -20,22 +22,23 @@ def make_maintenance_visit():
|
||||
|
||||
sales_person = make_sales_person("Dwight Schrute")
|
||||
|
||||
mv.append("purposes", {
|
||||
"item_code": "_Test Item",
|
||||
"sales_person": "Sales Team",
|
||||
"description": "Test Item",
|
||||
"work_done": "Test Work Done",
|
||||
"service_person": sales_person.name
|
||||
})
|
||||
mv.append(
|
||||
"purposes",
|
||||
{
|
||||
"item_code": "_Test Item",
|
||||
"sales_person": "Sales Team",
|
||||
"description": "Test Item",
|
||||
"work_done": "Test Work Done",
|
||||
"service_person": sales_person.name,
|
||||
},
|
||||
)
|
||||
mv.insert(ignore_permissions=True)
|
||||
|
||||
return mv
|
||||
|
||||
|
||||
def make_sales_person(name):
|
||||
sales_person = frappe.get_doc({
|
||||
'doctype': "Sales Person",
|
||||
'sales_person_name': name
|
||||
})
|
||||
sales_person.insert(ignore_if_duplicate = True)
|
||||
sales_person = frappe.get_doc({"doctype": "Sales Person", "sales_person_name": name})
|
||||
sales_person.insert(ignore_if_duplicate=True)
|
||||
|
||||
return sales_person
|
||||
|
||||
Reference in New Issue
Block a user