diff --git a/vsd_fleet_ms/hooks.py b/vsd_fleet_ms/hooks.py
index 953675d..4608ccc 100644
--- a/vsd_fleet_ms/hooks.py
+++ b/vsd_fleet_ms/hooks.py
@@ -64,7 +64,12 @@
# ------------
# before_install = "vsd_fleet_ms.install.before_install"
-# after_install = "vsd_fleet_ms.install.after_install"
+after_install = [
+ "vsd_fleet_ms.utils.service_job_card_tyre_fields.ensure_service_job_card_tyre_fields",
+]
+after_migrate = [
+ "vsd_fleet_ms.utils.service_job_card_tyre_fields.ensure_service_job_card_tyre_fields",
+]
# Uninstallation
# ------------
@@ -110,6 +115,51 @@
# }
# }
doc_events = {
+ "Trips": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Fuel Requests": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Cargo Registration": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Transportation Order": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Requested Payment": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Sales Invoice": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Sales Order": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Purchase Invoice": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Purchase Order": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Purchase Receipt": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Delivery Note": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Stock Entry": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Journal Entry": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Payment Entry": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
+ "Quotation": {
+ "validate": "vsd_fleet_ms.utils.fleet_company_fields.set_company_from_transport_settings",
+ },
"Service Job Card": {
"on_submit": "vsd_fleet_ms.utils.tyre_service_integration.create_tyre_movement_from_service_job_card"
}
diff --git a/vsd_fleet_ms/utils/fleet_company_fields.py b/vsd_fleet_ms/utils/fleet_company_fields.py
new file mode 100644
index 0000000..0cdc823
--- /dev/null
+++ b/vsd_fleet_ms/utils/fleet_company_fields.py
@@ -0,0 +1,11 @@
+import frappe
+
+
+def get_transport_company(fallback_company=None):
+ transport_company = frappe.db.get_single_value("Transport Settings", "company")
+ default_company = frappe.defaults.get_global_default("company")
+ return transport_company or default_company or fallback_company
+
+
+def set_company_from_transport_settings(doc, method=None):
+ doc.company = get_transport_company(doc.get("company"))
diff --git a/vsd_fleet_ms/utils/service_job_card_tyre_fields.py b/vsd_fleet_ms/utils/service_job_card_tyre_fields.py
new file mode 100644
index 0000000..6fa022d
--- /dev/null
+++ b/vsd_fleet_ms/utils/service_job_card_tyre_fields.py
@@ -0,0 +1,91 @@
+import frappe
+from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
+
+
+def ensure_service_job_card_tyre_fields():
+ """Create Fleet-specific tyre fields on Service Job Card.
+
+ Safe to run repeatedly on migrate/install and on sites where either app is absent.
+ """
+ if "servicems" not in frappe.get_installed_apps():
+ return
+
+ if not frappe.db.exists("DocType", "Service Job Card"):
+ return
+
+ required_doctypes = ["Tyre Master", "Tyre Position", "Trailers"]
+ if not all(frappe.db.exists("DocType", dt) for dt in required_doctypes):
+ return
+
+ create_custom_fields(
+ {
+ "Service Job Card": [
+ {
+ "fieldname": "custom_trailer",
+ "label": "Trailer",
+ "fieldtype": "Link",
+ "options": "Trailers",
+ "insert_after": "service_item_name",
+ },
+ {
+ "fieldname": "tyre_management_section",
+ "label": "Tyre Management",
+ "fieldtype": "Section Break",
+ "insert_after": "odometer_reading",
+ },
+ {
+ "fieldname": "tyre_serial",
+ "label": "Tyre Serial",
+ "fieldtype": "Link",
+ "options": "Tyre Master",
+ "insert_after": "tyre_management_section",
+ },
+ {
+ "fieldname": "tyre_movement_type",
+ "label": "Tyre Movement Type",
+ "fieldtype": "Select",
+ "options": "Installation\nRemoval\nPositional Change\nVehicle Transfer\nSend for Repair\nReturn from Repair\nScrap",
+ "default": "Installation",
+ "insert_after": "tyre_serial",
+ },
+ {
+ "fieldname": "tyre_install_on",
+ "label": "Movement On",
+ "fieldtype": "Select",
+ "options": "Truck\nTrailers",
+ "depends_on": "eval:doc.tyre_movement_type",
+ "insert_after": "tyre_movement_type",
+ },
+ {
+ "fieldname": "column_break_tyre_1",
+ "fieldtype": "Column Break",
+ "insert_after": "tyre_install_on",
+ },
+ {
+ "fieldname": "tyre_from_position",
+ "label": "From Position",
+ "fieldtype": "Link",
+ "options": "Tyre Position",
+ "depends_on": "eval:doc.tyre_movement_type == 'Positional Change'",
+ "insert_after": "column_break_tyre_1",
+ },
+ {
+ "fieldname": "tyre_to_position",
+ "label": "To Position",
+ "fieldtype": "Link",
+ "options": "Tyre Position",
+ "depends_on": "eval:doc.tyre_movement_type == 'Positional Change'",
+ "insert_after": "tyre_from_position",
+ },
+ {
+ "fieldname": "tyre_position",
+ "label": "Tyre Position",
+ "fieldtype": "Link",
+ "options": "Tyre Position",
+ "depends_on": "eval:doc.tyre_movement_type != 'Positional Change'",
+ "insert_after": "tyre_to_position",
+ },
+ ]
+ },
+ update=True,
+ )
diff --git a/vsd_fleet_ms/vsd_fleet_ms/doctype/bulk_cargo/bulk_cargo.py b/vsd_fleet_ms/vsd_fleet_ms/doctype/bulk_cargo/bulk_cargo.py
index 4962699..7fb750f 100644
--- a/vsd_fleet_ms/vsd_fleet_ms/doctype/bulk_cargo/bulk_cargo.py
+++ b/vsd_fleet_ms/vsd_fleet_ms/doctype/bulk_cargo/bulk_cargo.py
@@ -2,6 +2,7 @@
from frappe import _
from frappe.model.document import Document
from frappe.utils import nowdate, flt
+from vsd_fleet_ms.utils.fleet_company_fields import get_transport_company
class BulkCargo(Document):
def validate(self):
@@ -149,7 +150,7 @@ def create_sales_invoice(name):
"customer": bulk_cargo.customer_name,
"currency": frappe.defaults.get_global_default("currency"), # <-- fixed here
"posting_date": nowdate(),
- "company": frappe.defaults.get_global_default("company"),
+ "company": get_transport_company(),
"items": items
})
diff --git a/vsd_fleet_ms/vsd_fleet_ms/doctype/cargo_registration/cargo_registration.js b/vsd_fleet_ms/vsd_fleet_ms/doctype/cargo_registration/cargo_registration.js
index 1b646bc..db5ca68 100644
--- a/vsd_fleet_ms/vsd_fleet_ms/doctype/cargo_registration/cargo_registration.js
+++ b/vsd_fleet_ms/vsd_fleet_ms/doctype/cargo_registration/cargo_registration.js
@@ -3,6 +3,7 @@
frappe.ui.form.on('Cargo Registration', {
onload: function(frm){
+ setFleetCompanyDefault(frm);
if(!frm.doc.posting_date) {
frm.set_value('posting_date', frappe.datetime.nowdate());
}
@@ -57,6 +58,17 @@ frappe.ui.form.on('Cargo Registration', {
},
});
+const setFleetCompanyDefault = (frm) => {
+ if (!frm.is_new()) return;
+ frappe.db.get_single_value("Transport Settings", "company").then((company) => {
+ const fallback = (frappe.boot && frappe.boot.sysdefaults && frappe.boot.sysdefaults.company) || "";
+ const target_company = company || fallback;
+ if (target_company) {
+ frm.set_value("company", target_company);
+ }
+ });
+};
+
frappe.ui.form.on('Cargo Detail', {
form_render: function (frm, cdt, cdn) {
const container = document.querySelector('[data-fieldname="assign_manifest"]');
diff --git a/vsd_fleet_ms/vsd_fleet_ms/doctype/fuel_requests/fuel_requests.js b/vsd_fleet_ms/vsd_fleet_ms/doctype/fuel_requests/fuel_requests.js
index 3c28922..626d6e8 100644
--- a/vsd_fleet_ms/vsd_fleet_ms/doctype/fuel_requests/fuel_requests.js
+++ b/vsd_fleet_ms/vsd_fleet_ms/doctype/fuel_requests/fuel_requests.js
@@ -3,6 +3,7 @@
frappe.ui.form.on('Fuel Requests', {
onload: function (frm) {
+ setFleetCompanyDefault(frm);
//Load the approve and reject buttons
var html = ' ';
html += '';
@@ -129,6 +130,17 @@ cur_frm.cscript.approve_request = function (frm) {
}
};
+const setFleetCompanyDefault = (frm) => {
+ if (!frm.is_new()) return;
+ frappe.db.get_single_value("Transport Settings", "company").then((company) => {
+ const fallback = (frappe.boot && frappe.boot.sysdefaults && frappe.boot.sysdefaults.company) || "";
+ const target_company = company || fallback;
+ if (target_company) {
+ frm.set_value("company", target_company);
+ }
+ });
+};
+
//For reject button
cur_frm.cscript.reject_request = function (frm) {
//cur_frm.cscript.populate_child(cur_frm.doc.reference_doctype, cur_frm.doc.reference_docname);
diff --git a/vsd_fleet_ms/vsd_fleet_ms/doctype/fuel_requests/fuel_requests.py b/vsd_fleet_ms/vsd_fleet_ms/doctype/fuel_requests/fuel_requests.py
index 82e4d29..9968324 100644
--- a/vsd_fleet_ms/vsd_fleet_ms/doctype/fuel_requests/fuel_requests.py
+++ b/vsd_fleet_ms/vsd_fleet_ms/doctype/fuel_requests/fuel_requests.py
@@ -10,9 +10,12 @@
from frappe import _, msgprint
from frappe.model.mapper import get_mapped_doc
from frappe.utils import nowdate
+from vsd_fleet_ms.utils.fleet_company_fields import get_transport_company
class FuelRequests(Document):
def onload(self):
+ if not self.company:
+ self.company = get_transport_company(self.company)
trip = frappe.get_doc(self.reference_doctype, self.reference_docname)
if not self.main_route:
self.set("main_route", trip.route)
@@ -253,5 +256,7 @@ def make_stock_entry(source_name, target_doc=None):
},
target_doc,
)
+ source_company = frappe.db.get_value("Fuel Requests", source_name, "company")
+ doc.company = get_transport_company(source_company)
return doc
diff --git a/vsd_fleet_ms/vsd_fleet_ms/doctype/requested_payment/requested_payment.js b/vsd_fleet_ms/vsd_fleet_ms/doctype/requested_payment/requested_payment.js
index 6981a02..9824428 100644
--- a/vsd_fleet_ms/vsd_fleet_ms/doctype/requested_payment/requested_payment.js
+++ b/vsd_fleet_ms/vsd_fleet_ms/doctype/requested_payment/requested_payment.js
@@ -3,6 +3,7 @@
frappe.ui.form.on('Requested Payment', {
onload: function(frm){
+ setFleetCompanyDefault(frm);
//Load the approve and reject buttons
var html = ' ';
html += ''
@@ -189,6 +190,17 @@ frappe.ui.form.on('Requested Payment', {
}
}
});
+
+const setFleetCompanyDefault = (frm) => {
+ if (!frm.is_new()) return;
+ frappe.db.get_single_value("Transport Settings", "company").then((company) => {
+ const fallback = (frappe.boot && frappe.boot.sysdefaults && frappe.boot.sysdefaults.company) || "";
+ const target_company = company || fallback;
+ if (target_company) {
+ frm.set_value("company", target_company);
+ }
+ });
+};
frappe.ui.form.on('Requested Fund Details', {
form_render (frm, cdt, cdn) {
@@ -636,4 +648,3 @@ cur_frm.cscript.populate_child = function(reference_doctype, reference_docname){
});
};
-
diff --git a/vsd_fleet_ms/vsd_fleet_ms/doctype/requested_payment/requested_payment.py b/vsd_fleet_ms/vsd_fleet_ms/doctype/requested_payment/requested_payment.py
index 157afeb..a4eea0b 100644
--- a/vsd_fleet_ms/vsd_fleet_ms/doctype/requested_payment/requested_payment.py
+++ b/vsd_fleet_ms/vsd_fleet_ms/doctype/requested_payment/requested_payment.py
@@ -17,6 +17,7 @@
)
from erpnext.controllers.accounts_controller import set_balance_in_account_currency
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
+from vsd_fleet_ms.utils.fleet_company_fields import get_transport_company
class RequestedPayment(Document):
@@ -716,6 +717,8 @@ def make_payment(source_name, target_doc=None, ignore_permissions=False):
pe.mode_of_payment = "Cash"
pe.party_type = "Employee"
pe.allocate_payment_amount = 1
+ source_company = frappe.db.get_value("Requested Payment", source_name, "company")
+ pe.company = get_transport_company(source_company)
return pe
diff --git a/vsd_fleet_ms/vsd_fleet_ms/doctype/transport_settings/transport_settings.json b/vsd_fleet_ms/vsd_fleet_ms/doctype/transport_settings/transport_settings.json
index ce84f97..28f15b9 100644
--- a/vsd_fleet_ms/vsd_fleet_ms/doctype/transport_settings/transport_settings.json
+++ b/vsd_fleet_ms/vsd_fleet_ms/doctype/transport_settings/transport_settings.json
@@ -7,6 +7,7 @@
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
+ "company",
"vehicle_fuel_parent_warehouse",
"sales_item_group",
"fuel_item_group",
@@ -17,6 +18,7 @@
"default_compartment_capacity",
"require_purchase_order_for_fuel",
"require_journal_entry_for_funds",
+ "enforce_financial_booking_before_trip_submission",
"servicems_tab",
"servicems_section",
"enable_service_ms",
@@ -26,6 +28,12 @@
"accounting_dimension"
],
"fields": [
+ {
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "label": "Company",
+ "options": "Company"
+ },
{
"fieldname": "vehicle_fuel_parent_warehouse",
"fieldtype": "Link",
@@ -112,6 +120,13 @@
"default": 1,
"description": "Require Journal Entry For Funds in Trip"
},
+ {
+ "fieldname": "enforce_financial_booking_before_trip_submission",
+ "fieldtype": "Check",
+ "label": "Enforce Financial Booking Before Trip Submission",
+ "default": 0,
+ "description": "Block trip submission until fund requests and fuel stockout are fully processed"
+ },
{
"fieldname": "enable_service_ms",
"fieldtype": "Check",
diff --git a/vsd_fleet_ms/vsd_fleet_ms/doctype/transportation_order/transportation_order.js b/vsd_fleet_ms/vsd_fleet_ms/doctype/transportation_order/transportation_order.js
index 77d461a..01757c6 100644
--- a/vsd_fleet_ms/vsd_fleet_ms/doctype/transportation_order/transportation_order.js
+++ b/vsd_fleet_ms/vsd_fleet_ms/doctype/transportation_order/transportation_order.js
@@ -3,6 +3,7 @@
frappe.ui.form.on('Transportation Order', {
onload: function (frm) {
+ setFleetCompanyDefault(frm);
frm.get_field("assign_transport").grid.cannot_add_rows = true;
$("*[data-fieldname='assign_transport']").find(".grid-remove-rows").hide();
$("*[data-fieldname='assign_transport']").find(".grid-remove-all-rows").hide();
@@ -227,6 +228,17 @@ frappe.ui.form.on('Transportation Order', {
},
});
+const setFleetCompanyDefault = (frm) => {
+ if (!frm.is_new()) return;
+ frappe.db.get_single_value("Transport Settings", "company").then((company) => {
+ const fallback = (frappe.boot && frappe.boot.sysdefaults && frappe.boot.sysdefaults.company) || "";
+ const target_company = company || fallback;
+ if (target_company) {
+ frm.set_value("company", target_company);
+ }
+ });
+};
+
frappe.ui.form.on("Transport Assignments", {
form_render: function (frm, cdt, cdn) {
diff --git a/vsd_fleet_ms/vsd_fleet_ms/doctype/trips/trips.js b/vsd_fleet_ms/vsd_fleet_ms/doctype/trips/trips.js
index 5644154..8342dc8 100644
--- a/vsd_fleet_ms/vsd_fleet_ms/doctype/trips/trips.js
+++ b/vsd_fleet_ms/vsd_fleet_ms/doctype/trips/trips.js
@@ -2,6 +2,9 @@
// For license information, please see license.txt
frappe.ui.form.on("Trips", {
+ onload: function (frm) {
+ setFleetCompanyDefault(frm);
+ },
refresh: function (frm) {
approved_total();
requested_total();
@@ -14,6 +17,7 @@ frappe.ui.form.on("Trips", {
function () {
frm.set_value("trip_completed", 1);
frm.set_value("trip_completed_date", frappe.datetime.nowdate());
+ frm.set_value("trip_status", "Completed");
var truck = frm.doc.truck_number;
frm.save();
if (frm.doc.transporter_type == "In House") {
@@ -252,6 +256,17 @@ frappe.ui.form.on("Trips", {
},
});
+const setFleetCompanyDefault = (frm) => {
+ if (!frm.is_new()) return;
+ frappe.db.get_single_value("Transport Settings", "company").then((company) => {
+ const fallback = (frappe.boot && frappe.boot.sysdefaults && frappe.boot.sysdefaults.company) || "";
+ const target_company = company || fallback;
+ if (target_company) {
+ frm.set_value("company", target_company);
+ }
+ });
+};
+
function set_service_ms_costing_visibility(frm) {
frappe.db
.get_single_value("Transport Settings", "enable_service_ms")
diff --git a/vsd_fleet_ms/vsd_fleet_ms/doctype/trips/trips.py b/vsd_fleet_ms/vsd_fleet_ms/doctype/trips/trips.py
index e41d2fa..8f759ce 100644
--- a/vsd_fleet_ms/vsd_fleet_ms/doctype/trips/trips.py
+++ b/vsd_fleet_ms/vsd_fleet_ms/doctype/trips/trips.py
@@ -9,9 +9,10 @@
import json
from frappe.model.document import Document
from frappe.model.mapper import get_mapped_doc
-from frappe.utils import nowdate, now
+from frappe.utils import nowdate, now, cint
from frappe import _, msgprint
from vsd_fleet_ms.utils.dimension import set_dimension
+from vsd_fleet_ms.utils.fleet_company_fields import get_transport_company
from erpnext.setup.utils import get_exchange_rate
from vsd_fleet_ms.vsd_fleet_ms.doctype.requested_payment.requested_payment import request_funds
@@ -28,7 +29,7 @@ def on_submit(self):
def onload(self):
if not self.company:
- self.company = frappe.defaults.get_user_default("Company") or frappe.defaults.get_global_default("company")
+ self.company = get_transport_company(self.company)
if not self.fuel_stock_out:
self.fuel_stock_out = self.total_fuel
@@ -41,6 +42,8 @@ def before_insert(self):
self.requested_fund_accounts_table = []
def validate(self):
+ self.sync_trip_status()
+ self.validate_active_trip_for_truck()
if self.transporter_type == "In House":
self.validate_fuel_requests()
# self.set_permits()
@@ -112,6 +115,17 @@ def before_save(self):
self.date = datetime.datetime.now()
self.validate_main_route_inputs()
+ def after_insert(self):
+ self.sync_truck_status()
+
+ def on_update(self):
+ self.sync_truck_status()
+
+ def on_update_after_submit(self):
+ self.sync_trip_status()
+ self.validate_active_trip_for_truck()
+ self.sync_truck_status()
+
def validate_fuel_requests(self):
make_request = False
for request in self.get("fuel_request_history"):
@@ -134,6 +148,7 @@ def validate_fuel_requests(self):
else:
fuel_request = frappe.new_doc("Fuel Requests")
fuel_request.update({
+ "company": get_transport_company(self.company),
"truck_plate_number": self.get("vehicle_plate_number"),
"customer": self.get("customer"),
"truck": self.get("vehicle_plate_number"),
@@ -178,6 +193,131 @@ def validate_request_status(self):
if row.request_status == "Approved" and je_required and not row.journal_entry:
frappe.throw("All approved fund requests must have a Journal Entry before submitting the trip")
+ enforce_financial_booking = (
+ frappe.db.get_single_value(
+ "Transport Settings",
+ "enforce_financial_booking_before_trip_submission",
+ )
+ or 0
+ )
+ if not enforce_financial_booking:
+ return
+
+ issues = []
+ if self.transporter_type == "In House":
+ if not self.stock_out_entry:
+ issues.append(_("Fuel stockout is not processed: Stock Out Entry is missing"))
+ elif frappe.db.get_value("Stock Entry", self.stock_out_entry, "docstatus") != 1:
+ issues.append(
+ _("Fuel stockout is not processed: Stock Entry {0} is not submitted").format(
+ self.stock_out_entry
+ )
+ )
+
+ if po_required:
+ for row in self.fuel_request_history:
+ if row.status == "Approved" and row.purchase_order:
+ if frappe.db.get_value("Purchase Order", row.purchase_order, "docstatus") != 1:
+ issues.append(
+ _("Fuel request row #{0}: Purchase Order {1} is not submitted").format(
+ row.idx, row.purchase_order
+ )
+ )
+
+ if je_required:
+ for row in self.requested_fund_accounts_table:
+ if row.request_status == "Approved" and row.journal_entry:
+ if frappe.db.get_value("Journal Entry", row.journal_entry, "docstatus") != 1:
+ issues.append(
+ _("Fund request row #{0}: Journal Entry {1} is not submitted").format(
+ row.idx, row.journal_entry
+ )
+ )
+
+ if issues:
+ details = "
".join([f"- {frappe.utils.escape_html(i)}" for i in issues])
+ frappe.throw(
+ _(
+ "Trip submission blocked due to pending financial items:
{0}"
+ ).format(details)
+ )
+
+ def sync_trip_status(self):
+ if self.trip_status == "Breakdown":
+ return
+
+ self.trip_status = "Completed" if cint(self.trip_completed) == 1 else "Pending"
+
+ def get_truck_number(self):
+ if self.truck_number:
+ return self.truck_number
+ if self.manifest:
+ return frappe.db.get_value("Manifest", self.manifest, "truck")
+ return None
+
+ def validate_active_trip_for_truck(self):
+ truck_number = self.get_truck_number()
+ if self.transporter_type != "In House" or not truck_number:
+ return
+
+ if cint(self.trip_completed) == 1 or self.trip_status == "Breakdown":
+ return
+
+ filters = {
+ "truck_number": truck_number,
+ "trip_completed": 0,
+ "docstatus": ["!=", 2],
+ }
+ if self.name:
+ filters["name"] = ["!=", self.name]
+
+ active_trip = frappe.db.get_value("Trips", filters, "name", order_by="modified desc")
+ if active_trip:
+ frappe.throw(
+ _("Truck {0} is already on another trip: {1}").format(truck_number, active_trip)
+ )
+
+ def sync_truck_status(self):
+ truck_number = self.get_truck_number()
+ if self.transporter_type != "In House" or not truck_number:
+ return
+
+ if cint(self.trip_completed) == 0 and self.trip_status != "Breakdown":
+ frappe.db.set_value(
+ "Truck",
+ truck_number,
+ {"status": "On Trip", "trans_ms_current_trip": self.name},
+ update_modified=False,
+ )
+ return
+
+ other_active_trip = frappe.db.get_value(
+ "Trips",
+ {
+ "truck_number": truck_number,
+ "trip_completed": 0,
+ "docstatus": ["!=", 2],
+ "name": ["!=", self.name],
+ },
+ "name",
+ order_by="modified desc",
+ )
+
+ if other_active_trip:
+ frappe.db.set_value(
+ "Truck",
+ truck_number,
+ {"status": "On Trip", "trans_ms_current_trip": other_active_trip},
+ update_modified=False,
+ )
+ else:
+ frappe.db.set_value(
+ "Truck",
+ truck_number,
+ {"status": "Idle", "trans_ms_current_trip": ""},
+ update_modified=False,
+ )
+
# ------------------ Whitelisted Functions ------------------ #