Update Delivery Trip status based on visited stops (#15723)

* feat(delivery_trip_status): Update Delivery Trip status based on visited stops

* feat(delivery_trip_status): Fix tests

* feat(delivery_trip_status): Fix allow on submit for status

* feat(delivery_trip_status): Change status mapping

* feat(delivery_trip_status): Fix patch

* Update update_delivery_trip_status.py
This commit is contained in:
Alchez 2018-11-13 12:22:17 +05:30 committed by Nabin Hait
parent 9f87c441b0
commit ce3340903d
8 changed files with 196 additions and 6 deletions

1
erpnext/patches.txt Normal file → Executable file
View File

@ -576,3 +576,4 @@ erpnext.patches.v11_0.ewaybill_fields_gst_india
erpnext.patches.v11_0.drop_column_max_days_allowed
erpnext.patches.v11_0.change_healthcare_desktop_icons
erpnext.patches.v10_0.update_user_image_in_employee
erpnext.patches.v11_0.update_delivery_trip_status

View File

@ -0,0 +1,27 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc('stock', 'doctype', 'delivery_trip')
frappe.reload_doc('stock', 'doctype', 'delivery_stop', force=True)
for trip in frappe.get_all("Delivery Trip"):
trip_doc = frappe.get_doc("Delivery Trip", trip.name)
status = {
0: "Draft",
1: "Scheduled",
2: "Cancelled"
}[trip_doc.docstatus]
if trip_doc.docstatus == 1:
visited_stops = [stop.visited for stop in trip_doc.delivery_stops]
if all(visited_stops):
status = "Completed"
elif any(visited_stops):
status = "In Transit"
frappe.db.set_value("Delivery Trip", trip.name, "status", status, update_modified=False)

View File

@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
@ -173,6 +174,39 @@
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.docstatus==1",
"fieldname": "visited",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Visited",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@ -762,7 +796,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2018-10-11 22:32:27.450906",
"modified": "2018-10-16 05:23:25.661542",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Stop",

View File

@ -3,6 +3,8 @@
frappe.ui.form.on('Delivery Trip', {
setup: function (frm) {
frm.set_indicator_formatter('customer', (stop) => (stop.visited) ? "green" : "orange");
frm.set_query("driver", function () {
return {
filters: {

View File

@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
@ -540,7 +541,7 @@
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
@ -568,6 +569,70 @@
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Status",
"length": 0,
"no_copy": 1,
"options": "Draft\nScheduled\nIn Transit\nCompleted\nCancelled",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cb_more_info",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@ -611,7 +676,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-10-11 22:32:04.355068",
"modified": "2018-10-22 08:25:42.323147",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Trip",
@ -663,6 +728,7 @@
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "driver_name",
"track_changes": 0,
"track_seen": 0,
"track_views": 0

View File

@ -27,9 +27,14 @@ class DeliveryTrip(Document):
self.validate_stop_addresses()
def on_submit(self):
self.update_status()
self.update_delivery_notes()
def on_update_after_submit(self):
self.update_status()
def on_cancel(self):
self.update_status()
self.update_delivery_notes(delete=True)
def validate_stop_addresses(self):
@ -37,6 +42,22 @@ class DeliveryTrip(Document):
if not stop.customer_address:
stop.customer_address = get_address_display(frappe.get_doc("Address", stop.address).as_dict())
def update_status(self):
status = {
0: "Draft",
1: "Scheduled",
2: "Cancelled"
}[self.docstatus]
if self.docstatus == 1:
visited_stops = [stop.visited for stop in self.delivery_stops]
if all(visited_stops):
status = "Completed"
elif any(visited_stops):
status = "In Transit"
self.db_set("status", status)
def update_delivery_notes(self, delete=False):
"""
Update all connected Delivery Notes with Delivery Trip details

View File

@ -0,0 +1,12 @@
frappe.listview_settings['Delivery Trip'] = {
add_fields: ["status"],
get_indicator: function (doc) {
if (in_list(["Cancelled", "Draft"], doc.status)) {
return [__(doc.status), "red", "status,=," + doc.status];
} else if (in_list(["In Transit", "Scheduled"], doc.status)) {
return [__(doc.status), "orange", "status,=," + doc.status];
} else if (doc.status === "Completed") {
return [__(doc.status), "green", "status,=," + doc.status];
}
}
};

View File

@ -9,7 +9,7 @@ import erpnext
import frappe
from erpnext.stock.doctype.delivery_trip.delivery_trip import get_contact_and_address, notify_customers
from erpnext.tests.utils import create_test_contact_and_address
from frappe.utils import add_days, now_datetime
from frappe.utils import add_days, flt, now_datetime, nowdate
class TestDeliveryTrip(unittest.TestCase):
@ -72,6 +72,33 @@ class TestDeliveryTrip(unittest.TestCase):
self.assertEqual(len(route_list[0]), 2) # [home_address, locked_stop]
self.assertEqual(len(route_list[1]), 3) # [locked_stop, second_stop, home_address]
def test_delivery_trip_status_draft(self):
self.assertEqual(self.delivery_trip.status, "Draft")
def test_delivery_trip_status_scheduled(self):
self.delivery_trip.submit()
self.assertEqual(self.delivery_trip.status, "Scheduled")
def test_delivery_trip_status_cancelled(self):
self.delivery_trip.submit()
self.delivery_trip.cancel()
self.assertEqual(self.delivery_trip.status, "Cancelled")
def test_delivery_trip_status_in_transit(self):
self.delivery_trip.submit()
self.delivery_trip.delivery_stops[0].visited = 1
self.delivery_trip.save()
self.assertEqual(self.delivery_trip.status, "In Transit")
def test_delivery_trip_status_completed(self):
self.delivery_trip.submit()
for stop in self.delivery_trip.delivery_stops:
stop.visited = 1
self.delivery_trip.save()
self.assertEqual(self.delivery_trip.status, "Completed")
def create_driver():
if not frappe.db.exists("Driver", "Newton Scmander"):
@ -108,11 +135,11 @@ def create_vehicle():
"make": "Maruti",
"model": "PCM",
"last_odometer": 5000,
"acquisition_date": frappe.utils.nowdate(),
"acquisition_date": nowdate(),
"location": "Mumbai",
"chassis_no": "1234ABCD",
"uom": "Litre",
"vehicle_value": frappe.utils.flt(500000)
"vehicle_value": flt(500000)
})
vehicle.insert()