55 lines
2.0 KiB
Python
55 lines
2.0 KiB
Python
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)
|