Implement issue 1 search, order reuse and tracking

This commit is contained in:
reddaniel110
2026-10-14 11:25:43 +08:00
parent 0e45a58e5b
commit 4aaa6c6a14
17 changed files with 363 additions and 19 deletions
+22 -2
View File
@@ -18,9 +18,10 @@
<div>
<label>供应商</label>
<input type="text" name="supplier_name" id="supplier_name" value="{{ o.supplier_name or '' }}">
<input type="search" id="supplierSearch" placeholder="搜索供应商名称、简称或编号" aria-label="搜索供应商" style="margin-top:4px;">
<select id="supplierPick" style="margin-top:4px;">
<option value="">-- 从供应商库带入 --</option>
{% for s in suppliers %}<option value="{{ s.id }}">{{ s.name }}</option>{% endfor %}
{% for s in suppliers %}<option value="{{ s.id }}" data-search="{{ s.short_name or '' }} {{ s.code or '' }}">{{ s.name }}{{ '(' ~ s.short_name ~ ')' if s.short_name else '' }}</option>{% endfor %}
</select>
</div>
<div><label>联系人</label><input type="text" name="supplier_contact" id="supplier_contact" value="{{ o.supplier_contact or '' }}"></div>
@@ -61,6 +62,7 @@
<tr>
<td class="center seq">{{ loop.index }}</td>
<td><input type="text" name="item_code" value="{{ it.material_code or '' }}">
<input type="search" class="matsearch" placeholder="搜索代码或规格" aria-label="搜索物料" style="margin-top:3px;">
<select class="matpick" style="margin-top:3px;">
<option value="">-- 物料库 --</option>
{% for m in materials %}<option value="{{ m.id }}" data-code="{{ m.code }}" data-spec="{{ m.spec }}" data-unit="{{ m.unit }}" data-price="{{ m.price }}">{{ m.code }} {{ m.spec }}</option>{% endfor %}
@@ -82,6 +84,7 @@
<tr>
<td class="center seq">1</td>
<td><input type="text" name="item_code" value="">
<input type="search" class="matsearch" placeholder="搜索代码或规格" aria-label="搜索物料" style="margin-top:3px;">
<select class="matpick" style="margin-top:3px;">
<option value="">-- 物料库 --</option>
{% for m in materials %}<option value="{{ m.id }}" data-code="{{ m.code }}" data-spec="{{ m.spec }}" data-unit="{{ m.unit }}" data-price="{{ m.price }}">{{ m.code }} {{ m.spec }}</option>{% endfor %}
@@ -140,18 +143,32 @@
</div>
<script src="{{ url_for('static', filename='money.js') }}"></script>
<script src="{{ url_for('static', filename='search_select.js') }}"></script>
<script>
const MATERIALS = {{ materials|map(attribute='id')|list|tojson }};
let supplierPrices = {{ supplier_prices|tojson }};
POFilterSelect.bind(document.getElementById('supplierSearch'), document.getElementById('supplierPick'));
async function updateSupplierPrices(){
const name = document.getElementById('supplier_name').value.trim();
const tax = document.getElementById('supplier_tax_no').value.trim();
if (!name) { supplierPrices = {}; return; }
try {
const query = new URLSearchParams({supplier_name: name, supplier_tax_no: tax});
const response = await fetch('{{ url_for('api_material_prices') }}?' + query.toString());
if (response.ok) supplierPrices = await response.json();
} catch (error) { /* The catalog default remains usable offline. */ }
}
function bindRow(tr){
tr.querySelectorAll('.qty, .price').forEach(i => i.addEventListener('input', calc));
const pick = tr.querySelector('.matpick');
POFilterSelect.bind(tr.querySelector('.matsearch'), pick);
if (pick) pick.addEventListener('change', function(){
const opt = this.selectedOptions[0];
if (!opt || !opt.value) return;
tr.querySelector('[name=item_code]').value = opt.dataset.code || '';
tr.querySelector('[name=item_spec]').value = opt.dataset.spec || '';
tr.querySelector('[name=item_unit]').value = opt.dataset.unit || '';
tr.querySelector('.price').value = opt.dataset.price || 0;
tr.querySelector('.price').value = supplierPrices[opt.dataset.code] || opt.dataset.price || 0;
calc();
});
}
@@ -187,6 +204,8 @@ function delRow(btn){
btn.closest('tr').remove(); calc();
}
document.querySelectorAll('#itemTable tr').forEach(bindRow);
document.getElementById('supplier_name').addEventListener('change', updateSupplierPrices);
document.getElementById('supplier_tax_no').addEventListener('change', updateSupplierPrices);
calc();
document.getElementById('supplierPick').addEventListener('change', async function(){
if (!this.value) return;
@@ -200,6 +219,7 @@ document.getElementById('supplierPick').addEventListener('change', async functio
document.getElementById('supplier_bank_name').value = s.bank_name || '';
document.getElementById('supplier_bank_account').value = s.bank_account || '';
document.getElementById('payment_terms').value = s.payment_terms || '';
await updateSupplierPrices();
});
let dirty = false;
const orderForm = document.getElementById('orderForm');