PayrollManagementSystem/backend/app/services/tplus/report_labels.py
liuwenxin 1e53792ad6 feat(T+): 完成数据贯通与自动接入闭环
打通 T+ 快照、业务、发货、回款和核算准备链路,保留来源差异并提供待补状态。
新增业务自动接入任务、跨平台读取服务托管、权限复核、来源关联和前端核对页面。
补充迁移、隔离集成测试、浏览器模拟验收及角色授权边界修复。
2026-11-05 18:47:13 +08:00

97 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""核对报告中的固定业务说明,未知编码保留以便排查。"""
ACTION_LABELS = {
"CREATE": "新增",
"UPDATE": "更新",
"SKIP": "跳过",
"PENDING": "待补充",
"CONFLICT": "冲突",
"READY": "可核对",
"LEGACY": "旧应收冲平",
"WAITING_SHIPMENT": "预收待发货",
"EXCLUDED": "不纳入本次预演",
}
REASON_LABELS = {
"CORRECTION_PAIR_REQUIRED": "更正单尚未完成正负成对核对,请使用更正单处理入口",
"CORRECTION_RECONFIRM_REQUIRED": "更正单或实际回款来源已变化,请重新核对更正对",
"CORRECTION_EXCLUDED": "转客户正负更正单已成对排除,源单保留",
"REDIRECTED_RECEIPT": "实际回款已归原业务,在本客户不重复计提",
"CUSTOMER_SCOPE_CONFLICT": "同一客户存在不一致的期初或历史范围,请先合并为客户级核对资料",
"GUIDANCE_FINALIZATION_REQUIRED": "发货月份指导成本尚未录入完毕并封存",
"CUSTOMER_SCOPE_ALREADY_SELECTED": "该客户已纳入本次平账,重复选择已跳过",
"FORMAL_TARGET_CHANGED": "正式单据与已导入资料不一致,请先核对差异",
"INDEPENDENT_BUSINESS_REQUIRED": "请先按独立业务核实归属,跨业务冲款边界尚待答复",
"BUSINESS_DATA_PENDING": "该业务仍有资料待补,请查看对应核算预演",
"FORMAL_SOURCE_CHANGED": "源单据或人工依据与正式导入版本不同,请先核对差异",
"SOURCE_PRICE_REVIEW_REQUIRED": "已接入单价与来源未税单价不一致,请核对原单及正式明细",
"PENDING_SOURCE_CUSTOMER_CHANGED": "待核对单据的来源客户已变化,原关联已保留,请核对原单",
"PENDING_SOURCE_OUT_OF_RANGE": "待核对单据的来源日期已早于接入起点,原关联已保留,请核对原单",
"LEGACY_BUSINESS_APPLY_DISABLED": "旧规则预览不能执行,请使用自动业务接入重新生成计划",
"ORDER_SHIPMENT_MISMATCH": "发货关联的订单明细、订单号或产品不一致,请核对来源",
"SOURCE_DOCUMENT_MISSING": "来源单据在最新完整快照中消失,已有记录已保留,请核对",
"SOURCE_ALREADY_IMPORTED": "该源单据已经导入其他业务,不能重复导入",
"CUSTOMER_IMPORT_REQUIRED": "请先完成该客户的基础导入",
"PRODUCT_IMPORT_REQUIRED": "请先完成相关产品的基础导入",
"PERSONNEL_IMPORT_REQUIRED": "请先完成相关业务员及经理的基础导入",
"NOT_IN_PERSONNEL_ROSTER": "不在已确认人员名单中",
"PERSONNEL_IDENTITY_CONFLICT": "工号与名单姓名不一致",
"ROSTER_SOURCE_MISSING": "名单工号未在T+找到",
"BUSINESS_ROLE_MISSING": "系统岗位不存在",
"PRODUCT_CATEGORY_PENDING": "产品核算分类待补",
"PRODUCT_UNIT_PENDING": "产品单位待核对",
"NOT_CUSTOMER_ONLY": "往来单位不是仅客户性质",
"CUSTOMER_ATTRIBUTE_PENDING": "客户核算分类待补",
"TARGET_MISSING": "原导入目标已不存在",
"TARGET_UNIQUE_CONFLICT": "与现有记录唯一键冲突",
"DUPLICATE_SOURCE_IDENTITY": "源记录身份重复",
"GROUP_SCOPE_PENDING": "平账范围待确认",
"GROUP_FACT_REQUIRED": "尚未登记该平账组",
"OVERLAPPING_GROUPS": "同一单据被多个平账组重复选取",
"OPENING_BALANCE_PENDING": "期初应收待核实",
"HISTORICAL_SETTLEMENT_PENDING": "历史已核算或已发款待核实",
"VOUCHER_STATE_PENDING": "尚未核实收款已生成凭证",
"ACCOUNTING_VOUCHER_INVALID": "关联凭证缺失、已作废或制单状态异常",
"VOUCHER_EVIDENCE_CONFLICT": "凭证关联与人工核实不一致,请复核",
"NOT_GENERATED_VOUCHER": "无关联总账凭证,不纳入本次预演",
"NOT_RECEIPT": "属于付款单,不作为销售回款核算",
"GUIDANCE_PENDING": "缺少有效指导成本",
"QUANTITY_PENDING": "单位成本对应的发货数量需核对",
"GUIDANCE_MONTH_BASIS_PENDING": "指导价取值月份待确认",
"PREPAYMENT_PARAMETERS_PENDING": "预收业务采用发货日还是收款日参数待确认",
"AUGUST_RULE_PENDING": "8月调整参数待确认",
"PERSONNEL_PENDING": "归属人员待确认",
"PERSONNEL_ROLE_PENDING": "该业务发生月份的历史岗位待确认",
"CUSTOMER_CATEGORY_PENDING": "客户分类待确认",
"PARAMETERS_PENDING": "计提参数待补",
"NEGATIVE_OR_ZERO_DOCUMENT": "负数或零金额单据需人工核对",
"NEGATIVE_EVENT_REVIEW_REQUIRED": "红冲或作废业务需人工核对",
"LEGACY_SYSTEM_CALCULATES": "只冲旧应收,绩效由原软件计算",
"NO_ACTUAL_SHIPMENT": "未实际发货,暂不计提",
"FREIGHT_PENDING": "运费是否剔除及实际金额待核实",
"SHIPPING_OWNERSHIP_PENDING": "发货业务及人员归属待核实",
"HANDOVER_SHIPMENTS_PENDING": "在职交接的发货归属待核实",
"HANDOVER_PENDING": "离职日期或接手依据待补,不能猜测归属",
"TAX_AMOUNT_PENDING": "源含税金额缺失",
"SHIPMENT_STATE_PENDING": "销货单尚未核实为生效状态",
"GROUP_SOURCE_MISSING": "所选单据不在当前完整快照中",
"GROUP_CUSTOMER_MISMATCH": "平账组含有其他客户单据",
"SHIPMENT_DETAILS_MISSING": "发货明细不完整",
"SOURCE_REFRESH_REQUIRED": "需先完整读取相关源数据",
"AMOUNT_PRECISION_PENDING": "金额精度需核对",
"DATA_VALUE_INVALID": "源日期或金额格式需核对",
}
def reason_label(value):
return ";".join(REASON_LABELS.get(part, part) for part in (value or "").split(",") if part)
def spreadsheet_value(value):
"""防公式注入,并让带前导零的编号在电子表格中保持文本。"""
text = str(value) if value is not None else ""
if text.lstrip(" \t\r\n").startswith(("=", "+", "-", "@")) or (
text.isdigit() and ((text.startswith("0") and len(text) > 1) or len(text) > 15)
):
return "'" + text
return value