Add order editing and qualified downtime history
This commit is contained in:
@@ -18,6 +18,7 @@ from .schemas import (
|
||||
MachineConfigUpdate,
|
||||
MachineEventIn,
|
||||
ProductionOrderCreate,
|
||||
ProductionOrderUpdate,
|
||||
ScrapCreate,
|
||||
SimulatorEventCreate,
|
||||
SimulatorScenarioCreate,
|
||||
@@ -466,24 +467,27 @@ def get_machine_downtimes(machine_id: int, limit: int = Query(default=100, le=50
|
||||
@app.get("/api/production-orders")
|
||||
def list_production_orders(db: Session = Depends(get_db)) -> list[dict]:
|
||||
rows = db.execute(select(ProductionOrder).order_by(ProductionOrder.created_at.desc())).scalars()
|
||||
return [
|
||||
{
|
||||
"id": row.id,
|
||||
"order_number": row.order_number,
|
||||
"machine_id": row.machine_id,
|
||||
"article_ref": row.article_ref,
|
||||
"article_name": row.article_name,
|
||||
"mold_ref": row.mold_ref,
|
||||
"material_ref": row.material_ref,
|
||||
"planned_qty": row.planned_qty,
|
||||
"cavities": row.cavities,
|
||||
"theoretical_cycle_time_sec": row.theoretical_cycle_time_sec,
|
||||
"status": row.status,
|
||||
"started_at": row.started_at.isoformat() if row.started_at else None,
|
||||
"ended_at": row.ended_at.isoformat() if row.ended_at else None,
|
||||
}
|
||||
for row in rows
|
||||
]
|
||||
return [_serialize_production_order(db, row) for row in rows]
|
||||
|
||||
|
||||
def _serialize_production_order(db: Session, row: ProductionOrder) -> dict:
|
||||
machine = db.get(Machine, row.machine_id)
|
||||
return {
|
||||
"id": row.id,
|
||||
"order_number": row.order_number,
|
||||
"machine_id": row.machine_id,
|
||||
"machine_code": machine.code if machine else None,
|
||||
"article_ref": row.article_ref,
|
||||
"article_name": row.article_name,
|
||||
"mold_ref": row.mold_ref,
|
||||
"material_ref": row.material_ref,
|
||||
"planned_qty": row.planned_qty,
|
||||
"cavities": row.cavities,
|
||||
"theoretical_cycle_time_sec": row.theoretical_cycle_time_sec,
|
||||
"status": row.status,
|
||||
"started_at": row.started_at.isoformat() if row.started_at else None,
|
||||
"ended_at": row.ended_at.isoformat() if row.ended_at else None,
|
||||
}
|
||||
|
||||
|
||||
@app.post("/api/production-orders")
|
||||
@@ -503,6 +507,36 @@ def _find_order_or_404(db: Session, order_id: int) -> ProductionOrder:
|
||||
return order
|
||||
|
||||
|
||||
@app.patch("/api/production-orders/{order_id}")
|
||||
def update_production_order(order_id: int, payload: ProductionOrderUpdate, db: Session = Depends(get_db)) -> dict:
|
||||
order = _find_order_or_404(db, order_id)
|
||||
updates = payload.model_dump(exclude_unset=True)
|
||||
if not updates:
|
||||
return _serialize_production_order(db, order)
|
||||
|
||||
if "order_number" in updates and updates["order_number"] != order.order_number:
|
||||
existing = db.execute(select(ProductionOrder).where(ProductionOrder.order_number == updates["order_number"])).scalar_one_or_none()
|
||||
if existing is not None:
|
||||
raise HTTPException(status_code=400, detail="Production order number already exists")
|
||||
|
||||
if "machine_id" in updates and updates["machine_id"] != order.machine_id:
|
||||
target_machine = db.get(Machine, updates["machine_id"])
|
||||
if target_machine is None:
|
||||
raise HTTPException(status_code=404, detail="Machine not found")
|
||||
if order.status == "running":
|
||||
running_order = get_running_order(db, updates["machine_id"])
|
||||
if running_order and running_order.id != order.id:
|
||||
raise HTTPException(status_code=400, detail="Another order is already running on the target machine")
|
||||
|
||||
for field, value in updates.items():
|
||||
setattr(order, field, value)
|
||||
|
||||
db.commit()
|
||||
db.refresh(order)
|
||||
hub.notify({"type": "refresh", "source": "api", "machine_id": order.machine_id, "event_type": "production_order_updated"})
|
||||
return _serialize_production_order(db, order)
|
||||
|
||||
|
||||
@app.post("/api/production-orders/{order_id}/start")
|
||||
def start_production_order(order_id: int, db: Session = Depends(get_db)) -> dict:
|
||||
order = _find_order_or_404(db, order_id)
|
||||
@@ -565,6 +599,14 @@ def get_unqualified_downtimes(db: Session = Depends(get_db)) -> list[dict]:
|
||||
return [_serialize_downtime_for_qualification(db, row) for row in rows]
|
||||
|
||||
|
||||
@app.get("/api/downtimes/qualified")
|
||||
def get_qualified_downtimes(limit: int = Query(default=200, le=500), db: Session = Depends(get_db)) -> list[dict]:
|
||||
rows = db.execute(
|
||||
select(Downtime).where(Downtime.reason_code.is_not(None)).order_by(Downtime.start_time.desc()).limit(limit)
|
||||
).scalars()
|
||||
return [_serialize_downtime_for_qualification(db, row) for row in rows]
|
||||
|
||||
|
||||
def _serialize_downtime_for_qualification(db: Session, row: Downtime) -> dict:
|
||||
machine = db.get(Machine, row.machine_id)
|
||||
order = db.get(ProductionOrder, row.production_order_id) if row.production_order_id else None
|
||||
|
||||
Reference in New Issue
Block a user