(no commit message provided)

Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
This commit is contained in:
dxc
2026-02-09 15:07:54 +08:00
parent fdf22b9973
commit 40abb53721
4 changed files with 124 additions and 0 deletions

View File

@ -0,0 +1,7 @@
from flask import Blueprint
from .inbound import inbound_bp
from .bom import bom_bp
v1_bp = Blueprint('v1', __name__)
v1_bp.register_blueprint(inbound_bp, url_prefix='/inbound')
v1_bp.register_blueprint(bom_bp, url_prefix='/bom')

View File

@ -0,0 +1,37 @@
from flask import Blueprint, request, jsonify, current_app
from app.services.bom_service import BomService
from flask_jwt_extended import jwt_required
bom_bp = Blueprint('bom', __name__)
@bom_bp.route('/<int:parent_id>', methods=['GET'])
@jwt_required()
def get_bom(parent_id):
try:
data = BomService.get_bom_with_stock(parent_id)
return jsonify({
'code': 200,
'msg': 'success',
'data': data
})
except Exception as e:
current_app.logger.error(f'获取BOM失败: {str(e)}')
return jsonify({'code': 500, 'msg': '内部服务器错误'}), 500
@bom_bp.route('', methods=['POST'])
@jwt_required()
def save_bom():
try:
req_data = request.get_json()
parent_id = req_data.get('parent_id')
child_list = req_data.get('children', [])
if not parent_id or not isinstance(child_list, list):
return jsonify({'code': 400, 'msg': '参数错误'}), 400
BomService.create_or_update_bom(parent_id, child_list)
return jsonify({
'code': 200,
'msg': '保存成功'
})
except Exception as e:
current_app.logger.error(f'保存BOM失败: {str(e)}')
return jsonify({'code': 500, 'msg': '内部服务器错误'}), 500

View File

@ -0,0 +1,17 @@
from app.extensions import db
class BomTable(db.Model):
__tablename__ = 'bom_table'
id = db.Column(db.Integer, primary_key=True)
parent_id = db.Column(db.Integer, db.ForeignKey('material_base.id'), nullable=False)
child_id = db.Column(db.Integer, db.ForeignKey('material_base.id'), nullable=False)
bom_no = db.Column(db.String(100), comment='BOM编号')
version = db.Column(db.String(50), comment='版本')
dosage = db.Column(db.Numeric(19, 4), comment='用量')
loss_rate = db.Column(db.Numeric(5, 2), comment='损耗率%')
remark = db.Column(db.Text, comment='备注')
# relationships
parent = db.relationship('MaterialBase', foreign_keys=[parent_id], backref='bom_parents')
child = db.relationship('MaterialBase', foreign_keys=[child_id], backref='bom_children')

View File

@ -0,0 +1,63 @@
from app.extensions import db
from app.models.bom import BomTable
from app.models.base import MaterialBase
from app.models.inbound.buy import StockBuy
from sqlalchemy import func
class BomService:
@staticmethod
def create_or_update_bom(parent_id, child_list):
"""
保存/更新父件的BOM子件关系
child_list: [{"child_id": int, "dosage": float, "remark": str}, ...]
"""
# 删除该父件原有的BOM记录
BomTable.query.filter_by(parent_id=parent_id).delete()
# 插入新的
for item in child_list:
bom = BomTable(
parent_id=parent_id,
child_id=item['child_id'],
dosage=item.get('dosage', 0),
remark=item.get('remark', '')
)
db.session.add(bom)
db.session.commit()
return True
@staticmethod
def get_bom_with_stock(parent_id):
"""
查询父件的BOM结构及库存信息
"""
bom_items = db.session.query(
BomTable,
MaterialBase.name.label('child_name')
).join(
MaterialBase, BomTable.child_id == MaterialBase.id
).filter(
BomTable.parent_id == parent_id
).all()
result = []
for bom, child_name in bom_items:
# 查询该子件在 StockBuy 中的可用库存总量
stock_qty = db.session.query(
func.coalesce(func.sum(StockBuy.available_quantity), 0)
).filter(
StockBuy.base_id == bom.child_id
).scalar() or 0
# 计算最大可生产数量
dosage = float(bom.dosage) if bom.dosage else 0
max_producible = int(stock_qty // dosage) if dosage > 0 else 0
result.append({
'child_id': bom.child_id,
'child_name': child_name,
'dosage': dosage,
'current_stock': float(stock_qty),
'max_producible': max_producible,
'remark': bom.remark or ''
})
return result