from datetime import datetime from sqlalchemy import inspect, select from sqlalchemy.orm import Session from app.models.operations import PurchaseOrderItem, PurchaseOrderSalesOrderLink from app.models.planning import MaterialDemand from app.models.sales import SalesOrder, SalesOrderItem def ensure_purchase_order_sales_link_table(db: Session) -> None: """Keep the explicit purchase-sales link table available when DB patches lag behind code.""" if db.info.get("purchase_order_sales_link_table_ensured"): return bind = db.connection() inspector = inspect(bind) existed = inspector.has_table(PurchaseOrderSalesOrderLink.__tablename__) PurchaseOrderSalesOrderLink.__table__.create(bind=bind, checkfirst=True) if not existed: backfill_purchase_order_sales_links(db) db.info["purchase_order_sales_link_table_ensured"] = True def backfill_purchase_order_sales_links(db: Session) -> None: existing_pairs = { (int(row.purchase_order_id), int(row.sales_order_id)) for row in db.execute( select(PurchaseOrderSalesOrderLink.purchase_order_id, PurchaseOrderSalesOrderLink.sales_order_id) ) } inferred_rows = db.execute( select( PurchaseOrderItem.purchase_order_id.label("purchase_order_id"), SalesOrder.id.label("sales_order_id"), ) .join(MaterialDemand, MaterialDemand.id == PurchaseOrderItem.source_demand_id) .join(SalesOrderItem, SalesOrderItem.id == MaterialDemand.sales_order_item_id) .join(SalesOrder, SalesOrder.id == SalesOrderItem.sales_order_id) .distinct() ).all() now = datetime.now() for row in inferred_rows: pair = (int(row.purchase_order_id), int(row.sales_order_id)) if pair in existing_pairs: continue db.add( PurchaseOrderSalesOrderLink( purchase_order_id=pair[0], sales_order_id=pair[1], created_at=now, updated_at=now, ) ) existing_pairs.add(pair)