"""战略地图 · 收入口径(revenue caliber)状态 —— 单一事实源 口径来源:改造单 `project-20261018-cma-strategy-map-ux-revamp-fullstack` 增量 v2 §4。 截至本文件落地(2026-10-18T23:00),A1 收入口径**尚未闭合**: - 业务称谓「代理」≠ 会计判定(总额法 total / 净额法 net / 混合 mixed 未裁); - 财务净额件与项目侧「三问」总额判定并存,正由 A1 补充单裁决。 因此本模块只声明**状态**与**业务线维度**,不存任何金额: - 接口照常返回 `revenue_caliber` 与分业务位(amount=None + status=pending); - 前端不得写死任一方法,不得把两块合并成一个「营业收入」; - 口径闭合后只改本文件(status/caliber/decided_by/closed_at),并回填金额取数逻辑, 不需要改前端。 铁律:未闭合前,页面与接口都**不得**输出单一汇总收入数。 """ # 口径状态:unclosed / closed STATUS = "unclosed" CALIBER = None # closed 时取 "total" / "net" / "mixed" CALIBER_LABEL = "口径待定" DECIDED_BY = None # closed 时填裁决单/ASK 编号 CLOSED_AT = None # ISO 时间 REASON = ( "A1 收入口径尚未闭合(截至 2026-10-18T23:00):业务称谓「代理」≠ 会计判定," "总额法/净额法/混合法并存,待 A1 补充单裁决" ) # 分业务(不得合并;amount 由 closed 后的取数逻辑回填) BUSINESS_LINES = [ {"key": "liquor_agency", "label": "酒类代销"}, {"key": "it_self", "label": "IT自营"}, ] def snapshot(entity_id: int) -> dict: """返回对外口径快照(无金额;未闭合时 amount 一律 None)。""" return { "entity_id": entity_id, "status": STATUS, "caliber": CALIBER, "caliber_label": CALIBER_LABEL, "caliber_options": [ {"key": "total", "label": "总额法"}, {"key": "net", "label": "净额法"}, {"key": "mixed", "label": "混合法"}, ], "decided_by": DECIDED_BY, "closed_at": CLOSED_AT, "reason": REASON, "businesses": [ { "key": b["key"], "label": b["label"], "amount": None, "unit": "万元", "status": "pending", "missing_reason": "收入口径未闭合" if STATUS != "closed" else None, } for b in BUSINESS_LINES ], "allow_single_total": STATUS == "closed", "note": "未闭合前不显示单一汇总数;分业务分列,不合并为「营业收入」", }