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
+51 -6
View File
@@ -25,6 +25,7 @@ from models import (COMPANY_NAME, DOC_TYPES, ROLE_TEXT, STATUS_TEXT,
DEFAULT_OUR_PHONE, DEFAULT_OUR_TAX_NO, DEFAULT_TAX_RATE,
ApprovalLog, Material, Order, OrderItem, Supplier, User,
init_db)
from material_prices import remember_approved_prices, supplier_price_map
from pdf_export import build_pdf
# 打包成 EXE 后:资源在临时目录 _MEIPASS,数据必须写在 EXE 同级目录
@@ -100,6 +101,7 @@ def orders():
doc_type = request.args.get("doc_type", "")
date_from = request.args.get("date_from", "")
date_to = request.args.get("date_to", "")
material_kw = request.args.get('material_kw', '').strip()[:100]
if kw:
q = q.filter(Order.order_no.like("%%%s%%" % kw) |
Order.supplier_name.like("%%%s%%" % kw))
@@ -111,15 +113,26 @@ def orders():
q = q.filter(Order.order_date >= date_from)
if date_to:
q = q.filter(Order.order_date <= date_to)
if material_kw:
pattern = '%%%s%%' % material_kw
q = q.filter(Order.items.any((OrderItem.material_code.ilike(pattern)) |
(OrderItem.material_spec.ilike(pattern))))
if u.role == "maker":
q = q.filter(Order.created_by == u.id)
tracking = request.args.get('tracking', '')
q = filter_tracking(q, tracking)
if not tracking and request.args.get('show_completed') != '1':
if not tracking and not kw and not material_kw and request.args.get('show_completed') != '1':
q = q.filter(or_(Order.status != 'approved', ~tracking_conditions()['closed']))
rows = q.order_by(Order.id.desc()).all()
matched_items = {}
if material_kw and rows:
for item in (db.query(OrderItem).filter(OrderItem.order_id.in_([o.id for o in rows]),
(OrderItem.material_code.ilike(pattern)) |
(OrderItem.material_spec.ilike(pattern)))
.order_by(OrderItem.order_id, OrderItem.seq)):
matched_items.setdefault(item.order_id, []).append(item)
return render_template("orders.html", user=u, rows=rows, status_text=STATUS_TEXT,
doc_types=DOC_TYPES, args=request.args)
doc_types=DOC_TYPES, args=request.args, matched_items=matched_items)
@app.route("/import_template.xlsx")
@@ -165,8 +178,14 @@ def suppliers():
db.commit()
flash(u"已保存", "ok")
return redirect(url_for("suppliers"))
rows = db.query(Supplier).order_by(Supplier.id).all()
return render_template("suppliers.html", user=u, rows=rows)
kw = request.args.get('kw', '').strip()[:100]
query = db.query(Supplier)
if kw:
pattern = '%%%s%%' % kw
query = query.filter(Supplier.name.ilike(pattern) | Supplier.short_name.ilike(pattern) |
Supplier.code.ilike(pattern))
rows = query.order_by(Supplier.id).all()
return render_template("suppliers.html", user=u, rows=rows, kw=kw)
@app.route("/suppliers/<int:sid>/toggle", methods=["POST"])
@@ -307,8 +326,26 @@ def materials():
db.commit()
flash(u"已保存", "ok")
return redirect(url_for("materials"))
rows = db.query(Material).order_by(Material.id).all()
return render_template("materials.html", user=u, rows=rows)
kw = request.args.get('kw', '').strip()[:100]
query = db.query(Material)
if kw:
pattern = '%%%s%%' % kw
query = query.filter(Material.code.ilike(pattern) | Material.spec.ilike(pattern))
rows = query.order_by(Material.id).all()
return render_template("materials.html", user=u, rows=rows, kw=kw)
@app.post('/materials/prices/from-approved-orders')
@login_required
@role_required('admin')
def sync_approved_material_prices():
# Old approved orders may predate automatic catalog price updates.
orders = (db.query(Order).filter(Order.status == 'approved')
.order_by(Order.approved_at, Order.id).all())
count = sum(remember_approved_prices(db, order) for order in orders)
db.commit()
flash('已按审批先后同步 %s 张订单,更新 %s 条物料单价。' % (len(orders), count), 'ok')
return redirect(url_for('materials'))
@app.route("/materials/<int:mid>/toggle", methods=["POST"])
@@ -431,6 +468,14 @@ def api_suppliers():
"payment_terms": s.payment_terms} for s in rows])
@app.route('/api/material-prices')
@login_required
@role_required('maker')
def api_material_prices():
return jsonify(supplier_price_map(db, request.args.get('supplier_name', ''),
request.args.get('supplier_tax_no', ''), current_user()))
# ---------------- 用户 ----------------
@app.route("/users", methods=["GET", "POST"])
@login_required