Files
Inventory-Management-System/models.py
T
star 33efc7c846 feat: 入库新增「送货日期」字段(与业务日期区分)
- models.Inbound 增加 delivery_date 列(可空, 默认 None)
- 入库单笔录入表单新增「送货日期」输入(默认当天, 可改供应商实际到货日); 出库不受影响
- 物料明细页入库流水新增「送货日期」列展示
- seed_admin 增加幂等补列: 旧库启动时自动 ALTER TABLE inbound ADD COLUMN delivery_date, 开发/EXE 均兼容
- 教程补充送货日期字段说明

(注: instance/app.db 已本地补列, 但未纳入本次提交; dist/app.db 为运行库已 gitignore)
2026-09-23 14:21:57 +08:00

110 lines
4.9 KiB
Python

"""物料入库/出库系统 - 数据模型 (SQLAlchemy 2.0)
实体:
User 账号(admin / manager / operator)
Material 物料主数据
Inbound 入库流水(含"期初"来源的首笔)
Outbound 出库流水(含生产领用)
Bom BOM 清单(产品型号)
BomItem BOM 组成(某物料单套用量)
ProdOrder 生产订单(接单量) -> 按 BOM 展开领料需求
OperationLog 操作日志(谁/何时/做了什么)
库存口径: 在库 = SUM(入库) - SUM(出库), 由 app 实时聚合, 不冗余存储。
"""
import os
from datetime import datetime, date
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, nullable=False, index=True)
password = db.Column(db.String(128), nullable=False) # sha256 hex
role = db.Column(db.String(32), default="operator") # admin / manager / operator
display_name = db.Column(db.String(64), default="")
active = db.Column(db.Boolean, default=True)
class Material(db.Model):
__tablename__ = "material"
id = db.Column(db.Integer, primary_key=True)
part_number = db.Column(db.String(64), unique=True, nullable=False, index=True)
manufacturer = db.Column(db.String(255), default="") # 型号 / 规格
unit = db.Column(db.String(16), default="个")
safety_stock = db.Column(db.Float, default=0) # 安全库存
note = db.Column(db.String(255), default="")
created_at = db.Column(db.DateTime, default=datetime.now)
class Inbound(db.Model):
__tablename__ = "inbound"
id = db.Column(db.Integer, primary_key=True)
material_id = db.Column(db.Integer, db.ForeignKey("material.id"), nullable=False, index=True)
batch_no = db.Column(db.String(64), default="") # 批次号
qty = db.Column(db.Float, nullable=False) # 入库数量(正)
operator = db.Column(db.String(64), default="") # 经手人
source = db.Column(db.String(255), default="") # 来源 / 供应商
occur_date = db.Column(db.Date, default=date.today)
delivery_date = db.Column(db.Date, default=None) # 送货日期(供应商到货日, 可空)
remark = db.Column(db.String(255), default="")
created_at = db.Column(db.DateTime, default=datetime.now)
class Outbound(db.Model):
__tablename__ = "outbound"
id = db.Column(db.Integer, primary_key=True)
material_id = db.Column(db.Integer, db.ForeignKey("material.id"), nullable=False, index=True)
batch_no = db.Column(db.String(64), default="") # 批次号
qty = db.Column(db.Float, nullable=False) # 出库数量(正)
operator = db.Column(db.String(64), default="") # 经手人
purpose = db.Column(db.String(255), default="") # 用途
order_ref = db.Column(db.String(64), default="") # 关联生产单号
occur_date = db.Column(db.Date, default=date.today)
remark = db.Column(db.String(255), default="")
created_at = db.Column(db.DateTime, default=datetime.now)
# ---------------- M2: BOM 与生产订单 ----------------
class Bom(db.Model):
__tablename__ = "bom"
id = db.Column(db.Integer, primary_key=True)
code = db.Column(db.String(64), unique=True, nullable=False, index=True) # BOM 型号简码
name = db.Column(db.String(255), default="")
note = db.Column(db.String(255), default="")
created_at = db.Column(db.DateTime, default=datetime.now)
class BomItem(db.Model):
__tablename__ = "bom_item"
id = db.Column(db.Integer, primary_key=True)
bom_id = db.Column(db.Integer, db.ForeignKey("bom.id"), nullable=False, index=True)
material_id = db.Column(db.Integer, db.ForeignKey("material.id"), nullable=False, index=True)
qty_per_unit = db.Column(db.Float, nullable=False, default=0) # 单套用量
class ProdOrder(db.Model):
__tablename__ = "prod_order"
id = db.Column(db.Integer, primary_key=True)
order_no = db.Column(db.String(64), unique=True, nullable=False, index=True)
bom_id = db.Column(db.Integer, db.ForeignKey("bom.id"), nullable=False, index=True)
qty = db.Column(db.Float, nullable=False, default=0) # 接单量(台/套)
status = db.Column(db.String(32), default="planned") # planned / picked / closed
operator = db.Column(db.String(64), default="")
remark = db.Column(db.String(255), default="")
created_at = db.Column(db.DateTime, default=datetime.now)
# ---------------- M3: 操作日志 ----------------
class OperationLog(db.Model):
__tablename__ = "operation_log"
id = db.Column(db.Integer, primary_key=True)
operator = db.Column(db.String(64), default="")
action = db.Column(db.String(64), default="") # 动作分类
target = db.Column(db.String(255), default="") # 对象
detail = db.Column(db.String(512), default="") # 详情
created_at = db.Column(db.DateTime, default=datetime.now)