Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create delivery trip on draft notes #38559

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions erpnext/stock/doctype/delivery_note/delivery_note.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,14 @@
"per_returned",
"transporter_info",
"transporter",
"driver",
"lr_no",
"vehicle_no",
"delivery_trip",
"driver",
"col_break34",
"transporter_name",
"driver_name",
"lr_date",
"vehicle_no",
"driver_name",
"customer_po_details",
"po_no",
"column_break_17",
Expand Down Expand Up @@ -1391,13 +1392,20 @@
"fieldname": "named_place",
"fieldtype": "Data",
"label": "Named Place"
},
{
"fieldname": "delivery_trip",
"fieldtype": "Link",
"label": "Delivery Trip",
"options": "Delivery Trip",
"print_hide": 1
}
],
"icon": "fa fa-truck",
"idx": 146,
"is_submittable": 1,
"links": [],
"modified": "2024-03-27 13:06:49.519676",
"modified": "2024-03-29 19:03:55.374173",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note",
Expand Down
4 changes: 2 additions & 2 deletions erpnext/stock/doctype/delivery_note/delivery_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class DeliveryNote(SellingController):
customer_address: DF.Link | None
customer_group: DF.Link | None
customer_name: DF.Data | None
delivery_trip: DF.Link | None
disable_rounded_total: DF.Check
discount_amount: DF.Currency
dispatch_address: DF.TextEditor | None
Expand All @@ -76,7 +77,7 @@ class DeliveryNote(SellingController):
ignore_pricing_rule: DF.Check
in_words: DF.Data | None
incoterm: DF.Link | None
installation_status: DF.Literal[None]
installation_status: DF.LiteralNone
instructions: DF.Text | None
inter_company_reference: DF.Link | None
is_internal_customer: DF.Check
Expand Down Expand Up @@ -1068,7 +1069,6 @@ def make_delivery_trip(source_name, target_doc=None):
{
"Delivery Note": {
"doctype": "Delivery Stop",
"validation": {"docstatus": ["=", 1]},
"on_parent": target_doc,
"field_map": {
"name": "delivery_note",
Expand Down
6 changes: 0 additions & 6 deletions erpnext/stock/doctype/delivery_note/delivery_note_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ frappe.listview_settings["Delivery Note"] = {
const docnames = doclist.get_checked_items(true);

if (selected_docs.length > 0) {
for (let doc of selected_docs) {
if (!doc.docstatus) {
frappe.throw(__("Cannot create a Delivery Trip from Draft documents."));
}
}

frappe.new_doc("Delivery Trip").then(() => {
// Empty out the child table before inserting new ones
cur_frm.set_value("delivery_stops", []);
Expand Down
16 changes: 16 additions & 0 deletions erpnext/stock/doctype/delivery_note/test_delivery_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
make_delivery_trip,
make_sales_invoice,
)
from erpnext.stock.doctype.delivery_trip.test_delivery_trip import create_driver
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_entries
from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle import (
Expand Down Expand Up @@ -1064,6 +1065,21 @@ def test_delivery_trip(self):
dn = create_delivery_note()
dt = make_delivery_trip(dn.name)
self.assertEqual(dn.name, dt.delivery_stops[0].delivery_note)
dt.delivery_stops[0].customer_address = "fake string"
dt.flags.ignore_mandatory = True
dt.save()
dn.reload()
self.assertEqual(dn.delivery_trip, dt.name)

dn = create_delivery_note(do_not_submit=True)
dt = make_delivery_trip(dn.name)
self.assertEqual(dn.name, dt.delivery_stops[0].delivery_note)
dt.driver = create_driver()
self.assertRaisesRegex(
frappe.exceptions.ValidationError,
r"^Delivery Notes should not be in draft state when submitting a Delivery Trip.*",
dt.submit,
)

def test_delivery_note_with_cost_center(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
Expand Down
1 change: 0 additions & 1 deletion erpnext/stock/doctype/delivery_trip/delivery_trip.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ frappe.ui.form.on("Delivery Trip", {
company: frm.doc.company,
},
get_query_filters: {
docstatus: 1,
company: frm.doc.company,
},
});
Expand Down
38 changes: 33 additions & 5 deletions erpnext/stock/doctype/delivery_trip/delivery_trip.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,18 @@ def validate(self):
if self._action == "submit" and not self.driver:
frappe.throw(_("A driver must be set to submit."))

if self._action == "submit":
self.validate_delivery_note_not_draft()
self.validate_stop_addresses()

def on_update(self):
self.update_delivery_notes()

def on_trash(self):
self.update_delivery_notes(delete=True)

def on_submit(self):
self.update_status()
self.update_delivery_notes()

def on_update_after_submit(self):
self.update_status()
Expand All @@ -72,6 +79,20 @@ def validate_stop_addresses(self):
if not stop.customer_address:
stop.customer_address = get_address_display(frappe.get_doc("Address", stop.address).as_dict())

def validate_delivery_note_not_draft(self):
delivery_notes = list(set(stop.delivery_note for stop in self.delivery_stops if stop.delivery_note))
draft_delivery_notes = frappe.get_all(
"Delivery Note",
{"docstatus": 0, "name": ["in", delivery_notes]},
pluck="name",
)
if draft_delivery_notes:
frappe.throw(
_(
"Delivery Notes should not be in draft state when submitting a Delivery Trip. The following Delivery Notes are still in draft state: {0}. Please submit them first."
).format(", ".join(draft_delivery_notes))
)

def update_status(self):
status = {0: "Draft", 1: "Scheduled", 2: "Cancelled"}[self.docstatus]

Expand Down Expand Up @@ -100,22 +121,29 @@ def update_delivery_notes(self, delete=False):
"driver": self.driver,
"driver_name": self.driver_name,
"vehicle_no": self.vehicle,
"delivery_trip": self.name,
"lr_no": self.name,
"lr_date": self.departure_time,
}

delivery_notes_updated = set()

for delivery_note in delivery_notes:
note_doc = frappe.get_doc("Delivery Note", delivery_note)

for field, value in update_fields.items():
prev_value = getattr(note_doc, field)
value = None if delete else value
if prev_value != value:
delivery_notes_updated.add(delivery_note)
setattr(note_doc, field, value)

note_doc.flags.ignore_validate_update_after_submit = True
note_doc.save()
if delivery_note in delivery_notes_updated:
note_doc.flags.ignore_validate_update_after_submit = True
note_doc.save()

delivery_notes = [get_link_to_form("Delivery Note", note) for note in delivery_notes]
frappe.msgprint(_("Delivery Notes {0} updated").format(", ".join(delivery_notes)))
delivery_notes_updated = [get_link_to_form("Delivery Note", note) for note in delivery_notes_updated]
frappe.msgprint(_("Delivery Notes {0} updated").format(", ".join(delivery_notes_updated)))

@frappe.whitelist()
def process_route(self, optimize):
Expand Down
Loading