Files
Inventory-Management-System/templates/order_detail.html
T
star 639d7f1545 feat: BOM型号可编辑 + 生产订单BOM去括号 + 物料明细各工厂实时库存
- BOM编辑页「型号」输入框取消 readonly,可修改;bom_edit 增加非空与唯一校验(重复提示「BOM 型号已存在」、空值提示「BOM 型号必填」),改名不影响关联生产订单与流水
- 生产订单列表/详情/表单中 BOM 显示由 CODE (NAME) 改为 CODE · NAME,去掉括号
- 物料明细页新增「各工厂实时库存」表(工厂编号/名称/实时库存),显示每个工厂的实时聚合库存(入−出),不受顶栏工厂过滤影响
2026-10-15 14:03:16 +08:00

92 lines
5.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}订单 {{ o.order_no }}{% endblock %}
{% block content %}
<div class="toolbar">
<h3 style="margin:0">生产订单 {{ o.order_no }}</h3>
<span class="badge {{ 'ok' if o.status=='picked' else 'warn' }}">{{ '已领料' if o.status=='picked' else '待领料' }}</span>
<a class="btn" href="{{ url_for('order_edit', oid=o.id) }}">编辑订单</a>
</div>
<div class="card" style="margin-bottom:16px">
<p class="small muted" style="margin-top:0"><b>下单信息(按下单时记录)</b></p>
<p>BOM: <b>{{ bom.code if bom else '-' }}</b>{% if bom and bom.name %} · {{ bom.name }}{% endif %} | 接单量: <b>{{ '%.2f'|format(o.qty) }}</b> | 生产工厂: <b>{% if factory %}{{ factory.code }}{% if factory.name %} · {{ factory.name }}{% endif %}{% else %}未指定(按汇总库存){% endif %}</b> | 经手人: {{ o.operator or '-' }}{% if o.created_at %} | 下单时间: {{ o.created_at.strftime('%Y-%m-%d %H:%M') }}{% endif %}</p>
{% if o.remark %}<p class="small muted">备注: {{ o.remark }}</p>{% endif %}
<p class="small muted" style="margin-bottom:0">提示:点击「编辑订单」保存后,该订单会冲销已产生的调入/领料流水并清空调入计划,自动回到「刚下单」状态(待领料、未调拨),可重新规划。</p>
</div>
<h3>领料需求与调入 (单套用量 × 接单量){% if factory %} | 按下单前库存核算{% endif %}</h3>
<p class="small muted" style="margin-top:-6px">库存口径:下方「下单前库存」为 <b>订单下单那一刻、所属工厂的库存快照</b>(按下单时间截断,已自动排除该订单自身后续的调入/领料及下单后发生的其他出入库),用于还原下单时的可供料情况。{% if not factory %}本单未指定生产工厂,按下单前全部工厂汇总库存展示。{% endif %}</p>
<form method="post" action="{{ url_for('order_alloc_save', oid=o.id) }}">
<table class="tbl">
<thead><tr>
<th>物料编号</th><th>型号</th><th>下单前库存</th>
<th>需求数量</th><th>缺口</th><th>调入数量</th><th>状态</th><th>工厂库存</th><th>可替代料</th>
</tr></thead>
<tbody>
{% for r in reqs %}
<tr class="{{ 'row-danger' if r.short else ('row-warn' if r.have < (r.m.safety_stock or 0)) }}">
<td><a href="{{ url_for('material_detail', mid=r.m.id) }}" title="进入工厂物料">{{ r.m.part_number }}</a></td>
<td>{{ r.m.manufacturer or '-' }}</td>
<td class="num">{{ '%.2f'|format(r.have) }}</td>
<td class="num">{{ '%.2f'|format(r.need) }}</td>
<td class="num">{{ '%.2f'|format(r.gap) }}</td>
<td class="num">
{% if r.posted %}
<div style="margin-bottom:3px"><span class="badge ok" title="已生成入库流水, 可直接修改后保存/确认">已调入</span></div>
<input name="alloc_{{ r.m.id }}" type="number" step="0.01" min="0"
value="{{ '%.2f'|format(r.alloc) }}" style="width:96px">
{% else %}
<input name="alloc_{{ r.m.id }}" type="number" step="0.01" min="0"
value="{{ '%.2f'|format(r.alloc) if r.alloc else '' }}"
placeholder="{{ '%.2f'|format(r.need) }}" style="width:96px">
{% endif %}
</td>
<td><span class="badge {{ 'danger' if r.short else 'ok' }}">{{ '缺料' if r.short else '充足' }}</span></td>
<td class="num">{{ '%.2f'|format(r.gap + r.alloc) }}</td>
<td class="small">
{% if r.subs %}
{% for s in r.subs %}
<span class="{{ 'badge ok' if s.available else 'badge danger' }}">{{ s.pn }}·{{ s.stock }}{% if s.available %}✓{% else %}✗{% endif %}</span>
{% endfor %}
{% else %}<span class="muted">—</span>{% endif %}
</td>
</tr>
{% else %}
<tr><td colspan="8" class="muted">该 BOM 没有组成物料</td></tr>
{% endfor %}
</tbody>
</table>
<div class="row-actions" style="flex-wrap:wrap; align-items:flex-end">
<label style="display:flex; flex-direction:column; gap:4px; font-size:13px">
调入来源工厂
<select name="from_factory_id" style="padding:6px 8px; min-width:160px">
{% for f in factories %}
{% if f.id != (o.factory_id or 0) %}
<option value="{{ f.id }}" {{ 'selected' if f.code=='SELF' else '' }}>{{ f.code }}({{ f.name or '—' }})</option>
{% endif %}
{% endfor %}
</select>
</label>
<button class="primary" type="submit">保存调入数量</button>
<button class="secondary" type="submit"
formaction="{{ url_for('order_alloc_post', oid=o.id) }}"
onclick="return confirm('确认将待调入数量从上方所选来源工厂调拨到生产工厂? 总库存不变, 仅厂间转移。');">确认调入(厂间调拨)</button>
</div>
<p class="small muted">「确认调入」是一次厂间调拨:从来源工厂出库减、生产工厂入库加,系统总库存不变。</p>
</form>
<div class="card" style="margin:14px 0">
<b>调入总览:</b> 已调入 <b>{{ posted_count }}</b> 项,合计 <b>{{ '%.2f'|format(posted_total) }}</b> 件;
计划调入合计 <b>{{ '%.2f'|format(planned_total) }}</b> 件。
</div>
{% if o.status != 'picked' %}
<form method="post" action="{{ url_for('order_pick', oid=o.id) }}" onsubmit="return confirm('确认按 BOM 生成领料出库? 库存不足将记为负并在看板预警。');">
<div class="row-actions"><button class="primary">确认领料出库</button></div>
</form>
{% else %}
<p class="flash ok">该订单已领料出库。</p>
{% endif %}
{% endblock %}