补齐源快照、资料预演、正式导入及工资核算的依赖链路。 新增版本化输入、逐段 FIFO、生成锁和结构化当月调整, 并提供默认关闭的周期采集、有限重试及 Windows 托管。 原始客户资料、私有配置及首页改动不纳入本次提交。 BREAKING CHANGE: 升级前需应用新增迁移,并通过 PAYROLL_MAKER_USER_ID 绑定实际工资制作人,否则业务只读。 旧单批次核算默认关闭;历史兼容需显式启用 PAYROLL_ALLOW_LEGACY_CALCULATION。生产启用和真实金额待验收。
67 lines
3.5 KiB
Python
67 lines
3.5 KiB
Python
"""正式工资输入、分配过程与月度生成锁,和隔离预演分别留存。"""
|
|
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
|
|
from sqlalchemy import JSON, DateTime, Index, Integer, Numeric, String, UniqueConstraint
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.models.base import BIGINT_UNSIGNED, Base, TimestampMixin, mysql_table_args
|
|
|
|
|
|
class PayrollMonth(Base, TimestampMixin):
|
|
"""先锁月份行再修改方案或生成工资;生成标记不随审批退回清除。"""
|
|
|
|
__tablename__ = "payroll_months"
|
|
__table_args__ = mysql_table_args("工资月份控制表(首次生成即锁定分配,审批不解锁)")
|
|
id: Mapped[int] = mapped_column(
|
|
BIGINT_UNSIGNED, primary_key=True, autoincrement=True, comment="主键ID"
|
|
)
|
|
month: Mapped[str] = mapped_column(String(7), unique=True, comment="工资月份")
|
|
maker_id: Mapped[int] = mapped_column(BIGINT_UNSIGNED, comment="实际工资制作人账号ID")
|
|
maker_name: Mapped[str] = mapped_column(String(64), comment="制作人用户名快照")
|
|
generated_at: Mapped[datetime | None] = mapped_column(
|
|
DateTime, comment="首次成功生成时间(不可解锁)"
|
|
)
|
|
|
|
|
|
class PayrollInput(Base, TimestampMixin):
|
|
"""正式核算输入的版本:来源、成本、归属及期初均有依据,旧版本不覆盖。"""
|
|
|
|
__tablename__ = "payroll_inputs"
|
|
__table_args__ = mysql_table_args(
|
|
"正式工资输入版本表",
|
|
UniqueConstraint("business_id", "version", name="uk_payroll_inputs_business_version"),
|
|
Index("idx_payroll_inputs_source_group", "source_database", "group_key"),
|
|
)
|
|
id: Mapped[int] = mapped_column(
|
|
BIGINT_UNSIGNED, primary_key=True, autoincrement=True, comment="主键ID"
|
|
)
|
|
business_id: Mapped[int] = mapped_column(BIGINT_UNSIGNED, comment="正式业务ID")
|
|
version: Mapped[int] = mapped_column(Integer, comment="输入版本")
|
|
source_database: Mapped[str] = mapped_column(String(128), comment="源账套或人工来源")
|
|
group_key: Mapped[str] = mapped_column(String(128), comment="独立业务平账组")
|
|
fingerprint: Mapped[str] = mapped_column(String(64), comment="来源及事实指纹")
|
|
data_json: Mapped[dict] = mapped_column(JSON, comment="经核实的源数据及人工事实快照")
|
|
requested_by: Mapped[int] = mapped_column(BIGINT_UNSIGNED, comment="录入人账号ID")
|
|
|
|
|
|
class PayrollAllocation(Base, TimestampMixin):
|
|
"""一次正式计算的逐段过程;版本不可变,生效性由所属台账控制。"""
|
|
|
|
__tablename__ = "payroll_allocations"
|
|
__table_args__ = mysql_table_args(
|
|
"正式FIFO分配明细表",
|
|
UniqueConstraint("ledger_id", "line_no", name="uk_payroll_allocations_ledger_line"),
|
|
Index("idx_payroll_allocations_business_id", "business_id"),
|
|
)
|
|
id: Mapped[int] = mapped_column(
|
|
BIGINT_UNSIGNED, primary_key=True, autoincrement=True, comment="主键ID"
|
|
)
|
|
ledger_id: Mapped[int] = mapped_column(BIGINT_UNSIGNED, comment="所属正式台账ID")
|
|
business_id: Mapped[int] = mapped_column(BIGINT_UNSIGNED, comment="正式业务ID")
|
|
line_no: Mapped[int] = mapped_column(Integer, comment="本台账稳定明细序号")
|
|
input_id: Mapped[int] = mapped_column(BIGINT_UNSIGNED, comment="所用输入版本ID")
|
|
amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), comment="分配回款金额")
|
|
data_json: Mapped[dict] = mapped_column(JSON, comment="单据、成本、归属、参数和逐段计算依据")
|