53 lines
2.2 KiB
Python
53 lines
2.2 KiB
Python
"""Keep the material catalog's latest approved price and supplier-specific quotes."""
|
|
from decimal import Decimal
|
|
|
|
from models import Material, Order, OrderItem
|
|
|
|
|
|
def remember_approved_prices(db, order):
|
|
"""Update only unambiguous material codes in the approval transaction."""
|
|
updated = 0
|
|
for item in order.items:
|
|
code = (item.material_code or '').strip()
|
|
if not code or item.price is None or item.price <= 0:
|
|
continue
|
|
matches = db.query(Material).filter(Material.code == code).all()
|
|
exact = [material for material in matches if (material.spec or '').strip() == (item.material_spec or '').strip()]
|
|
if len(exact) == 1:
|
|
material = exact[0]
|
|
elif len(matches) == 1:
|
|
material = matches[0]
|
|
elif not matches:
|
|
material = Material(code=code, spec=item.material_spec or '', unit=item.unit or '', active=True)
|
|
db.add(material)
|
|
else:
|
|
# Duplicate codes with different specs are ambiguous; preserve both records.
|
|
continue
|
|
material.price = item.price
|
|
updated += 1
|
|
return updated
|
|
|
|
|
|
def supplier_price_map(db, supplier_name, supplier_tax_no='', user=None):
|
|
"""Most recent approved unit price for each code from the chosen supplier."""
|
|
name = (supplier_name or '').strip()
|
|
if not name:
|
|
return {}
|
|
query = (db.query(OrderItem.material_code, OrderItem.price, Order.supplier_tax_no)
|
|
.join(Order, OrderItem.order_id == Order.id)
|
|
.filter(Order.status == 'approved', Order.supplier_name == name,
|
|
OrderItem.material_code != '')
|
|
.order_by(Order.approved_at.desc(), Order.id.desc(), OrderItem.seq.desc()))
|
|
if user and user.role == 'maker':
|
|
query = query.filter(Order.created_by == user.id)
|
|
rows = query.all()
|
|
tax = (supplier_tax_no or '').strip()
|
|
if tax and any((row.supplier_tax_no or '').strip() == tax for row in rows):
|
|
rows = [row for row in rows if (row.supplier_tax_no or '').strip() == tax]
|
|
result = {}
|
|
for row in rows:
|
|
code = (row.material_code or '').strip()
|
|
if code and code not in result and row.price is not None:
|
|
result[code] = str(Decimal(row.price))
|
|
return result
|