Skip to content

Commit ad08443

Browse files
authored
Merge pull request #917 from efeone/avish_aprl22
feat: sync vehicle return details with transaction log and auto-update on project completion
2 parents 99cf0a0 + 269e379 commit ad08443

File tree

5 files changed

+193
-3
lines changed

5 files changed

+193
-3
lines changed

beams/beams/custom_scripts/project/project.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,46 @@ frappe.ui.form.on('Project', {
321321
}
322322
}
323323
});
324+
325+
frappe.ui.form.on('Allocated Vehicle Details', {
326+
return: function(frm, cdt, cdn) {
327+
let row = locals[cdt][cdn];
328+
frappe.prompt([
329+
{
330+
label: 'Return Date',
331+
fieldname: 'return_date',
332+
fieldtype: 'Datetime',
333+
reqd: 1
334+
},
335+
{
336+
label: 'Return Reason',
337+
fieldname: 'return_reason',
338+
fieldtype: 'Small Text',
339+
reqd: 1
340+
}
341+
],
342+
function(values) {
343+
row.return_date = values.return_date;
344+
row.return_reason = values.return_reason;
345+
row.returned = 1;
346+
frm.refresh_field('allocated_vehicle_details');
347+
frappe.call({
348+
method: "beams.beams.custom_scripts.project.project.update_vehicle_return_details_in_log",
349+
args: {
350+
project: frm.doc.name,
351+
vehicle: row.vehicle,
352+
return_date: values.return_date,
353+
return_reason: values.return_reason
354+
},
355+
callback: function(r) {
356+
if (!r.exc) {
357+
frappe.msgprint("Vehicle Transaction Log updated.");
358+
frm.save();
359+
}
360+
}
361+
});
362+
},
363+
'Return Vehicle',
364+
'Submit');
365+
}
366+
});

beams/beams/custom_scripts/project/project.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,3 +476,113 @@ def on_update_project(doc, method):
476476
if updated:
477477
log_doc.save(ignore_permissions=True)
478478
frappe.msgprint(f"Unreturned manpower records marked as returned due to project {doc.status.lower()}.")
479+
480+
def sync_vehicle_logs(doc, method):
481+
"""
482+
Sync vehicle transaction logs from Project's allocated_vehicle_details to
483+
Vehicle Transaction Log's vehicle_log_details, while preserving return data.
484+
"""
485+
486+
source_child_table = "allocated_vehicle_details"
487+
target_child_table = "vehicle_log_details"
488+
489+
log_name = frappe.db.get_value("Vehicle Transaction Log", {"project": doc.name})
490+
491+
if log_name:
492+
transaction_log = frappe.get_doc("Vehicle Transaction Log", log_name)
493+
else:
494+
transaction_log = frappe.new_doc("Vehicle Transaction Log")
495+
transaction_log.project = doc.name
496+
transaction_log.project_name = doc.project_name
497+
498+
if not transaction_log.meta.get_field(target_child_table):
499+
frappe.throw(f"Child table field '{target_child_table}' not found in Vehicle Transaction Log")
500+
501+
existing_logs = {
502+
row.vehicle: row
503+
for row in transaction_log.get(target_child_table)
504+
}
505+
506+
updated_rows = []
507+
508+
for row in doc.get(source_child_table) or []:
509+
vehicle = row.vehicle
510+
existing = existing_logs.get(vehicle)
511+
512+
from_location = frappe.db.get_value("Location", row.get("from"), "location_name") or row.get("from")
513+
to_location = frappe.db.get_value("Location", row.get("to"), "location_name") or row.get("to")
514+
515+
log_data = {
516+
"vehicle": vehicle,
517+
"from": from_location,
518+
"to": to_location,
519+
"no_of_travellers": row.no_of_travellers,
520+
"status": row.status,
521+
}
522+
523+
if existing:
524+
log_data["return_date"] = existing.return_date
525+
log_data["return_reason"] = existing.return_reason
526+
527+
updated_rows.append(log_data)
528+
529+
transaction_log.set(target_child_table, [])
530+
for data in updated_rows:
531+
transaction_log.append(target_child_table, data)
532+
533+
transaction_log.save(ignore_permissions=True)
534+
535+
@frappe.whitelist()
536+
def update_vehicle_return_details_in_log(project, vehicle, return_date, return_reason):
537+
"""
538+
Updates the return details of a vehicle in the 'Vehicle Transaction Log' for the given project.
539+
"""
540+
log_name = frappe.db.get_value("Vehicle Transaction Log", {"project": project})
541+
if not log_name:
542+
frappe.throw(_("No Vehicle Transaction Log found for this project."))
543+
544+
log_doc = frappe.get_doc("Vehicle Transaction Log", log_name)
545+
updated = False
546+
547+
for row in log_doc.vehicle_log_details:
548+
if row.vehicle == vehicle and not row.returned:
549+
row.returned = True
550+
row.return_date = return_date
551+
row.return_reason = return_reason
552+
updated = True
553+
if updated:
554+
log_doc.save(ignore_permissions=True)
555+
else:
556+
frappe.throw(_("No matching vehicle record found in the transaction log."))
557+
558+
def auto_return_vehicles_on_project_completion(doc, method):
559+
"""
560+
Automatically marks vehicles as returned in the 'Vehicle Transaction Log'
561+
when the associated project is marked as 'Completed' or 'Cancelled'.
562+
"""
563+
if doc.status not in ("Completed", "Cancelled"):
564+
return
565+
566+
log_name = frappe.db.get_value("Vehicle Transaction Log", {"project": doc.name})
567+
if not log_name:
568+
return
569+
570+
log_doc = frappe.get_doc("Vehicle Transaction Log", log_name)
571+
updated = False
572+
573+
for row in log_doc.vehicle_log_details:
574+
if not row.returned and not row.return_date and not row.return_reason:
575+
row.returned = True
576+
row.return_date = frappe.utils.nowdate()
577+
row.return_reason = "Project Completed" if doc.status == "Completed" else "Project Cancelled"
578+
updated = True
579+
580+
elif row.return_reason and row.return_date:
581+
row.returned = True
582+
updated = True
583+
584+
else:
585+
print(f" - Skipped (already returned or reason provided)")
586+
587+
if updated:
588+
log_doc.save(ignore_permissions=True)

beams/beams/doctype/vehicle_log_detail/vehicle_log_detail.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"to",
1414
"no_of_travellers",
1515
"status",
16+
"returned",
1617
"return_date",
1718
"return_reason"
1819
],
@@ -65,12 +66,20 @@
6566
"fieldtype": "Small Text",
6667
"in_list_view": 1,
6768
"label": "Return Reason"
69+
},
70+
{
71+
"allow_on_submit": 1,
72+
"default": "0",
73+
"fieldname": "returned",
74+
"fieldtype": "Check",
75+
"in_list_view": 1,
76+
"label": "returned"
6877
}
6978
],
7079
"index_web_pages_for_search": 1,
7180
"istable": 1,
7281
"links": [],
73-
"modified": "2025-04-19 11:51:05.520000",
82+
"modified": "2025-04-23 16:29:53.868218",
7483
"modified_by": "Administrator",
7584
"module": "BEAMS",
7685
"name": "Vehicle Log Detail",

beams/beams/doctype/vehicle_transaction_log/vehicle_transaction_log.json

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
"project",
1010
"transportation_request",
1111
"vehicle_hire_request",
12+
"section_break_iztv",
13+
"location",
14+
"bureau",
15+
"section_break_xcxm",
1216
"vehicle_log_details"
1317
],
1418
"fields": [
@@ -35,11 +39,33 @@
3539
"fieldtype": "Table",
3640
"label": "Vehicle Log Details",
3741
"options": "Vehicle Log Detail"
42+
},
43+
{
44+
"fieldname": "section_break_iztv",
45+
"fieldtype": "Column Break"
46+
},
47+
{
48+
"fetch_from": "project.location",
49+
"fieldname": "location",
50+
"fieldtype": "Link",
51+
"label": "Location",
52+
"options": "Location"
53+
},
54+
{
55+
"fetch_from": "project.bureau",
56+
"fieldname": "bureau",
57+
"fieldtype": "Link",
58+
"label": "Bureau",
59+
"options": "Bureau"
60+
},
61+
{
62+
"fieldname": "section_break_xcxm",
63+
"fieldtype": "Section Break"
3864
}
3965
],
4066
"index_web_pages_for_search": 1,
4167
"links": [],
42-
"modified": "2025-04-19 11:48:42.219763",
68+
"modified": "2025-04-22 11:10:05.592968",
4369
"modified_by": "Administrator",
4470
"module": "BEAMS",
4571
"name": "Vehicle Transaction Log",

beams/hooks.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,9 @@
324324
"beams.beams.custom_scripts.project.project.update_program_request_status_on_project_completion",
325325
"beams.beams.custom_scripts.project.project.validate_project",
326326
"beams.beams.custom_scripts.project.project.sync_manpower_logs",
327-
"beams.beams.custom_scripts.project.project.on_update_project"
327+
"beams.beams.custom_scripts.project.project.on_update_project",
328+
"beams.beams.custom_scripts.project.project.sync_vehicle_logs",
329+
"beams.beams.custom_scripts.project.project.auto_return_vehicles_on_project_completion"
328330
],
329331
"validate": "beams.beams.custom_scripts.project.project.validate_employee_assignment",
330332
"validate": "beams.beams.custom_scripts.project.project.validate_employee_assignment_in_same_project"

0 commit comments

Comments
 (0)