Files
cma-management/backend/app/models/cost_model.py
T
Hermes CI Fix fb9eba38a8 feat: 多租户隔离P2批2 — 预算/成本/费用/预警规则/BI报表加entity_id
- 12表加entity_id列(预算/偏差/规则/成本4表/费用2表/BI2表/驱动预算)
- 模型: BudgetPlan/StandardCost/ActualCost/AbcActivity/AbcAllocation/DriverFactorBudget/BiReport/Template/BudgetDeviationAlert/ExpenseRule/Reimbursement/AlertRule
- API隔离: budget plans / cost standard+actual / expenses rules+reimb / bi_reports list / alert_rules list 按token企业过滤
- 回填: kpi_id关联按KPI归属, 无关联默认酣客(entity=1); 当前数据全归酣客
- 验证: import+全端点200+pytest 451 passed
2026-08-23 18:20:29 +08:00

79 lines
4.4 KiB
Python

"""成本分析模型 — 管理会计OS
标准成本卡片、实际成本归集、作业成本法(ABC)
"""
from sqlalchemy import Column, Integer, String, Float, DateTime, Text, ForeignKey, JSON, func
from app.database import Base
class StandardCost(Base):
"""标准成本卡片 — 每项产品或服务的标准成本构成"""
__tablename__ = "standard_costs"
id = Column(Integer, primary_key=True, index=True)
entity_id = Column(Integer, default=1, comment="企业ID (P2多租户隔离 2026-08-23)")
product_code = Column(String(50), nullable=False, comment="产品/服务编码")
product_name = Column(String(200), nullable=False, comment="产品/服务名称")
cost_type = Column(String(20), nullable=False, comment="成本类型: material/labor/overhead")
item_name = Column(String(200), nullable=False, comment="成本项目名称")
standard_quantity = Column(Float, nullable=False, comment="标准用量")
unit = Column(String(20), nullable=True, comment="单位")
standard_price = Column(Float, nullable=False, comment="标准单价")
standard_cost = Column(Float, nullable=False, comment="标准成本 = 用量×单价")
version = Column(String(20), default="v1.0", comment="版本号")
status = Column(String(20), default="active", comment="active/archived")
remark = Column(Text, nullable=True)
created_at = Column(DateTime, server_default=func.now())
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
class ActualCost(Base):
"""实际成本归集 — 从ERP/手工录入的实际成本"""
__tablename__ = "actual_costs"
id = Column(Integer, primary_key=True, index=True)
entity_id = Column(Integer, default=1, comment="企业ID (P2多租户隔离 2026-08-23)")
period = Column(String(20), nullable=False, comment="期间 2026-05")
product_code = Column(String(50), nullable=False, comment="产品/服务编码")
product_name = Column(String(200), nullable=False, comment="产品/服务名称")
cost_type = Column(String(20), nullable=False, comment="成本类型: material/labor/overhead")
item_name = Column(String(200), nullable=False, comment="成本项目名称")
actual_quantity = Column(Float, nullable=False, comment="实际用量")
actual_price = Column(Float, nullable=False, comment="实际单价")
actual_cost = Column(Float, nullable=False, comment="实际成本 = 用量×单价")
source = Column(String(50), default="manual", comment="数据来源: erp/manual")
created_at = Column(DateTime, server_default=func.now())
class AbcActivity(Base):
"""ABC作业中心定义"""
__tablename__ = "abc_activities"
id = Column(Integer, primary_key=True, index=True)
entity_id = Column(Integer, default=1, comment="企业ID (P2多租户隔离 2026-08-23)")
activity_code = Column(String(50), unique=True, nullable=False, comment="作业编码")
activity_name = Column(String(200), nullable=False, comment="作业名称")
activity_desc = Column(Text, nullable=True, comment="作业描述")
cost_driver = Column(String(100), nullable=False, comment="成本动因")
driver_unit = Column(String(50), nullable=True, comment="动因单位")
total_cost = Column(Float, default=0, comment="作业总成本")
driver_volume = Column(Float, default=0, comment="动因总量")
driver_rate = Column(Float, default=0, comment="动因分配率 = 总成本/动因总量")
status = Column(String(20), default="active", comment="active/inactive")
created_at = Column(DateTime, server_default=func.now())
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
class AbcAllocation(Base):
"""ABC成本分配记录 — 按动因分配到产品"""
__tablename__ = "abc_allocations"
id = Column(Integer, primary_key=True, index=True)
entity_id = Column(Integer, default=1, comment="企业ID (P2多租户隔离 2026-08-23)")
period = Column(String(20), nullable=False, comment="期间 2026-05")
activity_id = Column(Integer, ForeignKey("abc_activities.id"), nullable=False)
product_code = Column(String(50), nullable=False, comment="产品/服务编码")
product_name = Column(String(200), nullable=False, comment="产品/服务名称")
driver_consumed = Column(Float, nullable=False, comment="消耗的动因量")
allocated_cost = Column(Float, nullable=False, comment="分配的成本")
created_at = Column(DateTime, server_default=func.now())