feat(核算)!: 添加 T+ 正式核算与采集托管
补齐源快照、资料预演、正式导入及工资核算的依赖链路。 新增版本化输入、逐段 FIFO、生成锁和结构化当月调整, 并提供默认关闭的周期采集、有限重试及 Windows 托管。 原始客户资料、私有配置及首页改动不纳入本次提交。 BREAKING CHANGE: 升级前需应用新增迁移,并通过 PAYROLL_MAKER_USER_ID 绑定实际工资制作人,否则业务只读。 旧单批次核算默认关闭;历史兼容需显式启用 PAYROLL_ALLOW_LEGACY_CALCULATION。生产启用和真实金额待验收。
This commit is contained in:
1 parent
1b074576fe
commit
108bf87225
154 files changed
+9515
-645
No files matched your search
@@ -0,0 +1,52 @@
|
||||
export const factKinds = { PERSONNEL: '人员名单', PRODUCT: '产品分类与单位', CUSTOMER: '客户分类与负责人', GROUP: '平账范围与期初应收', GUIDANCE: '月度指导成本', RECEIPT: '收款凭证核实', SHIPMENT: '发货归属与运费核实', HANDOVER: '业务交接', MANAGER: '经理分管业务', CORRECTION: 'T+更正单处理' }
|
||||
export const workKinds = { MASTER_PREVIEW: '基础导入预览', MASTER_APPLY: '基础数据导入', CALC_PREVIEW: '核算预演', BUSINESS_PREVIEW: '正式业务导入预览', BUSINESS_APPLY: '正式业务导入' }
|
||||
export const actions: Record<string, string> = { EXCLUDED: '不纳入本次预演', CREATE: '新增', UPDATE: '更新', SKIP: '跳过', PENDING: '待补充', CONFLICT: '冲突', READY: '可核对', LEGACY: '旧应收冲平', WAITING_SHIPMENT: '预收待发货', QUEUED: '排队中', RUNNING: '处理中', SUCCEEDED: '处理完成', PARTIAL: '部分待处理', FAILED: '失败' }
|
||||
export const reasons: Record<string, string> = {
|
||||
CUSTOMER_SCOPE_CONFLICT: '同一客户的期初或历史范围不一致,请先合并核对资料',
|
||||
GUIDANCE_FINALIZATION_REQUIRED: '发货月份指导成本尚未录入完毕并封存',
|
||||
CUSTOMER_SCOPE_ALREADY_SELECTED: '该客户已纳入本次平账,重复选择已跳过',
|
||||
FORMAL_SOURCE_CHANGED: '源单据或依据与正式版本不同,请先核对差异',
|
||||
FORMAL_TARGET_CHANGED: '正式单据与已导入资料不一致,请先核对差异',
|
||||
SOURCE_ALREADY_IMPORTED: '该源单据已经导入,不能重复占用',
|
||||
CUSTOMER_IMPORT_REQUIRED: '请先完成客户基础导入',
|
||||
PRODUCT_IMPORT_REQUIRED: '请先完成产品基础导入',
|
||||
PERSONNEL_IMPORT_REQUIRED: '相关人员尚未在本账套唯一关联,请核对工号及基础导入',
|
||||
BUSINESS_DATA_PENDING: '该客户业务资料仍待补充,请查看对应预演结果',
|
||||
NOT_IN_PERSONNEL_ROSTER: '不在已确认人员名单中', PERSONNEL_IDENTITY_CONFLICT: '工号与名单姓名不一致',
|
||||
BUSINESS_ROLE_MISSING: '系统岗位不存在', PRODUCT_CATEGORY_PENDING: '产品类型待填写',
|
||||
PRODUCT_UNIT_PENDING: '产品单位待核对', NOT_CUSTOMER_ONLY: '往来单位性质不是仅客户',
|
||||
CUSTOMER_ATTRIBUTE_PENDING: '客户属性或负责人待核对', TARGET_MISSING: '原导入目标已不存在',
|
||||
TARGET_UNIQUE_CONFLICT: '与现有数据重名或唯一键冲突', DUPLICATE_SOURCE_IDENTITY: '源数据身份重复',
|
||||
ROSTER_SOURCE_MISSING: '名单中的工号未在T+找到', PREVIEW_STALE: '数据或资料已变化,请重新预览',
|
||||
SOURCE_REFRESH_REQUIRED: '请先完整读取相关源数据', SOURCE_CHANGED: '源账套配置已变化',
|
||||
INTERRUPTED: '任务被中断,请重新创建任务', EXECUTION_ERROR: '执行失败,请核对配置和输入',
|
||||
GROUP_SCOPE_PENDING: '平账范围待明确', OPENING_BALANCE_PENDING: '期初应收待核实',
|
||||
HISTORICAL_SETTLEMENT_PENDING: '历史已核算及已发放款待核实',
|
||||
VOUCHER_STATE_PENDING: '收款尚未核实已生成凭证', GUIDANCE_PENDING: '缺少对应指导成本',
|
||||
GUIDANCE_MONTH_BASIS_PENDING: '指导价取发货月还是回款月尚未明确',
|
||||
AUGUST_RULE_PENDING: '2026年8月后的调整参数尚未确认', PERSONNEL_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: '在职交接的发货归属待确认', TAX_AMOUNT_PENDING: '源含税金额缺失',
|
||||
GROUP_SOURCE_MISSING: '所选单据未在本次完整快照中找到', GROUP_CUSTOMER_MISMATCH: '平账组包含其他客户的单据',
|
||||
SHIPMENT_DETAILS_MISSING: '发货明细不完整', OVERLAPPING_GROUPS: '单据被多个平账组重复选取',
|
||||
AMOUNT_PRECISION_PENDING: '金额精度超过分,需核对舍入口径', DATA_VALUE_INVALID: '源日期或金额格式需核对',
|
||||
REPLAY_UNAVAILABLE: '该记录缺少可重跑快照或规则版本已变化,请保留原报告并新建预演',
|
||||
QUANTITY_PENDING: '单位成本对应的发货数量需核对',
|
||||
GROUP_FACT_REQUIRED: '尚未登记该平账组',
|
||||
PREPAYMENT_PARAMETERS_PENDING: '预收业务采用发货日还是收款日参数待确认',
|
||||
HANDOVER_PENDING: '离职日期或接手依据待补,不能猜测归属',
|
||||
ACCOUNTING_VOUCHER_INVALID: '关联凭证缺失、已作废或制单状态异常',
|
||||
VOUCHER_EVIDENCE_CONFLICT: '凭证关联与人工核实不一致,请复核',
|
||||
NOT_GENERATED_VOUCHER: '无关联总账凭证,不纳入本次预演',
|
||||
NOT_RECEIPT: '属于付款单,不作为销售回款核算',
|
||||
SHIPMENT_STATE_PENDING: '销货单尚未核实为生效状态',
|
||||
CORRECTION_EXCLUDED: '已核对更正单,保留源记录但不参与绩效核算',
|
||||
REDIRECTED_RECEIPT: '回款已按核对结果归入原业务,当前客户不重复计提',
|
||||
}
|
||||
export function reasonText(value: unknown): string {
|
||||
const parts = Array.isArray(value) ? value : String(value ?? '').split(',')
|
||||
return parts.filter(Boolean).map(v => reasons[String(v)] ?? String(v)).join(';')
|
||||
}
|
||||
Reference in new issue
Block a user