feat: 打通采购申请与入库的按单入库链路

后端变更:
- PurchaseRequest 新增 base_id 硬关联 MaterialBase,StockBuy 新增 request_id 关联采购单
- handle_inbound 支持 request_id 入参,入库后自动反写采购单状态为已完成
- 新增 get_approved_requests 接口,返回已审批未入库采购单列表(含物料信息+历史数据回退匹配)
- create_purchase_request 新增 name+spec_model 自动匹配 MaterialBase
- 新增 SQL 和 Alembic 数据库迁移脚本

前端变更:
- 入库表单新增"从采购单导入"弹窗,支持搜索/选中已审批采购单并一键填充物料和商务信息
- 单价/总价交叉推算,缺项自动补全
- 选中行蓝色高亮+点击整行选中,行级交互优化
This commit is contained in:
yueli
2026-07-14 15:25:00 +08:00
parent 88b754120b
commit a11b7972c3
9 changed files with 643 additions and 16 deletions

View File

@ -0,0 +1,79 @@
"""打通采购申请与采购入库的按单入库链路
Revision ID: a1b2c3d4e5f6
Revises: None (或填当前最新 revision)
Create Date: 2026-07-14
变更内容:
1. purchase_request 表新增 base_id (FK → material_base.id)
2. stock_buy 表新增 request_id (FK → purchase_request.id)
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'a1b2c3d4e5f6'
down_revision = None # ← 替换为当前最新 revision ID
branch_labels = None
depends_on = None
def upgrade():
# ============================================================
# 1. purchase_request 新增 base_id
# ============================================================
with op.batch_alter_table('purchase_request', schema=None) as batch_op:
batch_op.add_column(
sa.Column('base_id', sa.Integer(), nullable=True,
comment='关联基础物料ID')
)
batch_op.create_foreign_key(
'fk_purchase_request_base_id',
'material_base',
['base_id'],
['id'],
ondelete='SET NULL'
)
batch_op.create_index(
'ix_purchase_request_base_id',
['base_id']
)
# ============================================================
# 2. stock_buy 新增 request_id
# ============================================================
with op.batch_alter_table('stock_buy', schema=None) as batch_op:
batch_op.add_column(
sa.Column('request_id', sa.Integer(), nullable=True,
comment='关联采购申请单ID')
)
batch_op.create_foreign_key(
'fk_stock_buy_request_id',
'purchase_request',
['request_id'],
['id'],
ondelete='SET NULL'
)
batch_op.create_index(
'ix_stock_buy_request_id',
['request_id']
)
def downgrade():
# ============================================================
# 回滚:stock_buy 删除 request_id
# ============================================================
with op.batch_alter_table('stock_buy', schema=None) as batch_op:
batch_op.drop_constraint('fk_stock_buy_request_id', type_='foreignkey')
batch_op.drop_index('ix_stock_buy_request_id')
batch_op.drop_column('request_id')
# ============================================================
# 回滚:purchase_request 删除 base_id
# ============================================================
with op.batch_alter_table('purchase_request', schema=None) as batch_op:
batch_op.drop_constraint('fk_purchase_request_base_id', type_='foreignkey')
batch_op.drop_index('ix_purchase_request_base_id')
batch_op.drop_column('base_id')