增加部分付款和部分交货状态、工作台筛选、权限校验、跟进记录及 v4 数据迁移;补充 Windows EXE 构建与验收脚本。附 16 页 PDF 使用升级手册及企业微信详细配置说明、生成脚本和测试截图。验证:76 项回归测试、EXE 浏览器验收与 PDF 逐页校验通过。
188 lines
9.2 KiB
HTML
188 lines
9.2 KiB
HTML
{% extends "base.html" %}
|
||
{% block body %}
|
||
<h1 class="page">{{ o.doc_type_text }} · {{ o.order_no }}
|
||
<span class="badge {{ o.status }}" style="font-size:13px;vertical-align:middle;">{{ o.status_text }}</span>
|
||
</h1>
|
||
|
||
<div class="toolbar">
|
||
{% if editable %}<a class="btn primary" href="{{ url_for('order_edit', oid=o.id) }}">编辑</a>{% endif %}
|
||
<a class="btn" href="{{ url_for('order_pdf', oid=o.id) }}" target="_blank">导出 / 预览 PDF</a>
|
||
<a class="btn" href="{{ url_for('order_pdf', oid=o.id) }}?dl=1" download>下载 PDF</a>
|
||
{% if user.role in ['maker','admin'] %}
|
||
<form method="post" action="{{ url_for('order_copy', oid=o.id) }}" style="display:inline;">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||
<input type="hidden" name="row_version" value="{{ o.row_version }}">
|
||
<input type="hidden" name="request_key" value="{{ request_key() }}">
|
||
<button class="btn">复制为新订单</button>
|
||
</form>{% endif %}
|
||
<span class="grow"></span>
|
||
<a class="btn" href="{{ url_for('orders') }}">返回列表</a>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>单据信息</h2>
|
||
<p class="mobile-only muted">单据信息和物料明细可左右滑动查看。</p>
|
||
<table class="kv-table" style="width:100%;">
|
||
<tr>
|
||
<td class="k">供应商</td><td>{{ o.supplier_name }}</td>
|
||
<td class="k">需方</td><td>{{ o.our_company }}</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="k">联系人</td><td>{{ o.supplier_contact }}</td>
|
||
<td class="k">联系人</td><td>{{ o.our_contact }}</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="k">电话</td><td>{{ o.supplier_phone }}</td>
|
||
<td class="k">电话</td><td>{{ o.our_phone }}</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="k">付款方式</td><td>{{ o.payment_terms }}</td>
|
||
<td class="k">税点</td><td>{{ o.tax_rate }}</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="k">税号</td><td>{{ o.supplier_tax_no }}</td>
|
||
<td class="k">税号</td><td>{{ o.our_tax_no }}</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="k">银行帐号</td><td>{{ o.supplier_bank_account }}</td>
|
||
<td class="k">采购单号</td><td>{{ o.order_no }}</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="k">开户银行</td><td>{{ o.supplier_bank_name }}</td>
|
||
<td class="k">采购日期</td><td>{{ o.order_date }}</td>
|
||
</tr>
|
||
<tr><td class="k">交货地点</td><td colspan="3">{{ o.delivery_place }}</td></tr>
|
||
</table>
|
||
|
||
<h3>物料明细</h3>
|
||
<table class="grid">
|
||
<tr><th>序号</th><th>物料代码</th><th>物料规格</th><th>单位</th><th class="num">数量</th>
|
||
<th class="num">含税单价</th><th class="num">金额</th><th>交期</th><th>备注</th></tr>
|
||
{% for it in o.items %}
|
||
<tr>
|
||
<td class="center">{{ loop.index }}</td>
|
||
<td>{{ it.material_code }}</td>
|
||
<td>{{ it.material_spec }}</td>
|
||
<td class="center">{{ it.unit }}</td>
|
||
<td class="num">{{ it.qty }}</td>
|
||
<td class="num">{{ it.price|price }}</td>
|
||
<td class="num">{{ '%.2f'|format(it.amount) }}</td>
|
||
<td>{{ it.delivery_date }}</td>
|
||
<td>{{ it.remark }}</td>
|
||
</tr>
|
||
{% else %}
|
||
<tr><td colspan="9" class="center muted">暂无明细</td></tr>
|
||
{% endfor %}
|
||
</table>
|
||
<div class="total-bar">
|
||
<span>合计(小写):<span class="amt">{{ '%.2f'|format(o.total_amount) }}</span> 元</span>
|
||
<span>大写:<b>{{ total_cn }}</b></span>
|
||
</div>
|
||
{% if o.note %}<p class="muted">补充说明:{{ o.note }}</p>{% endif %}
|
||
</div>
|
||
|
||
{% include 'order_tracking.html' %}
|
||
|
||
<div class="card">
|
||
<h2>审批流程</h2>
|
||
<table class="grid approval-flow">
|
||
<tr><th>环节</th><th>操作人</th><th>时间</th></tr>
|
||
<tr><td>制单</td><td>{{ o.created_by_name }}</td><td>{{ o.created_at.strftime('%Y-%m-%d %H:%M') if o.created_at else '-' }}</td></tr>
|
||
{% if o.reviewed_by %}<tr><td>旧流程审核(历史)</td><td>{{ o.reviewed_by or '—' }}</td><td>{{ o.reviewed_at.strftime('%Y-%m-%d %H:%M') if o.reviewed_at else '—' }}</td></tr>{% endif %}
|
||
<tr><td>审批</td><td>{{ o.approved_by or '—' }}</td><td>{{ o.approved_at.strftime('%Y-%m-%d %H:%M') if o.approved_at else '—' }}</td></tr>
|
||
</table>
|
||
|
||
{% if may_approve %}
|
||
<div style="margin-top:12px;">
|
||
<div id="apprStampBox" style="display:none; margin-bottom:10px;">
|
||
<div class="seal-wrap">
|
||
<div class="seal-tip">采购专用章预览(尚未提交)</div>
|
||
{% include 'seal_preview.html' %}
|
||
</div>
|
||
</div>
|
||
<form method="post" action="{{ url_for('order_approve', oid=o.id) }}" class="toolbar"
|
||
onsubmit="return checkStampA()">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||
<input type="hidden" name="row_version" value="{{ o.row_version }}">
|
||
<input type="hidden" name="stamped" id="apprStampedInput" value="0">
|
||
<input type="text" name="comment" placeholder="审批意见(选填)" style="width:280px;">
|
||
<button type="button" class="btn" id="apprStampBtn" onclick="applyStampA()">加盖采购专用章</button>
|
||
<button type="submit" class="btn ok" id="apprConfirmBtn" disabled
|
||
title="请先加盖采购专用章">确认审批通过</button>
|
||
</form>
|
||
<div class="muted" style="margin-top:6px;">流程:先点「加盖采购专用章」,确认无误后再点「确认审批通过」。</div>
|
||
</div>
|
||
<script>
|
||
function applyStampA(){
|
||
document.getElementById('apprStampedInput').value = '1';
|
||
document.getElementById('apprStampBox').style.display = 'block';
|
||
document.getElementById('apprConfirmBtn').disabled = false;
|
||
const s = document.getElementById('apprStampBtn');
|
||
s.disabled = true;
|
||
s.textContent = '已加章';
|
||
}
|
||
function checkStampA(){
|
||
if (document.getElementById('apprStampedInput').value !== '1'){
|
||
alert('请先点击「加盖采购专用章」,再确认审批。');
|
||
return false;
|
||
}
|
||
return confirm('确认审批通过?审批通过后即可导出正式 PDF。');
|
||
}
|
||
</script>
|
||
{% endif %}
|
||
{% if may_reject %}
|
||
<form method="post" action="{{ url_for('order_reject', oid=o.id) }}" class="toolbar" style="margin-top:8px;">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||
<input type="hidden" name="row_version" value="{{ o.row_version }}">
|
||
<input type="text" name="comment" placeholder="驳回原因(必填)" style="width:280px;" required>
|
||
<button class="btn danger">驳回给制单人</button>
|
||
</form>
|
||
{% endif %}
|
||
{% if editable and o.status in ['draft','rejected'] %}
|
||
<form method="post" action="{{ url_for('order_submit', oid=o.id) }}" class="toolbar" style="margin-top:8px;">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||
<input type="hidden" name="row_version" value="{{ o.row_version }}">
|
||
<input type="text" name="comment" placeholder="提交说明(选填)" style="width:280px;">
|
||
<button class="btn primary">提交审批</button>
|
||
</form>
|
||
{% endif %}
|
||
{% if o.status == 'rejected' and o.reject_reason %}
|
||
<div class="flash error">驳回原因:{{ o.reject_reason }}</div>
|
||
{% endif %}
|
||
|
||
{% if o.created_by == user.id and o.status == 'pending_approval' %}
|
||
<form method="post" action="{{ url_for('order_withdraw',oid=o.id) }}" class="toolbar">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||
<input type="hidden" name="row_version" value="{{ o.row_version }}">
|
||
<input name="comment" placeholder="撤回原因(必填)" required><button class="btn">撤回修改</button>
|
||
</form>
|
||
{% endif %}
|
||
{% if o.status == 'approved' and user.role in ['maker','admin'] and (o.created_by == user.id or user.role == 'admin') %}
|
||
<form method="post" action="{{ url_for('order_revise',oid=o.id) }}" class="toolbar" onsubmit="return confirm('原审批将停止使用,修改后须重新审批。确认发起变更?')">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||
<input type="hidden" name="row_version" value="{{ o.row_version }}">
|
||
<input name="comment" placeholder="变更原因(必填)" required><button class="btn">发起变更重审</button>
|
||
</form>
|
||
{% endif %}
|
||
{% if editable or (o.status == 'approved' and user.role in ['admin','approver']) %}
|
||
<form method="post" action="{{ url_for('order_void',oid=o.id) }}" class="toolbar" onsubmit="return confirm('确认作废此订单?已发出的文件也应通知接收人停止使用。')">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||
<input type="hidden" name="row_version" value="{{ o.row_version }}">
|
||
<input name="comment" placeholder="作废原因(必填)" required><button class="btn danger">作废订单</button>
|
||
</form>
|
||
{% endif %}
|
||
<h3>提交版本</h3>
|
||
{% for version in o.versions %}<p><a href="{{ url_for('order_version',oid=o.id,revision=version.revision) }}">第 {{ version.revision }} 次提交 · {{ version.created_at.strftime('%Y-%m-%d %H:%M') }}</a>{{ ' · 已归档正式文件' if version.pdf_data else '' }}</p>
|
||
{% else %}<p class="muted">尚无提交快照;升级前的审批记录可在下方查看。</p>{% endfor %}
|
||
<h3>审批与跟进记录</h3>
|
||
<ul class="timeline">
|
||
{% for lg in o.logs %}
|
||
<li>{{ lg.created_at.strftime('%Y-%m-%d %H:%M') }} · {{ lg.user_name }} · {{ lg.action }}(第 {{ lg.revision }} 次提交)
|
||
{% if lg.comment %}({{ lg.comment }}){% endif %}</li>
|
||
{% else %}
|
||
<li class="muted">暂无记录</li>
|
||
{% endfor %}
|
||
</ul>
|
||
</div>
|
||
{% endblock %}
|