diff --git a/erpnext/patches.txt b/erpnext/patches.txt old mode 100644 new mode 100755 index 19857d2cd9..1f231e69a2 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -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 \ No newline at end of file diff --git a/erpnext/patches/v11_0/update_delivery_trip_status.py b/erpnext/patches/v11_0/update_delivery_trip_status.py new file mode 100755 index 0000000000..64b3063bac --- /dev/null +++ b/erpnext/patches/v11_0/update_delivery_trip_status.py @@ -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) diff --git a/erpnext/stock/doctype/delivery_stop/delivery_stop.json b/erpnext/stock/doctype/delivery_stop/delivery_stop.json index 7bce72dfde..5610a8108a 100644 --- a/erpnext/stock/doctype/delivery_stop/delivery_stop.json +++ b/erpnext/stock/doctype/delivery_stop/delivery_stop.json @@ -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", diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.js b/erpnext/stock/doctype/delivery_trip/delivery_trip.js index a38c6d7a0a..a9e2f888fb 100755 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.js +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.js @@ -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: { diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.json b/erpnext/stock/doctype/delivery_trip/delivery_trip.json index a9236e88b5..1d32ecd12f 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.json +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.json @@ -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 diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py index 431eb6c6a5..01b4734bf5 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py @@ -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 diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip_list.js b/erpnext/stock/doctype/delivery_trip/delivery_trip_list.js new file mode 100644 index 0000000000..1d198b733f --- /dev/null +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip_list.js @@ -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]; + } + } +}; diff --git a/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py b/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py index b0a3d315ae..76b6fcda83 100644 --- a/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py +++ b/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py @@ -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()