44 lines
1.6 KiB
Python
44 lines
1.6 KiB
Python
from decimal import Decimal
|
|
|
|
from .models import Item
|
|
|
|
|
|
class PricingSuggestionService:
|
|
def suggest_for_item(self, item: Item):
|
|
recent_comp = (
|
|
Item.objects.filter(status=Item.Status.SOLD, category=item.category)
|
|
.exclude(sold_price__isnull=True)
|
|
.order_by("-sold_at", "-created_at")
|
|
.values_list("sold_price", flat=True)[:5]
|
|
)
|
|
recent_prices = list(recent_comp)
|
|
|
|
if recent_prices:
|
|
average_price = sum(recent_prices) / len(recent_prices)
|
|
return {
|
|
"price": average_price.quantize(Decimal("0.01")),
|
|
"source": "Recent sold comps",
|
|
"notes": f"Based on {len(recent_prices)} recent sold items in {item.category}.",
|
|
}
|
|
|
|
if item.estimated_resale_price is not None:
|
|
return {
|
|
"price": item.estimated_resale_price,
|
|
"source": "Item estimate",
|
|
"notes": "Using the item's existing estimated resale price.",
|
|
}
|
|
|
|
if item.template and item.template.default_estimated_resale_price is not None:
|
|
return {
|
|
"price": item.template.default_estimated_resale_price,
|
|
"source": "Template default",
|
|
"notes": "Using the template's default resale estimate.",
|
|
}
|
|
|
|
fallback = (item.purchase_price * Decimal("1.75")).quantize(Decimal("0.01"))
|
|
return {
|
|
"price": fallback,
|
|
"source": "Purchase-price fallback",
|
|
"notes": "No sold comps yet; using a purchase-price multiple as a starting point.",
|
|
}
|