"""T+ 字段映射元数据。 这里记录候选字段和确认状态,不把字典中的候选直接当成业务契约。 高风险口径在客户确认前保持 ``PENDING``,同步器只允许写入原始 staging。 """ from dataclasses import dataclass from enum import StrEnum class MappingStatus(StrEnum): """字段映射的证据状态。""" CONFIRMED = "CONFIRMED" CANDIDATE = "CANDIDATE" MISSING = "MISSING" PENDING = "PENDING" @dataclass(frozen=True, slots=True) class TPlusMapping: """一个实体的源表、候选字段和目标表说明。""" entity_type: str source_table: str source_fields: tuple[str, ...] target_table: str status: MappingStatus unresolved: tuple[str, ...] = () version: str = "0.2" schema_evidence: str = "ceshi20261026.bak,2026-10-27 恢复副本结构核验" TPLUS_MAPPINGS: tuple[TPlusMapping, ...] = ( TPlusMapping( "personnel", "AA_Person", ("id", "code", "name", "disabled", "mobilePhoneNo", "officePhoneNo", "iddepartment"), "personnel", MappingStatus.CANDIDATE, ("工号是否等于 code", "经理隶属关系", "入职日期", "试用期"), ), TPlusMapping( "products", "AA_Inventory", ("id", "code", "name", "specification", "idunit", "idinventoryclass"), "products", MappingStatus.CANDIDATE, ("库存数量语义", "参考价来源", "系统产品分类"), ), TPlusMapping( "customers", "AA_Partner", ("id", "code", "name", "Contact", "representative", "disabled", "updated"), "customers", MappingStatus.CANDIDATE, ("客户唯一键", "改名/合并规则", "系统客户分类"), ), TPlusMapping( "businesses", "SA_SaleOrder", ("id", "code", "voucherdate", "idcustomer", "idclerk", "idbusinesstype", "updated"), "businesses", MappingStatus.PENDING, ("成本口径", "业务负责人覆盖规则", "含税口径"), ), TPlusMapping( "shipments", "SA_SaleDelivery", ( "id", "code", "voucherdate", "SendDate", "deliveryDate", "auditeddate", "SourceVoucherCode", "updated", ), "shipments", MappingStatus.PENDING, ("发货日期", "订单关联路径", "退货/红冲规则", "运费来源"), ), TPlusMapping( "receipts", "ARAP_ReceivePayment", ( "id", "code", "voucherDate", "auditedDate", "createdTime", "SaleOrderCode", "SaleOrderID", "ts", ), "receipts", MappingStatus.PENDING, ("到账日期", "收款方式", "核销状态", "回款与发货关联"), ), ) DETAIL_MAPPINGS: tuple[TPlusMapping, ...] = ( TPlusMapping( "business_items", "SA_SaleOrder_b", ("id", "idSaleOrderDTO", "LatestCost"), "business_items", MappingStatus.PENDING, ("成本口径", "含税口径"), ), TPlusMapping( "shipment_items", "SA_SaleDelivery_b", ("ID", "idSaleDeliveryDTO", "saleOrderId"), "shipment_items", MappingStatus.PENDING, ("发货归属", "红冲和退货"), ), TPlusMapping( "receipt_items", "ARAP_ReceivePayment_b", ("id", "idArapReceivePaymentDTO", "saleorderid"), "receipts", MappingStatus.PENDING, ("回款拆分", "核销语义", "增量水位"), ), ) def get_mapping(entity_type: str) -> TPlusMapping: """按实体类型取得映射;未知实体直接拒绝。""" for mapping in (*TPLUS_MAPPINGS, *DETAIL_MAPPINGS): if mapping.entity_type == entity_type: return mapping raise KeyError(f"未知 T+ 实体类型:{entity_type}")