Cizz22 3 months ago
parent e7581a8983
commit 0cde56d64a

@ -1,5 +1,5 @@
from datetime import datetime from datetime import datetime
from sqlalchemy import select, func, cast, Numeric from sqlalchemy import select, func, cast, Numeric, text
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy import and_ from sqlalchemy import and_
from sqlalchemy.sql import not_ from sqlalchemy.sql import not_
@ -8,72 +8,144 @@ from src.database.core import CollectorDbSession
async def get_cm_cost_summary(collector_db: CollectorDbSession, last_oh_date:datetime, upcoming_oh_date:datetime): async def get_cm_cost_summary(collector_db: CollectorDbSession, last_oh_date:datetime, upcoming_oh_date:datetime):
query = select( query = text("""WITH part_costs AS (
WorkOrderData.location, SELECT
(func.sum(WorkOrderData.total_cost_max).cast(Numeric) / func.count(WorkOrderData.wonum)).label('avg_cost') mu.wonum,
).where( SUM(COALESCE(inv.avgcost, po.unit_cost, 0)) AS parts_total_cost
and_( FROM maximo_material_use_transactions mu
# WorkOrderData.wo_start >= last_oh_date, LEFT JOIN maximo_inventory inv
# WorkOrderData.wo_start <= upcoming_oh_date, ON mu.itemnum = inv.itemnum
WorkOrderData.worktype.in_(['CM', 'EM', 'PROACTIVE']), LEFT JOIN (
WorkOrderData.system_tag.in_(['HPB', 'AH', 'APC', 'SCR', 'CL', 'DM', 'CRH', 'ASH', 'BAD', 'DS', 'WTP', SELECT item_num, AVG(unit_cost) AS unit_cost
FROM maximo_sparepart_pr_po_line
GROUP BY item_num
) po
ON mu.itemnum = po.item_num
GROUP BY mu.wonum
),
wo_costs AS (
SELECT
w.wonum,
w.asset_location,
(COALESCE(w.mat_cost_max, 0) + COALESCE(pc.parts_total_cost, 0)) AS total_wo_cost
FROM wo_staging_maximo_2 w
LEFT JOIN part_costs pc
ON w.wonum = pc.wonum
WHERE
w.worktype IN ('CM', 'EM', 'PROACTIVE')
AND w.asset_system IN (
'HPB','AH','APC','SCR','CL','DM','CRH','ASH','BAD','DS','WTP',
'MT','SUP','DCS','FF','EG','AI','SPS','EVM','SCW','KLH','CH', 'MT','SUP','DCS','FF','EG','AI','SPS','EVM','SCW','KLH','CH',
'TUR','LOT','HRH','ESP','CAE','GMC','BFT','LSH','CHB','BSS', 'TUR','LOT','HRH','ESP','CAE','GMC','BFT','LSH','CHB','BSS',
'LOS','LPB','SAC','CP','EHS','RO','GG','MS','CW','SO','ATT', 'LOS','LPB','SAC','CP','EHS','RO','GG','MS','CW','SO','ATT',
'AFG','EHB','RP','FO','PC','APE','AF','DMW','BRS','GEN','ABS', 'AFG','EHB','RP','FO','PC','APE','AF','DMW','BRS','GEN','ABS',
'CHA','TR','H2','BDW','LOM','ACR','AL','FW','COND','CCCW','IA', 'CHA','TR','H2','BDW','LOM','ACR','AL','FW','COND','CCCW','IA',
'GSS', 'BOL', 'SSB', 'CO', 'OA', 'CTH-UPD', 'AS', 'DP']), 'GSS','BOL','SSB','CO','OA','CTH-UPD','AS','DP'
WorkOrderData.reportdate.is_not(None),
WorkOrderData.actstart.is_not(None),
WorkOrderData.actfinish.is_not(None),
WorkOrderData.unit.in_([3, 0]),
WorkOrderData.reportdate >= datetime.strptime('2015-01-01', '%Y-%m-%d'),
not_(WorkOrderData.wonum.like('T%'))
) )
).group_by( AND w.reportdate IS NOT NULL
WorkOrderData.location AND w.actstart IS NOT NULL
).order_by( AND w.actfinish IS NOT NULL
func.count(WorkOrderData.wonum).desc() AND w.asset_unit IN ('3','00')
AND w.reportdate >= '2015-01-01'
AND w.wonum NOT LIKE 'T%'
),
-- find max cost per location
location_max AS (
SELECT asset_location, MAX(total_wo_cost) AS max_cost
FROM wo_costs
WHERE total_wo_cost > 0
GROUP BY asset_location
),
-- filter WO costs to only reasonable range (e.g. >0 and >=10% of max)
filtered_wo AS (
SELECT w.*
FROM wo_costs w
JOIN location_max lm ON w.asset_location = lm.asset_location
WHERE w.total_wo_cost > 0
AND w.total_wo_cost >= lm.max_cost * 0.2 -- keep within 10% of max
) )
result = await collector_db.execute(query) SELECT
data = result.all() asset_location,
SUM(total_wo_cost)::numeric / COUNT(wonum) AS avg_cost
FROM filtered_wo
GROUP BY asset_location
ORDER BY avg_cost DESC;
""")
results = await collector_db.execute(query)
data = []
for row in results:
data.append({
"location_tag": row.asset_location,
"avg_cost": row.avg_cost
})
return { return {
data.location: data.avg_cost for data in data item["location_tag"]: item["avg_cost"] for item in data
} }
async def get_oh_cost_summary(collector_db: CollectorDbSession, last_oh_date:datetime, upcoming_oh_date:datetime): async def get_oh_cost_summary(collector_db: CollectorDbSession, last_oh_date:datetime, upcoming_oh_date:datetime):
query = select( query = text("""
WorkOrderData.location, WITH part_costs AS (
(func.sum(WorkOrderData.total_cost_max).cast(Numeric) / func.count(WorkOrderData.wonum)).label('avg_cost') SELECT
).where( mu.wonum,
and_( SUM(COALESCE(inv.avgcost, po.unit_cost, 0)) AS parts_total_cost
# WorkOrderData.wo_start >= last_oh_date, FROM maximo_material_use_transactions mu
# WorkOrderData.wo_start <= upcoming_oh_date, LEFT JOIN maximo_inventory inv
WorkOrderData.worktype.in_(['OH']), ON mu.itemnum = inv.itemnum
WorkOrderData.system_tag.in_(['HPB', 'AH', 'APC', 'SCR', 'CL', 'DM', 'CRH', 'ASH', 'BAD', 'DS', 'WTP', LEFT JOIN (
SELECT item_num, AVG(unit_cost) AS unit_cost
FROM maximo_sparepart_pr_po_line
GROUP BY item_num
) po
ON mu.itemnum = po.item_num
GROUP BY mu.wonum
)
, wo_costs AS (
SELECT
w.wonum,
w.asset_location,
(COALESCE(w.mat_cost_max, 0) + COALESCE(pc.parts_total_cost, 0)) AS total_wo_cost
FROM wo_staging_maximo_2 w
LEFT JOIN part_costs pc
ON w.wonum = pc.wonum
WHERE
w.worktype = 'OH'
AND w.asset_system IN (
'HPB', 'AH', 'APC', 'SCR', 'CL', 'DM', 'CRH', 'ASH', 'BAD', 'DS', 'WTP',
'MT', 'SUP', 'DCS', 'FF', 'EG', 'AI', 'SPS', 'EVM', 'SCW', 'KLH', 'CH', 'MT', 'SUP', 'DCS', 'FF', 'EG', 'AI', 'SPS', 'EVM', 'SCW', 'KLH', 'CH',
'TUR', 'LOT', 'HRH', 'ESP', 'CAE', 'GMC', 'BFT', 'LSH', 'CHB', 'BSS', 'TUR', 'LOT', 'HRH', 'ESP', 'CAE', 'GMC', 'BFT', 'LSH', 'CHB', 'BSS',
'LOS', 'LPB', 'SAC', 'CP', 'EHS', 'RO', 'GG', 'MS', 'CW', 'SO', 'ATT', 'LOS', 'LPB', 'SAC', 'CP', 'EHS', 'RO', 'GG', 'MS', 'CW', 'SO', 'ATT',
'AFG', 'EHB', 'RP', 'FO', 'PC', 'APE', 'AF', 'DMW', 'BRS', 'GEN', 'ABS', 'AFG', 'EHB', 'RP', 'FO', 'PC', 'APE', 'AF', 'DMW', 'BRS', 'GEN', 'ABS',
'CHA', 'TR', 'H2', 'BDW', 'LOM', 'ACR', 'AL', 'FW', 'COND', 'CCCW', 'IA', 'CHA', 'TR', 'H2', 'BDW', 'LOM', 'ACR', 'AL', 'FW', 'COND', 'CCCW', 'IA',
'GSS', 'BOL', 'SSB', 'CO', 'OA', 'CTH-UPD', 'AS', 'DP']), 'GSS', 'BOL', 'SSB', 'CO', 'OA', 'CTH-UPD', 'AS', 'DP'
WorkOrderData.reportdate.is_not(None),
WorkOrderData.actstart.is_not(None),
WorkOrderData.actfinish.is_not(None),
WorkOrderData.unit.in_([3, 0]),
WorkOrderData.reportdate >= datetime.strptime('2015-01-01', '%Y-%m-%d'),
not_(WorkOrderData.wonum.like('T%'))
) )
).group_by( AND w.reportdate IS NOT NULL
WorkOrderData.location AND w.actstart IS NOT NULL
).order_by( AND w.actfinish IS NOT NULL
func.count(WorkOrderData.wonum).desc() AND w.asset_unit IN ('3', '00')
AND w.reportdate >= '2015-01-01'
AND w.wonum NOT LIKE 'T%'
) )
SELECT
asset_location,
SUM(total_wo_cost)::numeric / COUNT(wonum) AS avg_cost
FROM wo_costs
GROUP BY asset_location
ORDER BY COUNT(wonum) DESC;
""")
result = await collector_db.execute(query) result = await collector_db.execute(query)
data = result.all() data = []
for row in result:
data.append({
"location_tag": row.asset_location,
"avg_cost": row.avg_cost
})
return { return {
data.location: data.avg_cost for data in data item["location_tag"]: item["avg_cost"] for item in data
} }

Loading…
Cancel
Save