v0.1.12
This commit is contained in:
@@ -76,6 +76,21 @@ def _fractional_bag_warning(batch_size_kg: float, total_bags: float, unit_of_mea
|
||||
)
|
||||
|
||||
|
||||
def _mix_calculator_label(product: Product) -> str:
|
||||
return product.mix.name if product.mix else product.name
|
||||
|
||||
|
||||
def _mix_calculator_option_rank(product: Product) -> tuple[int, int, float, int]:
|
||||
unit_label = (product.unit_of_measure or "").lower()
|
||||
unit_size = extract_unit_quantity_kg(product.unit_of_measure)
|
||||
return (
|
||||
0 if abs(unit_size - 20) < 1e-9 and "bag" in unit_label and "bulka" not in unit_label else 1,
|
||||
0 if "bulka" not in unit_label else 1,
|
||||
unit_size if unit_size > 0 else 999999,
|
||||
product.id,
|
||||
)
|
||||
|
||||
|
||||
def calculate_mix_calculator_preview(
|
||||
db: Session,
|
||||
*,
|
||||
@@ -117,12 +132,15 @@ def calculate_mix_calculator_preview(
|
||||
}
|
||||
)
|
||||
|
||||
mix_label = _mix_calculator_label(product)
|
||||
return {
|
||||
"client_name": product.client_name,
|
||||
"product_id": product.id,
|
||||
"product_name": product.name,
|
||||
# The source workbook labels this as Product, but for the calculator
|
||||
# it is the mix/formula being produced.
|
||||
"product_name": mix_label,
|
||||
"mix_id": product.mix_id,
|
||||
"mix_name": product.mix.name if product.mix else product.name,
|
||||
"mix_name": mix_label,
|
||||
"mix_date": values["mix_date"],
|
||||
"batch_size_kg": round(batch_size_kg, 4),
|
||||
"total_bags": total_bags,
|
||||
@@ -156,21 +174,43 @@ def build_mix_calculator_options(db: Session, *, tenant_id: str) -> dict:
|
||||
).all()
|
||||
mix_totals: dict[int, float] = {mix_id: round(total or 0.0, 4) for mix_id, total in mix_totals_rows}
|
||||
|
||||
product_ids_with_formulas = select(ProductIngredient.product_id).where(ProductIngredient.tenant_id == tenant_id)
|
||||
products = db.scalars(
|
||||
select(Product)
|
||||
.where(Product.tenant_id == tenant_id, Product.visible.is_(True))
|
||||
.where(
|
||||
Product.tenant_id == tenant_id,
|
||||
Product.visible.is_(True),
|
||||
Product.id.in_(product_ids_with_formulas),
|
||||
)
|
||||
.options(joinedload(Product.mix))
|
||||
.order_by(Product.client_name, Product.name)
|
||||
).all()
|
||||
|
||||
representative_products: dict[tuple[str, str], Product] = {}
|
||||
for product in products:
|
||||
mix_label = _mix_calculator_label(product)
|
||||
key = (product.client_name, mix_label)
|
||||
current = representative_products.get(key)
|
||||
if current is None:
|
||||
representative_products[key] = product
|
||||
continue
|
||||
|
||||
if _mix_calculator_option_rank(product) < _mix_calculator_option_rank(current):
|
||||
representative_products[key] = product
|
||||
|
||||
products = sorted(
|
||||
representative_products.values(),
|
||||
key=lambda product: (product.client_name, _mix_calculator_label(product), product.id),
|
||||
)
|
||||
|
||||
clients = sorted({product.client_name for product in products})
|
||||
product_rows = [
|
||||
{
|
||||
"product_id": product.id,
|
||||
"client_name": product.client_name,
|
||||
"product_name": product.name,
|
||||
"product_name": _mix_calculator_label(product),
|
||||
"mix_id": product.mix_id,
|
||||
"mix_name": product.mix.name if product.mix else "",
|
||||
"mix_name": _mix_calculator_label(product),
|
||||
"unit_of_measure": product.unit_of_measure,
|
||||
"unit_size_kg": round(extract_unit_quantity_kg(product.unit_of_measure), 4),
|
||||
"mix_total_kg": product_totals.get(product.id, mix_totals.get(product.mix_id, 0.0)),
|
||||
|
||||
Reference in New Issue
Block a user