fix error in gitignore

This commit is contained in:
2026-09-24 12:32:59 +03:30
commit 86c117ee2a
165 changed files with 5963 additions and 0 deletions
+117
View File
@@ -0,0 +1,117 @@
"""Backend-authoritative pricing engine.
Produces a full, explainable breakdown and is always the source of truth —
the frontend may display estimates but must never be trusted for financial
values.
"""
from decimal import Decimal, ROUND_HALF_UP
CHARGE_TYPES = {"fixed", "per_kg", "per_unit", "percentage", "tiered", "fee"}
class PricingEngine:
def calculate(self, weight_kg, selected_steps, currency: str = "IRR") -> dict:
weight = Decimal(str(weight_kg))
lines = []
subtotal = Decimal("0")
# Pass 1 — charge rules.
for step in selected_steps:
for rule in step.pricing_rules.filter(active=True, rule_type__in=CHARGE_TYPES).order_by("priority"):
line = self._apply_charge_rule(rule, weight)
if line is None:
continue
lines.append(line)
subtotal += Decimal(line["amount"])
# Pass 2 — discounts (fixed or percentage of subtotal).
discounts = Decimal("0")
for step in selected_steps:
for rule in step.pricing_rules.filter(active=True, rule_type="discount"):
amt = Decimal(str(rule.amount))
if (rule.config or {}).get("percentage"):
amt = subtotal * amt / Decimal("100")
discounts += amt
lines.append(
self._line(rule, weight, "discount", Decimal("0"), amt)
)
# Pass 3 — taxes on (subtotal - discounts).
taxes = Decimal("0")
taxable = subtotal - discounts
for step in selected_steps:
for rule in step.pricing_rules.filter(active=True, rule_type="tax"):
amt = taxable * Decimal(str(rule.amount)) / Decimal("100")
taxes += amt
lines.append(self._line(rule, weight, "tax", Decimal("0"), amt))
total = subtotal - discounts + taxes
if total < 0:
total = Decimal("0")
return {
"currency": currency,
"lines": lines,
"subtotal": str(self._q(subtotal)),
"discounts": str(self._q(discounts)),
"taxes": str(self._q(taxes)),
"total": str(self._q(total)),
}
def _q(self, v: Decimal) -> Decimal:
return v.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
def _line(self, rule, weight, kind, unit_price, amount, quantity=None) -> dict:
return {
"step_key": rule.step.key,
"rule": rule.name,
"kind": kind,
"quantity": str(quantity if quantity is not None else weight),
"unit_price": str(self._q(unit_price)),
"amount": str(self._q(amount)),
}
def _apply_charge_rule(self, rule, weight):
kind = rule.rule_type
cfg = rule.config or {}
amount = Decimal(str(rule.amount))
unit_price = Decimal("0")
quantity = weight
if kind == "fixed":
unit_price = amount
elif kind == "per_kg":
unit_price = amount
amount = amount * weight
elif kind == "per_unit":
units = Decimal(str(cfg.get("units", 1)))
unit_price = amount
amount = amount * units
quantity = units
elif kind == "percentage":
base = Decimal(str(cfg.get("base", 0)))
unit_price = amount
amount = base * amount / Decimal("100")
elif kind == "tiered":
unit_price = self._tier_unit_price(cfg.get("tiers", []), weight)
amount = unit_price * weight
elif kind == "fee":
unit_price = Decimal("0")
else:
return None
min_c = cfg.get("min_charge")
max_c = cfg.get("max_charge")
if min_c is not None and amount < Decimal(str(min_c)):
amount = Decimal(str(min_c))
if max_c is not None and amount > Decimal(str(max_c)):
amount = Decimal(str(max_c))
return self._line(rule, weight, kind, unit_price, amount, quantity)
def _tier_unit_price(self, tiers, weight) -> Decimal:
best = Decimal("0")
for tier in tiers or []:
low = Decimal(str(tier.get("from", 0)))
if weight >= low:
best = Decimal(str(tier.get("price", 0)))
return best