Skip to content
Open
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
5 changes: 5 additions & 0 deletions vsd_fleet_ms/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@
# "vsd_fleet_ms.tasks.monthly"
# ],
# }
scheduler_events = {
"daily": [
"vsd_fleet_ms.utils.document_expiry.notify_expiring_documents",
],
}

# Testing
# -------
Expand Down
110 changes: 110 additions & 0 deletions vsd_fleet_ms/utils/document_expiry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import frappe
from frappe.utils import getdate, nowdate


DEFAULT_ALERT_DAYS = {7, 3, 1, 0}


def _get_recipients_by_roles(roles):
if not roles:
return []

users = frappe.get_all(
"Has Role",
filters={"role": ["in", roles]},
fields=["parent"],
distinct=True,
)
user_ids = [u.parent for u in users]
if not user_ids:
return []

return [
u.email
for u in frappe.get_all(
"User",
filters={"name": ["in", user_ids], "enabled": 1},
fields=["email"],
)
if u.email
]


def _already_notified(subject):
return frappe.db.exists(
"Notification Log",
{"subject": subject, "creation": (">=", nowdate())},
)


def notify_expiring_documents():
"""Notify on expiring Truck/Trailer documents (Document Attachments)."""
today = getdate(nowdate())
roles = ["Fleet Manager", "Logistic Master", "System Manager"]
recipients = _get_recipients_by_roles(roles)

rows = frappe.get_all(
"Document Attachments",
filters={"parenttype": ["in", ["Truck", "Trailers"]]},
fields=["name1", "reference_number", "expire_date", "parenttype", "parent"],
)

for row in rows:
if not row.expire_date:
continue
exp_date = getdate(row.expire_date)
days_left = (exp_date - today).days

is_expired = days_left < 0
if not is_expired and days_left not in DEFAULT_ALERT_DAYS:
continue

if is_expired:
subject = (
f"Document expiry Reminder: {row.parenttype} {row.parent} "
f"Document {row.name1 or row.reference_number} expired"
)
else:
subject = (
f"Document expiry Reminder: {row.parenttype} {row.parent} "
f"Document {row.name1 or row.reference_number} expires in {days_left} day(s)"
)

if _already_notified(subject):
continue

if is_expired:
days_ago = abs(days_left)
message = (
f"{row.parenttype} {row.parent} document "
f"{row.name1 or row.reference_number} expired on {exp_date} "
f"({days_ago} day(s) ago). "
"Please update the document validation."
)
else:
message = (
f"{row.parenttype} {row.parent} document "
f"{row.name1 or row.reference_number} expires on {exp_date} "
f"({days_left} day(s) left). "
"Please update the document validation."
)

frappe.get_doc(
{
"doctype": "Notification Log",
"subject": subject,
"type": "Alert",
"document_type": row.parenttype,
"document_name": row.parent,
"email_content": message,
"for_user": "Administrator",
}
).insert(ignore_permissions=True)

if recipients:
frappe.sendmail(
recipients=recipients,
subject=subject,
message=message,
now=True,
)
55 changes: 55 additions & 0 deletions vsd_fleet_ms/vsd_fleet_ms/doctype/trips/trips.js
Original file line number Diff line number Diff line change
Expand Up @@ -498,5 +498,60 @@ function fuel_amount() {
'<p class="text-muted small">Total Fuel Rejected: <b>' +
rejected_fuel.toLocaleString() +
"</b></p>";

if (cur_frm.doc.transporter_type !== "In House" || !cur_frm.doc.truck_number) {
cur_frm.get_field("html4").wrapper.innerHTML = content;
if (cur_frm.fields_dict.custom_truck_tank_fuel_balance) {
cur_frm.get_field("custom_truck_tank_fuel_balance").wrapper.innerHTML = "";
}
return;
}

cur_frm.get_field("html4").wrapper.innerHTML = content;

frappe.db
.get_value("Truck", cur_frm.doc.truck_number, "trans_ms_fuel_warehouse")
.then((r) => {
var warehouse = null;
if (r && r.message) {
warehouse = r.message.trans_ms_fuel_warehouse;
}
if (!warehouse) {
return;
}

frappe.db.get_single_value("Transport Settings", "fuel_item").then((fuel_item) => {
if (!fuel_item) {
return;
}

frappe.db
.get_value("Bin", { item_code: fuel_item, warehouse: warehouse }, "actual_qty")
.then((b) => {
var balance = 0;
if (b && b.message) {
balance = b.message.actual_qty || 0;
}
if (cur_frm.fields_dict.custom_truck_tank_fuel_balance) {
cur_frm.get_field("custom_truck_tank_fuel_balance").wrapper.innerHTML =
'<p class="text-muted small">Trip Tank Fuel Balance: <b>' +
balance.toLocaleString() +
"</b></p>";
}
});
});
});
}


frappe.ui.form.on("Trips", {
stock_out_entry: function () {
fuel_amount();
},
fuel_request_history: function () {
fuel_amount();
},
total_fuel: function () {
fuel_amount();
},
});
6 changes: 6 additions & 0 deletions vsd_fleet_ms/vsd_fleet_ms/doctype/trips/trips.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"fuel_stock_out",
"reduce_stock",
"html4",
"custom_truck_tank_fuel_balance",
"column_break_c2lwo",
"stock_out_entry",
"section_break_vefjo",
Expand Down Expand Up @@ -548,6 +549,11 @@
"fieldtype": "HTML",
"label": "Fuel Amount"
},
{
"fieldname": "custom_truck_tank_fuel_balance",
"fieldtype": "HTML",
"label": "Truck Tank Fuel Balance"
},
{
"allow_on_submit": 1,
"fieldname": "trip_completed_date",
Expand Down
Loading