(no commit message provided)
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
This commit is contained in:
@ -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')
|
||||
|
||||
37
inventory-backend/app/api/v1/bom.py
Normal file
37
inventory-backend/app/api/v1/bom.py
Normal 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
|
||||
17
inventory-backend/app/models/bom.py
Normal file
17
inventory-backend/app/models/bom.py
Normal 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')
|
||||
63
inventory-backend/app/services/bom_service.py
Normal file
63
inventory-backend/app/services/bom_service.py
Normal 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
|
||||
Reference in New Issue
Block a user