BuyingAgent/backend/app/scoring/deal.py
Lars b276758ee1
All checks were successful
Deploy Development / deploy (push) Successful in 1m19s
Test Suite / pytest-backend (push) Successful in 31s
Test Suite / smoke-dev (push) Successful in 0s
Test Suite / frontend-checks (push) Successful in 28s
Stelle den Frontend-MVP und die v0.3-API auf develop bereit, damit Dev API und PWA zusammen deployen.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-04 13:04:59 +02:00

43 lines
1.5 KiB
Python

from decimal import Decimal
from app.domain.enums import Classification, Eligibility
from app.domain.models import ScoringModel
from app.scoring.mathutil import clamp
def classify_deal_score(score: Decimal, model: ScoringModel) -> str:
for bound in model.classification_upper_bounds:
if bound.inclusive and score <= bound.upper:
return bound.label
if not bound.inclusive and score < bound.upper:
return bound.label
return Classification.EXCEPTIONAL.value
def score_deal(product_score: Decimal, price_score: Decimal, model: ScoringModel) -> Decimal:
return clamp(model.product_weight * product_score + model.price_weight * price_score)
def eligibility_from_parts(product: Eligibility, offer: Eligibility) -> Eligibility:
if Eligibility.INELIGIBLE in {product, offer}:
return Eligibility.INELIGIBLE
if Eligibility.UNKNOWN in {product, offer}:
return Eligibility.UNKNOWN
return Eligibility.ELIGIBLE
def derive_eligible(overall: Eligibility) -> bool | None:
if overall == Eligibility.ELIGIBLE:
return True
if overall == Eligibility.INELIGIBLE:
return False
return None
def classification_for(overall: Eligibility, deal_score: Decimal | None, model: ScoringModel) -> str:
if overall == Eligibility.INELIGIBLE:
return Classification.INELIGIBLE.value
if overall == Eligibility.UNKNOWN or deal_score is None:
return Classification.INSUFFICIENT_DATA.value
return classify_deal_score(deal_score, model)