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:
parent
9f87c441b0
commit
ce3340903d
1
erpnext/patches.txt
Normal file → Executable file
1
erpnext/patches.txt
Normal file → Executable 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.drop_column_max_days_allowed
|
||||||
erpnext.patches.v11_0.change_healthcare_desktop_icons
|
erpnext.patches.v11_0.change_healthcare_desktop_icons
|
||||||
erpnext.patches.v10_0.update_user_image_in_employee
|
erpnext.patches.v10_0.update_user_image_in_employee
|
||||||
|
erpnext.patches.v11_0.update_delivery_trip_status
|
27
erpnext/patches/v11_0/update_delivery_trip_status.py
Executable file
27
erpnext/patches/v11_0/update_delivery_trip_status.py
Executable 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)
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
@ -173,6 +174,39 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 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_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
@ -762,7 +796,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-10-11 22:32:27.450906",
|
"modified": "2018-10-16 05:23:25.661542",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Delivery Stop",
|
"name": "Delivery Stop",
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
frappe.ui.form.on('Delivery Trip', {
|
frappe.ui.form.on('Delivery Trip', {
|
||||||
setup: function (frm) {
|
setup: function (frm) {
|
||||||
|
frm.set_indicator_formatter('customer', (stop) => (stop.visited) ? "green" : "orange");
|
||||||
|
|
||||||
frm.set_query("driver", function () {
|
frm.set_query("driver", function () {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
@ -540,7 +541,7 @@
|
|||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
@ -568,6 +569,70 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 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_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
@ -611,7 +676,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-10-11 22:32:04.355068",
|
"modified": "2018-10-22 08:25:42.323147",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Delivery Trip",
|
"name": "Delivery Trip",
|
||||||
@ -663,6 +728,7 @@
|
|||||||
"show_name_in_global_search": 0,
|
"show_name_in_global_search": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"title_field": "driver_name",
|
||||||
"track_changes": 0,
|
"track_changes": 0,
|
||||||
"track_seen": 0,
|
"track_seen": 0,
|
||||||
"track_views": 0
|
"track_views": 0
|
||||||
|
@ -27,9 +27,14 @@ class DeliveryTrip(Document):
|
|||||||
self.validate_stop_addresses()
|
self.validate_stop_addresses()
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
|
self.update_status()
|
||||||
self.update_delivery_notes()
|
self.update_delivery_notes()
|
||||||
|
|
||||||
|
def on_update_after_submit(self):
|
||||||
|
self.update_status()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
|
self.update_status()
|
||||||
self.update_delivery_notes(delete=True)
|
self.update_delivery_notes(delete=True)
|
||||||
|
|
||||||
def validate_stop_addresses(self):
|
def validate_stop_addresses(self):
|
||||||
@ -37,6 +42,22 @@ class DeliveryTrip(Document):
|
|||||||
if not stop.customer_address:
|
if not stop.customer_address:
|
||||||
stop.customer_address = get_address_display(frappe.get_doc("Address", stop.address).as_dict())
|
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):
|
def update_delivery_notes(self, delete=False):
|
||||||
"""
|
"""
|
||||||
Update all connected Delivery Notes with Delivery Trip details
|
Update all connected Delivery Notes with Delivery Trip details
|
||||||
|
12
erpnext/stock/doctype/delivery_trip/delivery_trip_list.js
Normal file
12
erpnext/stock/doctype/delivery_trip/delivery_trip_list.js
Normal 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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -9,7 +9,7 @@ import erpnext
|
|||||||
import frappe
|
import frappe
|
||||||
from erpnext.stock.doctype.delivery_trip.delivery_trip import get_contact_and_address, notify_customers
|
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 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):
|
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[0]), 2) # [home_address, locked_stop]
|
||||||
self.assertEqual(len(route_list[1]), 3) # [locked_stop, second_stop, home_address]
|
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():
|
def create_driver():
|
||||||
if not frappe.db.exists("Driver", "Newton Scmander"):
|
if not frappe.db.exists("Driver", "Newton Scmander"):
|
||||||
@ -108,11 +135,11 @@ def create_vehicle():
|
|||||||
"make": "Maruti",
|
"make": "Maruti",
|
||||||
"model": "PCM",
|
"model": "PCM",
|
||||||
"last_odometer": 5000,
|
"last_odometer": 5000,
|
||||||
"acquisition_date": frappe.utils.nowdate(),
|
"acquisition_date": nowdate(),
|
||||||
"location": "Mumbai",
|
"location": "Mumbai",
|
||||||
"chassis_no": "1234ABCD",
|
"chassis_no": "1234ABCD",
|
||||||
"uom": "Litre",
|
"uom": "Litre",
|
||||||
"vehicle_value": frappe.utils.flt(500000)
|
"vehicle_value": flt(500000)
|
||||||
})
|
})
|
||||||
vehicle.insert()
|
vehicle.insert()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user