Add related work orders to asset detail view (live extraction DB query). Add location filter to work orders list. Add Related Work Orders card in frontend.
This commit is contained in:
@@ -1292,6 +1292,69 @@ def get_asset(asset_id: int):
|
||||
"work_orders": msfs.get("work_orders", []),
|
||||
}
|
||||
|
||||
# Enrich with related work orders from extraction DB (live query)
|
||||
try:
|
||||
ext = _get_extraction_db()
|
||||
if ext:
|
||||
cur_ext = ext.cursor()
|
||||
asset_name = result.get("name", "")
|
||||
asset_company = result.get("company", "")
|
||||
related_wos = []
|
||||
|
||||
# Match by customer asset name
|
||||
if asset_name:
|
||||
cur_ext.execute(
|
||||
"""SELECT msdyn_name, "msdyn_serviceaccount!name" AS account_name,
|
||||
msdyn_systemstatus, msdyn_datewindowstart,
|
||||
"msdyn_functionallocation!name" AS functional_location,
|
||||
msdyn_workordersummary
|
||||
FROM msdyn_workorder
|
||||
WHERE "msdyn_customerasset!name" = ?
|
||||
ORDER BY msdyn_datewindowstart DESC
|
||||
LIMIT 20""",
|
||||
(asset_name,),
|
||||
)
|
||||
for r in cur_ext.fetchall():
|
||||
related_wos.append({
|
||||
"name": r["msdyn_name"],
|
||||
"account_name": r["account_name"],
|
||||
"status_code": str(r["msdyn_systemstatus"]),
|
||||
"status": _status_label(r["msdyn_systemstatus"]),
|
||||
"functional_location": r["functional_location"],
|
||||
"summary": r["msdyn_workordersummary"],
|
||||
"datewindow_start": r["msdyn_datewindowstart"],
|
||||
})
|
||||
|
||||
# Also match by company name (account name)
|
||||
if asset_company and not related_wos:
|
||||
cur_ext.execute(
|
||||
"""SELECT msdyn_name, "msdyn_serviceaccount!name" AS account_name,
|
||||
msdyn_systemstatus, msdyn_datewindowstart,
|
||||
"msdyn_functionallocation!name" AS functional_location,
|
||||
msdyn_workordersummary
|
||||
FROM msdyn_workorder
|
||||
WHERE "msdyn_serviceaccount!name" = ?
|
||||
ORDER BY msdyn_datewindowstart DESC
|
||||
LIMIT 20""",
|
||||
(asset_company,),
|
||||
)
|
||||
for r in cur_ext.fetchall():
|
||||
related_wos.append({
|
||||
"name": r["msdyn_name"],
|
||||
"account_name": r["account_name"],
|
||||
"status_code": str(r["msdyn_systemstatus"]),
|
||||
"status": _status_label(r["msdyn_systemstatus"]),
|
||||
"functional_location": r["functional_location"],
|
||||
"summary": r["msdyn_workordersummary"],
|
||||
"datewindow_start": r["msdyn_datewindowstart"],
|
||||
})
|
||||
|
||||
if related_wos:
|
||||
result["related_work_orders"] = related_wos
|
||||
ext.close()
|
||||
except Exception:
|
||||
pass # Extraction DB might not be available, silently skip
|
||||
|
||||
# Enrich with Seed data (from mycantaloupe.com)
|
||||
seed_row = conn.execute(
|
||||
"SELECT raw_data, imported_at FROM seed_data WHERE asset_id = ?",
|
||||
@@ -3585,6 +3648,7 @@ async def workorders_list(
|
||||
q: str = Query("", description="Search term"),
|
||||
status: str = Query("", description="Comma-separated status codes to include"),
|
||||
tech: str = Query("", description="Comma-separated technician names"),
|
||||
location: str = Query("", description="Filter by city, functional location, or account name"),
|
||||
date_from: str = Query("", description="ISO date filter start (inclusive)"),
|
||||
date_to: str = Query("", description="ISO date filter end (inclusive)"),
|
||||
date_field: str = Query("createdon", description="Date field to filter on: createdon, msdyn_completedon"),
|
||||
@@ -3642,6 +3706,14 @@ async def workorders_list(
|
||||
where_clauses.append("(" + " OR ".join(tech_conditions) + ")")
|
||||
params.extend(tech_names * 4)
|
||||
|
||||
# Location filter — matches city, functional location, or account name
|
||||
if location:
|
||||
like = f"%{location}%"
|
||||
where_clauses.append(
|
||||
"(a.address1_city LIKE ? OR w.\"msdyn_functionallocation!name\" LIKE ? OR w.\"msdyn_serviceaccount!name\" LIKE ?)"
|
||||
)
|
||||
params.extend([like, like, like])
|
||||
|
||||
# Date range filter
|
||||
if date_from:
|
||||
where_clauses.append(f"w.{date_field} >= ?")
|
||||
|
||||
Reference in New Issue
Block a user