增加委外管理模块
This commit is contained in:
parent
23cf2ed453
commit
a04c222f0a
@ -152,6 +152,26 @@
|
||||
<a href="#/plan-mgmt/reconciliation" class="dropdown-item" data-route="plan-mgmt-reconciliation">对账单</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topnav-item has-dropdown" data-menu="outsourcing">
|
||||
<span class="nav-left">
|
||||
<span class="nav-icon" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" />
|
||||
<circle cx="9" cy="7" r="4" />
|
||||
<path d="M22 21v-2a4 4 0 0 0-3-3.87" />
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="topnav-text">委外管理</span>
|
||||
</span>
|
||||
<span class="topnav-caret"></span>
|
||||
<div class="topnav-dropdown">
|
||||
<a href="#/outsourcing-mgmt/orders" class="dropdown-item" data-route="outsourcing-mgmt-orders">委外工单</a>
|
||||
<a href="#/outsourcing-mgmt/material-issue" class="dropdown-item" data-route="outsourcing-mgmt-material-issue">委外发料</a>
|
||||
<a href="#/outsourcing-mgmt/finished-goods-receipt" class="dropdown-item" data-route="outsourcing-mgmt-finished-goods-receipt">成品入库</a>
|
||||
<a href="#/outsourcing-mgmt/wip-stock" class="dropdown-item" data-route="outsourcing-mgmt-wip-stock">委外在制库存</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topnav-item has-dropdown" data-menu="collect">
|
||||
<span class="nav-left">
|
||||
<span class="nav-icon" aria-hidden="true">
|
||||
@ -475,6 +495,10 @@
|
||||
<script src="./js/components/purchase-demand.js?v=20260312" defer></script>
|
||||
<script src="./js/components/customer-order.js" defer></script>
|
||||
<script src="./js/components/reconciliation.js" defer></script>
|
||||
<script src="./js/components/outsourcing-orders.js" defer></script>
|
||||
<script src="./js/components/outsourcing-material-issue.js" defer></script>
|
||||
<script src="./js/components/finished-goods-receipt.js" defer></script>
|
||||
<script src="./js/components/outsourcing-wip-stock.js" defer></script>
|
||||
<script src="./js/components/export.js" defer></script>
|
||||
<script src="./js/components/settings.js" defer></script>
|
||||
<script src="./js/components/notifications.js" defer></script>
|
||||
|
||||
490
server/app.py
490
server/app.py
@ -314,6 +314,65 @@ def init_db():
|
||||
updated_at TEXT
|
||||
)''')
|
||||
|
||||
# 委外工单表 - 记录委外生产订单
|
||||
c.execute('''CREATE TABLE IF NOT EXISTS outsourcing_orders(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
order_no TEXT NOT NULL UNIQUE,
|
||||
customer_order_no TEXT NOT NULL,
|
||||
product_code TEXT NOT NULL,
|
||||
product_name TEXT NOT NULL,
|
||||
production_qty INTEGER NOT NULL,
|
||||
outsourcing_factory TEXT NOT NULL,
|
||||
delivery_date TEXT NOT NULL,
|
||||
status TEXT DEFAULT 'pending',
|
||||
created_by TEXT,
|
||||
created_at TEXT,
|
||||
updated_at TEXT
|
||||
)''')
|
||||
|
||||
# 委外发料表 - 记录发给外协厂的物料
|
||||
c.execute('''CREATE TABLE IF NOT EXISTS outsourcing_material_issue(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
issue_no TEXT NOT NULL UNIQUE,
|
||||
outsourcing_order_no TEXT NOT NULL,
|
||||
material_code TEXT NOT NULL,
|
||||
material_name TEXT NOT NULL,
|
||||
issue_qty INTEGER NOT NULL,
|
||||
unit TEXT DEFAULT 'pcs',
|
||||
issue_date TEXT NOT NULL,
|
||||
created_by TEXT,
|
||||
created_at TEXT,
|
||||
updated_at TEXT,
|
||||
FOREIGN KEY(outsourcing_order_no) REFERENCES outsourcing_orders(order_no)
|
||||
)''')
|
||||
|
||||
# 委外在制库存表 - 记录发给外协厂但未完工的物料
|
||||
c.execute('''CREATE TABLE IF NOT EXISTS outsourcing_wip_stock(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
outsourcing_order_no TEXT NOT NULL,
|
||||
material_code TEXT NOT NULL UNIQUE,
|
||||
material_name TEXT NOT NULL,
|
||||
wip_qty INTEGER DEFAULT 0,
|
||||
unit TEXT DEFAULT 'pcs',
|
||||
updated_at TEXT,
|
||||
FOREIGN KEY(outsourcing_order_no) REFERENCES outsourcing_orders(order_no)
|
||||
)''')
|
||||
|
||||
# 成品入库表 - 记录外协厂完工的整机入库
|
||||
c.execute('''CREATE TABLE IF NOT EXISTS finished_goods_receipt(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
receipt_no TEXT NOT NULL UNIQUE,
|
||||
outsourcing_order_no TEXT NOT NULL,
|
||||
product_code TEXT NOT NULL,
|
||||
product_name TEXT NOT NULL,
|
||||
receipt_qty INTEGER NOT NULL,
|
||||
receipt_date TEXT NOT NULL,
|
||||
created_by TEXT,
|
||||
created_at TEXT,
|
||||
updated_at TEXT,
|
||||
FOREIGN KEY(outsourcing_order_no) REFERENCES outsourcing_orders(order_no)
|
||||
)''')
|
||||
|
||||
conn.commit()
|
||||
# create default admin
|
||||
c.execute('SELECT id FROM users WHERE username=?', ('admin',))
|
||||
@ -7159,6 +7218,437 @@ def import_purchase_demand():
|
||||
conn.close()
|
||||
|
||||
|
||||
# ==================== 委外工单管理 API ====================
|
||||
|
||||
@app.get('/api/outsourcing-orders')
|
||||
@require_login
|
||||
@require_any_role('superadmin', 'admin')
|
||||
def get_outsourcing_orders():
|
||||
"""获取委外工单列表"""
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
c.execute('SELECT * FROM outsourcing_orders ORDER BY created_at DESC')
|
||||
rows = c.fetchall()
|
||||
conn.close()
|
||||
return jsonify({'list': [dict(r) for r in rows]})
|
||||
|
||||
|
||||
@app.post('/api/outsourcing-orders')
|
||||
@require_login
|
||||
@require_any_role('superadmin', 'admin')
|
||||
def create_outsourcing_order():
|
||||
"""创建委外工单"""
|
||||
data = request.get_json() or {}
|
||||
|
||||
customer_order_no = data.get('customer_order_no', '').strip()
|
||||
product_code = data.get('product_code', '').strip()
|
||||
product_name = data.get('product_name', '').strip()
|
||||
production_qty = data.get('production_qty', 0)
|
||||
outsourcing_factory = data.get('outsourcing_factory', '').strip()
|
||||
delivery_date = data.get('delivery_date', '').strip()
|
||||
|
||||
if not all([customer_order_no, product_code, product_name, outsourcing_factory, delivery_date]):
|
||||
return jsonify({'error': '请填写所有必填字段'}), 400
|
||||
|
||||
try:
|
||||
production_qty = int(production_qty)
|
||||
if production_qty <= 0:
|
||||
return jsonify({'error': '生产数量必须大于0'}), 400
|
||||
except (ValueError, TypeError):
|
||||
return jsonify({'error': '生产数量必须是有效整数'}), 400
|
||||
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
|
||||
# 生成委外工单号 WW+年月日+4位流水号
|
||||
now = get_beijing_time()
|
||||
date_str = datetime.now().strftime('%Y%m%d')
|
||||
c.execute("SELECT COUNT(*) FROM outsourcing_orders WHERE order_no LIKE ?", (f'WW{date_str}%',))
|
||||
count = c.fetchone()[0]
|
||||
order_no = f'WW{date_str}{str(count + 1).zfill(4)}'
|
||||
|
||||
username = session.get('username', '')
|
||||
|
||||
try:
|
||||
c.execute('''INSERT INTO outsourcing_orders(
|
||||
order_no, customer_order_no, product_code, product_name,
|
||||
production_qty, outsourcing_factory, delivery_date, status,
|
||||
created_by, created_at, updated_at
|
||||
) VALUES(?,?,?,?,?,?,?,?,?,?,?)''', (
|
||||
order_no, customer_order_no, product_code, product_name,
|
||||
production_qty, outsourcing_factory, delivery_date, 'pending',
|
||||
username, now, now
|
||||
))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
log('create_outsourcing_order', f'创建委外工单: {order_no}')
|
||||
return jsonify({'ok': True, 'order_no': order_no, 'message': '委外工单创建成功'})
|
||||
except Exception as e:
|
||||
conn.close()
|
||||
return jsonify({'error': f'创建失败: {str(e)}'}), 500
|
||||
|
||||
|
||||
@app.get('/api/outsourcing-orders/<int:order_id>')
|
||||
@require_login
|
||||
@require_any_role('superadmin', 'admin')
|
||||
def get_outsourcing_order_detail(order_id):
|
||||
"""获取委外工单详情及物料明细"""
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
|
||||
# 获取工单基本信息
|
||||
c.execute('SELECT * FROM outsourcing_orders WHERE id=?', (order_id,))
|
||||
order = c.fetchone()
|
||||
|
||||
if not order:
|
||||
conn.close()
|
||||
return jsonify({'error': '委外工单不存在'}), 404
|
||||
|
||||
# 获取该产品的BOM物料清单
|
||||
c.execute('SELECT * FROM bom WHERE product_code=?', (order['product_code'],))
|
||||
bom_list = c.fetchall()
|
||||
|
||||
# 计算每种物料的需发数量 = BOM用量 * 生产数量
|
||||
materials = []
|
||||
for bom in bom_list:
|
||||
need_qty = int(math.ceil(bom['unit_qty'] * order['production_qty']))
|
||||
materials.append({
|
||||
'material_code': bom['material_code'],
|
||||
'material_name': bom['material_name'],
|
||||
'bom_unit_qty': bom['unit_qty'],
|
||||
'need_qty': need_qty,
|
||||
'unit': bom['unit']
|
||||
})
|
||||
|
||||
conn.close()
|
||||
|
||||
return jsonify({
|
||||
'order': dict(order),
|
||||
'materials': materials
|
||||
})
|
||||
|
||||
|
||||
@app.put('/api/outsourcing-orders/<int:order_id>')
|
||||
@require_login
|
||||
@require_any_role('superadmin', 'admin')
|
||||
def update_outsourcing_order(order_id):
|
||||
"""更新委外工单"""
|
||||
data = request.get_json() or {}
|
||||
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
|
||||
c.execute('SELECT * FROM outsourcing_orders WHERE id=?', (order_id,))
|
||||
existing = c.fetchone()
|
||||
|
||||
if not existing:
|
||||
conn.close()
|
||||
return jsonify({'error': '委外工单不存在'}), 404
|
||||
|
||||
update_fields = []
|
||||
update_values = []
|
||||
|
||||
if 'production_qty' in data:
|
||||
update_fields.append('production_qty=?')
|
||||
update_values.append(int(data['production_qty']))
|
||||
|
||||
if 'outsourcing_factory' in data:
|
||||
update_fields.append('outsourcing_factory=?')
|
||||
update_values.append(data['outsourcing_factory'])
|
||||
|
||||
if 'delivery_date' in data:
|
||||
update_fields.append('delivery_date=?')
|
||||
update_values.append(data['delivery_date'])
|
||||
|
||||
if 'status' in data:
|
||||
update_fields.append('status=?')
|
||||
update_values.append(data['status'])
|
||||
|
||||
update_fields.append('updated_at=?')
|
||||
update_values.append(get_beijing_time())
|
||||
|
||||
update_values.append(order_id)
|
||||
|
||||
c.execute(f'UPDATE outsourcing_orders SET {", ".join(update_fields)} WHERE id=?', update_values)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
log('update_outsourcing_order', f'更新委外工单 ID: {order_id}')
|
||||
return jsonify({'ok': True, 'message': '更新成功'})
|
||||
|
||||
|
||||
@app.delete('/api/outsourcing-orders/<int:order_id>')
|
||||
@require_login
|
||||
@require_any_role('superadmin', 'admin')
|
||||
def delete_outsourcing_order(order_id):
|
||||
"""删除委外工单"""
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
|
||||
c.execute('SELECT order_no FROM outsourcing_orders WHERE id=?', (order_id,))
|
||||
row = c.fetchone()
|
||||
if not row:
|
||||
conn.close()
|
||||
return jsonify({'error': '委外工单不存在'}), 404
|
||||
|
||||
c.execute('DELETE FROM outsourcing_orders WHERE id=?', (order_id,))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
log('delete_outsourcing_order', f'删除委外工单 ID: {order_id}')
|
||||
return jsonify({'ok': True, 'message': '删除成功'})
|
||||
|
||||
|
||||
# ==================== 委外发料管理 API ====================
|
||||
|
||||
@app.get('/api/outsourcing-material-issue')
|
||||
@require_login
|
||||
@require_any_role('superadmin', 'admin')
|
||||
def get_material_issue_list():
|
||||
"""获取委外发料列表"""
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
c.execute('SELECT * FROM outsourcing_material_issue ORDER BY created_at DESC')
|
||||
rows = c.fetchall()
|
||||
conn.close()
|
||||
return jsonify({'list': [dict(r) for r in rows]})
|
||||
|
||||
|
||||
@app.post('/api/outsourcing-material-issue')
|
||||
@require_login
|
||||
@require_any_role('superadmin', 'admin')
|
||||
def create_material_issue():
|
||||
"""创建委外发料单"""
|
||||
data = request.get_json() or {}
|
||||
|
||||
outsourcing_order_no = data.get('outsourcing_order_no', '').strip()
|
||||
materials = data.get('materials', [])
|
||||
issue_date = data.get('issue_date', '').strip()
|
||||
|
||||
if not outsourcing_order_no or not materials or not issue_date:
|
||||
return jsonify({'error': '请填写所有必填字段'}), 400
|
||||
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
|
||||
# 验证委外工单是否存在
|
||||
c.execute('SELECT * FROM outsourcing_orders WHERE order_no=?', (outsourcing_order_no,))
|
||||
order = c.fetchone()
|
||||
if not order:
|
||||
conn.close()
|
||||
return jsonify({'error': '委外工单不存在'}), 404
|
||||
|
||||
# 生成发料单号 FL+年月日+4位流水号
|
||||
now = get_beijing_time()
|
||||
date_str = datetime.now().strftime('%Y%m%d')
|
||||
c.execute("SELECT COUNT(*) FROM outsourcing_material_issue WHERE issue_no LIKE ?", (f'FL{date_str}%',))
|
||||
count = c.fetchone()[0]
|
||||
issue_no = f'FL{date_str}{str(count + 1).zfill(4)}'
|
||||
|
||||
username = session.get('username', '')
|
||||
|
||||
try:
|
||||
for material in materials:
|
||||
material_code = material.get('material_code', '').strip()
|
||||
material_name = material.get('material_name', '').strip()
|
||||
issue_qty = int(material.get('issue_qty', 0))
|
||||
unit = material.get('unit', 'pcs').strip()
|
||||
|
||||
if not material_code or issue_qty <= 0:
|
||||
continue
|
||||
|
||||
# 插入发料记录
|
||||
c.execute('''INSERT INTO outsourcing_material_issue(
|
||||
issue_no, outsourcing_order_no, material_code, material_name,
|
||||
issue_qty, unit, issue_date, created_by, created_at, updated_at
|
||||
) VALUES(?,?,?,?,?,?,?,?,?,?)''', (
|
||||
issue_no, outsourcing_order_no, material_code, material_name,
|
||||
issue_qty, unit, issue_date, username, now, now
|
||||
))
|
||||
|
||||
# 扣减期初库存
|
||||
c.execute('SELECT stock_qty FROM initial_stock WHERE material_code=?', (material_code,))
|
||||
stock_row = c.fetchone()
|
||||
if stock_row:
|
||||
new_stock = stock_row['stock_qty'] - issue_qty
|
||||
c.execute('UPDATE initial_stock SET stock_qty=?, updated_at=? WHERE material_code=?',
|
||||
(new_stock, now, material_code))
|
||||
|
||||
# 增加委外在制库存
|
||||
c.execute('SELECT wip_qty FROM outsourcing_wip_stock WHERE material_code=?', (material_code,))
|
||||
wip_row = c.fetchone()
|
||||
if wip_row:
|
||||
new_wip = wip_row['wip_qty'] + issue_qty
|
||||
c.execute('UPDATE outsourcing_wip_stock SET wip_qty=?, updated_at=? WHERE material_code=?',
|
||||
(new_wip, now, material_code))
|
||||
else:
|
||||
c.execute('''INSERT INTO outsourcing_wip_stock(
|
||||
outsourcing_order_no, material_code, material_name, wip_qty, unit, updated_at
|
||||
) VALUES(?,?,?,?,?,?)''', (
|
||||
outsourcing_order_no, material_code, material_name, issue_qty, unit, now
|
||||
))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
log('create_material_issue', f'创建委外发料单: {issue_no}')
|
||||
return jsonify({'ok': True, 'issue_no': issue_no, 'message': '发料成功'})
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
conn.close()
|
||||
return jsonify({'error': f'发料失败: {str(e)}'}), 500
|
||||
|
||||
|
||||
# ==================== 成品入库管理 API ====================
|
||||
|
||||
@app.get('/api/finished-goods-receipt')
|
||||
@require_login
|
||||
@require_any_role('superadmin', 'admin')
|
||||
def get_finished_goods_receipt_list():
|
||||
"""获取成品入库列表"""
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
c.execute('SELECT * FROM finished_goods_receipt ORDER BY created_at DESC')
|
||||
rows = c.fetchall()
|
||||
conn.close()
|
||||
return jsonify({'list': [dict(r) for r in rows]})
|
||||
|
||||
|
||||
@app.post('/api/finished-goods-receipt')
|
||||
@require_login
|
||||
@require_any_role('superadmin', 'admin')
|
||||
def create_finished_goods_receipt():
|
||||
"""创建成品入库单"""
|
||||
data = request.get_json() or {}
|
||||
|
||||
outsourcing_order_no = data.get('outsourcing_order_no', '').strip()
|
||||
receipt_qty = data.get('receipt_qty', 0)
|
||||
receipt_date = data.get('receipt_date', '').strip()
|
||||
|
||||
if not outsourcing_order_no or not receipt_date:
|
||||
return jsonify({'error': '请填写所有必填字段'}), 400
|
||||
|
||||
try:
|
||||
receipt_qty = int(receipt_qty)
|
||||
if receipt_qty <= 0:
|
||||
return jsonify({'error': '入库数量必须大于0'}), 400
|
||||
except (ValueError, TypeError):
|
||||
return jsonify({'error': '入库数量必须是有效整数'}), 400
|
||||
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
|
||||
# 验证委外工单是否存在
|
||||
c.execute('SELECT * FROM outsourcing_orders WHERE order_no=?', (outsourcing_order_no,))
|
||||
order = c.fetchone()
|
||||
if not order:
|
||||
conn.close()
|
||||
return jsonify({'error': '委外工单不存在'}), 404
|
||||
|
||||
# 生成入库单号 RK+年月日+4位流水号
|
||||
now = get_beijing_time()
|
||||
date_str = datetime.now().strftime('%Y%m%d')
|
||||
c.execute("SELECT COUNT(*) FROM finished_goods_receipt WHERE receipt_no LIKE ?", (f'RK{date_str}%',))
|
||||
count = c.fetchone()[0]
|
||||
receipt_no = f'RK{date_str}{str(count + 1).zfill(4)}'
|
||||
|
||||
username = session.get('username', '')
|
||||
|
||||
try:
|
||||
# 插入入库记录
|
||||
c.execute('''INSERT INTO finished_goods_receipt(
|
||||
receipt_no, outsourcing_order_no, product_code, product_name,
|
||||
receipt_qty, receipt_date, created_by, created_at, updated_at
|
||||
) VALUES(?,?,?,?,?,?,?,?,?)''', (
|
||||
receipt_no, outsourcing_order_no, order['product_code'], order['product_name'],
|
||||
receipt_qty, receipt_date, username, now, now
|
||||
))
|
||||
|
||||
# 获取该产品的BOM,计算物料消耗
|
||||
c.execute('SELECT * FROM bom WHERE product_code=?', (order['product_code'],))
|
||||
bom_list = c.fetchall()
|
||||
|
||||
material_consumption = []
|
||||
for bom in bom_list:
|
||||
material_code = bom['material_code']
|
||||
consumed_qty = int(math.ceil(bom['unit_qty'] * receipt_qty))
|
||||
|
||||
# 扣减委外在制库存
|
||||
c.execute('SELECT wip_qty FROM outsourcing_wip_stock WHERE material_code=?', (material_code,))
|
||||
wip_row = c.fetchone()
|
||||
if wip_row:
|
||||
new_wip = max(0, wip_row['wip_qty'] - consumed_qty)
|
||||
c.execute('UPDATE outsourcing_wip_stock SET wip_qty=?, updated_at=? WHERE material_code=?',
|
||||
(new_wip, now, material_code))
|
||||
|
||||
material_consumption.append({
|
||||
'material_code': material_code,
|
||||
'material_name': bom['material_name'],
|
||||
'consumed_qty': consumed_qty
|
||||
})
|
||||
|
||||
# 增加成品库存(如果需要跟踪成品库存)
|
||||
c.execute('SELECT stock_qty FROM initial_stock WHERE material_code=?', (order['product_code'],))
|
||||
product_stock = c.fetchone()
|
||||
if product_stock:
|
||||
new_stock = product_stock['stock_qty'] + receipt_qty
|
||||
c.execute('UPDATE initial_stock SET stock_qty=?, updated_at=? WHERE material_code=?',
|
||||
(new_stock, now, order['product_code']))
|
||||
else:
|
||||
c.execute('''INSERT INTO initial_stock(
|
||||
material_code, material_name, stock_qty, unit, created_at, updated_at
|
||||
) VALUES(?,?,?,?,?,?)''', (
|
||||
order['product_code'], order['product_name'], receipt_qty, 'pcs', now, now
|
||||
))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
log('create_finished_goods_receipt', f'创建成品入库单: {receipt_no}')
|
||||
return jsonify({
|
||||
'ok': True,
|
||||
'receipt_no': receipt_no,
|
||||
'material_consumption': material_consumption,
|
||||
'message': '入库成功'
|
||||
})
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
conn.close()
|
||||
return jsonify({'error': f'入库失败: {str(e)}'}), 500
|
||||
|
||||
|
||||
# ==================== 委外在制库存查询 API ====================
|
||||
|
||||
@app.get('/api/outsourcing-wip-stock')
|
||||
@require_login
|
||||
@require_any_role('superadmin', 'admin')
|
||||
def get_outsourcing_wip_stock():
|
||||
"""获取委外在制库存列表"""
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
c.execute('SELECT * FROM outsourcing_wip_stock WHERE wip_qty > 0 ORDER BY updated_at DESC')
|
||||
rows = c.fetchall()
|
||||
conn.close()
|
||||
return jsonify({'list': [dict(r) for r in rows]})
|
||||
|
||||
|
||||
# ==================== 客户订单查询 API(用于委外工单关联) ====================
|
||||
|
||||
@app.get('/api/customer-orders-for-outsourcing')
|
||||
@require_login
|
||||
@require_any_role('superadmin', 'admin')
|
||||
def get_customer_orders_for_outsourcing():
|
||||
"""获取客户订单列表(用于委外工单关联)"""
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
c.execute('SELECT DISTINCT order_no, customer_name, material FROM customer_orders ORDER BY created_at DESC LIMIT 100')
|
||||
rows = c.fetchall()
|
||||
conn.close()
|
||||
return jsonify({'list': [dict(r) for r in rows]})
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
def not_found(e):
|
||||
# 如果请求的是 HTML 页面(通过 Accept header 判断),返回 index.html
|
||||
|
||||
Loading…
Reference in New Issue
Block a user