fix(stock): reject unfit drivers when submitting delivery trips

The form filter does not protect submissions or trips saved before a driver becomes unfit. Check status and licence expiry against departure date at submit time, including direct API submissions.

Issue: frappe/erpnext-bug-reviews#381 (bug 1)
(cherry picked from commit f031fa61aa)
This commit is contained in:
Krishna Shirsath
2026-10-27 22:57:56 +05:30
parent a1dcf42195
commit 3e73aa2934
2 changed files with 29 additions and 2 deletions
@@ -8,7 +8,7 @@ import frappe
from frappe import _
from frappe.contacts.doctype.address.address import get_address_display
from frappe.model.document import Document
from frappe.utils import cint, get_datetime, get_link_to_form
from frappe.utils import cint, get_datetime, get_link_to_form, getdate
class DeliveryTrip(Document):
@@ -58,9 +58,18 @@ class DeliveryTrip(Document):
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_driver()
self.validate_stop_addresses()
def validate_driver(self):
status, expiry_date = frappe.db.get_value("Driver", self.driver, ["status", "expiry_date"])
if status != "Active":
frappe.throw(_("The driver must be active to submit a Delivery Trip."))
if expiry_date and getdate(expiry_date) < getdate(self.departure_time):
frappe.throw(_("The driver's licence must be valid on the departure date."))
def on_submit(self):
self.update_status()
self.update_delivery_notes()
@@ -4,7 +4,7 @@
import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import add_days, flt, now_datetime, nowdate
from frappe.utils import add_days, flt, getdate, now_datetime, nowdate
import erpnext
from erpnext.stock.doctype.delivery_note.delivery_note import make_delivery_trip
@@ -77,6 +77,23 @@ class TestDeliveryTrip(FrappeTestCase):
def test_delivery_trip_status_draft(self):
self.assertEqual(self.delivery_trip.status, "Draft")
def test_unfit_driver_cannot_submit(self):
for status, expiry_date in (("Left", None), ("Suspended", None), ("Active", add_days(nowdate(), -1))):
with self.subTest(status=status, expiry_date=expiry_date):
frappe.db.set_value(
"Driver", self.delivery_trip.driver, {"status": status, "expiry_date": expiry_date}
)
with self.assertRaises(frappe.ValidationError):
self.delivery_trip.submit()
self.delivery_trip.reload()
def test_license_valid_on_departure_date_can_submit(self):
frappe.db.set_value(
"Driver", self.delivery_trip.driver, "expiry_date", getdate(self.delivery_trip.departure_time)
)
self.delivery_trip.submit()
self.assertEqual(self.delivery_trip.docstatus, 1)
def test_delivery_trip_status_scheduled(self):
self.delivery_trip.submit()
self.assertEqual(self.delivery_trip.status, "Scheduled")
@@ -156,6 +173,7 @@ def create_driver():
{
"doctype": "Driver",
"full_name": "Newton Scmander",
"status": "Active",
"cell_number": "98343424242",
"license_number": "B809",
}