完善采购审批流程、企业微信通知和采购专用章
This commit is contained in:
@@ -8,15 +8,20 @@
|
||||
{% 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>
|
||||
</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>
|
||||
@@ -60,7 +65,7 @@
|
||||
<td>{{ it.material_spec }}</td>
|
||||
<td class="center">{{ it.unit }}</td>
|
||||
<td class="num">{{ it.qty }}</td>
|
||||
<td class="num">{{ '%.2f'|format(it.price) }}</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>
|
||||
@@ -77,89 +82,38 @@
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>审核流程</h2>
|
||||
<table class="grid">
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
{% 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 user.role in ['reviewer','admin'] and o.status == 'pending_review' %}
|
||||
<div style="margin-top:12px;">
|
||||
<div id="stampBox" style="display:none; margin-bottom:10px;">
|
||||
<div class="seal-wrap">
|
||||
<div class="seal-tip">已加盖主管审核章</div>
|
||||
<div class="seal-circle">
|
||||
<span class="co">{{ o.our_company or COMPANY_NAME }}</span>
|
||||
<span class="txt">审核专用</span>
|
||||
<span class="who">{{ user.name }}<br><span id="stampTime"></span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form method="post" action="{{ url_for('order_review', oid=o.id) }}" class="toolbar"
|
||||
onsubmit="return checkStamp()">
|
||||
<input type="hidden" name="stamped" id="stampedInput" value="0">
|
||||
<input type="text" name="comment" placeholder="审核意见(选填)" style="width:280px;">
|
||||
<button type="button" class="btn" id="stampBtn" onclick="applyStamp()">加盖审核章</button>
|
||||
<button type="submit" class="btn ok" id="confirmBtn" disabled
|
||||
title="请先加盖审核章">确认审核通过 → 提交经理批准</button>
|
||||
</form>
|
||||
<div class="muted" style="margin-top:6px;">流程:先点「加盖审核章」,确认无误后再点「确认审核通过」。</div>
|
||||
</div>
|
||||
<script>
|
||||
function applyStamp(){
|
||||
document.getElementById('stampedInput').value = '1';
|
||||
document.getElementById('stampBox').style.display = 'block';
|
||||
const d = new Date(), p = n => String(n).padStart(2, '0');
|
||||
document.getElementById('stampTime').textContent =
|
||||
d.getFullYear() + '-' + p(d.getMonth() + 1) + '-' + p(d.getDate()) +
|
||||
' ' + p(d.getHours()) + ':' + p(d.getMinutes());
|
||||
const c = document.getElementById('confirmBtn');
|
||||
c.disabled = false;
|
||||
const s = document.getElementById('stampBtn');
|
||||
s.disabled = true;
|
||||
s.textContent = '已加章';
|
||||
}
|
||||
function checkStamp(){
|
||||
if (document.getElementById('stampedInput').value !== '1'){
|
||||
alert('请先点击「加盖审核章」,再确认审核。');
|
||||
return false;
|
||||
}
|
||||
return confirm('确认审核通过并提交经理批准?');
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% if user.role in ['approver','admin'] and o.status == 'pending_approval' %}
|
||||
{% 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>
|
||||
<div class="seal-circle">
|
||||
<span class="co">{{ o.our_company or COMPANY_NAME }}</span>
|
||||
<span class="txt">批准专用</span>
|
||||
<span class="who">{{ user.name }}<br><span id="apprStampTime"></span></span>
|
||||
</div>
|
||||
<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>
|
||||
<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>
|
||||
title="请先加盖采购专用章">确认审批通过</button>
|
||||
</form>
|
||||
<div class="muted" style="margin-top:6px;">流程:先点「加盖批准章」,确认无误后再点「确认批准通过」。</div>
|
||||
<div class="muted" style="margin-top:6px;">流程:先点「加盖采购专用章」,确认无误后再点「确认审批通过」。</div>
|
||||
</div>
|
||||
<script>
|
||||
function applyStampA(){
|
||||
document.getElementById('apprStampedInput').value = '1';
|
||||
document.getElementById('apprStampBox').style.display = 'block';
|
||||
const d = new Date(), p = n => String(n).padStart(2, '0');
|
||||
document.getElementById('apprStampTime').textContent =
|
||||
d.getFullYear() + '-' + p(d.getMonth() + 1) + '-' + p(d.getDate()) +
|
||||
' ' + p(d.getHours()) + ':' + p(d.getMinutes());
|
||||
document.getElementById('apprConfirmBtn').disabled = false;
|
||||
const s = document.getElementById('apprStampBtn');
|
||||
s.disabled = true;
|
||||
@@ -167,33 +121,61 @@
|
||||
}
|
||||
function checkStampA(){
|
||||
if (document.getElementById('apprStampedInput').value !== '1'){
|
||||
alert('请先点击「加盖批准章」,再确认批准。');
|
||||
alert('请先点击「加盖采购专用章」,再确认审批。');
|
||||
return false;
|
||||
}
|
||||
return confirm('确认批准通过?批准后即可导出正式 PDF。');
|
||||
return confirm('确认审批通过?审批通过后即可导出正式 PDF。');
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% if user.role in ['reviewer','approver','admin'] and o.status in ['pending_review','pending_approval'] %}
|
||||
{% 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>
|
||||
<button class="btn primary">提交审批</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% if o.status == 'rejected' and o.reject_reason %}
|
||||
<div class="flash error">驳回原因:{{ o.reject_reason }}</div>
|
||||
{% endif %}
|
||||
|
||||
<h3>审核记录</h3>
|
||||
{% 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 }}
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user