from __future__ import annotations

from collections import defaultdict
from datetime import date, datetime, time, timedelta
from decimal import Decimal, ROUND_FLOOR
import re

from fastapi import HTTPException
from sqlalchemy import Integer, Select, and_, bindparam, case, func, literal, or_, select, text
from sqlalchemy.orm import Session, aliased

from app.models.document_archive import DocumentArchive
from app.models.master_data import Bom, BomItem, Item, Material, Product, StockBalance, Unit, Warehouse
from app.models.operations import (
    AccountingPeriod,
    CompletionReceipt,
    CompletionReceiptItem,
    CostAllocation,
    Delivery,
    DeliveryItem,
    Equipment,
    InventoryTxn,
    MaintenanceOrder,
    MaintenancePlan,
    OverheadEntry,
    ProcessRoute,
    ProcessRouteOperation,
    PurchaseOrder,
    PurchaseOrderItem,
    PurchaseReceipt,
    PurchaseReceiptItem,
    PurchaseReturn,
    PurchaseReturnItem,
    ReturnDisposition,
    ReturnItem,
    ReturnOrder,
    ScrapRecord,
    StatementSnapshot,
    StockLot,
    Supplier,
    WarehouseLocation,
    WorkCenter,
    WorkOrder,
    WorkOrderMaterialIssue,
    WorkOrderMaterial,
    WorkOrderOperation,
    OperationReport,
)
from app.models.org import Department, Employee, User
from app.models.planning import MaterialDemand
from app.models.sales import Customer, SalesOrder, SalesOrderItem
from app.schemas.operations import (
    CostAllocationRead,
    ProductMaterialCostBoardRead,
    ProductMaterialCostExpenseRead,
    ProductMaterialCostRowRead,
    ProductMaterialCostSummaryRead,
)
from app.services.document_archives import (
    ARCHIVE_STATUS_MISSING,
    DOCUMENT_TYPE_PRODUCTION_INBOUND_SETTLEMENT,
    DOCUMENT_TYPE_PRODUCTION_MATERIAL_OUT,
    DOCUMENT_TYPE_WAREHOUSE_OPERATION,
    FILE_FORMAT_PDF,
)
from app.services.sales_planning import code_token, decimalize, next_doc_no
from app.services.system_config import get_raw_material_lot_prefix, lock_raw_material_lot_prefix_config


def to_decimal(value: float | Decimal | int | None, places: str = "0.000001") -> Decimal:
    raw = value if value is not None else 0
    return decimalize(raw, places)


def start_of_day(value: date) -> datetime:
    return datetime.combine(value, time.min)


def end_of_day(value: date) -> datetime:
    return datetime.combine(value, time.max)


def clamp_non_negative(value: Decimal, places: str = "0.000001") -> Decimal:
    return max(Decimal("0"), value).quantize(Decimal(places))


def is_raw_material_item(db: Session, item_id: int) -> bool:
    item = db.get(Item, item_id)
    return bool(item and item.item_type == "RAW_MATERIAL")


def is_weight_only_stock_context(db: Session, item_id: int, warehouse_id: int) -> bool:
    _ = item_id
    warehouse = db.get(Warehouse, warehouse_id)
    warehouse_type = str(warehouse.warehouse_type if warehouse else "").upper()
    return warehouse_type in {"RAW", "SCRAP"}


def _raw_lot_sequence_width(next_sequence: int) -> int:
    return 4 if next_sequence <= 9999 else len(str(next_sequence))


def build_inventory_lot_no(db: Session, material_item_id: int) -> str:
    _ = material_item_id
    lock_raw_material_lot_prefix_config(db)
    prefix = get_raw_material_lot_prefix(db)
    existing_lot_nos = db.scalars(
        select(StockLot.lot_no).where(StockLot.lot_no.like(f"{prefix}%"))
    ).all()
    max_sequence = 0
    pattern = re.compile(rf"{re.escape(prefix)}(\d+)")
    for lot_no in existing_lot_nos:
        match = pattern.fullmatch(str(lot_no))
        if match:
            max_sequence = max(max_sequence, int(match.group(1)))
    sequence = max_sequence + 1
    candidate = f"{prefix}{sequence:0{_raw_lot_sequence_width(sequence)}d}"
    while db.scalar(select(func.count(StockLot.id)).where(StockLot.lot_no == candidate)):
        sequence += 1
        candidate = f"{prefix}{sequence:0{_raw_lot_sequence_width(sequence)}d}"
    return candidate


def build_yearly_product_work_order_no(db: Session, product: Item, now: datetime | None = None) -> str:
    current_time = now or datetime.now()
    year_part = current_time.strftime("%Y")
    existing_nos = db.scalars(select(WorkOrder.work_order_no).where(WorkOrder.work_order_no.like(f"{year_part}____-%"))).all()
    used_sequences = [
        int(work_order_no[4:8])
        for work_order_no in existing_nos
        if len(work_order_no) > 8
        and work_order_no[:4] == year_part
        and work_order_no[4:8].isdigit()
        and work_order_no[8] == "-"
    ]
    next_sequence = max(used_sequences, default=0) + 1
    product_name = " ".join(str(product.item_name or product.item_code or f"产品{product.id}").split()).strip("- ") or f"产品{product.id}"
    max_product_name_length = max(80 - len(year_part) - 4 - 1, 1)
    return f"{year_part}{next_sequence:04d}-{product_name[:max_product_name_length]}"


def build_raw_lot_product_work_order_no(*, biz_time: datetime, lot_no: str, product: Item) -> str:
    date_part = biz_time.strftime("%Y%m%d")
    normalized_product_name = " ".join(str(product.item_name or product.item_code or f"产品{product.id}").split()).strip("- ")
    product_name = normalized_product_name or str(product.item_code or f"产品{product.id}")
    prefix = f"{date_part}-{lot_no}-"
    max_product_name_length = max(80 - len(prefix), 0)
    return f"{prefix}{product_name[:max_product_name_length]}"[:80]


def first_positive_decimal(*values: Decimal) -> Decimal:
    for value in values:
        if value > 0:
            return value
    return Decimal("0")


FINANCE_EXPENSE_LAYOUT = [
    ("material_usage_value", "使用原材料价值："),
    ("material_loss_value", "不良率损耗："),
    ("operator_wage", "操作工人工资：（按照报工系统核实）"),
    ("manager_wage", "管理人员工资："),
    ("finance_charge", "财务费用："),
    ("mould_maintenance", "模具维护成本："),
    ("outsource_process", "（生产）制造费用 -外协加工费"),
    ("production_packaging", "（生产）制造费用-生产包装"),
    ("equipment_depreciation", "设备折旧费"),
    ("utility", "水电能耗："),
    ("office_supplies", "管理费用-办公用品："),
    ("factory_rent", "厂房租金："),
    ("temporary_wage", "临时工工资："),
    ("staff_welfare", "职工福利-餐费、饮品等"),
    ("social_insurance", "社保费："),
    ("cash_misc", "现金支出的白条费用："),
    ("other", "其它："),
]

OVERHEAD_TYPE_ALIASES = {
    "OPERATOR_WAGE": "operator_wage",
    "DIRECT_LABOR": "operator_wage",
    "LABOR": "operator_wage",
    "MANAGER_WAGE": "manager_wage",
    "MANAGER_SALARY": "manager_wage",
    "MANAGEMENT_WAGE": "manager_wage",
    "FINANCE_CHARGE": "finance_charge",
    "FINANCE_FEE": "finance_charge",
    "FINANCIAL_EXPENSE": "finance_charge",
    "MOULD_MAINTENANCE": "mould_maintenance",
    "MOLD_MAINTENANCE": "mould_maintenance",
    "OUTSOURCE_PROCESS": "outsource_process",
    "OUTSOURCE_FEE": "outsource_process",
    "PRODUCTION_PACKAGING": "production_packaging",
    "PACKAGING": "production_packaging",
    "EQUIPMENT_DEPRECIATION": "equipment_depreciation",
    "DEPRECIATION": "equipment_depreciation",
    "UTILITY": "utility",
    "WATER_ELECTRIC": "utility",
    "OFFICE_SUPPLIES": "office_supplies",
    "FACTORY_RENT": "factory_rent",
    "RENT": "factory_rent",
    "TEMPORARY_WAGE": "temporary_wage",
    "TEMP_WAGE": "temporary_wage",
    "STAFF_WELFARE": "staff_welfare",
    "WELFARE": "staff_welfare",
    "SOCIAL_INSURANCE": "social_insurance",
    "INSURANCE": "social_insurance",
    "CASH_MISC": "cash_misc",
    "CASH_WHITE_STRIP": "cash_misc",
    "OTHER": "other",
}


def _to_decimal_sum(value: float | Decimal | int | None, places: str = "0.000001") -> Decimal:
    return to_decimal(value, places)


def _to_float(value: Decimal | float | int | None, places: str = "0.000001") -> float:
    return float(to_decimal(value, places))


def _normalize_overhead_type(value: str | None) -> str | None:
    if not value:
        return None
    normalized = str(value).strip().upper()
    return OVERHEAD_TYPE_ALIASES.get(normalized, "other")


def _join_distinct(parts: list[str]) -> str | None:
    cleaned = [part for part in parts if part]
    if not cleaned:
        return None
    result: list[str] = []
    seen: set[str] = set()
    for part in cleaned:
        if part in seen:
            continue
        seen.add(part)
        result.append(part)
    return " + ".join(result)


def _to_candidate_datetime(value: date | datetime | None) -> datetime | None:
    if value is None:
        return None
    if isinstance(value, datetime):
        return value
    if isinstance(value, date):
        return datetime.combine(value, time.min)
    return None


def _extract_overhead_effective_date(description: str | None) -> date | None:
    if not description:
        return None
    match = re.search(r"\[EXPENSE_DATE:(\d{4}-\d{2}-\d{2})\]", description)
    if not match:
        return None
    try:
        return date.fromisoformat(match.group(1))
    except ValueError:
        return None


def build_supplier_code(db: Session | None = None) -> str:
    date_part = date.today().strftime("%Y%m%d")
    prefix = f"SUP-NB-{date_part}"
    if db is None:
        return f"{prefix}-{datetime.now().strftime('%H%M%S')}"
    return next_doc_no(db, Supplier, "supplier_code", prefix)


def get_default_location(db: Session, warehouse_id: int) -> WarehouseLocation | None:
    return db.scalar(
        select(WarehouseLocation)
        .where(
            WarehouseLocation.warehouse_id == warehouse_id,
            WarehouseLocation.status == "ACTIVE",
        )
        .order_by(WarehouseLocation.is_default.desc(), WarehouseLocation.id)
    )


def get_location_or_default(db: Session, warehouse_id: int, location_id: int | None) -> WarehouseLocation | None:
    if location_id:
        location = db.get(WarehouseLocation, location_id)
        if not location:
            raise HTTPException(status_code=404, detail="库位不存在")
        return location
    return get_default_location(db, warehouse_id)


def get_default_bom(db: Session, product_item_id: int) -> Bom:
    bom = db.scalar(
        select(Bom).where(
            Bom.product_item_id == product_item_id,
            Bom.is_default == 1,
            Bom.status == "ACTIVE",
        )
    )
    if not bom:
        raise HTTPException(status_code=400, detail="产品缺少默认 BOM")
    return bom


def get_default_route(db: Session, product_item_id: int) -> ProcessRoute:
    route = db.scalar(
        select(ProcessRoute).where(
            ProcessRoute.product_item_id == product_item_id,
            ProcessRoute.is_default == 1,
            ProcessRoute.status == "ACTIVE",
        )
    )
    if not route:
        raise HTTPException(status_code=400, detail="产品缺少默认工艺路线")
    return route


def get_stock_balance_record(
    db: Session,
    item_id: int,
    warehouse_id: int,
    location_id: int | None,
) -> StockBalance | None:
    stmt = select(StockBalance).where(
        StockBalance.item_id == item_id,
        StockBalance.warehouse_id == warehouse_id,
    )
    if location_id is None:
        stmt = stmt.where(StockBalance.location_id.is_(None))
    else:
        stmt = stmt.where(StockBalance.location_id == location_id)
    stmt = stmt.with_for_update()
    return db.scalar(stmt)


def _assert_balance_delta_not_negative(current: Decimal, delta: Decimal, label: str) -> None:
    if to_decimal(current) + to_decimal(delta) < 0:
        raise HTTPException(status_code=400, detail=f"库存余额不足，不能执行出库扣减：{label}不足")


def upsert_stock_balance(
    db: Session,
    *,
    item_id: int,
    warehouse_id: int,
    location_id: int | None,
    qty_delta: Decimal,
    weight_delta: Decimal,
    available_qty_delta: Decimal | None = None,
    available_weight_delta: Decimal | None = None,
    allocated_qty_delta: Decimal | None = None,
    allocated_weight_delta: Decimal | None = None,
    unit_cost: Decimal | None = None,
) -> StockBalance:
    weight_only_stock = is_weight_only_stock_context(db, item_id, warehouse_id)
    if weight_only_stock:
        qty_delta = Decimal("0")
        available_qty_delta = Decimal("0") if available_qty_delta is not None else None
        allocated_qty_delta = Decimal("0") if allocated_qty_delta is not None else None

    effective_available_qty_delta = available_qty_delta if available_qty_delta is not None else qty_delta
    effective_available_weight_delta = available_weight_delta if available_weight_delta is not None else weight_delta
    effective_allocated_qty_delta = allocated_qty_delta if allocated_qty_delta is not None else Decimal("0")
    effective_allocated_weight_delta = allocated_weight_delta if allocated_weight_delta is not None else Decimal("0")

    balance = get_stock_balance_record(db, item_id, warehouse_id, location_id)
    if balance is None:
        _assert_balance_delta_not_negative(Decimal("0"), qty_delta, "现存数量")
        _assert_balance_delta_not_negative(Decimal("0"), weight_delta, "现存重量")
        _assert_balance_delta_not_negative(Decimal("0"), effective_available_qty_delta, "可用数量")
        _assert_balance_delta_not_negative(Decimal("0"), effective_available_weight_delta, "可用重量")
        _assert_balance_delta_not_negative(Decimal("0"), effective_allocated_qty_delta, "已分配数量")
        _assert_balance_delta_not_negative(Decimal("0"), effective_allocated_weight_delta, "已分配重量")
    else:
        _assert_balance_delta_not_negative(to_decimal(balance.qty_on_hand), qty_delta, "现存数量")
        _assert_balance_delta_not_negative(to_decimal(balance.weight_on_hand_kg), weight_delta, "现存重量")
        _assert_balance_delta_not_negative(to_decimal(balance.qty_available), effective_available_qty_delta, "可用数量")
        _assert_balance_delta_not_negative(
            to_decimal(balance.weight_available_kg),
            effective_available_weight_delta,
            "可用重量",
        )
        _assert_balance_delta_not_negative(to_decimal(balance.qty_allocated), effective_allocated_qty_delta, "已分配数量")
        _assert_balance_delta_not_negative(
            to_decimal(balance.weight_allocated_kg),
            effective_allocated_weight_delta,
            "已分配重量",
        )

    if balance is None:
        balance = StockBalance(
            item_id=item_id,
            warehouse_id=warehouse_id,
            location_id=location_id,
            qty_on_hand=to_decimal(0),
            weight_on_hand_kg=to_decimal(0),
            qty_available=to_decimal(0),
            weight_available_kg=to_decimal(0),
            qty_allocated=to_decimal(0),
            weight_allocated_kg=to_decimal(0),
            avg_unit_cost=to_decimal(unit_cost or 0, "0.0001"),
        )
        db.add(balance)
        db.flush()

    previous_weight = to_decimal(balance.weight_on_hand_kg)
    previous_cost = to_decimal(balance.avg_unit_cost, "0.0001")
    incoming_weight = max(Decimal("0"), weight_delta)
    incoming_cost = to_decimal(unit_cost or 0, "0.0001")

    balance.qty_on_hand = clamp_non_negative(to_decimal(balance.qty_on_hand) + qty_delta)
    balance.weight_on_hand_kg = clamp_non_negative(to_decimal(balance.weight_on_hand_kg) + weight_delta)
    balance.qty_available = clamp_non_negative(to_decimal(balance.qty_available) + effective_available_qty_delta)
    balance.weight_available_kg = clamp_non_negative(
        to_decimal(balance.weight_available_kg) + effective_available_weight_delta
    )
    balance.qty_allocated = clamp_non_negative(to_decimal(balance.qty_allocated) + effective_allocated_qty_delta)
    balance.weight_allocated_kg = clamp_non_negative(
        to_decimal(balance.weight_allocated_kg) + effective_allocated_weight_delta
    )
    if weight_only_stock:
        balance.qty_on_hand = Decimal("0")
        balance.qty_available = Decimal("0")
        balance.qty_allocated = Decimal("0")

    if incoming_weight > 0:
        total_weight = previous_weight + incoming_weight
        if total_weight > 0:
            weighted_cost = ((previous_weight * previous_cost) + (incoming_weight * incoming_cost)) / total_weight
            balance.avg_unit_cost = to_decimal(weighted_cost, "0.0001")
    elif unit_cost is not None and to_decimal(balance.avg_unit_cost, "0.0001") == 0:
        balance.avg_unit_cost = incoming_cost

    db.add(balance)
    return balance


def create_inventory_txn(
    db: Session,
    *,
    txn_type: str,
    item_id: int,
    warehouse_id: int,
    location_id: int | None,
    lot_id: int | None,
    qty_change: Decimal,
    weight_change: Decimal,
    unit_cost: Decimal,
    source_doc_type: str,
    source_doc_id: int,
    source_line_id: int | None,
    biz_time: datetime,
    operator_user_id: int | None,
    remark: str | None = None,
    amount_basis: str = "QTY",
    logistics_waybill_no: str | None = None,
    logistics_freight_amount: Decimal | None = None,
    logistics_photo_url: str | None = None,
) -> InventoryTxn:
    if is_weight_only_stock_context(db, item_id, warehouse_id):
        qty_change = Decimal("0")
        if abs(weight_change) > 0:
            amount_basis = "WEIGHT"

    base_value = abs(weight_change) if amount_basis == "WEIGHT" and abs(weight_change) > 0 else abs(qty_change)
    amount = to_decimal(base_value * unit_cost, "0.01")
    txn = InventoryTxn(
        txn_no=next_doc_no(
            db,
            InventoryTxn,
            "txn_no",
            f"TXN-NB-{biz_time.strftime('%Y%m%d')}-{code_token(txn_type, 'BIZ', 10)}-{code_token(source_doc_type, 'SRC', 10)}",
        ),
        txn_type=txn_type,
        item_id=item_id,
        warehouse_id=warehouse_id,
        location_id=location_id,
        lot_id=lot_id,
        qty_change=qty_change,
        weight_change_kg=weight_change,
        unit_cost=to_decimal(unit_cost, "0.0001"),
        amount=amount,
        source_doc_type=source_doc_type,
        source_doc_id=source_doc_id,
        source_line_id=source_line_id,
        biz_time=biz_time,
        operator_user_id=operator_user_id,
        logistics_waybill_no=logistics_waybill_no,
        logistics_freight_amount=logistics_freight_amount,
        logistics_photo_url=logistics_photo_url,
        remark=remark,
    )
    db.add(txn)
    db.flush()
    return txn


def issue_item_from_lots(
    db: Session,
    *,
    item_id: int,
    required_qty: Decimal,
    required_weight: Decimal,
    enforce_qty: bool,
    enforce_weight: bool,
    source_doc_id: int,
    source_line_id: int | None,
    biz_time: datetime,
    operator_user_id: int | None,
    remark: str | None = None,
) -> tuple[Decimal, Decimal, Decimal]:
    raw_material = is_raw_material_item(db, item_id)
    if raw_material:
        enforce_qty = False
        enforce_weight = required_weight > 0

    remaining_weight = required_weight if enforce_weight else Decimal("0")
    remaining_qty = required_qty if enforce_qty else Decimal("0")
    total_qty = Decimal("0")
    total_weight = Decimal("0")
    total_amount = Decimal("0")

    lot_filters = [
        StockLot.item_id == item_id,
        StockLot.quality_status == "PASS",
        StockLot.status == "AVAILABLE",
        StockLot.remaining_weight_kg > 0 if raw_material else or_(StockLot.remaining_qty > 0, StockLot.remaining_weight_kg > 0),
    ]
    if raw_material:
        lot_filters.append(StockLot.warehouse_id.in_(select(Warehouse.id).where(Warehouse.warehouse_type == "RAW")))

    lots = db.scalars(
        select(StockLot)
        .where(*lot_filters)
        .order_by(StockLot.created_at, StockLot.id)
    ).all()

    for lot in lots:
        available_qty = Decimal("0") if raw_material else clamp_non_negative(to_decimal(lot.remaining_qty) - to_decimal(lot.locked_qty))
        available_weight = clamp_non_negative(
            to_decimal(lot.remaining_weight_kg) - to_decimal(lot.locked_weight_kg)
        )
        if (raw_material and available_weight <= 0) or (not raw_material and available_qty <= 0 and available_weight <= 0):
            continue

        if raw_material:
            take_weight = min(remaining_weight, available_weight)
            take_qty = Decimal("0")
        elif remaining_weight > 0 and available_weight > 0:
            take_weight = min(remaining_weight, available_weight)
            ratio = take_weight / available_weight if available_weight > 0 else Decimal("0")
            take_qty = available_qty * ratio if available_qty > 0 else Decimal("0")
        else:
            take_qty = min(remaining_qty, available_qty)
            ratio = take_qty / available_qty if available_qty > 0 else Decimal("0")
            take_weight = available_weight * ratio if available_weight > 0 else Decimal("0")

        take_qty = clamp_non_negative(take_qty)
        take_weight = clamp_non_negative(take_weight)
        if take_qty <= 0 and take_weight <= 0:
            continue

        lot.remaining_qty = Decimal("0") if raw_material else clamp_non_negative(to_decimal(lot.remaining_qty) - take_qty)
        lot.remaining_weight_kg = clamp_non_negative(to_decimal(lot.remaining_weight_kg) - take_weight)
        if raw_material:
            lot.locked_qty = Decimal("0")
        if (raw_material and lot.remaining_weight_kg <= 0) or (not raw_material and lot.remaining_qty <= 0 and lot.remaining_weight_kg <= 0):
            lot.status = "DEPLETED"
        db.add(lot)

        upsert_stock_balance(
            db,
            item_id=item_id,
            warehouse_id=lot.warehouse_id,
            location_id=lot.location_id,
            qty_delta=-take_qty,
            weight_delta=-take_weight,
            available_qty_delta=-take_qty,
            available_weight_delta=-take_weight,
            unit_cost=to_decimal(lot.unit_cost, "0.0001"),
        )
        txn = create_inventory_txn(
            db,
            txn_type="MATERIAL_ISSUE",
            item_id=item_id,
            warehouse_id=lot.warehouse_id,
            location_id=lot.location_id,
            lot_id=lot.id,
            qty_change=-take_qty,
            weight_change=-take_weight,
            unit_cost=to_decimal(lot.unit_cost, "0.0001"),
            source_doc_type="WORK_ORDER",
            source_doc_id=source_doc_id,
            source_line_id=source_line_id,
            biz_time=biz_time,
            operator_user_id=operator_user_id,
            remark=remark,
            amount_basis="WEIGHT" if take_weight > 0 else "QTY",
        )
        material_sub_batch_no = lot.lot_no
        txn.remark = f"{remark or '生产领料'}；库存批次号 {material_sub_batch_no}"
        db.add(txn)
        if source_line_id:
            db.add(
                WorkOrderMaterialIssue(
                    work_order_material_id=source_line_id,
                    work_order_id=source_doc_id,
                    material_item_id=item_id,
                    source_lot_id=lot.id,
                    material_sub_batch_no=material_sub_batch_no,
                    issued_qty=take_qty,
                    issued_weight_kg=take_weight,
                    unit_cost=to_decimal(lot.unit_cost, "0.0001"),
                    amount=to_decimal(txn.amount, "0.01"),
                    issue_time=biz_time,
                    operator_user_id=operator_user_id,
                    remark=remark,
                )
            )

        total_qty += take_qty
        total_weight += take_weight
        total_amount += to_decimal(txn.amount, "0.01")
        remaining_qty = clamp_non_negative(remaining_qty - take_qty)
        remaining_weight = clamp_non_negative(remaining_weight - take_weight)

        if remaining_qty <= 0 and remaining_weight <= 0:
            break

    if (enforce_qty and remaining_qty > 0) or (enforce_weight and remaining_weight > 0):
        raise HTTPException(status_code=400, detail="原材料可用库存不足，无法自动领料")

    return total_qty, total_weight, total_amount


def issue_selected_stock_lots(
    db: Session,
    *,
    work_order_id: int,
    work_order_material_id: int,
    material_item_id: int,
    selected_lots: list[dict],
    operator_user_id: int | None,
) -> list[WorkOrderMaterialIssue]:
    if not selected_lots:
        raise HTTPException(status_code=400, detail="请选择至少一个库存批次")

    source_lot_ids = [int(row.get("source_lot_id") or 0) for row in selected_lots]
    if len(source_lot_ids) != len(set(source_lot_ids)):
        raise HTTPException(status_code=400, detail="库存批次重复选择")

    issues: list[WorkOrderMaterialIssue] = []
    biz_time = datetime.now()
    for row in selected_lots:
        source_lot_id = int(row.get("source_lot_id") or 0)
        issued_weight = to_decimal(row.get("issued_weight_kg"))
        if issued_weight <= 0:
            raise HTTPException(status_code=400, detail="出库重量必须大于0")

        lot = db.scalar(select(StockLot).where(StockLot.id == source_lot_id).with_for_update())
        if not lot or int(lot.item_id) != int(material_item_id):
            raise HTTPException(status_code=400, detail="库存批次不存在或物料不匹配")
        warehouse = db.get(Warehouse, lot.warehouse_id)
        if not warehouse or warehouse.warehouse_type != "RAW":
            raise HTTPException(status_code=400, detail="库存批次不属于原材料库")

        usable_weight = clamp_non_negative(to_decimal(lot.remaining_weight_kg) - to_decimal(lot.locked_weight_kg))
        if lot.quality_status != "PASS" or lot.status != "AVAILABLE" or usable_weight <= 0:
            raise HTTPException(status_code=400, detail=f"库存批次 {lot.lot_no} 不可用")
        if issued_weight > usable_weight:
            raise HTTPException(status_code=400, detail=f"库存批次 {lot.lot_no} 剩余重量不足")

        lot.remaining_qty = Decimal("0")
        lot.remaining_weight_kg = clamp_non_negative(to_decimal(lot.remaining_weight_kg) - issued_weight)
        if to_decimal(lot.remaining_weight_kg) <= 0:
            lot.status = "DEPLETED"
        db.add(lot)

        unit_cost = to_decimal(lot.unit_cost, "0.0001")
        upsert_stock_balance(
            db,
            item_id=material_item_id,
            warehouse_id=lot.warehouse_id,
            location_id=lot.location_id,
            qty_delta=Decimal("0"),
            weight_delta=-issued_weight,
            available_qty_delta=Decimal("0"),
            available_weight_delta=-issued_weight,
            unit_cost=unit_cost,
        )
        txn = create_inventory_txn(
            db,
            txn_type="MATERIAL_ISSUE",
            item_id=material_item_id,
            warehouse_id=lot.warehouse_id,
            location_id=lot.location_id,
            lot_id=lot.id,
            qty_change=Decimal("0"),
            weight_change=-issued_weight,
            unit_cost=unit_cost,
            source_doc_type="WORK_ORDER",
            source_doc_id=work_order_id,
            source_line_id=work_order_material_id,
            biz_time=biz_time,
            operator_user_id=operator_user_id,
            remark=f"生产出库：{lot.lot_no}",
            amount_basis="WEIGHT",
        )
        db.add(txn)

        issue = WorkOrderMaterialIssue(
            work_order_material_id=work_order_material_id,
            work_order_id=work_order_id,
            material_item_id=material_item_id,
            source_lot_id=lot.id,
            material_sub_batch_no=lot.lot_no,
            issued_qty=Decimal("0"),
            issued_weight_kg=issued_weight,
            unit_cost=unit_cost,
            amount=to_decimal(issued_weight * unit_cost, "0.01"),
            issue_time=biz_time,
            operator_user_id=operator_user_id,
            remark=f"生产出库：{lot.lot_no}",
        )
        db.add(issue)
        issues.append(issue)

    db.flush()
    return issues


def sync_purchase_order_item_status(item: PurchaseOrderItem) -> None:
    ordered_qty = to_decimal(item.order_qty)
    received_qty = to_decimal(item.received_qty)
    ordered_weight = to_decimal(item.order_weight_kg)
    received_weight = to_decimal(item.received_weight_kg)
    if ordered_qty > 0:
        if received_qty >= ordered_qty:
            item.status = "CLOSED"
        elif received_qty > 0:
            item.status = "PARTIAL"
        else:
            item.status = "OPEN"
    elif ordered_weight > 0 and received_weight >= ordered_weight:
        item.status = "CLOSED"
    elif received_weight > 0:
        item.status = "PARTIAL"
    else:
        item.status = "OPEN"


def recalc_purchase_order_item_received_weight(db: Session, purchase_order_item_id: int) -> PurchaseOrderItem | None:
    item = db.get(PurchaseOrderItem, purchase_order_item_id)
    if not item:
        return None
    accepted_qty = db.scalar(
        select(func.coalesce(func.sum(PurchaseReceiptItem.accepted_qty), 0))
        .where(
            PurchaseReceiptItem.purchase_order_item_id == purchase_order_item_id,
            PurchaseReceiptItem.status == "PASSED",
        )
    ) or Decimal("0")
    accepted_weight = db.scalar(
        select(func.coalesce(func.sum(PurchaseReceiptItem.accepted_weight_kg), 0))
        .where(
            PurchaseReceiptItem.purchase_order_item_id == purchase_order_item_id,
            PurchaseReceiptItem.status == "PASSED",
        )
    ) or Decimal("0")
    item.received_qty = to_decimal(accepted_qty)
    item.received_weight_kg = to_decimal(accepted_weight)
    sync_purchase_order_item_status(item)
    db.add(item)
    return item


def sync_purchase_order_status(db: Session, purchase_order_id: int) -> None:
    order = db.get(PurchaseOrder, purchase_order_id)
    if not order:
        return
    if order.status == "LOCKED":
        db.add(order)
        return
    items = db.scalars(
        select(PurchaseOrderItem).where(PurchaseOrderItem.purchase_order_id == purchase_order_id)
    ).all()
    pending_count = db.scalar(
        select(func.count(PurchaseReceiptItem.id))
        .join(PurchaseReceipt, PurchaseReceipt.id == PurchaseReceiptItem.receipt_id)
        .where(PurchaseReceipt.purchase_order_id == purchase_order_id, PurchaseReceiptItem.status == "PENDING_QC")
    ) or 0
    rejected_count = db.scalar(
        select(func.count(PurchaseReceiptItem.id))
        .join(PurchaseReceipt, PurchaseReceipt.id == PurchaseReceiptItem.receipt_id)
        .where(PurchaseReceipt.purchase_order_id == purchase_order_id, PurchaseReceiptItem.status == "REJECTED")
    ) or 0
    if pending_count > 0:
        order.status = "PENDING_QC"
    elif items and all(item.status == "CLOSED" for item in items):
        order.status = "RECEIVED"
    elif any(item.status in {"PARTIAL", "CLOSED"} for item in items):
        order.status = "PARTIAL"
    elif rejected_count > 0:
        order.status = "REJECTED"
    elif order.status in {"LOCKED", "PENDING_QC", "PARTIAL", "REJECTED", "RECEIVED"}:
        order.status = "LOCKED"
    else:
        order.status = "OPEN"
    db.add(order)


def sync_sales_order_status(db: Session, sales_order_id: int) -> None:
    if not sales_order_id:
        return
    order = db.get(SalesOrder, sales_order_id)
    if not order:
        return
    items = db.scalars(select(SalesOrderItem).where(SalesOrderItem.sales_order_id == sales_order_id)).all()
    if items and all(to_decimal(item.delivered_qty) >= to_decimal(item.order_qty) for item in items):
        order.status = "CLOSED"
    elif any(to_decimal(item.delivered_qty) > 0 for item in items):
        order.status = "PARTIAL"
    else:
        order.status = "OPEN"
    db.add(order)


def sync_return_order_status(db: Session, return_order_id: int) -> None:
    order = db.get(ReturnOrder, return_order_id)
    if not order:
        return
    items = db.scalars(select(ReturnItem).where(ReturnItem.return_order_id == return_order_id)).all()
    if items and all(item.disposition_status == "CLOSED" for item in items):
        order.status = "CLOSED"
    elif any(item.disposition_status != "PENDING" for item in items):
        order.status = "PARTIAL"
    else:
        order.status = "CREATED"
    db.add(order)


def sync_work_order_status(db: Session, work_order_id: int) -> None:
    work_order = db.get(WorkOrder, work_order_id)
    if not work_order:
        return
    if str(work_order.status or "").upper() == "SETTLED":
        return
    planned_qty = to_decimal(work_order.planned_qty)
    finished_qty = to_decimal(work_order.finished_qty)
    operation_count = db.scalar(
        select(func.count(WorkOrderOperation.id)).where(WorkOrderOperation.work_order_id == work_order_id)
    ) or 0
    done_count = db.scalar(
        select(func.count(WorkOrderOperation.id)).where(
            WorkOrderOperation.work_order_id == work_order_id,
            WorkOrderOperation.status == "DONE",
        )
    ) or 0
    if finished_qty >= planned_qty and planned_qty > 0:
        work_order.status = "COMPLETED"
        work_order.actual_end_time = work_order.actual_end_time or datetime.now()
    elif done_count == operation_count and operation_count > 0:
        work_order.status = "READY_TO_RECEIPT"
    elif work_order.actual_start_time is not None or done_count > 0:
        work_order.status = "IN_PROGRESS"
    elif to_decimal(work_order.released_qty) > 0:
        work_order.status = "RELEASED"
    else:
        work_order.status = "CREATED"
    db.add(work_order)


def calculate_work_order_reference_qty(db: Session, work_order: WorkOrder) -> Decimal | None:
    material_rows = db.execute(
        select(
            WorkOrderMaterial.id.label("work_order_material_id"),
            WorkOrderMaterial.issued_weight_kg.label("issued_weight_kg"),
            WorkOrderMaterial.required_weight_kg.label("required_weight_kg"),
            BomItem.gross_weight_per_piece_kg.label("gross_weight_per_piece_kg"),
            Item.unit_weight_kg.label("product_unit_weight_kg"),
        )
        .join(BomItem, BomItem.id == WorkOrderMaterial.bom_item_id)
        .join(WorkOrder, WorkOrder.id == WorkOrderMaterial.work_order_id)
        .join(Item, Item.id == WorkOrder.product_item_id)
        .where(WorkOrderMaterial.work_order_id == work_order.id)
        .order_by(BomItem.seq_no, WorkOrderMaterial.id)
    ).mappings().all()
    material_row = next((row for row in material_rows if to_decimal(row["issued_weight_kg"]) > 0), None)
    if not material_row and material_rows:
        material_row = material_rows[0]
    if not material_row:
        return None

    issue_weight = to_decimal(material_row["issued_weight_kg"])
    if issue_weight <= 0:
        issue_weight = to_decimal(material_row["required_weight_kg"])
    gross_weight = to_decimal(material_row["gross_weight_per_piece_kg"])
    if gross_weight <= 0:
        gross_weight = to_decimal(material_row["product_unit_weight_kg"])
    if issue_weight <= 0 or gross_weight <= 0:
        return None
    return (issue_weight / gross_weight).to_integral_value(rounding=ROUND_FLOOR)


def sync_work_order_reference_qty(db: Session, work_order_id: int) -> bool:
    work_order = db.get(WorkOrder, work_order_id)
    if not work_order:
        return False
    reference_qty = calculate_work_order_reference_qty(db, work_order)
    if reference_qty is None or reference_qty <= 0:
        return False

    current_qty = to_decimal(work_order.planned_qty)
    changed = current_qty != reference_qty or to_decimal(work_order.released_qty) != reference_qty
    if changed:
        work_order.planned_qty = reference_qty
        work_order.released_qty = reference_qty
        db.add(work_order)

    operations = db.scalars(select(WorkOrderOperation).where(WorkOrderOperation.work_order_id == work_order_id)).all()
    for operation in operations:
        if to_decimal(operation.planned_qty) != reference_qty:
            operation.planned_qty = reference_qty
            changed = True
        report_qty = to_decimal(operation.report_qty)
        next_status = "DONE" if report_qty >= reference_qty else "IN_PROGRESS" if report_qty > 0 else "PENDING"
        if operation.status != next_status:
            operation.status = next_status
            changed = True
        db.add(operation)

    material_rows = db.execute(
        select(WorkOrderMaterial, BomItem)
        .join(BomItem, BomItem.id == WorkOrderMaterial.bom_item_id)
        .where(WorkOrderMaterial.work_order_id == work_order_id)
        .order_by(BomItem.seq_no, WorkOrderMaterial.id)
    ).all()
    for material_row, bom_item in material_rows:
        issued_weight = to_decimal(material_row.issued_weight_kg)
        expected_required_weight = issued_weight if issued_weight > 0 else reference_qty * to_decimal(bom_item.gross_weight_per_piece_kg)
        expected_required_weight = to_decimal(expected_required_weight)
        if to_decimal(material_row.required_weight_kg) != expected_required_weight:
            material_row.required_weight_kg = expected_required_weight
            changed = True
        db.add(material_row)

    if changed:
        sync_work_order_status(db, work_order_id)
    return changed


def sync_recent_work_order_reference_qty(db: Session, limit: int = 500) -> bool:
    work_order_ids = db.scalars(select(WorkOrder.id).order_by(WorkOrder.id.desc()).limit(limit)).all()
    changed = False
    for work_order_id in work_order_ids:
        changed = sync_work_order_reference_qty(db, work_order_id) or changed
    return changed


def calculate_work_order_cost_summary(db: Session, work_order_id: int) -> dict[str, Decimal]:
    work_order = db.get(WorkOrder, work_order_id)
    if not work_order:
        raise HTTPException(status_code=404, detail="工单不存在")

    material_amount = to_decimal(
        db.scalar(
            select(func.coalesce(func.sum(InventoryTxn.amount), 0)).where(
                InventoryTxn.txn_type == "MATERIAL_ISSUE",
                InventoryTxn.source_doc_type == "WORK_ORDER",
                InventoryTxn.source_doc_id == work_order_id,
            )
        ),
        "0.01",
    )

    active_scrap_record_ids = (
        select(func.max(ScrapRecord.id).label("scrap_record_id"))
        .where(ScrapRecord.status != "OVERRIDDEN")
        .group_by(ScrapRecord.report_id)
        .subquery()
    )

    operations = db.scalars(
        select(WorkOrderOperation).where(WorkOrderOperation.work_order_id == work_order_id)
    ).all()
    labor_amount = Decimal("0")
    machine_amount = Decimal("0")
    for operation in operations:
        report_qty = to_decimal(operation.report_qty)
        labor_amount += report_qty * to_decimal(operation.std_labor_cost, "0.0001")
        machine_amount += report_qty * to_decimal(operation.std_machine_cost, "0.0001")

    rework_labor_amount = to_decimal(
        db.scalar(
            select(func.coalesce(func.sum(ScrapRecord.scrap_qty * WorkOrderOperation.std_labor_cost), 0))
            .join(WorkOrderOperation, WorkOrderOperation.id == ScrapRecord.work_order_operation_id)
            .where(ScrapRecord.id.in_(select(active_scrap_record_ids.c.scrap_record_id)))
            .where(
                ScrapRecord.work_order_id == work_order_id,
                ScrapRecord.disposal_type == "REWORK",
                ScrapRecord.status == "CONFIRMED",
            )
        ),
        "0.01",
    )
    labor_amount += rework_labor_amount

    abnormal_loss_amount = to_decimal(
        db.scalar(
            select(func.coalesce(func.sum(ScrapRecord.scrap_cost_amount), 0)).where(
                ScrapRecord.id.in_(select(active_scrap_record_ids.c.scrap_record_id)),
                ScrapRecord.work_order_id == work_order_id,
                ScrapRecord.status == "CONFIRMED",
            )
        ),
        "0.01",
    )
    abnormal_loss_amount += to_decimal(
        db.scalar(
            select(func.coalesce(func.sum(OperationReport.extra_cost_amount), 0)).where(
                OperationReport.work_order_id == work_order_id,
                OperationReport.is_abnormal == 1,
            )
        ),
        "0.01",
    )
    total_cost_amount = material_amount + labor_amount + machine_amount + abnormal_loss_amount
    finished_qty = to_decimal(work_order.finished_qty)
    base_qty = finished_qty if finished_qty > 0 else to_decimal(work_order.planned_qty)
    unit_cost = (total_cost_amount / base_qty) if base_qty > 0 else Decimal("0")
    return {
        "material_amount": to_decimal(material_amount, "0.01"),
        "labor_amount": to_decimal(labor_amount, "0.01"),
        "machine_amount": to_decimal(machine_amount, "0.01"),
        "abnormal_loss_amount": to_decimal(abnormal_loss_amount, "0.01"),
        "total_cost_amount": to_decimal(total_cost_amount, "0.01"),
        "unit_cost": to_decimal(unit_cost, "0.0001"),
    }


def create_work_order_materials_and_operations(
    db: Session,
    *,
    work_order: WorkOrder,
    bom: Bom,
    route: ProcessRoute,
    auto_issue_materials: bool,
    operator_user_id: int | None,
    issue_weight_override: Decimal | None = None,
) -> None:
    bom_items = db.scalars(select(BomItem).where(BomItem.bom_id == bom.id).order_by(BomItem.seq_no)).all()
    planned_qty = to_decimal(work_order.planned_qty)
    for index, bom_item in enumerate(bom_items):
        required_qty = Decimal("0")
        required_weight = planned_qty * to_decimal(bom_item.gross_weight_per_piece_kg)
        if index == 0 and issue_weight_override is not None and issue_weight_override > 0:
            required_weight = to_decimal(issue_weight_override)
        enforce_qty = False
        enforce_weight = required_weight > 0
        material_row = WorkOrderMaterial(
            work_order_id=work_order.id,
            bom_item_id=bom_item.id,
            material_item_id=bom_item.material_item_id,
            required_qty=required_qty,
            required_weight_kg=required_weight,
            issued_qty=to_decimal(0),
            issued_weight_kg=to_decimal(0),
            returned_qty=to_decimal(0),
            returned_weight_kg=to_decimal(0),
            status="OPEN",
            remark=None,
        )
        db.add(material_row)
        db.flush()

        if auto_issue_materials and required_weight > 0:
            issued_qty, issued_weight, _ = issue_item_from_lots(
                db,
                item_id=bom_item.material_item_id,
                required_qty=required_qty,
                required_weight=required_weight,
                enforce_qty=enforce_qty,
                enforce_weight=enforce_weight,
                source_doc_id=work_order.id,
                source_line_id=material_row.id,
                biz_time=work_order.planned_start_time or datetime.now(),
                operator_user_id=operator_user_id,
                remark=f"工单 {work_order.work_order_no} 自动领料",
            )
            material_row.issued_qty = issued_qty
            material_row.issued_weight_kg = issued_weight
            material_row.status = "ISSUED"
            db.add(material_row)

    route_ops = db.scalars(
        select(ProcessRouteOperation)
        .where(ProcessRouteOperation.route_id == route.id, ProcessRouteOperation.status == "ACTIVE")
        .order_by(ProcessRouteOperation.seq_no)
    ).all()
    for route_op in route_ops:
        db.add(
            WorkOrderOperation(
                work_order_id=work_order.id,
                route_operation_id=route_op.id,
                seq_no=route_op.seq_no,
                operation_name=route_op.operation_name,
                work_center_id=route_op.work_center_id,
                planned_qty=planned_qty,
                report_qty=to_decimal(0),
                good_qty=to_decimal(0),
                scrap_qty=to_decimal(0),
                rework_qty=to_decimal(0),
                std_labor_cost=to_decimal(route_op.std_labor_cost, "0.0001"),
                std_machine_cost=to_decimal(route_op.std_machine_cost, "0.0001"),
                std_outsource_cost=to_decimal(route_op.std_outsource_cost, "0.0001"),
                allowed_scrap_rate=to_decimal(route_op.allowed_scrap_rate, "0.0001"),
                is_abnormal=0,
                status="PENDING",
                remark=None,
            )
        )


def generate_cost_allocations(db: Session, period_id: int) -> list[CostAllocationRead]:
    period = db.get(AccountingPeriod, period_id)
    if not period:
        raise HTTPException(status_code=404, detail="财务期间不存在")

    period_start = start_of_day(period.start_date)
    period_end = end_of_day(period.end_date)
    total_overhead = to_decimal(
        db.scalar(select(func.coalesce(func.sum(OverheadEntry.amount), 0)).where(OverheadEntry.period_id == period_id)),
        "0.01",
    )

    db.query(CostAllocation).filter(CostAllocation.period_id == period_id).delete()
    db.flush()

    work_orders = db.scalars(
        select(WorkOrder).where(
            or_(
                and_(WorkOrder.actual_end_time.is_not(None), WorkOrder.actual_end_time.between(period_start, period_end)),
                WorkOrder.updated_at.between(period_start, period_end),
            )
        )
    ).all()
    if not work_orders:
        return []

    basis_map: dict[int, Decimal] = {}
    total_basis = Decimal("0")
    for work_order in work_orders:
        basis = to_decimal(work_order.finished_qty)
        if basis <= 0:
            basis = to_decimal(work_order.released_qty)
        if basis <= 0:
            basis = to_decimal(work_order.planned_qty)
        basis_map[work_order.id] = basis
        total_basis += basis

    rows: list[CostAllocation] = []
    for work_order in work_orders:
        product = db.get(Item, work_order.product_item_id)
        if not product:
            continue
        basis = basis_map[work_order.id]
        cost_summary = calculate_work_order_cost_summary(db, work_order.id)
        overhead_amount = (total_overhead * basis / total_basis) if total_basis > 0 else Decimal("0")
        total_cost = cost_summary["total_cost_amount"] + overhead_amount
        base_qty = to_decimal(work_order.finished_qty)
        if base_qty <= 0:
            base_qty = to_decimal(work_order.planned_qty)
        allocation = CostAllocation(
            period_id=period_id,
            work_order_id=work_order.id,
            product_item_id=work_order.product_item_id,
            allocation_basis_value=basis,
            overhead_amount=to_decimal(overhead_amount, "0.01"),
            material_amount=cost_summary["material_amount"],
            labor_amount=cost_summary["labor_amount"],
            machine_amount=cost_summary["machine_amount"],
            abnormal_loss_amount=cost_summary["abnormal_loss_amount"],
            total_cost_amount=to_decimal(total_cost, "0.01"),
            unit_cost=to_decimal((total_cost / base_qty) if base_qty > 0 else 0, "0.0001"),
        )
        db.add(allocation)
        rows.append(allocation)

    db.flush()
    return get_cost_allocation_rows(db, period_id=period_id, limit=500)


def build_statement_summary(db: Session, period_id: int, report_date: date) -> dict:
    overhead_total = float(
        db.scalar(select(func.coalesce(func.sum(OverheadEntry.amount), 0)).where(OverheadEntry.period_id == period_id)) or 0
    )
    allocation_total = float(
        db.scalar(select(func.coalesce(func.sum(CostAllocation.total_cost_amount), 0)).where(CostAllocation.period_id == period_id))
        or 0
    )
    statement_rows = db.execute(
        select(
            Item.item_type.label("item_type"),
            func.count(StockBalance.id).label("line_count"),
            func.coalesce(func.sum(StockBalance.qty_on_hand), 0).label("qty_on_hand"),
            func.coalesce(func.sum(StockBalance.weight_on_hand_kg), 0).label("weight_on_hand_kg"),
	            func.coalesce(
	                func.sum(
	                    case(
	                        (Item.item_type == "RAW_MATERIAL", StockBalance.avg_unit_cost * StockBalance.weight_on_hand_kg),
	                        else_=StockBalance.avg_unit_cost * StockBalance.qty_on_hand,
	                    )
	                ),
	                0,
	            ).label("stock_amount"),
        )
        .join(Item, Item.id == StockBalance.item_id)
        .group_by(Item.item_type)
    ).mappings()
    inventory_summary = [dict(row) for row in statement_rows]
    return {
        "report_date": report_date.isoformat(),
        "overhead_total": overhead_total,
        "allocation_total": allocation_total,
        "inventory_summary": inventory_summary,
    }


def _build_finance_expense_rows(expense_amounts: dict[str, Decimal]) -> list[ProductMaterialCostExpenseRead]:
    return [
        ProductMaterialCostExpenseRead(
            key=key,
            label=label,
            amount=_to_float(expense_amounts.get(key, Decimal("0")), "0.01"),
        )
        for key, label in FINANCE_EXPENSE_LAYOUT
    ]


def build_product_material_cost_board(
    db: Session,
    *,
    date_from: date,
    date_to: date,
) -> ProductMaterialCostBoardRead:
    if date_to < date_from:
        raise HTTPException(status_code=400, detail="结束日期不能早于开始日期")

    start_dt = start_of_day(date_from)
    end_dt = end_of_day(date_to)

    base_rows = db.execute(
        text(
            """
            select
                wo.id as work_order_id,
                wo.work_order_no,
                wo.created_at,
                wo.updated_at,
                wo.actual_end_time,
                wo.planned_qty,
                wo.finished_qty,
                wo.scrap_qty,
                wo.status,
                wo.source_sales_order_item_id,
                prod_item.id as product_item_id,
                prod_item.item_code as product_code,
                prod_item.item_name as product_name,
                prod_item.unit_weight_kg as product_unit_weight_kg,
                so_item.order_qty as order_qty,
                so_item.unit_price as unit_price,
                so_item.customer_part_no as customer_part_no,
                so.order_no as source_order_no,
                so.order_date,
                customer.customer_name
            from pp_work_order wo
            join md_item prod_item on prod_item.id = wo.product_item_id
            left join so_sales_order_item so_item on so_item.id = wo.source_sales_order_item_id
            left join so_sales_order so on so.id = so_item.sales_order_id
            left join md_customer customer on customer.id = so.customer_id
            order by wo.id desc
            """
        )
    ).mappings().all()

    work_order_ids = [int(row["work_order_id"]) for row in base_rows]
    if not work_order_ids:
        empty_expenses = _build_finance_expense_rows({key: Decimal("0") for key, _ in FINANCE_EXPENSE_LAYOUT})
        return ProductMaterialCostBoardRead(
            title="冲压产品材料成本核算表",
            date_from=date_from,
            date_to=date_to,
            generated_at=datetime.now(),
            rows=[],
            expense_rows=empty_expenses,
            summary=ProductMaterialCostSummaryRead(
                row_count=0,
                sales_total=0,
                gross_material_total=0,
                scrap_revenue_total=0,
                material_cost_total=0,
                material_loss_total=0,
                labor_total=0,
                outsource_total=0,
                rework_total=0,
                scrap_total=0,
                overhead_total=0,
                direct_cost_total=0,
                profit_amount=0,
                cost_ratio=0,
            ),
        )

    material_stmt = text(
        """
        select
            wom.work_order_id,
            wom.material_item_id,
            wom.required_weight_kg,
            wom.issued_weight_kg,
            bi.gross_weight_per_piece_kg,
            bi.net_weight_per_piece_kg,
            bi.loss_rate,
            material_item.item_code as material_code,
            material_item.item_name as material_name,
            material_item.material_grade as material_grade,
            material_item.scrap_sale_price as material_scrap_sale_price
        from pp_work_order_material wom
        join md_bom_item bi on bi.id = wom.bom_item_id
        join md_item material_item on material_item.id = wom.material_item_id
        where wom.work_order_id in :work_order_ids
        order by wom.work_order_id, wom.id
        """
    ).bindparams(bindparam("work_order_ids", expanding=True))
    material_rows = db.execute(material_stmt, {"work_order_ids": work_order_ids}).mappings().all()

    materials_by_work_order: dict[int, list[dict]] = defaultdict(list)
    material_item_ids: set[int] = set()
    for row in material_rows:
        payload = dict(row)
        materials_by_work_order[int(payload["work_order_id"])].append(payload)
        material_item_ids.add(int(payload["material_item_id"]))

    report_stmt = text(
        """
        select
            r.work_order_id,
            coalesce(sum(r.report_qty), 0) as report_qty,
            coalesce(sum(r.good_qty), 0) as good_qty,
            coalesce(sum(r.scrap_qty), 0) as scrap_qty,
            coalesce(sum(r.rework_qty), 0) as rework_qty,
            coalesce(sum(r.extra_cost_amount), 0) as extra_cost_amount,
            max(r.end_time) as last_report_time
        from pp_operation_report r
        where r.work_order_id in :work_order_ids
          and r.end_time <= :end_dt
        group by r.work_order_id
        """
    ).bindparams(bindparam("work_order_ids", expanding=True))
    report_rows = db.execute(report_stmt, {"work_order_ids": work_order_ids, "end_dt": end_dt}).mappings().all()
    report_map = {int(row["work_order_id"]): dict(row) for row in report_rows}

    final_report_stmt = text(
        """
        select
            final_operation.work_order_id,
            coalesce(sum(r.report_qty), 0) as report_qty,
            coalesce(sum(r.good_qty), 0) as good_qty,
            coalesce(sum(r.scrap_qty), 0) as scrap_qty,
            coalesce(sum(r.rework_qty), 0) as rework_qty,
            max(r.end_time) as last_report_time
        from (
            select
                woo.work_order_id,
                woo.id as work_order_operation_id
            from pp_work_order_operation woo
            join (
                select
                    work_order_id,
                    max(seq_no) as max_seq_no
                from pp_work_order_operation
                where work_order_id in :work_order_ids
                group by work_order_id
            ) final_seq
                on final_seq.work_order_id = woo.work_order_id
               and final_seq.max_seq_no = woo.seq_no
        ) final_operation
        left join pp_operation_report r
            on r.work_order_operation_id = final_operation.work_order_operation_id
           and r.end_time <= :end_dt
        group by final_operation.work_order_id
        """
    ).bindparams(bindparam("work_order_ids", expanding=True))
    final_report_rows = db.execute(
        final_report_stmt,
        {"work_order_ids": work_order_ids, "end_dt": end_dt},
    ).mappings().all()
    final_report_map = {int(row["work_order_id"]): dict(row) for row in final_report_rows}

    operation_cost_stmt = text(
        """
        select
            r.work_order_id,
            coalesce(sum(r.report_qty * woo.std_labor_cost), 0) as labor_amount,
            coalesce(sum(r.report_qty * woo.std_outsource_cost), 0) as outsource_amount
        from pp_operation_report r
        join pp_work_order_operation woo on woo.id = r.work_order_operation_id
        where r.work_order_id in :work_order_ids
          and r.end_time <= :end_dt
        group by r.work_order_id
        """
    ).bindparams(bindparam("work_order_ids", expanding=True))
    operation_cost_rows = db.execute(
        operation_cost_stmt, {"work_order_ids": work_order_ids, "end_dt": end_dt}
    ).mappings().all()
    operation_cost_map = {int(row["work_order_id"]): dict(row) for row in operation_cost_rows}

    receipt_stmt = text(
        """
        select
            cr.work_order_id,
            coalesce(sum(cri.receipt_qty), 0) as receipt_qty,
            max(cr.receipt_time) as last_receipt_time,
            group_concat(distinct cr.receipt_no separator ', ') as receipt_nos
        from pp_completion_receipt cr
        join pp_completion_receipt_item cri on cri.completion_receipt_id = cr.id
        where cr.work_order_id in :work_order_ids
          and cr.receipt_time <= :end_dt
        group by cr.work_order_id
        """
    ).bindparams(bindparam("work_order_ids", expanding=True))
    receipt_rows = db.execute(receipt_stmt, {"work_order_ids": work_order_ids, "end_dt": end_dt}).mappings().all()
    receipt_map = {int(row["work_order_id"]): dict(row) for row in receipt_rows}

    delivery_stmt = text(
        """
        select
            cr.work_order_id,
            coalesce(sum(di.delivery_qty), 0) as delivery_qty,
            max(d.delivery_date) as last_delivery_date,
            group_concat(distinct d.delivery_no separator ', ') as delivery_nos
        from so_delivery_item di
        join so_delivery d on d.id = di.delivery_id
        join wh_stock_lot lot on lot.id = di.lot_id and lot.source_doc_type = 'FG_RECEIPT'
        join pp_completion_receipt_item cri on cri.id = lot.source_line_id
        join pp_completion_receipt cr on cr.id = cri.completion_receipt_id and lot.source_doc_id = cr.id
        where cr.work_order_id in :work_order_ids
          and d.delivery_date <= :end_dt
        group by cr.work_order_id
        """
    ).bindparams(bindparam("work_order_ids", expanding=True))
    delivery_rows = db.execute(delivery_stmt, {"work_order_ids": work_order_ids, "end_dt": end_dt}).mappings().all()
    delivery_map = {int(row["work_order_id"]): dict(row) for row in delivery_rows}

    scrap_stmt = text(
        """
        select
            sr.work_order_id,
            coalesce(sum(case when sr.disposal_type = 'SCRAP' then sr.scrap_qty else 0 end), 0) as scrap_qty,
            coalesce(sum(case when sr.disposal_type = 'SCRAP' then sr.scrap_weight_kg else 0 end), 0) as scrap_weight_kg,
            coalesce(sum(case when sr.disposal_type = 'SCRAP' then sr.saleable_scrap_weight_kg else 0 end), 0) as saleable_scrap_weight_kg,
            coalesce(sum(case when sr.disposal_type = 'SCRAP' then sr.scrap_cost_amount else 0 end), 0) as scrap_cost_amount,
            coalesce(sum(case when sr.disposal_type = 'REWORK' then sr.scrap_qty else 0 end), 0) as rework_qty,
            coalesce(sum(case when sr.disposal_type = 'REWORK' then sr.scrap_cost_amount else 0 end), 0) as rework_cost_amount,
            max(sr.created_at) as last_scrap_time
        from pp_scrap_record sr
        join (
            select max(id) as id
            from pp_scrap_record
            where status <> 'OVERRIDDEN'
              and created_at <= :end_dt
            group by report_id
        ) active_sr on active_sr.id = sr.id
        where sr.work_order_id in :work_order_ids
          and sr.status <> 'OVERRIDDEN'
          and sr.created_at <= :end_dt
        group by sr.work_order_id
        """
    ).bindparams(bindparam("work_order_ids", expanding=True))
    scrap_rows = db.execute(scrap_stmt, {"work_order_ids": work_order_ids, "end_dt": end_dt}).mappings().all()
    scrap_map = {int(row["work_order_id"]): dict(row) for row in scrap_rows}

    return_disposition_stmt = text(
        """
        select
            mapped.work_order_id,
            coalesce(sum(case when mapped.disposition_type = 'REWORK' then mapped.return_qty else 0 end), 0) as return_rework_qty,
            coalesce(sum(case when mapped.disposition_type = 'REWORK' then mapped.extra_cost_amount else 0 end), 0) as return_rework_cost_amount,
            coalesce(sum(case when mapped.disposition_type = 'SCRAP' then mapped.return_qty else 0 end), 0) as return_scrap_qty,
            coalesce(sum(case when mapped.disposition_type = 'SCRAP' then mapped.scrap_weight_kg else 0 end), 0) as return_scrap_weight_kg,
            coalesce(sum(case when mapped.disposition_type = 'SCRAP' then mapped.scrap_sale_amount else 0 end), 0) as return_scrap_sale_amount,
            max(mapped.closed_at) as last_return_disposition_time
        from (
            select
                coalesce(cr.work_order_id, source_wo.id) as work_order_id,
                rd.disposition_type,
                ri.return_qty,
                rd.extra_cost_amount,
                rd.scrap_weight_kg,
                rd.scrap_sale_amount,
                rd.closed_at
            from rt_return_disposition rd
            join rt_return_item ri on ri.id = rd.return_item_id
            left join wh_stock_lot source_lot
                on source_lot.id = ri.source_lot_id
               and source_lot.source_doc_type = 'FG_RECEIPT'
            left join pp_completion_receipt_item cri on cri.id = source_lot.source_line_id
            left join pp_completion_receipt cr on cr.id = cri.completion_receipt_id
            left join pp_work_order source_wo on source_wo.source_sales_order_item_id = ri.sales_order_item_id
            where rd.status = 'CLOSED'
              and rd.closed_at <= :end_dt
        ) mapped
        where mapped.work_order_id in :work_order_ids
        group by mapped.work_order_id
        """
    ).bindparams(bindparam("work_order_ids", expanding=True))
    return_disposition_rows = db.execute(
        return_disposition_stmt,
        {"work_order_ids": work_order_ids, "end_dt": end_dt},
    ).mappings().all()
    return_disposition_map = {int(row["work_order_id"]): dict(row) for row in return_disposition_rows}

    issue_stmt = text(
        """
        select
            txn.source_doc_id as work_order_id,
            txn.item_id as material_item_id,
            coalesce(sum(abs(txn.weight_change_kg)), 0) as issued_weight_kg,
            coalesce(sum(abs(txn.amount)), 0) as issued_amount
        from wh_inventory_txn txn
        where txn.source_doc_type = 'WORK_ORDER'
          and txn.txn_type = 'MATERIAL_ISSUE'
          and txn.source_doc_id in :work_order_ids
          and txn.biz_time <= :end_dt
        group by txn.source_doc_id, txn.item_id
        """
    ).bindparams(bindparam("work_order_ids", expanding=True))
    issue_rows = db.execute(issue_stmt, {"work_order_ids": work_order_ids, "end_dt": end_dt}).mappings().all()
    issue_map: dict[tuple[int, int], dict] = {}
    for row in issue_rows:
        issue_map[(int(row["work_order_id"]), int(row["material_item_id"]))] = dict(row)

    material_stock_map: dict[int, dict] = {}
    balance_cost_map: dict[int, Decimal] = {}
    if material_item_ids:
        material_item_list = sorted(material_item_ids)

        material_stat_stmt = text(
            """
            select
                txn.item_id,
                coalesce(sum(case when txn.txn_type = 'PURCHASE_IN' then abs(txn.weight_change_kg) else 0 end), 0) as purchased_weight_kg,
                coalesce(sum(case when txn.txn_type = 'PURCHASE_IN' then abs(txn.amount) else 0 end), 0) as purchased_amount,
                coalesce(sum(case when txn.txn_type = 'MATERIAL_ISSUE' then abs(txn.weight_change_kg) else 0 end), 0) as issued_weight_kg
            from wh_inventory_txn txn
            where txn.item_id in :material_item_ids
              and txn.txn_type in ('PURCHASE_IN', 'MATERIAL_ISSUE')
              and txn.biz_time <= :end_dt
            group by txn.item_id
            """
        ).bindparams(bindparam("material_item_ids", expanding=True))
        material_stat_rows = db.execute(
            material_stat_stmt,
            {"material_item_ids": material_item_list, "end_dt": end_dt},
        ).mappings().all()
        material_stock_map = {int(row["item_id"]): dict(row) for row in material_stat_rows}

        balance_cost_stmt = text(
            """
            select
                sb.item_id,
                case
                    when sum(sb.weight_on_hand_kg) > 0 then sum(sb.avg_unit_cost * sb.weight_on_hand_kg) / sum(sb.weight_on_hand_kg)
                    else avg(sb.avg_unit_cost)
                end as avg_unit_cost
            from wh_stock_balance sb
            where sb.item_id in :material_item_ids
            group by sb.item_id
            """
        ).bindparams(bindparam("material_item_ids", expanding=True))
        for row in db.execute(balance_cost_stmt, {"material_item_ids": material_item_list}).mappings().all():
            balance_cost_map[int(row["item_id"])] = to_decimal(row["avg_unit_cost"], "0.0001")

    overhead_amounts: dict[str, Decimal] = defaultdict(lambda: Decimal("0"))
    overhead_rows = db.execute(
        text(
            """
            select
                oe.overhead_type,
                oe.amount,
                oe.description,
                ap.start_date,
                ap.end_date
            from fi_overhead_entry oe
            join fi_accounting_period ap on ap.id = oe.period_id
            where ap.end_date >= :date_from
              and ap.start_date <= :date_to
            """
        ),
        {"date_from": date_from, "date_to": date_to},
    ).mappings().all()
    for row in overhead_rows:
        normalized_key = _normalize_overhead_type(row["overhead_type"]) or "other"
        effective_date = _extract_overhead_effective_date(row.get("description"))
        if effective_date:
            if date_from <= effective_date <= date_to:
                overhead_amounts[normalized_key] += to_decimal(row["amount"], "0.01")
            continue

        period_start = row["start_date"]
        period_end = row["end_date"]
        if not period_start or not period_end:
            continue
        overlap_start = max(period_start, date_from)
        overlap_end = min(period_end, date_to)
        if overlap_start > overlap_end:
            continue
        total_days = max((period_end - period_start).days + 1, 1)
        overlap_days = (overlap_end - overlap_start).days + 1
        prorated_amount = to_decimal(row["amount"], "0.01") * Decimal(overlap_days) / Decimal(total_days)
        overhead_amounts[normalized_key] += to_decimal(prorated_amount, "0.01")

    maintenance_cost_rows = db.execute(
        text(
            """
            select
                maintenance_type,
                coalesce(sum(cost_amount), 0) as cost_amount
            from em_maintenance_order
            where status = 'COMPLETED'
              and coalesce(end_time, start_time, created_at) >= :start_dt
              and coalesce(end_time, start_time, created_at) <= :end_dt
            group by maintenance_type
            """
        ),
        {"start_dt": start_dt, "end_dt": end_dt},
    ).mappings().all()
    for row in maintenance_cost_rows:
        maintenance_type = str(row.get("maintenance_type") or "").upper()
        target_key = "mould_maintenance" if any(token in maintenance_type for token in ("MOULD", "MOLD", "模具")) else "other"
        overhead_amounts[target_key] += to_decimal(row.get("cost_amount"), "0.01")

    board_rows: list[ProductMaterialCostRowRead] = []
    row_payloads: list[dict] = []

    for base_row in base_rows:
        work_order_id = int(base_row["work_order_id"])
        report_summary = report_map.get(work_order_id, {})
        final_report_summary = final_report_map.get(work_order_id, {})
        receipt_summary = receipt_map.get(work_order_id, {})
        delivery_summary = delivery_map.get(work_order_id, {})
        scrap_summary = scrap_map.get(work_order_id, {})
        return_disposition_summary = return_disposition_map.get(work_order_id, {})
        operation_cost_summary = operation_cost_map.get(work_order_id, {})

        relevant_dates: list[datetime] = []
        if base_row.get("order_date") and date_from <= base_row["order_date"] <= date_to:
            relevant_dates.append(datetime.combine(base_row["order_date"], time.min))
        for candidate in (
            report_summary.get("last_report_time"),
            receipt_summary.get("last_receipt_time"),
            delivery_summary.get("last_delivery_date"),
            return_disposition_summary.get("last_return_disposition_time"),
        ):
            candidate_dt = _to_candidate_datetime(candidate)
            if candidate_dt and start_dt <= candidate_dt <= end_dt:
                relevant_dates.append(candidate_dt)
        if base_row.get("created_at") and start_dt <= base_row["created_at"] <= end_dt:
            relevant_dates.append(base_row["created_at"])
        if base_row.get("updated_at") and start_dt <= base_row["updated_at"] <= end_dt:
            relevant_dates.append(base_row["updated_at"])

        if not relevant_dates:
            continue

        work_order_material_rows = materials_by_work_order.get(work_order_id, [])
        material_codes: list[str] = []
        material_names: list[str] = []
        material_grades: list[str] = []
        gross_weight_kg = Decimal("0")
        net_weight_kg = Decimal("0")
        loss_rate = Decimal("0")
        purchase_material_weight = Decimal("0")
        used_material_weight = Decimal("0")
        material_inventory_weight = Decimal("0")
        material_inventory_value = Decimal("0")
        material_price_weight_total = Decimal("0")
        weighted_material_cost_sum = Decimal("0")
        scrap_price_weight_total = Decimal("0")
        weighted_scrap_sale_price_sum = Decimal("0")

        for material_row in work_order_material_rows:
            material_item_id = int(material_row["material_item_id"])
            material_codes.append(material_row.get("material_code") or "")
            material_names.append(material_row.get("material_name") or "")
            material_grades.append(material_row.get("material_grade") or "")
            gross_weight_kg += to_decimal(material_row.get("gross_weight_per_piece_kg"))
            net_weight_kg += to_decimal(material_row.get("net_weight_per_piece_kg"))
            loss_rate = max(loss_rate, to_decimal(material_row.get("loss_rate"), "0.0001"))

            issue_detail = issue_map.get((work_order_id, material_item_id), {})
            item_issue_weight = to_decimal(
                issue_detail.get("issued_weight_kg")
                if issue_detail.get("issued_weight_kg") is not None
                else material_row.get("issued_weight_kg"),
                "0.000001",
            )
            item_issue_amount = to_decimal(issue_detail.get("issued_amount"), "0.01")
            material_stats = material_stock_map.get(material_item_id, {})
            purchased_weight_total = to_decimal(material_stats.get("purchased_weight_kg"), "0.000001")
            purchased_amount_total = to_decimal(material_stats.get("purchased_amount"), "0.01")
            issued_weight_total = to_decimal(material_stats.get("issued_weight_kg"), "0.000001")
            remaining_weight_total = max(Decimal("0"), purchased_weight_total - issued_weight_total)

            if item_issue_weight > 0 and item_issue_amount > 0:
                material_unit_price = item_issue_amount / item_issue_weight
            elif purchased_weight_total > 0 and purchased_amount_total > 0:
                material_unit_price = purchased_amount_total / purchased_weight_total
            else:
                material_unit_price = balance_cost_map.get(material_item_id, Decimal("0"))

            if issued_weight_total > 0 and item_issue_weight > 0:
                allocated_remaining_weight = remaining_weight_total * item_issue_weight / issued_weight_total
            elif item_issue_weight > 0:
                allocated_remaining_weight = remaining_weight_total
            else:
                allocated_remaining_weight = Decimal("0")

            purchase_material_weight += item_issue_weight + allocated_remaining_weight
            used_material_weight += item_issue_weight
            material_inventory_weight += allocated_remaining_weight
            material_inventory_value += allocated_remaining_weight * material_unit_price
            material_price_weight_total += item_issue_weight
            weighted_material_cost_sum += material_unit_price * item_issue_weight
            scrap_sale_price = to_decimal(material_row.get("material_scrap_sale_price"), "0.0001")
            scrap_price_basis = item_issue_weight if item_issue_weight > 0 else to_decimal(
                material_row.get("required_weight_kg"), "0.000001"
            )
            if scrap_price_basis > 0:
                scrap_price_weight_total += scrap_price_basis
                weighted_scrap_sale_price_sum += scrap_sale_price * scrap_price_basis

        if gross_weight_kg <= 0 and base_row.get("product_unit_weight_kg") is not None:
            gross_weight_kg = to_decimal(base_row["product_unit_weight_kg"])
        if net_weight_kg <= 0:
            net_weight_kg = to_decimal(base_row.get("product_unit_weight_kg"))

        actual_end_time = _to_candidate_datetime(base_row.get("actual_end_time"))
        completed_before_cutoff = bool(actual_end_time and actual_end_time <= end_dt)
        disposed_scrap_qty = to_decimal(scrap_summary.get("scrap_qty"), "0.000001")
        work_order_scrap_qty = to_decimal(base_row.get("scrap_qty"), "0.000001")
        final_report_scrap_qty = to_decimal(final_report_summary.get("scrap_qty"), "0.000001")
        production_scrap_qty = first_positive_decimal(
            disposed_scrap_qty,
            final_report_scrap_qty,
            work_order_scrap_qty if completed_before_cutoff else Decimal("0"),
        )
        return_scrap_qty = to_decimal(return_disposition_summary.get("return_scrap_qty"), "0.000001")
        actual_scrap_qty = production_scrap_qty + return_scrap_qty
        receipt_qty = to_decimal(receipt_summary.get("receipt_qty"), "0.000001")
        final_report_good_qty = to_decimal(final_report_summary.get("good_qty"), "0.000001")
        effective_rework_qty = to_decimal(scrap_summary.get("rework_qty"), "0.000001")
        finished_qty = to_decimal(base_row.get("finished_qty"), "0.000001")
        actual_production_qty = first_positive_decimal(
            receipt_qty,
            final_report_good_qty + effective_rework_qty,
            finished_qty if completed_before_cutoff else Decimal("0"),
        )
        shipped_qty = to_decimal(delivery_summary.get("delivery_qty"), "0.000001")
        inventory_qty = max(Decimal("0"), actual_production_qty - shipped_qty)

        order_qty = to_decimal(base_row.get("order_qty"), "0.000001")
        if order_qty <= 0:
            order_qty = to_decimal(base_row.get("planned_qty"), "0.000001")

        untaxed_unit_price = to_decimal(base_row.get("unit_price"), "0.0001")
        material_unit_price_kg = (
            weighted_material_cost_sum / material_price_weight_total
            if material_price_weight_total > 0
            else balance_cost_map.get(
                int(work_order_material_rows[0]["material_item_id"]) if work_order_material_rows else 0,
                Decimal("0"),
            )
        )

        scrap_unit_price_kg = (
            weighted_scrap_sale_price_sum / scrap_price_weight_total
            if scrap_price_weight_total > 0
            else to_decimal(work_order_material_rows[0].get("material_scrap_sale_price"), "0.0001")
            if work_order_material_rows
            else Decimal("0")
        )
        gross_material_cost_per_piece = material_unit_price_kg * gross_weight_kg
        gross_material_total_cost = actual_production_qty * gross_material_cost_per_piece
        scrap_weight_kg = max(Decimal("0"), gross_weight_kg - net_weight_kg)
        scrap_revenue_per_piece = scrap_weight_kg * scrap_unit_price_kg
        return_scrap_sale_amount = to_decimal(return_disposition_summary.get("return_scrap_sale_amount"), "0.01")
        scrap_total_revenue = actual_production_qty * scrap_revenue_per_piece + return_scrap_sale_amount
        material_cost_per_piece = gross_material_cost_per_piece - scrap_revenue_per_piece
        material_total_cost = actual_production_qty * material_cost_per_piece
        loss_total_cost = material_total_cost * loss_rate

        labor_total_cost = to_decimal(operation_cost_summary.get("labor_amount"), "0.01")
        outsource_total_cost = to_decimal(operation_cost_summary.get("outsource_amount"), "0.01")
        labor_cost_per_piece = (labor_total_cost / actual_production_qty) if actual_production_qty > 0 else Decimal("0")
        outsource_cost_per_piece = (
            outsource_total_cost / actual_production_qty if actual_production_qty > 0 else Decimal("0")
        )

        product_cost_per_piece = material_cost_per_piece * (Decimal("1") + loss_rate) + labor_cost_per_piece + outsource_cost_per_piece

        production_rework_qty = first_positive_decimal(
            to_decimal(scrap_summary.get("rework_qty"), "0.000001"),
            to_decimal(final_report_summary.get("rework_qty"), "0.000001"),
            to_decimal(report_summary.get("rework_qty"), "0.000001"),
        )
        return_rework_qty = to_decimal(return_disposition_summary.get("return_rework_qty"), "0.000001")
        rework_qty = production_rework_qty + return_rework_qty
        production_rework_cost_total = to_decimal(scrap_summary.get("rework_cost_amount"), "0.01")
        if production_rework_cost_total <= 0 and production_rework_qty > 0:
            production_rework_cost_total = production_rework_qty * (labor_cost_per_piece + outsource_cost_per_piece)
        return_rework_cost_total = to_decimal(return_disposition_summary.get("return_rework_cost_amount"), "0.01")
        rework_cost_total = production_rework_cost_total + return_rework_cost_total
        rework_cost_per_piece = (rework_cost_total / rework_qty) if rework_qty > 0 else Decimal("0")

        scrap_residual_value_per_piece = net_weight_kg * scrap_unit_price_kg
        production_scrap_total_cost = max(Decimal("0"), product_cost_per_piece - scrap_residual_value_per_piece) * production_scrap_qty
        return_scrap_total_cost = max(Decimal("0"), product_cost_per_piece * return_scrap_qty - return_scrap_sale_amount)
        scrap_total_cost = production_scrap_total_cost + return_scrap_total_cost
        batch_adjustment_avg_cost = (
            (rework_cost_total + scrap_total_cost) / actual_production_qty if actual_production_qty > 0 else Decimal("0")
        )
        product_cost_with_adjustment_per_piece = product_cost_per_piece + batch_adjustment_avg_cost
        product_total_cost = product_cost_with_adjustment_per_piece * actual_production_qty

        material_inventory_producible_qty = (
            material_inventory_weight / gross_weight_kg if gross_weight_kg > 0 else Decimal("0")
        )
        inventory_value = inventory_qty * untaxed_unit_price
        untaxed_total_amount = actual_production_qty * untaxed_unit_price

        if material_unit_price_kg <= 0 and outsource_total_cost > 0:
            supply_mode = "外协发加工"
        elif material_unit_price_kg <= 0:
            supply_mode = "客供料"
        else:
            supply_mode = "自家料"

        biz_date = max(relevant_dates).date() if relevant_dates else None
        delivery_note_no = (
            delivery_summary.get("delivery_nos")
            or receipt_summary.get("receipt_nos")
            or base_row.get("source_order_no")
            or base_row["work_order_no"]
        )

        row_payloads.append(
            {
                "work_order_id": work_order_id,
                "work_order_no": base_row["work_order_no"],
                "biz_date": biz_date,
                "product_code": base_row.get("customer_part_no") or base_row["product_code"],
                "customer_name": base_row.get("customer_name"),
                "product_name": base_row["product_name"],
                "supply_mode": supply_mode,
                "delivery_note_no": delivery_note_no,
                "order_qty": order_qty,
                "actual_production_qty": actual_production_qty,
                "shipped_qty": shipped_qty,
                "inventory_qty": inventory_qty,
                "inventory_value": inventory_value,
                "untaxed_unit_price": untaxed_unit_price,
                "untaxed_total_amount": untaxed_total_amount,
                "purchase_material_weight_kg": purchase_material_weight,
                "used_material_weight_kg": used_material_weight,
                "material_inventory_weight_kg": material_inventory_weight,
                "material_inventory_producible_qty": material_inventory_producible_qty,
                "material_inventory_value": material_inventory_value,
                "material_grade": _join_distinct(material_grades),
                "material_unit_price_kg": material_unit_price_kg,
                "gross_weight_g": gross_weight_kg * Decimal("1000"),
                "gross_material_cost_per_piece": gross_material_cost_per_piece,
                "gross_material_total_cost": gross_material_total_cost,
                "net_weight_g": net_weight_kg * Decimal("1000"),
                "scrap_weight_g": scrap_weight_kg * Decimal("1000"),
                "scrap_unit_price_kg": scrap_unit_price_kg,
                "scrap_revenue_per_piece": scrap_revenue_per_piece,
                "scrap_total_revenue": scrap_total_revenue,
                "material_cost_per_piece": material_cost_per_piece,
                "material_total_cost": material_total_cost,
                "loss_rate": loss_rate,
                "loss_total_cost": loss_total_cost,
                "labor_cost_per_piece": labor_cost_per_piece,
                "labor_total_cost": labor_total_cost,
                "outsource_cost_per_piece": outsource_cost_per_piece,
                "outsource_total_cost": outsource_total_cost,
                "product_cost_per_piece": product_cost_per_piece,
                "product_cost_with_adjustment_per_piece": product_cost_with_adjustment_per_piece,
                "product_total_cost": product_total_cost,
                "rework_qty": rework_qty,
                "rework_cost_per_piece": rework_cost_per_piece,
                "rework_total_cost": rework_cost_total,
                "scrap_qty": actual_scrap_qty,
                "scrap_residual_value_per_piece": scrap_residual_value_per_piece,
                "scrap_total_cost": scrap_total_cost,
                "batch_adjustment_avg_cost": batch_adjustment_avg_cost,
            }
        )

    row_payloads.sort(
        key=lambda row: (
            row["biz_date"] or date.min,
            row["work_order_no"],
        ),
        reverse=True,
    )

    for index, payload in enumerate(row_payloads, start=1):
        board_rows.append(
            ProductMaterialCostRowRead(
                work_order_id=payload["work_order_id"],
                work_order_no=payload["work_order_no"],
                row_no=index,
                biz_date=payload["biz_date"],
                product_code=payload["product_code"],
                customer_name=payload["customer_name"],
                product_name=payload["product_name"],
                supply_mode=payload["supply_mode"],
                delivery_note_no=payload["delivery_note_no"],
                order_qty=_to_float(payload["order_qty"], "0.000001"),
                actual_production_qty=_to_float(payload["actual_production_qty"], "0.000001"),
                shipped_qty=_to_float(payload["shipped_qty"], "0.000001"),
                inventory_qty=_to_float(payload["inventory_qty"], "0.000001"),
                inventory_value=_to_float(payload["inventory_value"], "0.01"),
                untaxed_unit_price=_to_float(payload["untaxed_unit_price"], "0.0001"),
                untaxed_total_amount=_to_float(payload["untaxed_total_amount"], "0.01"),
                purchase_material_weight_kg=_to_float(payload["purchase_material_weight_kg"], "0.000001"),
                used_material_weight_kg=_to_float(payload["used_material_weight_kg"], "0.000001"),
                material_inventory_weight_kg=_to_float(payload["material_inventory_weight_kg"], "0.000001"),
                material_inventory_producible_qty=_to_float(payload["material_inventory_producible_qty"], "0.000001"),
                material_inventory_value=_to_float(payload["material_inventory_value"], "0.01"),
                material_grade=payload["material_grade"],
                material_unit_price_kg=_to_float(payload["material_unit_price_kg"], "0.0001"),
                gross_weight_g=_to_float(payload["gross_weight_g"], "0.001"),
                gross_material_cost_per_piece=_to_float(payload["gross_material_cost_per_piece"], "0.0001"),
                gross_material_total_cost=_to_float(payload["gross_material_total_cost"], "0.01"),
                net_weight_g=_to_float(payload["net_weight_g"], "0.001"),
                scrap_weight_g=_to_float(payload["scrap_weight_g"], "0.001"),
                scrap_unit_price_kg=_to_float(payload["scrap_unit_price_kg"], "0.0001"),
                scrap_revenue_per_piece=_to_float(payload["scrap_revenue_per_piece"], "0.0001"),
                scrap_total_revenue=_to_float(payload["scrap_total_revenue"], "0.01"),
                material_cost_per_piece=_to_float(payload["material_cost_per_piece"], "0.0001"),
                material_total_cost=_to_float(payload["material_total_cost"], "0.01"),
                loss_rate=_to_float(payload["loss_rate"], "0.0001"),
                loss_total_cost=_to_float(payload["loss_total_cost"], "0.01"),
                labor_cost_per_piece=_to_float(payload["labor_cost_per_piece"], "0.0001"),
                labor_total_cost=_to_float(payload["labor_total_cost"], "0.01"),
                outsource_cost_per_piece=_to_float(payload["outsource_cost_per_piece"], "0.0001"),
                outsource_total_cost=_to_float(payload["outsource_total_cost"], "0.01"),
                product_cost_per_piece=_to_float(payload["product_cost_per_piece"], "0.0001"),
                product_cost_with_adjustment_per_piece=_to_float(
                    payload["product_cost_with_adjustment_per_piece"], "0.0001"
                ),
                product_total_cost=_to_float(payload["product_total_cost"], "0.01"),
                rework_qty=_to_float(payload["rework_qty"], "0.000001"),
                rework_cost_per_piece=_to_float(payload["rework_cost_per_piece"], "0.0001"),
                rework_total_cost=_to_float(payload["rework_total_cost"], "0.01"),
                scrap_qty=_to_float(payload["scrap_qty"], "0.000001"),
                scrap_residual_value_per_piece=_to_float(payload["scrap_residual_value_per_piece"], "0.0001"),
                scrap_total_cost=_to_float(payload["scrap_total_cost"], "0.01"),
                batch_adjustment_avg_cost=_to_float(payload["batch_adjustment_avg_cost"], "0.0001"),
            )
        )

    sales_total = sum(to_decimal(row.untaxed_total_amount, "0.01") for row in board_rows)
    gross_material_total = sum(to_decimal(row.gross_material_total_cost, "0.01") for row in board_rows)
    scrap_revenue_total = sum(to_decimal(row.scrap_total_revenue, "0.01") for row in board_rows)
    material_cost_total = sum(to_decimal(row.material_total_cost, "0.01") for row in board_rows)
    material_loss_total = sum(to_decimal(row.loss_total_cost, "0.01") for row in board_rows)
    labor_total = sum(to_decimal(row.labor_total_cost, "0.01") for row in board_rows)
    outsource_total = sum(to_decimal(row.outsource_total_cost, "0.01") for row in board_rows)
    rework_total = sum(to_decimal(row.rework_total_cost, "0.01") for row in board_rows)
    scrap_total = sum(to_decimal(row.scrap_total_cost, "0.01") for row in board_rows)
    direct_cost_total = sum(to_decimal(row.product_total_cost, "0.01") for row in board_rows)

    expense_amounts: dict[str, Decimal] = defaultdict(lambda: Decimal("0"))
    expense_amounts["material_usage_value"] = material_cost_total
    expense_amounts["material_loss_value"] = material_loss_total
    expense_amounts["operator_wage"] = labor_total if labor_total > 0 else overhead_amounts.get("operator_wage", Decimal("0"))
    expense_amounts["manager_wage"] = overhead_amounts.get("manager_wage", Decimal("0"))
    expense_amounts["finance_charge"] = overhead_amounts.get("finance_charge", Decimal("0"))
    expense_amounts["mould_maintenance"] = overhead_amounts.get("mould_maintenance", Decimal("0"))
    expense_amounts["outsource_process"] = (
        outsource_total if outsource_total > 0 else overhead_amounts.get("outsource_process", Decimal("0"))
    )
    expense_amounts["production_packaging"] = overhead_amounts.get("production_packaging", Decimal("0"))
    expense_amounts["equipment_depreciation"] = overhead_amounts.get("equipment_depreciation", Decimal("0"))
    expense_amounts["utility"] = overhead_amounts.get("utility", Decimal("0"))
    expense_amounts["office_supplies"] = overhead_amounts.get("office_supplies", Decimal("0"))
    expense_amounts["factory_rent"] = overhead_amounts.get("factory_rent", Decimal("0"))
    expense_amounts["temporary_wage"] = overhead_amounts.get("temporary_wage", Decimal("0"))
    expense_amounts["staff_welfare"] = overhead_amounts.get("staff_welfare", Decimal("0"))
    expense_amounts["social_insurance"] = overhead_amounts.get("social_insurance", Decimal("0"))
    expense_amounts["cash_misc"] = overhead_amounts.get("cash_misc", Decimal("0"))
    expense_amounts["other"] = overhead_amounts.get("other", Decimal("0")) + rework_total + scrap_total

    profit_amount = sales_total - sum(expense_amounts.values())
    overhead_total = sum(overhead_amounts.values())
    cost_ratio = (sales_total - profit_amount) / sales_total if sales_total > 0 else Decimal("0")

    return ProductMaterialCostBoardRead(
        title="冲压产品材料成本核算表",
        date_from=date_from,
        date_to=date_to,
        generated_at=datetime.now(),
        rows=board_rows,
        expense_rows=_build_finance_expense_rows(expense_amounts),
        summary=ProductMaterialCostSummaryRead(
            row_count=len(board_rows),
            sales_total=_to_float(sales_total, "0.01"),
            gross_material_total=_to_float(gross_material_total, "0.01"),
            scrap_revenue_total=_to_float(scrap_revenue_total, "0.01"),
            material_cost_total=_to_float(material_cost_total, "0.01"),
            material_loss_total=_to_float(material_loss_total, "0.01"),
            labor_total=_to_float(labor_total, "0.01"),
            outsource_total=_to_float(outsource_total, "0.01"),
            rework_total=_to_float(rework_total, "0.01"),
            scrap_total=_to_float(scrap_total, "0.01"),
            overhead_total=_to_float(overhead_total, "0.01"),
            direct_cost_total=_to_float(direct_cost_total, "0.01"),
            profit_amount=_to_float(profit_amount, "0.01"),
            cost_ratio=_to_float(cost_ratio, "0.0001"),
        ),
    )


def get_cost_allocation_rows(db: Session, period_id: int | None = None, limit: int = 100) -> list[CostAllocationRead]:
    stmt = (
        select(
            CostAllocation.id.label("cost_allocation_id"),
            CostAllocation.period_id.label("period_id"),
            AccountingPeriod.period_code.label("period_code"),
            CostAllocation.work_order_id.label("work_order_id"),
            WorkOrder.work_order_no.label("work_order_no"),
            CostAllocation.product_item_id.label("product_item_id"),
            Item.item_code.label("product_code"),
            Item.item_name.label("product_name"),
            CostAllocation.allocation_basis_value.label("allocation_basis_value"),
            CostAllocation.overhead_amount.label("overhead_amount"),
            CostAllocation.material_amount.label("material_amount"),
            CostAllocation.labor_amount.label("labor_amount"),
            CostAllocation.machine_amount.label("machine_amount"),
            CostAllocation.abnormal_loss_amount.label("abnormal_loss_amount"),
            CostAllocation.total_cost_amount.label("total_cost_amount"),
            CostAllocation.unit_cost.label("unit_cost"),
        )
        .join(AccountingPeriod, AccountingPeriod.id == CostAllocation.period_id)
        .join(WorkOrder, WorkOrder.id == CostAllocation.work_order_id)
        .join(Item, Item.id == CostAllocation.product_item_id)
        .order_by(CostAllocation.id.desc())
        .limit(limit)
    )
    if period_id:
        stmt = stmt.where(CostAllocation.period_id == period_id)
    rows = db.execute(stmt).mappings().all()
    return [CostAllocationRead.model_validate(dict(row)) for row in rows]


def create_rework_work_order(
    db: Session,
    *,
    product_item_id: int,
    planned_qty: Decimal,
    remark: str | None,
) -> WorkOrder:
    route = get_default_route(db, product_item_id)
    bom = get_default_bom(db, product_item_id)
    product = db.get(Item, product_item_id)
    if not product:
        raise HTTPException(status_code=404, detail="返工工单产品不存在")
    work_order = WorkOrder(
        work_order_no=build_yearly_product_work_order_no(db, product),
        work_order_type="REWORK",
        source_sales_order_item_id=None,
        product_item_id=product_item_id,
        route_id=route.id,
        bom_id=bom.id,
        planned_qty=planned_qty,
        released_qty=planned_qty,
        finished_qty=to_decimal(0),
        scrap_qty=to_decimal(0),
        planned_start_time=datetime.now(),
        planned_end_time=None,
        actual_start_time=None,
        actual_end_time=None,
        priority_level=2,
        status="RELEASED",
        remark=remark,
    )
    db.add(work_order)
    db.flush()
    create_work_order_materials_and_operations(
        db,
        work_order=work_order,
        bom=bom,
        route=route,
        auto_issue_materials=False,
        operator_user_id=None,
    )
    return work_order


def get_purchase_order_query(limit: int = 50) -> Select:
    receipt_item_subquery = (
        select(
            PurchaseReceiptItem.purchase_order_item_id.label("purchase_order_item_id"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "PASSED", PurchaseReceiptItem.accepted_qty), else_=0)), 0).label("accepted_qty"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "PASSED", PurchaseReceiptItem.accepted_weight_kg), else_=0)), 0).label("accepted_weight_kg"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "PENDING_QC", 1), else_=0)), 0).label("pending_count"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "PASSED", 1), else_=0)), 0).label("passed_count"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "REJECTED", 1), else_=0)), 0).label("rejected_count"),
        )
        .group_by(PurchaseReceiptItem.purchase_order_item_id)
        .subquery()
    )
    return_item_subquery = (
        select(
            PurchaseReturnItem.purchase_order_item_id.label("purchase_order_item_id"),
            func.coalesce(func.sum(PurchaseReturnItem.return_weight_kg), 0).label("returned_weight_kg"),
        )
        .join(PurchaseReturn, PurchaseReturn.id == PurchaseReturnItem.purchase_return_id)
        .where(PurchaseReturn.status != "CANCELED", PurchaseReturnItem.status != "CANCELED")
        .group_by(PurchaseReturnItem.purchase_order_item_id)
        .subquery()
    )
    line_subquery = (
        select(
            PurchaseOrderItem.purchase_order_id.label("purchase_order_id"),
            func.count(PurchaseOrderItem.id).label("line_count"),
            func.coalesce(func.sum(PurchaseOrderItem.order_qty), 0).label("total_order_qty"),
            func.coalesce(func.sum(PurchaseOrderItem.order_weight_kg), 0).label("total_order_weight_kg"),
            func.coalesce(func.sum(receipt_item_subquery.c.accepted_qty), 0).label("total_received_qty"),
            func.coalesce(func.sum(receipt_item_subquery.c.accepted_weight_kg), 0).label("total_received_weight_kg"),
            func.coalesce(func.sum(return_item_subquery.c.returned_weight_kg), 0).label("total_return_weight_kg"),
            func.coalesce(func.sum(receipt_item_subquery.c.pending_count), 0).label("pending_qc_count"),
            func.coalesce(func.sum(receipt_item_subquery.c.passed_count), 0).label("passed_count"),
            func.coalesce(func.sum(receipt_item_subquery.c.rejected_count), 0).label("rejected_count"),
            func.count(func.distinct(SalesOrder.id)).label("source_order_count"),
            literal(None).label("source_order_nos"),
        )
        .outerjoin(receipt_item_subquery, receipt_item_subquery.c.purchase_order_item_id == PurchaseOrderItem.id)
        .outerjoin(return_item_subquery, return_item_subquery.c.purchase_order_item_id == PurchaseOrderItem.id)
        .outerjoin(MaterialDemand, MaterialDemand.id == PurchaseOrderItem.source_demand_id)
        .outerjoin(SalesOrderItem, SalesOrderItem.id == MaterialDemand.sales_order_item_id)
        .outerjoin(SalesOrder, SalesOrder.id == SalesOrderItem.sales_order_id)
        .group_by(PurchaseOrderItem.purchase_order_id)
        .subquery()
    )
    latest_archive_version_subquery = (
        select(
            DocumentArchive.business_id.label("business_id"),
            func.max(DocumentArchive.archive_version).label("archive_version"),
        )
        .where(DocumentArchive.document_type == "采购订单", DocumentArchive.file_format == "PDF")
        .group_by(DocumentArchive.business_id)
        .subquery()
    )
    latest_archive_id_subquery = (
        select(
            DocumentArchive.business_id.label("business_id"),
            func.max(DocumentArchive.id).label("archive_id"),
        )
        .join(
            latest_archive_version_subquery,
            and_(
                latest_archive_version_subquery.c.business_id == DocumentArchive.business_id,
                latest_archive_version_subquery.c.archive_version == DocumentArchive.archive_version,
            ),
        )
        .where(DocumentArchive.document_type == "采购订单", DocumentArchive.file_format == "PDF")
        .group_by(DocumentArchive.business_id)
        .subquery()
    )
    latest_archive_subquery = (
        select(
            DocumentArchive.business_id.label("business_id"),
            DocumentArchive.status.label("archive_status"),
            DocumentArchive.archive_version.label("archive_version"),
            DocumentArchive.created_at.label("archive_created_at"),
            DocumentArchive.error_message.label("archive_error_message"),
        )
        .join(
            latest_archive_id_subquery,
            latest_archive_id_subquery.c.archive_id == DocumentArchive.id,
        )
        .where(DocumentArchive.document_type == "采购订单", DocumentArchive.file_format == "PDF")
        .subquery()
    )
    total_order_qty = func.coalesce(line_subquery.c.total_order_qty, 0)
    total_order_weight = func.coalesce(line_subquery.c.total_order_weight_kg, 0)
    total_received_qty = func.coalesce(line_subquery.c.total_received_qty, 0)
    total_received_weight = func.coalesce(line_subquery.c.total_received_weight_kg, 0)
    total_return_weight = func.coalesce(line_subquery.c.total_return_weight_kg, 0)
    pending_qc_count = func.coalesce(line_subquery.c.pending_qc_count, 0)
    rejected_count = func.coalesce(line_subquery.c.rejected_count, 0)
    display_status = case(
        (pending_qc_count > 0, "PENDING_QC"),
        (and_(total_order_qty > 0, total_received_qty >= total_order_qty), "RECEIVED"),
        (total_received_qty > 0, "PARTIAL_RECEIVED"),
        (and_(total_order_weight > 0, total_received_weight >= total_order_weight), "RECEIVED"),
        (total_received_weight > 0, "PARTIAL_RECEIVED"),
        (rejected_count > 0, "REJECTED"),
        else_=PurchaseOrder.status,
    )
    purchaser = aliased(Employee)
    return (
        select(
            PurchaseOrder.id.label("purchase_order_id"),
            PurchaseOrder.po_no.label("po_no"),
            case(
                (func.coalesce(line_subquery.c.source_order_count, 0) > 0, "SALES_ORDER"),
                else_="STOCKING",
            ).label("source_type"),
            line_subquery.c.source_order_nos.label("source_order_nos"),
            PurchaseOrder.supplier_id.label("supplier_id"),
            Supplier.supplier_code.label("supplier_code"),
            Supplier.supplier_name.label("supplier_name"),
            PurchaseOrder.order_date.label("order_date"),
            PurchaseOrder.expected_date.label("expected_date"),
            PurchaseOrder.warning_lead_days.label("warning_lead_days"),
            PurchaseOrder.purchaser_employee_id.label("purchaser_employee_id"),
            purchaser.employee_name.label("purchaser_name"),
            PurchaseOrder.target_warehouse_type.label("target_warehouse_type"),
            PurchaseOrder.tax_rate.label("tax_rate"),
            PurchaseOrder.total_amount.label("total_amount"),
            PurchaseOrder.status.label("status"),
            display_status.label("display_status"),
            PurchaseOrder.remark.label("remark"),
            func.coalesce(line_subquery.c.line_count, 0).label("line_count"),
            total_order_qty.label("total_order_qty"),
            total_order_weight.label("total_order_weight_kg"),
            total_received_qty.label("total_received_qty"),
            total_received_weight.label("total_received_weight_kg"),
            (total_return_weight > 0).label("has_return"),
            total_return_weight.label("total_return_weight_kg"),
            func.coalesce(latest_archive_subquery.c.archive_status, "未生成").label("archive_status"),
            latest_archive_subquery.c.archive_version.label("archive_version"),
            latest_archive_subquery.c.archive_created_at.label("archive_created_at"),
            latest_archive_subquery.c.archive_error_message.label("archive_error_message"),
        )
        .join(Supplier, Supplier.id == PurchaseOrder.supplier_id)
        .outerjoin(purchaser, purchaser.id == PurchaseOrder.purchaser_employee_id)
        .outerjoin(line_subquery, line_subquery.c.purchase_order_id == PurchaseOrder.id)
        .outerjoin(latest_archive_subquery, latest_archive_subquery.c.business_id == PurchaseOrder.id)
        .order_by(PurchaseOrder.id.desc())
        .limit(limit)
    )


def get_purchase_order_items_query(limit: int = 100, purchase_order_id: int | None = None) -> Select:
    receipt_item_subquery = (
        select(
            PurchaseReceiptItem.purchase_order_item_id.label("purchase_order_item_id"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "PASSED", PurchaseReceiptItem.accepted_qty), else_=0)), 0).label("accepted_qty"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "PASSED", PurchaseReceiptItem.accepted_weight_kg), else_=0)), 0).label("accepted_weight_kg"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "PENDING_QC", 1), else_=0)), 0).label("pending_count"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "REJECTED", 1), else_=0)), 0).label("rejected_count"),
        )
        .group_by(PurchaseReceiptItem.purchase_order_item_id)
        .subquery()
    )
    return_item_subquery = (
        select(
            PurchaseReturnItem.purchase_order_item_id.label("purchase_order_item_id"),
            func.coalesce(func.sum(PurchaseReturnItem.return_weight_kg), 0).label("returned_weight_kg"),
        )
        .join(PurchaseReturn, PurchaseReturn.id == PurchaseReturnItem.purchase_return_id)
        .where(PurchaseReturn.status != "CANCELED", PurchaseReturnItem.status != "CANCELED")
        .group_by(PurchaseReturnItem.purchase_order_item_id)
        .subquery()
    )
    accepted_qty = func.coalesce(receipt_item_subquery.c.accepted_qty, 0)
    accepted_weight = func.coalesce(receipt_item_subquery.c.accepted_weight_kg, 0)
    returned_weight = func.coalesce(return_item_subquery.c.returned_weight_kg, 0)
    net_received_weight = case((accepted_weight - returned_weight < 0, 0), else_=accepted_weight - returned_weight)
    item_display_status = case(
        (func.coalesce(receipt_item_subquery.c.pending_count, 0) > 0, "PENDING_QC"),
        (and_(PurchaseOrderItem.order_qty > 0, accepted_qty >= PurchaseOrderItem.order_qty), "CLOSED"),
        (accepted_qty > 0, "PARTIAL_RECEIVED"),
        (and_(PurchaseOrderItem.order_weight_kg > 0, accepted_weight >= PurchaseOrderItem.order_weight_kg), "CLOSED"),
        (accepted_weight > 0, "PARTIAL_RECEIVED"),
        (func.coalesce(receipt_item_subquery.c.rejected_count, 0) > 0, "REJECTED"),
        else_=PurchaseOrderItem.status,
    )
    stmt = (
        select(
            PurchaseOrderItem.id.label("purchase_order_item_id"),
            PurchaseOrderItem.purchase_order_id.label("purchase_order_id"),
            PurchaseOrder.po_no.label("po_no"),
            PurchaseOrderItem.line_no.label("line_no"),
            PurchaseOrderItem.material_item_id.label("material_item_id"),
            Item.item_code.label("material_code"),
            Item.item_name.label("material_name"),
            Item.specification.label("specification"),
            Item.material_grade.label("material_grade"),
            Material.quality_rule.label("performance_requirement"),
            Material.purchase_calc_mode.label("purchase_calc_mode"),
            PurchaseOrderItem.source_demand_id.label("source_demand_id"),
            PurchaseOrderItem.order_qty.label("order_qty"),
            PurchaseOrderItem.order_weight_kg.label("order_weight_kg"),
            accepted_qty.label("received_qty"),
            accepted_weight.label("received_weight_kg"),
            returned_weight.label("returned_weight_kg"),
            net_received_weight.label("net_received_weight_kg"),
            (returned_weight > 0).label("has_return"),
            PurchaseOrderItem.unit_price.label("unit_price"),
            PurchaseOrderItem.line_amount.label("line_amount"),
            PurchaseOrderItem.status.label("status"),
            item_display_status.label("display_status"),
            PurchaseOrderItem.remark.label("remark"),
        )
        .join(PurchaseOrder, PurchaseOrder.id == PurchaseOrderItem.purchase_order_id)
        .join(Item, Item.id == PurchaseOrderItem.material_item_id)
        .outerjoin(Material, Material.item_id == PurchaseOrderItem.material_item_id)
        .outerjoin(receipt_item_subquery, receipt_item_subquery.c.purchase_order_item_id == PurchaseOrderItem.id)
        .outerjoin(return_item_subquery, return_item_subquery.c.purchase_order_item_id == PurchaseOrderItem.id)
        .order_by(PurchaseOrderItem.id.desc())
        .limit(limit)
    )
    if purchase_order_id:
        stmt = stmt.where(PurchaseOrderItem.purchase_order_id == purchase_order_id)
    return stmt


def get_purchase_receipt_query(limit: int = 50) -> Select:
    line_subquery = (
        select(
            PurchaseReceiptItem.receipt_id.label("receipt_id"),
            func.count(PurchaseReceiptItem.id).label("line_count"),
            func.coalesce(func.sum(PurchaseReceiptItem.received_qty), 0).label("total_received_qty"),
            func.coalesce(func.sum(PurchaseReceiptItem.received_weight_kg), 0).label("total_received_weight_kg"),
            func.group_concat(func.distinct(Item.item_name)).label("material_names"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "PENDING_QC", 1), else_=0)), 0).label("pending_count"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "PASSED", 1), else_=0)), 0).label("passed_count"),
            func.coalesce(func.sum(case((PurchaseReceiptItem.status == "REJECTED", 1), else_=0)), 0).label("rejected_count"),
        )
        .join(Item, Item.id == PurchaseReceiptItem.material_item_id)
        .group_by(PurchaseReceiptItem.receipt_id)
        .subquery()
    )
    line_count = func.coalesce(line_subquery.c.line_count, 0)
    pending_count = func.coalesce(line_subquery.c.pending_count, 0)
    passed_count = func.coalesce(line_subquery.c.passed_count, 0)
    rejected_count = func.coalesce(line_subquery.c.rejected_count, 0)
    receipt_status = case(
        (line_count <= 0, PurchaseReceipt.status),
        (pending_count > 0, "PENDING_QC"),
        (passed_count == line_count, "PASSED"),
        (rejected_count == line_count, "REJECTED"),
        (passed_count + rejected_count == line_count, "PARTIAL"),
        else_=PurchaseReceipt.status,
    )
    latest_archive_version_subquery = (
        select(
            DocumentArchive.business_id.label("business_id"),
            func.max(DocumentArchive.archive_version).label("archive_version"),
        )
        .where(DocumentArchive.document_type == "到货入库单", DocumentArchive.file_format == "PDF")
        .group_by(DocumentArchive.business_id)
        .subquery()
    )
    latest_archive_id_subquery = (
        select(
            DocumentArchive.business_id.label("business_id"),
            func.max(DocumentArchive.id).label("archive_id"),
        )
        .join(
            latest_archive_version_subquery,
            and_(
                latest_archive_version_subquery.c.business_id == DocumentArchive.business_id,
                latest_archive_version_subquery.c.archive_version == DocumentArchive.archive_version,
            ),
        )
        .where(DocumentArchive.document_type == "到货入库单", DocumentArchive.file_format == "PDF")
        .group_by(DocumentArchive.business_id)
        .subquery()
    )
    latest_archive_subquery = (
        select(
            DocumentArchive.business_id.label("business_id"),
            DocumentArchive.status.label("archive_status"),
            DocumentArchive.archive_version.label("archive_version"),
            DocumentArchive.created_at.label("archive_created_at"),
            DocumentArchive.error_message.label("archive_error_message"),
        )
        .join(
            latest_archive_id_subquery,
            latest_archive_id_subquery.c.archive_id == DocumentArchive.id,
        )
        .where(DocumentArchive.document_type == "到货入库单", DocumentArchive.file_format == "PDF")
        .subquery()
    )
    receiver = aliased(Employee)
    return (
        select(
            PurchaseReceipt.id.label("receipt_id"),
            PurchaseReceipt.receipt_no.label("receipt_no"),
            PurchaseReceipt.purchase_order_id.label("purchase_order_id"),
            PurchaseOrder.po_no.label("po_no"),
            PurchaseOrder.supplier_id.label("supplier_id"),
            Supplier.supplier_name.label("supplier_name"),
            PurchaseReceipt.warehouse_id.label("warehouse_id"),
            Warehouse.warehouse_name.label("warehouse_name"),
            PurchaseOrder.target_warehouse_type.label("target_warehouse_type"),
            PurchaseReceipt.receipt_date.label("receipt_date"),
            PurchaseReceipt.receiver_employee_id.label("receiver_employee_id"),
            receiver.employee_name.label("receiver_name"),
            PurchaseReceipt.supplier_delivery_no.label("supplier_delivery_no"),
            PurchaseReceipt.logistics_waybill_no.label("logistics_waybill_no"),
            PurchaseReceipt.logistics_freight_amount.label("logistics_freight_amount"),
            PurchaseReceipt.logistics_photo_url.label("logistics_photo_url"),
            line_subquery.c.material_names.label("material_names"),
            receipt_status.label("status"),
            PurchaseReceipt.remark.label("remark"),
            func.coalesce(line_subquery.c.line_count, 0).label("line_count"),
            func.coalesce(line_subquery.c.total_received_qty, 0).label("total_received_qty"),
            func.coalesce(line_subquery.c.total_received_weight_kg, 0).label("total_received_weight_kg"),
            func.coalesce(latest_archive_subquery.c.archive_status, "未生成").label("archive_status"),
            latest_archive_subquery.c.archive_version.label("archive_version"),
            latest_archive_subquery.c.archive_created_at.label("archive_created_at"),
            latest_archive_subquery.c.archive_error_message.label("archive_error_message"),
        )
        .join(PurchaseOrder, PurchaseOrder.id == PurchaseReceipt.purchase_order_id)
        .join(Supplier, Supplier.id == PurchaseOrder.supplier_id)
        .join(Warehouse, Warehouse.id == PurchaseReceipt.warehouse_id)
        .outerjoin(receiver, receiver.id == PurchaseReceipt.receiver_employee_id)
        .outerjoin(line_subquery, line_subquery.c.receipt_id == PurchaseReceipt.id)
        .outerjoin(latest_archive_subquery, latest_archive_subquery.c.business_id == PurchaseReceipt.id)
        .order_by(PurchaseReceipt.id.desc())
        .limit(limit)
    )


def get_purchase_receipt_items_query(limit: int = 100, receipt_id: int | None = None) -> Select:
    stmt = (
        select(
            PurchaseReceiptItem.id.label("receipt_item_id"),
            PurchaseReceiptItem.receipt_id.label("receipt_id"),
            PurchaseReceipt.receipt_no.label("receipt_no"),
            PurchaseReceiptItem.line_no.label("line_no"),
            PurchaseReceiptItem.purchase_order_item_id.label("purchase_order_item_id"),
            PurchaseReceiptItem.material_item_id.label("material_item_id"),
            Item.item_code.label("material_code"),
            Item.item_name.label("material_name"),
            PurchaseReceipt.warehouse_id.label("warehouse_id"),
            Warehouse.warehouse_name.label("warehouse_name"),
            PurchaseReceiptItem.location_id.label("location_id"),
            WarehouseLocation.location_name.label("location_name"),
            PurchaseReceiptItem.lot_no.label("lot_no"),
            PurchaseReceiptItem.received_qty.label("received_qty"),
            PurchaseReceiptItem.received_weight_kg.label("received_weight_kg"),
            PurchaseReceiptItem.accepted_qty.label("accepted_qty"),
            PurchaseReceiptItem.accepted_weight_kg.label("accepted_weight_kg"),
            PurchaseReceiptItem.unit_cost.label("unit_cost"),
            PurchaseReceiptItem.status.label("status"),
            case(
                (PurchaseReceiptItem.status == "PENDING_QC", "PENDING_QC"),
                (PurchaseReceiptItem.status == "PASSED", "PASS"),
                (PurchaseReceiptItem.status == "REJECTED", "REJECT"),
                else_=func.coalesce(StockLot.quality_status, "PENDING_QC"),
            ).label("quality_status"),
            PurchaseReceiptItem.remark.label("remark"),
        )
        .join(PurchaseReceipt, PurchaseReceipt.id == PurchaseReceiptItem.receipt_id)
        .join(Warehouse, Warehouse.id == PurchaseReceipt.warehouse_id)
        .join(Item, Item.id == PurchaseReceiptItem.material_item_id)
        .outerjoin(WarehouseLocation, WarehouseLocation.id == PurchaseReceiptItem.location_id)
        .outerjoin(
            StockLot,
            or_(
                and_(
                    StockLot.source_doc_type == "PURCHASE_RECEIPT",
                    StockLot.source_doc_id == PurchaseReceiptItem.receipt_id,
                    StockLot.source_line_id == PurchaseReceiptItem.id,
                ),
                StockLot.id == PurchaseReceiptItem.merge_to_lot_id,
            ),
        )
        .order_by(PurchaseReceiptItem.id.desc())
        .limit(limit)
    )
    if receipt_id:
        stmt = stmt.where(PurchaseReceiptItem.receipt_id == receipt_id)
    return stmt


def sync_purchase_receipt_status(db: Session, receipt_id: int) -> str | None:
    receipt = db.get(PurchaseReceipt, receipt_id)
    if not receipt:
        return None

    statuses = [
        str(status or "").upper()
        for status in db.scalars(
            select(PurchaseReceiptItem.status).where(PurchaseReceiptItem.receipt_id == receipt_id)
        ).all()
    ]
    if not statuses:
        return receipt.status

    if any(status == "PENDING_QC" for status in statuses):
        next_status = "PENDING_QC"
    elif all(status == "PASSED" for status in statuses):
        next_status = "PASSED"
    elif all(status == "REJECTED" for status in statuses):
        next_status = "REJECTED"
    elif all(status in {"PASSED", "REJECTED"} for status in statuses):
        next_status = "PARTIAL"
    else:
        next_status = receipt.status

    receipt.status = next_status
    db.add(receipt)
    return next_status


def get_stock_lots_query(limit: int = 100, item_type: str | None = None) -> Select:
    source_material_lot = aliased(StockLot)
    stmt = (
        select(
            StockLot.id.label("lot_id"),
            StockLot.lot_no.label("lot_no"),
            StockLot.parent_lot_id.label("parent_lot_id"),
            StockLot.lot_role.label("lot_role"),
            StockLot.material_sub_batch_no.label("material_sub_batch_no"),
            StockLot.item_id.label("item_id"),
            Item.item_code.label("item_code"),
            Item.item_name.label("item_name"),
            Item.item_type.label("item_type"),
            Item.specification.label("specification"),
            StockLot.warehouse_id.label("warehouse_id"),
            Warehouse.warehouse_name.label("warehouse_name"),
            Warehouse.warehouse_type.label("warehouse_type"),
            StockLot.location_id.label("location_id"),
            WarehouseLocation.location_name.label("location_name"),
            StockLot.source_doc_type.label("source_doc_type"),
            StockLot.source_doc_id.label("source_doc_id"),
            StockLot.source_line_id.label("source_line_id"),
            PurchaseReceipt.receipt_no.label("source_receipt_no"),
            PurchaseOrder.po_no.label("source_purchase_order_no"),
            StockLot.source_material_lot_id.label("source_material_lot_id"),
            func.coalesce(source_material_lot.lot_no, StockLot.source_material_sub_batch_no).label(
                "source_material_lot_no"
            ),
            StockLot.source_material_sub_batch_no.label("source_material_sub_batch_no"),
            StockLot.source_material_summary.label("source_material_summary"),
            StockLot.logistics_waybill_no.label("logistics_waybill_no"),
            StockLot.logistics_freight_amount.label("logistics_freight_amount"),
            StockLot.logistics_photo_url.label("logistics_photo_url"),
            case((Warehouse.warehouse_type.in_(("RAW", "SCRAP")), literal(0)), else_=StockLot.inbound_qty).label("inbound_qty"),
            StockLot.inbound_weight_kg.label("inbound_weight_kg"),
            case((Warehouse.warehouse_type.in_(("RAW", "SCRAP")), literal(0)), else_=StockLot.remaining_qty).label("remaining_qty"),
            StockLot.remaining_weight_kg.label("remaining_weight_kg"),
            case((Warehouse.warehouse_type.in_(("RAW", "SCRAP")), literal(0)), else_=StockLot.locked_qty).label("locked_qty"),
            StockLot.locked_weight_kg.label("locked_weight_kg"),
            StockLot.unit_cost.label("unit_cost"),
            StockLot.quality_status.label("quality_status"),
            StockLot.remark.label("quality_user_name"),
            StockLot.status.label("status"),
            StockLot.created_at.label("created_at"),
        )
        .join(Item, Item.id == StockLot.item_id)
        .join(Warehouse, Warehouse.id == StockLot.warehouse_id)
        .outerjoin(WarehouseLocation, WarehouseLocation.id == StockLot.location_id)
        .outerjoin(
            PurchaseReceiptItem,
            and_(
                StockLot.source_doc_type == "PURCHASE_RECEIPT",
                PurchaseReceiptItem.receipt_id == StockLot.source_doc_id,
                PurchaseReceiptItem.id == StockLot.source_line_id,
            ),
        )
        .outerjoin(PurchaseReceipt, PurchaseReceipt.id == PurchaseReceiptItem.receipt_id)
        .outerjoin(PurchaseOrder, PurchaseOrder.id == PurchaseReceipt.purchase_order_id)
        .outerjoin(source_material_lot, source_material_lot.id == StockLot.source_material_lot_id)
        .order_by(StockLot.id.desc())
        .limit(limit)
    )
    if item_type:
            stmt = stmt.where(Item.item_type == item_type)
    return stmt


def get_stock_lot_options_query(material_item_id: int | None = None) -> Select:
    usable_weight_expr = StockLot.remaining_weight_kg - StockLot.locked_weight_kg
    is_available_expr = case(
        (
            (StockLot.quality_status == "PASS")
            & (StockLot.status == "AVAILABLE")
            & (usable_weight_expr > 0),
            1,
        ),
        else_=0,
    )
    stmt = (
        select(
            StockLot.id.label("lot_id"),
            StockLot.lot_no.label("lot_no"),
            StockLot.item_id.label("item_id"),
            Item.item_code.label("item_code"),
            Item.item_name.label("item_name"),
            StockLot.warehouse_id.label("warehouse_id"),
            Warehouse.warehouse_name.label("warehouse_name"),
            StockLot.remaining_weight_kg.label("remaining_weight_kg"),
            StockLot.unit_cost.label("unit_cost"),
            StockLot.quality_status.label("quality_status"),
            StockLot.status.label("status"),
            is_available_expr.label("is_available_for_issue"),
            case(
                (StockLot.quality_status != "PASS", "未质检放行"),
                (usable_weight_expr <= 0, "已用完"),
                (StockLot.status != "AVAILABLE", "当前状态不可用"),
                else_=None,
            ).label("disabled_reason"),
        )
        .join(Item, Item.id == StockLot.item_id)
        .join(Warehouse, Warehouse.id == StockLot.warehouse_id)
        .where(Warehouse.warehouse_type == "RAW")
        .order_by(is_available_expr.desc(), StockLot.lot_no.asc(), StockLot.id.asc())
    )
    if material_item_id is not None:
        stmt = stmt.where(StockLot.item_id == material_item_id)
    return stmt


def get_stock_lot_purchase_links(db: Session, lot_id: int) -> list[dict[str, object]]:
    lot = db.get(StockLot, lot_id)
    if not lot:
        raise HTTPException(status_code=404, detail="库存批次不存在")

    returned_subquery = (
        select(
            PurchaseReturnItem.purchase_order_item_id.label("purchase_order_item_id"),
            PurchaseReturnItem.lot_id.label("lot_id"),
            func.coalesce(func.sum(PurchaseReturnItem.return_weight_kg), 0).label("returned_weight_kg"),
        )
        .join(PurchaseReturn, PurchaseReturn.id == PurchaseReturnItem.purchase_return_id)
        .where(PurchaseReturn.status != "CANCELED", PurchaseReturnItem.status != "CANCELED")
        .group_by(PurchaseReturnItem.purchase_order_item_id, PurchaseReturnItem.lot_id)
        .subquery()
    )

    accepted_weight = func.coalesce(func.sum(PurchaseReceiptItem.accepted_weight_kg), 0)
    returned_weight = func.coalesce(returned_subquery.c.returned_weight_kg, 0)
    available_by_receipt = accepted_weight - returned_weight
    non_negative_returnable = case((available_by_receipt < 0, 0), else_=available_by_receipt)
    available_lot_weight = StockLot.remaining_weight_kg - StockLot.locked_weight_kg
    non_negative_available_lot_weight = case((available_lot_weight < 0, 0), else_=available_lot_weight)
    returnable_weight = case(
        (non_negative_returnable > non_negative_available_lot_weight, non_negative_available_lot_weight),
        else_=non_negative_returnable,
    )
    direct_receipt_item = and_(
        StockLot.source_doc_type == "PURCHASE_RECEIPT",
        PurchaseReceiptItem.receipt_id == StockLot.source_doc_id,
        PurchaseReceiptItem.id == StockLot.source_line_id,
    )
    merged_receipt_item = PurchaseReceiptItem.merge_to_lot_id == StockLot.id
    stmt = (
        select(
            PurchaseOrder.id.label("purchase_order_id"),
            PurchaseOrder.po_no.label("po_no"),
            PurchaseOrderItem.id.label("purchase_order_item_id"),
            PurchaseOrderItem.material_item_id.label("material_item_id"),
            Item.item_code.label("material_code"),
            Item.item_name.label("material_name"),
            StockLot.id.label("lot_id"),
            StockLot.lot_no.label("lot_no"),
            accepted_weight.label("accepted_weight_kg"),
            returned_weight.label("returned_weight_kg"),
            returnable_weight.label("returnable_weight_kg"),
            PurchaseReceiptItem.unit_cost.label("unit_cost"),
        )
        .select_from(PurchaseReceiptItem)
        .join(PurchaseReceipt, PurchaseReceipt.id == PurchaseReceiptItem.receipt_id)
        .join(PurchaseOrder, PurchaseOrder.id == PurchaseReceipt.purchase_order_id)
        .join(PurchaseOrderItem, PurchaseOrderItem.id == PurchaseReceiptItem.purchase_order_item_id)
        .join(Item, Item.id == PurchaseReceiptItem.material_item_id)
        .join(StockLot, StockLot.id == lot_id)
        .outerjoin(
            returned_subquery,
            (returned_subquery.c.purchase_order_item_id == PurchaseOrderItem.id)
            & (returned_subquery.c.lot_id == StockLot.id),
        )
        .where(
            PurchaseReceipt.warehouse_id == StockLot.warehouse_id,
            or_(direct_receipt_item, merged_receipt_item),
            PurchaseReceiptItem.material_item_id == lot.item_id,
            PurchaseReceiptItem.lot_no == lot.lot_no,
            PurchaseReceiptItem.status == "PASSED",
        )
        .group_by(
            PurchaseOrder.id,
            PurchaseOrder.po_no,
            PurchaseOrderItem.id,
            PurchaseOrderItem.material_item_id,
            Item.item_code,
            Item.item_name,
            StockLot.id,
            StockLot.lot_no,
            returned_subquery.c.returned_weight_kg,
            PurchaseReceiptItem.unit_cost,
            StockLot.remaining_weight_kg,
            StockLot.locked_weight_kg,
        )
        .order_by(PurchaseOrder.id.asc(), PurchaseOrderItem.line_no.asc())
    )
    return [dict(row) for row in db.execute(stmt).mappings().all()]


def get_stock_balances_query(limit: int = 100) -> Select:
    stock_unit = aliased(Unit)
    purchase_unit = aliased(Unit)
    sales_unit = aliased(Unit)
    return (
        select(
            StockBalance.id.label("stock_balance_id"),
            StockBalance.item_id.label("item_id"),
            Item.item_code.label("item_code"),
            Item.item_name.label("item_name"),
            Item.item_type.label("item_type"),
            Item.specification.label("specification"),
            Item.remark.label("item_remark"),
            stock_unit.unit_name.label("stock_unit_name"),
            purchase_unit.unit_name.label("purchase_unit_name"),
            sales_unit.unit_name.label("sales_unit_name"),
            StockBalance.warehouse_id.label("warehouse_id"),
            Warehouse.warehouse_name.label("warehouse_name"),
            Warehouse.warehouse_type.label("warehouse_type"),
            StockBalance.location_id.label("location_id"),
            WarehouseLocation.location_name.label("location_name"),
            case((Warehouse.warehouse_type.in_(("RAW", "SCRAP")), literal(0)), else_=StockBalance.qty_on_hand).label("qty_on_hand"),
            StockBalance.weight_on_hand_kg.label("weight_on_hand_kg"),
            case((Warehouse.warehouse_type.in_(("RAW", "SCRAP")), literal(0)), else_=StockBalance.qty_available).label("qty_available"),
            StockBalance.weight_available_kg.label("weight_available_kg"),
            case((Warehouse.warehouse_type.in_(("RAW", "SCRAP")), literal(0)), else_=StockBalance.qty_allocated).label("qty_allocated"),
            StockBalance.weight_allocated_kg.label("weight_allocated_kg"),
            StockBalance.avg_unit_cost.label("avg_unit_cost"),
            StockBalance.updated_at.label("updated_at"),
        )
        .join(Item, Item.id == StockBalance.item_id)
        .join(Warehouse, Warehouse.id == StockBalance.warehouse_id)
        .outerjoin(WarehouseLocation, WarehouseLocation.id == StockBalance.location_id)
        .outerjoin(stock_unit, stock_unit.id == Item.stock_unit_id)
        .outerjoin(purchase_unit, purchase_unit.id == Item.purchase_unit_id)
        .outerjoin(sales_unit, sales_unit.id == Item.sales_unit_id)
        .order_by(StockBalance.updated_at.desc(), StockBalance.id.desc())
        .limit(limit)
    )


WAREHOUSE_LEDGER_TYPES = {"RAW", "SEMI", "FINISHED", "AUX", "SCRAP", "RETURN"}

WAREHOUSE_LEDGER_SORT_COLUMNS = {
    "biz_time": InventoryTxn.biz_time,
    "txn_type": InventoryTxn.txn_type,
    "item_code": Item.item_code,
    "item_name": Item.item_name,
    "lot_no": StockLot.lot_no,
    "qty_change": InventoryTxn.qty_change,
    "weight_change_kg": InventoryTxn.weight_change_kg,
    "amount": InventoryTxn.amount,
}


def inventory_txn_direction_expression():
    return case(
        (or_(InventoryTxn.txn_type.like("STOCKTAKE_%"), InventoryTxn.source_doc_type == "STOCKTAKE"), "ADJUST"),
        (or_(InventoryTxn.weight_change_kg > 0, InventoryTxn.qty_change > 0), "IN"),
        (or_(InventoryTxn.weight_change_kg < 0, InventoryTxn.qty_change < 0), "OUT"),
        else_="ADJUST",
    )


def inventory_txn_archive_document_type_expression():
    return case(
        (
            and_(
                InventoryTxn.source_doc_type == "生产台账",
                InventoryTxn.txn_type.in_(("PRODUCTION_OUT", "MATERIAL_ISSUE")),
            ),
            DOCUMENT_TYPE_PRODUCTION_MATERIAL_OUT,
        ),
        (
            InventoryTxn.txn_type.in_(
                (
                    "FG_IN",
                    "PRODUCTION_FINISHED_IN",
                    "PRODUCTION_SURPLUS_IN",
                    "PRODUCTION_SCRAP_IN",
                    "成品入库",
                    "生产余料入库",
                    "生产废料入库",
                )
            ),
            DOCUMENT_TYPE_PRODUCTION_INBOUND_SETTLEMENT,
        ),
        else_=DOCUMENT_TYPE_WAREHOUSE_OPERATION,
    )


def inventory_txn_archive_business_id_expression():
    return case(
        (
            and_(
                InventoryTxn.source_doc_type == "生产台账",
                InventoryTxn.txn_type.in_(("PRODUCTION_OUT", "MATERIAL_ISSUE")),
            ),
            InventoryTxn.source_doc_id,
        ),
        else_=InventoryTxn.id,
    )


def latest_inventory_archive_subquery():
    return (
        select(
            DocumentArchive.document_type.label("document_type"),
            DocumentArchive.business_id.label("business_id"),
            DocumentArchive.status.label("archive_status"),
            DocumentArchive.error_message.label("archive_error_message"),
            func.row_number()
            .over(
                partition_by=(DocumentArchive.document_type, DocumentArchive.business_id),
                order_by=(DocumentArchive.archive_version.desc(), DocumentArchive.id.desc()),
            )
            .label("row_no"),
        )
        .where(DocumentArchive.file_format == FILE_FORMAT_PDF)
        .subquery()
    )


def get_inventory_txn_ledger_query(
    *,
    warehouse_type: str,
    warehouse_id: int | None = None,
    keyword: str | None = None,
    direction: str = "ALL",
    txn_type: str | None = None,
    item_id: int | None = None,
    lot_no: str | None = None,
    start_date: date | None = None,
    end_date: date | None = None,
    sort_key: str = "biz_time",
    sort_direction: str = "desc",
) -> Select:
    normalized_warehouse_type = str(warehouse_type or "").upper()
    direction_expr = inventory_txn_direction_expression().label("direction")
    archive_document_type_expr = inventory_txn_archive_document_type_expression().label("archive_document_type")
    archive_business_id_expr = inventory_txn_archive_business_id_expression().label("archive_business_id")
    latest_archive_subquery = latest_inventory_archive_subquery()
    operator_employee = aliased(Employee)
    source_material_lot = aliased(StockLot)
    stmt = (
        select(
            InventoryTxn.id.label("inventory_txn_id"),
            InventoryTxn.txn_no.label("txn_no"),
            InventoryTxn.txn_type.label("txn_type"),
            InventoryTxn.item_id.label("item_id"),
            Item.item_code.label("item_code"),
            Item.item_name.label("item_name"),
            InventoryTxn.warehouse_id.label("warehouse_id"),
            Warehouse.warehouse_name.label("warehouse_name"),
            Warehouse.warehouse_type.label("warehouse_type"),
            InventoryTxn.location_id.label("location_id"),
            WarehouseLocation.location_name.label("location_name"),
            InventoryTxn.lot_id.label("lot_id"),
            StockLot.lot_no.label("lot_no"),
            case((Warehouse.warehouse_type.in_(("RAW", "SCRAP")), literal(0)), else_=InventoryTxn.qty_change).label("qty_change"),
            InventoryTxn.weight_change_kg.label("weight_change_kg"),
            InventoryTxn.unit_cost.label("unit_cost"),
            InventoryTxn.amount.label("amount"),
            InventoryTxn.source_doc_type.label("source_doc_type"),
            InventoryTxn.source_doc_id.label("source_doc_id"),
            InventoryTxn.source_line_id.label("source_line_id"),
            StockLot.source_material_lot_id.label("source_material_lot_id"),
            func.coalesce(source_material_lot.lot_no, StockLot.source_material_sub_batch_no).label(
                "source_material_lot_no"
            ),
            StockLot.source_material_sub_batch_no.label("source_material_sub_batch_no"),
            StockLot.source_material_summary.label("source_material_summary"),
            InventoryTxn.biz_time.label("biz_time"),
            InventoryTxn.operator_user_id.label("operator_user_id"),
            func.coalesce(operator_employee.employee_name, User.nickname, User.username).label("operator_name"),
            InventoryTxn.logistics_waybill_no.label("logistics_waybill_no"),
            InventoryTxn.logistics_freight_amount.label("logistics_freight_amount"),
            InventoryTxn.logistics_photo_url.label("logistics_photo_url"),
            InventoryTxn.remark.label("remark"),
            direction_expr,
            archive_document_type_expr,
            archive_business_id_expr,
            func.coalesce(latest_archive_subquery.c.archive_status, ARCHIVE_STATUS_MISSING).label("archive_status"),
            latest_archive_subquery.c.archive_error_message.label("archive_error_message"),
        )
        .join(Item, Item.id == InventoryTxn.item_id)
        .join(Warehouse, Warehouse.id == InventoryTxn.warehouse_id)
        .outerjoin(WarehouseLocation, WarehouseLocation.id == InventoryTxn.location_id)
        .outerjoin(StockLot, StockLot.id == InventoryTxn.lot_id)
        .outerjoin(source_material_lot, source_material_lot.id == StockLot.source_material_lot_id)
        .outerjoin(User, User.id == InventoryTxn.operator_user_id)
        .outerjoin(operator_employee, operator_employee.id == User.employee_id)
        .outerjoin(
            latest_archive_subquery,
            and_(
                latest_archive_subquery.c.document_type == archive_document_type_expr,
                latest_archive_subquery.c.business_id == archive_business_id_expr,
                latest_archive_subquery.c.row_no == 1,
            ),
        )
        .where(Warehouse.warehouse_type == normalized_warehouse_type)
    )
    if warehouse_id:
        stmt = stmt.where(InventoryTxn.warehouse_id == warehouse_id)
    if txn_type:
        stmt = stmt.where(InventoryTxn.txn_type == str(txn_type).upper())
    if item_id:
        stmt = stmt.where(InventoryTxn.item_id == item_id)
    if lot_no:
        lot_no_pattern = f"%{lot_no.strip()}%"
        stmt = stmt.where(
            or_(
                StockLot.lot_no.like(lot_no_pattern),
                source_material_lot.lot_no.like(lot_no_pattern),
                StockLot.source_material_sub_batch_no.like(lot_no_pattern),
            )
        )
    if start_date:
        stmt = stmt.where(InventoryTxn.biz_time >= start_of_day(start_date))
    if end_date:
        stmt = stmt.where(InventoryTxn.biz_time <= end_of_day(end_date))
    if keyword and keyword.strip():
        pattern = f"%{keyword.strip()}%"
        stmt = stmt.where(
            or_(
                Item.item_code.like(pattern),
                Item.item_name.like(pattern),
                InventoryTxn.txn_type.like(pattern),
                InventoryTxn.source_doc_type.like(pattern),
                InventoryTxn.txn_no.like(pattern),
                InventoryTxn.logistics_waybill_no.like(pattern),
                InventoryTxn.remark.like(pattern),
                StockLot.lot_no.like(pattern),
                source_material_lot.lot_no.like(pattern),
                StockLot.source_material_sub_batch_no.like(pattern),
                StockLot.source_material_summary.like(pattern),
            )
        )
    normalized_direction = str(direction or "ALL").upper()
    if normalized_direction in {"IN", "OUT", "ADJUST"}:
        stmt = stmt.where(direction_expr == normalized_direction)

    sort_column = WAREHOUSE_LEDGER_SORT_COLUMNS.get(sort_key, InventoryTxn.biz_time)
    if str(sort_direction or "desc").lower() == "asc":
        stmt = stmt.order_by(sort_column.asc(), InventoryTxn.id.asc())
    else:
        stmt = stmt.order_by(sort_column.desc(), InventoryTxn.id.desc())
    return stmt


def summarize_inventory_txn_ledger(db: Session, ledger_stmt: Select) -> dict[str, object]:
    ledger_subquery = ledger_stmt.order_by(None).subquery()
    row = db.execute(
        select(
            func.coalesce(func.sum(case((ledger_subquery.c.direction == "IN", 1), else_=0)), 0).label("in_count"),
            func.coalesce(func.sum(case((ledger_subquery.c.direction == "OUT", 1), else_=0)), 0).label("out_count"),
            func.coalesce(func.sum(case((ledger_subquery.c.direction == "ADJUST", 1), else_=0)), 0).label("adjust_count"),
            func.coalesce(
                func.sum(case((ledger_subquery.c.direction == "IN", func.abs(ledger_subquery.c.qty_change)), else_=0)),
                0,
            ).label("in_qty"),
            func.coalesce(
                func.sum(case((ledger_subquery.c.direction == "OUT", func.abs(ledger_subquery.c.qty_change)), else_=0)),
                0,
            ).label("out_qty"),
            func.coalesce(
                func.sum(case((ledger_subquery.c.direction == "IN", func.abs(ledger_subquery.c.weight_change_kg)), else_=0)),
                0,
            ).label("in_weight_kg"),
            func.coalesce(
                func.sum(case((ledger_subquery.c.direction == "OUT", func.abs(ledger_subquery.c.weight_change_kg)), else_=0)),
                0,
            ).label("out_weight_kg"),
            func.max(ledger_subquery.c.biz_time).label("latest_biz_time"),
        )
    ).mappings().one()
    return {
        "in_count": int(row["in_count"] or 0),
        "out_count": int(row["out_count"] or 0),
        "adjust_count": int(row["adjust_count"] or 0),
        "in_qty": to_decimal(row["in_qty"]),
        "out_qty": to_decimal(row["out_qty"]),
        "in_weight_kg": to_decimal(row["in_weight_kg"]),
        "out_weight_kg": to_decimal(row["out_weight_kg"]),
        "latest_biz_time": row["latest_biz_time"],
    }


def get_inventory_txn_query(limit: int = 200) -> Select:
    source_material_lot = aliased(StockLot)
    archive_document_type_expr = inventory_txn_archive_document_type_expression().label("archive_document_type")
    archive_business_id_expr = inventory_txn_archive_business_id_expression().label("archive_business_id")
    latest_archive_subquery = latest_inventory_archive_subquery()
    return (
        select(
            InventoryTxn.id.label("inventory_txn_id"),
            InventoryTxn.txn_no.label("txn_no"),
            InventoryTxn.txn_type.label("txn_type"),
            InventoryTxn.item_id.label("item_id"),
            Item.item_code.label("item_code"),
            Item.item_name.label("item_name"),
            InventoryTxn.warehouse_id.label("warehouse_id"),
            Warehouse.warehouse_name.label("warehouse_name"),
            Warehouse.warehouse_type.label("warehouse_type"),
            InventoryTxn.location_id.label("location_id"),
            WarehouseLocation.location_name.label("location_name"),
            InventoryTxn.lot_id.label("lot_id"),
            StockLot.lot_no.label("lot_no"),
            case((Warehouse.warehouse_type.in_(("RAW", "SCRAP")), literal(0)), else_=InventoryTxn.qty_change).label("qty_change"),
            InventoryTxn.weight_change_kg.label("weight_change_kg"),
            InventoryTxn.unit_cost.label("unit_cost"),
            InventoryTxn.amount.label("amount"),
            InventoryTxn.source_doc_type.label("source_doc_type"),
            InventoryTxn.source_doc_id.label("source_doc_id"),
            InventoryTxn.source_line_id.label("source_line_id"),
            StockLot.source_material_lot_id.label("source_material_lot_id"),
            func.coalesce(source_material_lot.lot_no, StockLot.source_material_sub_batch_no).label(
                "source_material_lot_no"
            ),
            StockLot.source_material_sub_batch_no.label("source_material_sub_batch_no"),
            StockLot.source_material_summary.label("source_material_summary"),
            InventoryTxn.biz_time.label("biz_time"),
            InventoryTxn.logistics_waybill_no.label("logistics_waybill_no"),
            InventoryTxn.logistics_freight_amount.label("logistics_freight_amount"),
            InventoryTxn.logistics_photo_url.label("logistics_photo_url"),
            InventoryTxn.remark.label("remark"),
            archive_document_type_expr,
            archive_business_id_expr,
            func.coalesce(latest_archive_subquery.c.archive_status, ARCHIVE_STATUS_MISSING).label("archive_status"),
            latest_archive_subquery.c.archive_error_message.label("archive_error_message"),
        )
        .join(Item, Item.id == InventoryTxn.item_id)
        .join(Warehouse, Warehouse.id == InventoryTxn.warehouse_id)
        .outerjoin(WarehouseLocation, WarehouseLocation.id == InventoryTxn.location_id)
        .outerjoin(StockLot, StockLot.id == InventoryTxn.lot_id)
        .outerjoin(source_material_lot, source_material_lot.id == StockLot.source_material_lot_id)
        .outerjoin(
            latest_archive_subquery,
            and_(
                latest_archive_subquery.c.document_type == archive_document_type_expr,
                latest_archive_subquery.c.business_id == archive_business_id_expr,
                latest_archive_subquery.c.row_no == 1,
            ),
        )
        .order_by(InventoryTxn.biz_time.desc(), InventoryTxn.id.desc())
        .limit(limit)
    )


def get_inventory_settlements(db: Session, limit: int = 200) -> list[dict[str, object]]:
    payable_amount = func.coalesce(
        func.sum(
            PurchaseReceiptItem.received_weight_kg * PurchaseReceiptItem.unit_cost
        ),
        0,
    )
    payable_rows = db.execute(
        select(
            PurchaseReceipt.id.label("source_doc_id"),
            PurchaseReceipt.receipt_no.label("doc_no"),
            Supplier.supplier_name.label("counterparty_name"),
            PurchaseReceipt.receipt_date.label("biz_date"),
            payable_amount.label("amount"),
            PurchaseReceipt.status.label("status"),
            PurchaseReceipt.remark.label("remark"),
        )
        .join(PurchaseOrder, PurchaseOrder.id == PurchaseReceipt.purchase_order_id)
        .join(Supplier, Supplier.id == PurchaseOrder.supplier_id)
        .join(PurchaseReceiptItem, PurchaseReceiptItem.receipt_id == PurchaseReceipt.id)
        .group_by(
            PurchaseReceipt.id,
            PurchaseReceipt.receipt_no,
            Supplier.supplier_name,
            PurchaseReceipt.receipt_date,
            PurchaseReceipt.status,
            PurchaseReceipt.remark,
        )
        .order_by(PurchaseReceipt.receipt_date.desc(), PurchaseReceipt.id.desc())
        .limit(limit)
    ).mappings().all()

    order_customer = aliased(Customer)
    direct_customer = aliased(Customer)
    receivable_rows = db.execute(
        select(
            Delivery.id.label("source_doc_id"),
            Delivery.delivery_no.label("doc_no"),
            func.coalesce(direct_customer.customer_name, order_customer.customer_name).label("counterparty_name"),
            Delivery.delivery_date.label("biz_date"),
            func.coalesce(func.sum(DeliveryItem.line_amount), 0).label("amount"),
            Delivery.status.label("status"),
            Delivery.remark.label("remark"),
        )
        .outerjoin(SalesOrder, SalesOrder.id == Delivery.sales_order_id)
        .outerjoin(order_customer, order_customer.id == SalesOrder.customer_id)
        .outerjoin(direct_customer, direct_customer.id == Delivery.customer_id)
        .join(DeliveryItem, DeliveryItem.delivery_id == Delivery.id)
        .group_by(
            Delivery.id,
            Delivery.delivery_no,
            order_customer.customer_name,
            direct_customer.customer_name,
            Delivery.delivery_date,
            Delivery.status,
            Delivery.remark,
        )
        .order_by(Delivery.delivery_date.desc(), Delivery.id.desc())
        .limit(limit)
    ).mappings().all()

    rows: list[dict[str, object]] = []
    for row in payable_rows:
        amount = to_decimal(row["amount"], "0.01")
        rows.append(
            {
                "settlement_type": "PAYABLE",
                "source_doc_type": "PURCHASE_RECEIPT",
                "source_doc_id": row["source_doc_id"],
                "doc_no": row["doc_no"],
                "counterparty_name": row["counterparty_name"],
                "biz_date": row["biz_date"],
                "amount": float(amount),
                "settled_amount": 0,
                "open_amount": float(amount),
                "status": row["status"],
                "remark": row["remark"],
            }
        )
    for row in receivable_rows:
        amount = to_decimal(row["amount"], "0.01")
        rows.append(
            {
                "settlement_type": "RECEIVABLE",
                "source_doc_type": "DELIVERY",
                "source_doc_id": row["source_doc_id"],
                "doc_no": row["doc_no"],
                "counterparty_name": row["counterparty_name"],
                "biz_date": row["biz_date"],
                "amount": float(amount),
                "settled_amount": 0,
                "open_amount": float(amount),
                "status": row["status"],
                "remark": row["remark"],
            }
        )
    return sorted(rows, key=lambda item: str(item["biz_date"]), reverse=True)[:limit]


def get_work_orders_query(limit: int = 100) -> Select:
    product_item = aliased(Item)
    line_subquery = (
        select(
            WorkOrderOperation.work_order_id.label("work_order_id"),
            func.count(WorkOrderOperation.id).label("operation_count"),
            func.coalesce(func.sum(WorkOrderOperation.is_abnormal), 0).label("abnormal_operation_count"),
            func.coalesce(
                func.sum(
                    (WorkOrderOperation.status == "DONE").cast(Integer)  # type: ignore[attr-defined]
                ),
                0,
            ).label("done_count"),
        )
        .group_by(WorkOrderOperation.work_order_id)
        .subquery()
    )
    final_operation_seq_subquery = (
        select(
            WorkOrderOperation.work_order_id.label("work_order_id"),
            func.max(WorkOrderOperation.seq_no).label("max_seq_no"),
        )
        .group_by(WorkOrderOperation.work_order_id)
        .subquery()
    )
    final_operation = aliased(WorkOrderOperation)
    active_scrap_record_ids = (
        select(func.max(ScrapRecord.id).label("scrap_record_id"))
        .where(ScrapRecord.status != "OVERRIDDEN")
        .group_by(ScrapRecord.report_id)
        .subquery()
    )
    rework_subquery = (
        select(
            ScrapRecord.work_order_id.label("work_order_id"),
            func.coalesce(func.sum(ScrapRecord.scrap_qty), 0).label("rework_qty"),
        )
        .where(ScrapRecord.id.in_(select(active_scrap_record_ids.c.scrap_record_id)))
        .where(
            ScrapRecord.disposal_type == "REWORK",
            ScrapRecord.status == "CONFIRMED",
        )
        .group_by(ScrapRecord.work_order_id)
        .subquery()
    )
    receipt_subquery = (
        select(
            CompletionReceipt.work_order_id.label("work_order_id"),
            func.coalesce(func.sum(CompletionReceiptItem.receipt_qty), 0).label("received_qty"),
        )
        .join(CompletionReceiptItem, CompletionReceiptItem.completion_receipt_id == CompletionReceipt.id)
        .group_by(CompletionReceipt.work_order_id)
        .subquery()
    )
    return (
        select(
            WorkOrder.id.label("work_order_id"),
            WorkOrder.work_order_no.label("work_order_no"),
            WorkOrder.work_order_type.label("work_order_type"),
            WorkOrder.source_sales_order_item_id.label("source_sales_order_item_id"),
            SalesOrder.order_no.label("source_order_no"),
            WorkOrder.product_item_id.label("product_item_id"),
            product_item.item_code.label("product_code"),
            product_item.item_name.label("product_name"),
            Product.version_no.label("product_version_no"),
            WorkOrder.route_id.label("route_id"),
            ProcessRoute.route_name.label("route_name"),
            WorkOrder.bom_id.label("bom_id"),
            WorkOrder.planned_qty.label("planned_qty"),
            WorkOrder.released_qty.label("released_qty"),
            WorkOrder.finished_qty.label("finished_qty"),
            WorkOrder.scrap_qty.label("scrap_qty"),
            WorkOrder.planned_start_time.label("planned_start_time"),
            WorkOrder.planned_end_time.label("planned_end_time"),
            WorkOrder.actual_start_time.label("actual_start_time"),
            WorkOrder.actual_end_time.label("actual_end_time"),
            WorkOrder.priority_level.label("priority_level"),
            WorkOrder.status.label("status"),
            WorkOrder.remark.label("remark"),
            func.coalesce(line_subquery.c.operation_count, 0).label("operation_count"),
            func.coalesce(line_subquery.c.abnormal_operation_count, 0).label("abnormal_operation_count"),
            (
                func.coalesce(final_operation.good_qty, 0) + func.coalesce(rework_subquery.c.rework_qty, 0)
            ).label("reported_good_qty"),
            func.coalesce(receipt_subquery.c.received_qty, 0).label("received_qty"),
            func.greatest(
                (
                    func.coalesce(final_operation.good_qty, 0) + func.coalesce(rework_subquery.c.rework_qty, 0)
                )
                - func.coalesce(receipt_subquery.c.received_qty, 0),
                0,
            ).label("max_receivable_qty"),
            (
                (func.coalesce(line_subquery.c.operation_count, 0) > 0)
                & (func.coalesce(line_subquery.c.done_count, 0) == func.coalesce(line_subquery.c.operation_count, 0))
            ).label("all_operations_done"),
        )
        .join(product_item, product_item.id == WorkOrder.product_item_id)
        .join(ProcessRoute, ProcessRoute.id == WorkOrder.route_id)
        .outerjoin(Product, Product.item_id == WorkOrder.product_item_id)
        .outerjoin(SalesOrderItem, SalesOrderItem.id == WorkOrder.source_sales_order_item_id)
        .outerjoin(SalesOrder, SalesOrder.id == SalesOrderItem.sales_order_id)
        .outerjoin(line_subquery, line_subquery.c.work_order_id == WorkOrder.id)
        .outerjoin(final_operation_seq_subquery, final_operation_seq_subquery.c.work_order_id == WorkOrder.id)
        .outerjoin(rework_subquery, rework_subquery.c.work_order_id == WorkOrder.id)
        .outerjoin(
            final_operation,
            and_(
                final_operation.work_order_id == WorkOrder.id,
                final_operation.seq_no == final_operation_seq_subquery.c.max_seq_no,
            ),
        )
        .outerjoin(receipt_subquery, receipt_subquery.c.work_order_id == WorkOrder.id)
        .order_by(WorkOrder.id.desc())
        .limit(limit)
    )


def get_work_order_materials_query(limit: int = 200, work_order_id: int | None = None) -> Select:
    issue_subquery = (
        select(
            WorkOrderMaterialIssue.work_order_material_id.label("work_order_material_id"),
            func.group_concat(WorkOrderMaterialIssue.material_sub_batch_no).label("material_sub_batch_summary"),
            func.coalesce(func.sum(WorkOrderMaterialIssue.amount), 0).label("issue_amount"),
        )
        .group_by(WorkOrderMaterialIssue.work_order_material_id)
        .subquery()
    )
    stmt = (
        select(
            WorkOrderMaterial.id.label("work_order_material_id"),
            WorkOrderMaterial.work_order_id.label("work_order_id"),
            WorkOrder.work_order_no.label("work_order_no"),
            WorkOrderMaterial.bom_item_id.label("bom_item_id"),
            WorkOrderMaterial.material_item_id.label("material_item_id"),
            Item.item_code.label("material_code"),
            Item.item_name.label("material_name"),
            literal(0).label("required_qty"),
            WorkOrderMaterial.required_weight_kg.label("required_weight_kg"),
            literal(0).label("issued_qty"),
            WorkOrderMaterial.issued_weight_kg.label("issued_weight_kg"),
            literal(0).label("returned_qty"),
            WorkOrderMaterial.returned_weight_kg.label("returned_weight_kg"),
            issue_subquery.c.material_sub_batch_summary.label("material_sub_batch_summary"),
            func.coalesce(issue_subquery.c.issue_amount, 0).label("issue_amount"),
            WorkOrderMaterial.status.label("status"),
            WorkOrderMaterial.remark.label("remark"),
        )
        .join(WorkOrder, WorkOrder.id == WorkOrderMaterial.work_order_id)
        .join(Item, Item.id == WorkOrderMaterial.material_item_id)
        .outerjoin(issue_subquery, issue_subquery.c.work_order_material_id == WorkOrderMaterial.id)
        .order_by(WorkOrderMaterial.id.desc())
        .limit(limit)
    )
    if work_order_id:
        stmt = stmt.where(WorkOrderMaterial.work_order_id == work_order_id)
    return stmt


def get_work_order_material_issues_query(limit: int = 300, work_order_id: int | None = None) -> Select:
    stmt = (
        select(
            WorkOrderMaterialIssue.id.label("material_issue_id"),
            WorkOrderMaterialIssue.work_order_material_id.label("work_order_material_id"),
            WorkOrderMaterialIssue.work_order_id.label("work_order_id"),
            WorkOrder.work_order_no.label("work_order_no"),
            WorkOrderMaterialIssue.material_item_id.label("material_item_id"),
            Item.item_code.label("material_code"),
            Item.item_name.label("material_name"),
            WorkOrderMaterialIssue.source_lot_id.label("source_lot_id"),
            StockLot.lot_no.label("source_lot_no"),
            WorkOrderMaterialIssue.material_sub_batch_no.label("material_sub_batch_no"),
            literal(0).label("issued_qty"),
            WorkOrderMaterialIssue.issued_weight_kg.label("issued_weight_kg"),
            WorkOrderMaterialIssue.unit_cost.label("unit_cost"),
            WorkOrderMaterialIssue.amount.label("amount"),
            WorkOrderMaterialIssue.issue_time.label("issue_time"),
            WorkOrderMaterialIssue.remark.label("remark"),
        )
        .join(WorkOrder, WorkOrder.id == WorkOrderMaterialIssue.work_order_id)
        .join(Item, Item.id == WorkOrderMaterialIssue.material_item_id)
        .join(StockLot, StockLot.id == WorkOrderMaterialIssue.source_lot_id)
        .order_by(WorkOrderMaterialIssue.issue_time.desc(), WorkOrderMaterialIssue.id.desc())
        .limit(limit)
    )
    if work_order_id:
        stmt = stmt.where(WorkOrderMaterialIssue.work_order_id == work_order_id)
    return stmt


def get_work_order_operations_query(limit: int = 200, work_order_id: int | None = None) -> Select:
    stmt = (
        select(
            WorkOrderOperation.id.label("work_order_operation_id"),
            WorkOrderOperation.work_order_id.label("work_order_id"),
            WorkOrder.work_order_no.label("work_order_no"),
            WorkOrderOperation.route_operation_id.label("route_operation_id"),
            WorkOrderOperation.seq_no.label("seq_no"),
            WorkOrderOperation.operation_name.label("operation_name"),
            WorkOrderOperation.work_center_id.label("work_center_id"),
            WorkCenter.center_name.label("work_center_name"),
            WorkOrderOperation.planned_qty.label("planned_qty"),
            WorkOrderOperation.report_qty.label("report_qty"),
            WorkOrderOperation.good_qty.label("good_qty"),
            WorkOrderOperation.scrap_qty.label("scrap_qty"),
            WorkOrderOperation.rework_qty.label("rework_qty"),
            WorkOrderOperation.std_labor_cost.label("std_labor_cost"),
            WorkOrderOperation.std_machine_cost.label("std_machine_cost"),
            WorkOrderOperation.std_outsource_cost.label("std_outsource_cost"),
            WorkOrderOperation.allowed_scrap_rate.label("allowed_scrap_rate"),
            WorkOrderOperation.is_abnormal.label("is_abnormal"),
            WorkOrderOperation.status.label("status"),
            WorkOrderOperation.remark.label("remark"),
        )
        .join(WorkOrder, WorkOrder.id == WorkOrderOperation.work_order_id)
        .join(WorkCenter, WorkCenter.id == WorkOrderOperation.work_center_id)
        .order_by(WorkOrderOperation.work_order_id.desc(), WorkOrderOperation.seq_no)
        .limit(limit)
    )
    if work_order_id:
        stmt = stmt.where(WorkOrderOperation.work_order_id == work_order_id)
    return stmt


def get_operation_reports_query(limit: int = 200, work_order_id: int | None = None) -> Select:
    employee = aliased(Employee)
    equipment = aliased(Equipment)
    stmt = (
        select(
            OperationReport.id.label("report_id"),
            OperationReport.report_no.label("report_no"),
            OperationReport.work_order_id.label("work_order_id"),
            WorkOrder.work_order_no.label("work_order_no"),
            OperationReport.work_order_operation_id.label("work_order_operation_id"),
            WorkOrderOperation.seq_no.label("seq_no"),
            WorkOrderOperation.operation_name.label("operation_name"),
            OperationReport.employee_id.label("employee_id"),
            employee.employee_name.label("employee_name"),
            OperationReport.equipment_id.label("equipment_id"),
            equipment.equipment_name.label("equipment_name"),
            OperationReport.report_source.label("report_source"),
            OperationReport.shift_code.label("shift_code"),
            OperationReport.start_time.label("start_time"),
            OperationReport.end_time.label("end_time"),
            OperationReport.report_qty.label("report_qty"),
            OperationReport.good_qty.label("good_qty"),
            OperationReport.scrap_qty.label("scrap_qty"),
            OperationReport.rework_qty.label("rework_qty"),
            OperationReport.downtime_minutes.label("downtime_minutes"),
            OperationReport.extra_cost_amount.label("extra_cost_amount"),
            OperationReport.is_abnormal.label("is_abnormal"),
            WorkOrderOperation.allowed_scrap_rate.label("allowed_scrap_rate"),
            ProcessRouteOperation.std_cycle_seconds.label("ref_cycle_seconds"),
            OperationReport.scrap_reason.label("scrap_reason"),
            OperationReport.remark.label("remark"),
        )
        .join(WorkOrder, WorkOrder.id == OperationReport.work_order_id)
        .join(WorkOrderOperation, WorkOrderOperation.id == OperationReport.work_order_operation_id)
        .outerjoin(ProcessRouteOperation, ProcessRouteOperation.id == WorkOrderOperation.route_operation_id)
        .join(employee, employee.id == OperationReport.employee_id)
        .outerjoin(equipment, equipment.id == OperationReport.equipment_id)
        .order_by(OperationReport.id.desc())
        .limit(limit)
    )
    if work_order_id:
        stmt = stmt.where(OperationReport.work_order_id == work_order_id)
    return stmt


def get_scrap_records_query(limit: int = 200) -> Select:
    return (
        select(
            ScrapRecord.id.label("scrap_record_id"),
            ScrapRecord.scrap_no.label("scrap_no"),
            ScrapRecord.report_id.label("report_id"),
            OperationReport.report_no.label("report_no"),
            ScrapRecord.work_order_id.label("work_order_id"),
            WorkOrder.work_order_no.label("work_order_no"),
            ScrapRecord.work_order_operation_id.label("work_order_operation_id"),
            WorkOrderOperation.operation_name.label("operation_name"),
            ScrapRecord.item_id.label("item_id"),
            Item.item_code.label("item_code"),
            Item.item_name.label("item_name"),
            ScrapRecord.scrap_qty.label("scrap_qty"),
            ScrapRecord.scrap_weight_kg.label("scrap_weight_kg"),
            ScrapRecord.scrap_reason.label("scrap_reason"),
            ScrapRecord.disposal_type.label("disposal_type"),
            ScrapRecord.saleable_scrap_weight_kg.label("saleable_scrap_weight_kg"),
            ScrapRecord.scrap_cost_amount.label("scrap_cost_amount"),
            ScrapRecord.status.label("status"),
            ScrapRecord.created_at.label("created_at"),
        )
        .join(OperationReport, OperationReport.id == ScrapRecord.report_id)
        .join(WorkOrder, WorkOrder.id == ScrapRecord.work_order_id)
        .join(WorkOrderOperation, WorkOrderOperation.id == ScrapRecord.work_order_operation_id)
        .join(Item, Item.id == ScrapRecord.item_id)
        .order_by(ScrapRecord.id.desc())
        .limit(limit)
    )


def get_completion_receipts_query(limit: int = 100) -> Select:
    line_subquery = (
        select(
            CompletionReceiptItem.completion_receipt_id.label("completion_receipt_id"),
            func.count(CompletionReceiptItem.id).label("line_count"),
            func.coalesce(func.sum(CompletionReceiptItem.receipt_qty), 0).label("total_receipt_qty"),
            func.coalesce(func.sum(CompletionReceiptItem.receipt_weight_kg), 0).label("total_receipt_weight_kg"),
        )
        .group_by(CompletionReceiptItem.completion_receipt_id)
        .subquery()
    )
    first_item_subquery = (
        select(
            CompletionReceiptItem.completion_receipt_id.label("completion_receipt_id"),
            func.min(CompletionReceiptItem.product_item_id).label("product_item_id"),
        )
        .group_by(CompletionReceiptItem.completion_receipt_id)
        .subquery()
    )
    receiver = aliased(Employee)
    return (
        select(
            CompletionReceipt.id.label("completion_receipt_id"),
            CompletionReceipt.receipt_no.label("receipt_no"),
            CompletionReceipt.work_order_id.label("work_order_id"),
            WorkOrder.work_order_no.label("work_order_no"),
            first_item_subquery.c.product_item_id.label("product_item_id"),
            Item.item_code.label("product_code"),
            Item.item_name.label("product_name"),
            CompletionReceipt.warehouse_id.label("warehouse_id"),
            Warehouse.warehouse_name.label("warehouse_name"),
            CompletionReceipt.receipt_time.label("receipt_time"),
            CompletionReceipt.receiver_employee_id.label("receiver_employee_id"),
            receiver.employee_name.label("receiver_name"),
            CompletionReceipt.status.label("status"),
            func.coalesce(line_subquery.c.line_count, 0).label("line_count"),
            func.coalesce(line_subquery.c.total_receipt_qty, 0).label("total_receipt_qty"),
            func.coalesce(line_subquery.c.total_receipt_weight_kg, 0).label("total_receipt_weight_kg"),
            CompletionReceipt.remark.label("remark"),
        )
        .join(WorkOrder, WorkOrder.id == CompletionReceipt.work_order_id)
        .join(Warehouse, Warehouse.id == CompletionReceipt.warehouse_id)
        .outerjoin(receiver, receiver.id == CompletionReceipt.receiver_employee_id)
        .outerjoin(line_subquery, line_subquery.c.completion_receipt_id == CompletionReceipt.id)
        .outerjoin(first_item_subquery, first_item_subquery.c.completion_receipt_id == CompletionReceipt.id)
        .outerjoin(Item, Item.id == first_item_subquery.c.product_item_id)
        .order_by(CompletionReceipt.id.desc())
        .limit(limit)
    )


def get_completion_receipt_items_query(limit: int = 200, receipt_id: int | None = None) -> Select:
    source_material_lot = aliased(StockLot)
    stmt = (
        select(
            CompletionReceiptItem.id.label("completion_receipt_item_id"),
            CompletionReceiptItem.completion_receipt_id.label("completion_receipt_id"),
            CompletionReceipt.receipt_no.label("receipt_no"),
            CompletionReceiptItem.line_no.label("line_no"),
            CompletionReceiptItem.product_item_id.label("product_item_id"),
            Item.item_code.label("product_code"),
            Item.item_name.label("product_name"),
            CompletionReceipt.warehouse_id.label("warehouse_id"),
            Warehouse.warehouse_name.label("warehouse_name"),
            CompletionReceiptItem.location_id.label("location_id"),
            WarehouseLocation.location_name.label("location_name"),
            CompletionReceiptItem.lot_no.label("lot_no"),
            CompletionReceiptItem.source_material_lot_id.label("source_material_lot_id"),
            func.coalesce(source_material_lot.lot_no, CompletionReceiptItem.source_material_sub_batch_no).label(
                "source_material_lot_no"
            ),
            func.coalesce(source_material_lot.lot_no, CompletionReceiptItem.source_material_sub_batch_no).label(
                "source_material_sub_batch_no"
            ),
            CompletionReceiptItem.source_material_summary.label("source_material_summary"),
            CompletionReceiptItem.receipt_qty.label("receipt_qty"),
            CompletionReceiptItem.receipt_weight_kg.label("receipt_weight_kg"),
            CompletionReceiptItem.unit_cost.label("unit_cost"),
            CompletionReceiptItem.status.label("status"),
            CompletionReceiptItem.remark.label("remark"),
        )
        .join(CompletionReceipt, CompletionReceipt.id == CompletionReceiptItem.completion_receipt_id)
        .join(Warehouse, Warehouse.id == CompletionReceipt.warehouse_id)
        .join(Item, Item.id == CompletionReceiptItem.product_item_id)
        .outerjoin(WarehouseLocation, WarehouseLocation.id == CompletionReceiptItem.location_id)
        .outerjoin(source_material_lot, source_material_lot.id == CompletionReceiptItem.source_material_lot_id)
        .order_by(CompletionReceiptItem.id.desc())
        .limit(limit)
    )
    if receipt_id:
        stmt = stmt.where(CompletionReceiptItem.completion_receipt_id == receipt_id)
    return stmt


def get_deliveries_query(limit: int = 100) -> Select:
    line_subquery = (
        select(
            DeliveryItem.delivery_id.label("delivery_id"),
            func.count(DeliveryItem.id).label("line_count"),
            func.coalesce(func.sum(DeliveryItem.delivery_qty), 0).label("total_delivery_qty"),
            func.coalesce(func.sum(DeliveryItem.line_amount), 0).label("total_line_amount"),
            func.group_concat(func.distinct(Item.item_name)).label("product_names"),
        )
        .join(Item, Item.id == DeliveryItem.product_item_id)
        .group_by(DeliveryItem.delivery_id)
        .subquery()
    )
    shipper = aliased(Employee)
    order_customer = aliased(Customer)
    direct_customer = aliased(Customer)
    return (
        select(
            Delivery.id.label("delivery_id"),
            Delivery.delivery_no.label("delivery_no"),
            Delivery.sales_order_id.label("sales_order_id"),
            Delivery.customer_id.label("customer_id"),
            SalesOrder.order_no.label("order_no"),
            func.coalesce(direct_customer.customer_name, order_customer.customer_name).label("customer_name"),
            Delivery.warehouse_id.label("warehouse_id"),
            Warehouse.warehouse_name.label("warehouse_name"),
            Delivery.delivery_date.label("delivery_date"),
            Delivery.shipper_employee_id.label("shipper_employee_id"),
            shipper.employee_name.label("shipper_name"),
            Delivery.consignee_name.label("consignee_name"),
            Delivery.consignee_phone.label("consignee_phone"),
            Delivery.delivery_address.label("delivery_address"),
            Delivery.logistics_waybill_no.label("logistics_waybill_no"),
            Delivery.logistics_freight_amount.label("logistics_freight_amount"),
            Delivery.logistics_photo_url.label("logistics_photo_url"),
            line_subquery.c.product_names.label("product_names"),
            Delivery.status.label("status"),
            func.coalesce(line_subquery.c.line_count, 0).label("line_count"),
            func.coalesce(line_subquery.c.total_delivery_qty, 0).label("total_delivery_qty"),
            func.coalesce(line_subquery.c.total_line_amount, 0).label("total_line_amount"),
            Delivery.remark.label("remark"),
        )
        .outerjoin(SalesOrder, SalesOrder.id == Delivery.sales_order_id)
        .outerjoin(order_customer, order_customer.id == SalesOrder.customer_id)
        .outerjoin(direct_customer, direct_customer.id == Delivery.customer_id)
        .join(Warehouse, Warehouse.id == Delivery.warehouse_id)
        .outerjoin(shipper, shipper.id == Delivery.shipper_employee_id)
        .outerjoin(line_subquery, line_subquery.c.delivery_id == Delivery.id)
        .order_by(Delivery.id.desc())
        .limit(limit)
    )


def get_delivery_items_query(limit: int = 200, delivery_id: int | None = None) -> Select:
    source_material_lot = aliased(StockLot)
    source_material_item = aliased(Item)
    stmt = (
        select(
            DeliveryItem.id.label("delivery_item_id"),
            DeliveryItem.delivery_id.label("delivery_id"),
            Delivery.delivery_no.label("delivery_no"),
            DeliveryItem.line_no.label("line_no"),
            DeliveryItem.sales_order_item_id.label("sales_order_item_id"),
            SalesOrder.order_no.label("order_no"),
            DeliveryItem.product_item_id.label("product_item_id"),
            Item.item_code.label("product_code"),
            Item.item_name.label("product_name"),
            DeliveryItem.lot_id.label("lot_id"),
            StockLot.lot_no.label("lot_no"),
            StockLot.source_material_lot_id.label("source_material_lot_id"),
            func.coalesce(source_material_lot.lot_no, StockLot.source_material_sub_batch_no).label("source_material_lot_no"),
            source_material_item.item_code.label("source_material_code"),
            source_material_item.item_name.label("source_material_name"),
            func.coalesce(source_material_lot.lot_no, StockLot.source_material_sub_batch_no).label(
                "source_material_sub_batch_no"
            ),
            StockLot.source_material_summary.label("source_material_summary"),
            DeliveryItem.delivery_qty.label("delivery_qty"),
            DeliveryItem.delivery_weight_kg.label("delivery_weight_kg"),
            DeliveryItem.unit_price.label("unit_price"),
            DeliveryItem.line_amount.label("line_amount"),
            DeliveryItem.status.label("status"),
            DeliveryItem.remark.label("remark"),
        )
        .join(Delivery, Delivery.id == DeliveryItem.delivery_id)
        .outerjoin(SalesOrder, SalesOrder.id == Delivery.sales_order_id)
        .join(Item, Item.id == DeliveryItem.product_item_id)
        .outerjoin(StockLot, StockLot.id == DeliveryItem.lot_id)
        .outerjoin(source_material_lot, source_material_lot.id == StockLot.source_material_lot_id)
        .outerjoin(source_material_item, source_material_item.id == source_material_lot.item_id)
        .order_by(DeliveryItem.id.desc())
        .limit(limit)
    )
    if delivery_id:
        stmt = stmt.where(DeliveryItem.delivery_id == delivery_id)
    return stmt


def get_equipment_query(limit: int = 100) -> Select:
    return (
        select(
            Equipment.id.label("equipment_id"),
            Equipment.equipment_code.label("equipment_code"),
            Equipment.equipment_name.label("equipment_name"),
            Equipment.category_name.label("category_name"),
            Equipment.work_center_id.label("work_center_id"),
            WorkCenter.center_name.label("work_center_name"),
            Equipment.manufacturer.label("manufacturer"),
            Equipment.model_no.label("model_no"),
            Equipment.install_date.label("install_date"),
            Equipment.rated_power_kw.label("rated_power_kw"),
            Equipment.occupied_area_sqm.label("occupied_area_sqm"),
            Equipment.maintenance_cycle_hours.label("maintenance_cycle_hours"),
            Equipment.last_maintenance_at.label("last_maintenance_at"),
            Equipment.next_maintenance_at.label("next_maintenance_at"),
            Equipment.status.label("status"),
            Equipment.remark.label("remark"),
        )
        .join(WorkCenter, WorkCenter.id == Equipment.work_center_id)
        .order_by(Equipment.id.desc())
        .limit(limit)
    )


def get_maintenance_plans_query(limit: int = 100) -> Select:
    return (
        select(
            MaintenancePlan.id.label("maintenance_plan_id"),
            MaintenancePlan.plan_code.label("plan_code"),
            MaintenancePlan.equipment_id.label("equipment_id"),
            Equipment.equipment_code.label("equipment_code"),
            Equipment.equipment_name.label("equipment_name"),
            MaintenancePlan.plan_name.label("plan_name"),
            MaintenancePlan.maintenance_type.label("maintenance_type"),
            MaintenancePlan.cycle_hours.label("cycle_hours"),
            MaintenancePlan.cycle_days.label("cycle_days"),
            MaintenancePlan.last_execute_at.label("last_execute_at"),
            MaintenancePlan.next_execute_at.label("next_execute_at"),
            MaintenancePlan.status.label("status"),
            MaintenancePlan.remark.label("remark"),
        )
        .join(Equipment, Equipment.id == MaintenancePlan.equipment_id)
        .order_by(MaintenancePlan.id.desc())
        .limit(limit)
    )


def get_maintenance_orders_query(limit: int = 100) -> Select:
    owner = aliased(Employee)
    return (
        select(
            MaintenanceOrder.id.label("maintenance_order_id"),
            MaintenanceOrder.order_no.label("order_no"),
            MaintenanceOrder.equipment_id.label("equipment_id"),
            Equipment.equipment_code.label("equipment_code"),
            Equipment.equipment_name.label("equipment_name"),
            MaintenanceOrder.plan_id.label("plan_id"),
            MaintenancePlan.plan_name.label("plan_name"),
            MaintenanceOrder.maintenance_type.label("maintenance_type"),
            MaintenanceOrder.start_time.label("start_time"),
            MaintenanceOrder.end_time.label("end_time"),
            MaintenanceOrder.downtime_minutes.label("downtime_minutes"),
            MaintenanceOrder.owner_employee_id.label("owner_employee_id"),
            owner.employee_name.label("owner_name"),
            MaintenanceOrder.result_summary.label("result_summary"),
            MaintenanceOrder.cost_amount.label("cost_amount"),
            MaintenanceOrder.status.label("status"),
        )
        .join(Equipment, Equipment.id == MaintenanceOrder.equipment_id)
        .outerjoin(MaintenancePlan, MaintenancePlan.id == MaintenanceOrder.plan_id)
        .outerjoin(owner, owner.id == MaintenanceOrder.owner_employee_id)
        .order_by(MaintenanceOrder.id.desc())
        .limit(limit)
    )


def get_quality_inspections_query(limit: int = 100, pending_only: bool = False) -> Select:
    latest_archive_version_subquery = (
        select(
            DocumentArchive.business_id.label("business_id"),
            func.max(DocumentArchive.archive_version).label("archive_version"),
        )
        .where(DocumentArchive.document_type == "质量校验单", DocumentArchive.file_format == "PDF")
        .group_by(DocumentArchive.business_id)
        .subquery()
    )
    latest_archive_id_subquery = (
        select(
            DocumentArchive.business_id.label("business_id"),
            func.max(DocumentArchive.id).label("archive_id"),
        )
        .join(
            latest_archive_version_subquery,
            and_(
                latest_archive_version_subquery.c.business_id == DocumentArchive.business_id,
                latest_archive_version_subquery.c.archive_version == DocumentArchive.archive_version,
            ),
        )
        .where(DocumentArchive.document_type == "质量校验单", DocumentArchive.file_format == "PDF")
        .group_by(DocumentArchive.business_id)
        .subquery()
    )
    latest_archive_subquery = (
        select(
            DocumentArchive.business_id.label("business_id"),
            DocumentArchive.status.label("archive_status"),
            DocumentArchive.archive_version.label("archive_version"),
            DocumentArchive.created_at.label("archive_created_at"),
            DocumentArchive.error_message.label("archive_error_message"),
        )
        .join(
            latest_archive_id_subquery,
            latest_archive_id_subquery.c.archive_id == DocumentArchive.id,
        )
        .where(DocumentArchive.document_type == "质量校验单", DocumentArchive.file_format == "PDF")
        .subquery()
    )
    stmt = (
        select(
            PurchaseReceiptItem.id.label("receipt_item_id"),
            PurchaseReceiptItem.receipt_id.label("receipt_id"),
            PurchaseReceipt.receipt_no.label("receipt_no"),
            PurchaseOrder.po_no.label("po_no"),
            Supplier.supplier_name.label("supplier_name"),
            PurchaseOrder.target_warehouse_type.label("target_warehouse_type"),
            PurchaseReceiptItem.material_item_id.label("material_item_id"),
            Item.item_code.label("material_code"),
            Item.item_name.label("material_name"),
            Warehouse.warehouse_name.label("warehouse_name"),
            WarehouseLocation.location_name.label("location_name"),
            PurchaseReceiptItem.lot_no.label("lot_no"),
            PurchaseReceiptItem.received_qty.label("received_qty"),
            PurchaseReceiptItem.received_weight_kg.label("received_weight_kg"),
            PurchaseReceiptItem.accepted_qty.label("accepted_qty"),
            PurchaseReceiptItem.accepted_weight_kg.label("accepted_weight_kg"),
            PurchaseReceiptItem.status.label("status"),
            case(
                (PurchaseReceiptItem.status == "PENDING_QC", "PENDING_QC"),
                (PurchaseReceiptItem.status == "PASSED", "PASS"),
                (PurchaseReceiptItem.status == "REJECTED", "REJECT"),
                else_=func.coalesce(StockLot.quality_status, "PENDING_QC"),
            ).label("quality_status"),
            StockLot.remark.label("inspector_name"),
            PurchaseReceipt.receipt_date.label("receipt_date"),
            PurchaseReceiptItem.remark.label("remark"),
            func.coalesce(latest_archive_subquery.c.archive_status, "未生成").label("archive_status"),
            latest_archive_subquery.c.archive_version.label("archive_version"),
            latest_archive_subquery.c.archive_created_at.label("archive_created_at"),
            latest_archive_subquery.c.archive_error_message.label("archive_error_message"),
        )
        .join(PurchaseReceipt, PurchaseReceipt.id == PurchaseReceiptItem.receipt_id)
        .join(PurchaseOrder, PurchaseOrder.id == PurchaseReceipt.purchase_order_id)
        .join(Supplier, Supplier.id == PurchaseOrder.supplier_id)
        .join(Item, Item.id == PurchaseReceiptItem.material_item_id)
        .join(Warehouse, Warehouse.id == PurchaseReceipt.warehouse_id)
        .outerjoin(WarehouseLocation, WarehouseLocation.id == PurchaseReceiptItem.location_id)
        .outerjoin(
            StockLot,
            or_(
                and_(
                    StockLot.source_doc_type == "PURCHASE_RECEIPT",
                    StockLot.source_doc_id == PurchaseReceipt.id,
                    StockLot.source_line_id == PurchaseReceiptItem.id,
                ),
                StockLot.id == PurchaseReceiptItem.merge_to_lot_id,
            ),
        )
        .outerjoin(latest_archive_subquery, latest_archive_subquery.c.business_id == PurchaseReceiptItem.id)
        .order_by(PurchaseReceiptItem.id.desc())
        .limit(limit)
    )
    if pending_only:
        stmt = stmt.where(PurchaseReceiptItem.status == "PENDING_QC")
    return stmt


def get_periods_query(limit: int = 50) -> Select:
    return (
        select(
            AccountingPeriod.id.label("period_id"),
            AccountingPeriod.period_code.label("period_code"),
            AccountingPeriod.year_no.label("year_no"),
            AccountingPeriod.month_no.label("month_no"),
            AccountingPeriod.start_date.label("start_date"),
            AccountingPeriod.end_date.label("end_date"),
            AccountingPeriod.close_status.label("close_status"),
            AccountingPeriod.closed_at.label("closed_at"),
        )
        .order_by(AccountingPeriod.year_no.desc(), AccountingPeriod.month_no.desc())
        .limit(limit)
    )


def get_overheads_query(limit: int = 100) -> Select:
    return (
        select(
            OverheadEntry.id.label("overhead_entry_id"),
            OverheadEntry.period_id.label("period_id"),
            AccountingPeriod.period_code.label("period_code"),
            AccountingPeriod.year_no.label("year_no"),
            AccountingPeriod.month_no.label("month_no"),
            OverheadEntry.overhead_type.label("overhead_type"),
            OverheadEntry.dept_id.label("dept_id"),
            Department.dept_name.label("dept_name"),
            OverheadEntry.amount.label("amount"),
            OverheadEntry.allocation_basis.label("allocation_basis"),
            OverheadEntry.description.label("description"),
            OverheadEntry.created_at.label("created_at"),
        )
        .join(AccountingPeriod, AccountingPeriod.id == OverheadEntry.period_id)
        .outerjoin(Department, Department.id == OverheadEntry.dept_id)
        .order_by(OverheadEntry.id.desc())
        .limit(limit)
    )


def get_statement_snapshots_query(limit: int = 100) -> Select:
    return (
        select(
            StatementSnapshot.id.label("statement_snapshot_id"),
            StatementSnapshot.snapshot_no.label("snapshot_no"),
            StatementSnapshot.period_id.label("period_id"),
            AccountingPeriod.period_code.label("period_code"),
            StatementSnapshot.statement_type.label("statement_type"),
            StatementSnapshot.report_date.label("report_date"),
            StatementSnapshot.summary_json.label("summary_json"),
            StatementSnapshot.created_at.label("created_at"),
        )
        .join(AccountingPeriod, AccountingPeriod.id == StatementSnapshot.period_id)
        .order_by(StatementSnapshot.id.desc())
        .limit(limit)
    )


def get_return_orders_query(limit: int = 100) -> Select:
    line_subquery = (
        select(
            ReturnItem.return_order_id.label("return_order_id"),
            func.count(ReturnItem.id).label("line_count"),
            func.coalesce(func.sum(ReturnItem.return_qty), 0).label("total_return_qty"),
            func.group_concat(func.distinct(Item.item_name)).label("product_names"),
        )
        .join(Item, Item.id == ReturnItem.product_item_id)
        .group_by(ReturnItem.return_order_id)
        .subquery()
    )
    handler = aliased(Employee)
    return (
        select(
            ReturnOrder.id.label("return_order_id"),
            ReturnOrder.return_no.label("return_no"),
            ReturnOrder.customer_id.label("customer_id"),
            Customer.customer_name.label("customer_name"),
            ReturnOrder.sales_order_id.label("sales_order_id"),
            SalesOrder.order_no.label("order_no"),
            ReturnOrder.delivery_id.label("delivery_id"),
            Delivery.delivery_no.label("delivery_no"),
            ReturnOrder.return_date.label("return_date"),
            ReturnOrder.return_reason.label("return_reason"),
            ReturnOrder.handler_employee_id.label("handler_employee_id"),
            handler.employee_name.label("handler_name"),
            line_subquery.c.product_names.label("product_names"),
            ReturnOrder.status.label("status"),
            func.coalesce(line_subquery.c.line_count, 0).label("line_count"),
            func.coalesce(line_subquery.c.total_return_qty, 0).label("total_return_qty"),
            ReturnOrder.remark.label("remark"),
        )
        .join(Customer, Customer.id == ReturnOrder.customer_id)
        .outerjoin(SalesOrder, SalesOrder.id == ReturnOrder.sales_order_id)
        .outerjoin(Delivery, Delivery.id == ReturnOrder.delivery_id)
        .outerjoin(handler, handler.id == ReturnOrder.handler_employee_id)
        .outerjoin(line_subquery, line_subquery.c.return_order_id == ReturnOrder.id)
        .order_by(ReturnOrder.id.desc())
        .limit(limit)
    )


def get_return_items_query(limit: int = 200, return_order_id: int | None = None) -> Select:
    source_lot = aliased(StockLot)
    source_material_lot = aliased(StockLot)
    source_material_item = aliased(Item)
    stmt = (
        select(
            ReturnItem.id.label("return_item_id"),
            ReturnItem.return_order_id.label("return_order_id"),
            ReturnOrder.return_no.label("return_no"),
            ReturnItem.line_no.label("line_no"),
            ReturnItem.sales_order_item_id.label("sales_order_item_id"),
            ReturnItem.delivery_item_id.label("delivery_item_id"),
            Delivery.delivery_no.label("delivery_no"),
            ReturnItem.product_item_id.label("product_item_id"),
            Item.item_code.label("product_code"),
            Item.item_name.label("product_name"),
            ReturnItem.source_lot_id.label("source_lot_id"),
            source_lot.lot_no.label("source_lot_no"),
            source_lot.source_material_lot_id.label("source_material_lot_id"),
            func.coalesce(source_material_lot.lot_no, source_lot.source_material_sub_batch_no).label("source_material_lot_no"),
            source_material_item.item_code.label("source_material_code"),
            source_material_item.item_name.label("source_material_name"),
            func.coalesce(source_material_lot.lot_no, source_lot.source_material_sub_batch_no).label(
                "source_material_sub_batch_no"
            ),
            source_lot.source_material_summary.label("source_material_summary"),
            ReturnItem.return_qty.label("return_qty"),
            ReturnItem.return_weight_kg.label("return_weight_kg"),
            ReturnItem.disposition_status.label("disposition_status"),
            ReturnItem.responsibility_type.label("responsibility_type"),
            ReturnItem.remark.label("remark"),
        )
        .join(ReturnOrder, ReturnOrder.id == ReturnItem.return_order_id)
        .join(Item, Item.id == ReturnItem.product_item_id)
        .outerjoin(DeliveryItem, DeliveryItem.id == ReturnItem.delivery_item_id)
        .outerjoin(Delivery, Delivery.id == DeliveryItem.delivery_id)
        .outerjoin(source_lot, source_lot.id == ReturnItem.source_lot_id)
        .outerjoin(source_material_lot, source_material_lot.id == source_lot.source_material_lot_id)
        .outerjoin(source_material_item, source_material_item.id == source_material_lot.item_id)
        .order_by(ReturnItem.id.desc())
        .limit(limit)
    )
    if return_order_id:
        stmt = stmt.where(ReturnItem.return_order_id == return_order_id)
    return stmt


def get_return_dispositions_query(limit: int = 100) -> Select:
    rework_work_order = aliased(WorkOrder)
    report_subquery = (
        select(
            OperationReport.work_order_id.label("work_order_id"),
            func.coalesce(func.sum(OperationReport.good_qty), 0).label("rework_report_good_qty"),
            func.coalesce(func.sum(OperationReport.scrap_qty), 0).label("rework_report_scrap_qty"),
        )
        .group_by(OperationReport.work_order_id)
        .subquery()
    )
    finished_inbound_subquery = (
        select(
            InventoryTxn.source_doc_id.label("work_order_id"),
            func.coalesce(func.sum(InventoryTxn.qty_change), 0).label("rework_finished_inbound_qty"),
        )
        .where(
            InventoryTxn.txn_type == "REWORK_FINISHED_IN",
            InventoryTxn.source_doc_type == "WORK_ORDER",
        )
        .group_by(InventoryTxn.source_doc_id)
        .subquery()
    )
    scrap_inbound_subquery = (
        select(
            StockLot.source_doc_id.label("work_order_id"),
            func.coalesce(func.sum(StockLot.inbound_qty), 0).label("rework_scrap_inbound_qty"),
        )
        .where(
            StockLot.lot_role == "REWORK_SCRAP",
            StockLot.source_doc_type == "WORK_ORDER",
        )
        .group_by(StockLot.source_doc_id)
        .subquery()
    )
    report_good_qty = func.coalesce(report_subquery.c.rework_report_good_qty, 0)
    report_scrap_qty = func.coalesce(report_subquery.c.rework_report_scrap_qty, 0)
    finished_inbound_qty = func.coalesce(finished_inbound_subquery.c.rework_finished_inbound_qty, 0)
    scrap_inbound_qty = func.coalesce(scrap_inbound_subquery.c.rework_scrap_inbound_qty, 0)
    remaining_finished_qty = case((report_good_qty - finished_inbound_qty < 0, 0), else_=report_good_qty - finished_inbound_qty)
    remaining_scrap_qty = case((report_scrap_qty - scrap_inbound_qty < 0, 0), else_=report_scrap_qty - scrap_inbound_qty)
    processed_qty = finished_inbound_qty + scrap_inbound_qty
    return (
        select(
            ReturnDisposition.id.label("return_disposition_id"),
            ReturnDisposition.disposition_no.label("disposition_no"),
            ReturnDisposition.return_item_id.label("return_item_id"),
            ReturnOrder.return_no.label("return_no"),
            ReturnItem.product_item_id.label("product_item_id"),
            Item.item_code.label("product_code"),
            Item.item_name.label("product_name"),
            ReturnItem.return_qty.label("return_qty"),
            ReturnItem.return_weight_kg.label("return_weight_kg"),
            ReturnDisposition.disposition_type.label("disposition_type"),
            ReturnDisposition.rework_work_order_id.label("rework_work_order_id"),
            rework_work_order.work_order_no.label("rework_work_order_no"),
            report_good_qty.label("rework_report_good_qty"),
            report_scrap_qty.label("rework_report_scrap_qty"),
            finished_inbound_qty.label("rework_finished_inbound_qty"),
            scrap_inbound_qty.label("rework_scrap_inbound_qty"),
            remaining_finished_qty.label("remaining_rework_finished_inbound_qty"),
            remaining_scrap_qty.label("remaining_rework_scrap_inbound_qty"),
            case((processed_qty >= ReturnItem.return_qty, True), else_=False).label("rework_close_ready"),
            case(
                (func.upper(func.coalesce(rework_work_order.status, "")) == "SETTLED", "已结单"),
                (processed_qty >= ReturnItem.return_qty, "可结单"),
                (processed_qty > 0, "部分处理"),
                else_="待处理",
            ).label("rework_close_status"),
            ReturnDisposition.scrap_weight_kg.label("scrap_weight_kg"),
            ReturnDisposition.extra_cost_amount.label("extra_cost_amount"),
            ReturnDisposition.scrap_sale_amount.label("scrap_sale_amount"),
            ReturnDisposition.closed_at.label("closed_at"),
            ReturnDisposition.status.label("status"),
            ReturnDisposition.remark.label("remark"),
        )
        .join(ReturnItem, ReturnItem.id == ReturnDisposition.return_item_id)
        .join(ReturnOrder, ReturnOrder.id == ReturnItem.return_order_id)
        .join(Item, Item.id == ReturnItem.product_item_id)
        .outerjoin(rework_work_order, rework_work_order.id == ReturnDisposition.rework_work_order_id)
        .outerjoin(report_subquery, report_subquery.c.work_order_id == ReturnDisposition.rework_work_order_id)
        .outerjoin(finished_inbound_subquery, finished_inbound_subquery.c.work_order_id == ReturnDisposition.rework_work_order_id)
        .outerjoin(scrap_inbound_subquery, scrap_inbound_subquery.c.work_order_id == ReturnDisposition.rework_work_order_id)
        .order_by(ReturnDisposition.id.desc())
        .limit(limit)
    )
