diff --git a/core/vendors/__init__.py b/core/vendors/__init__.py index 8e35dec6..3ae2ec56 100644 --- a/core/vendors/__init__.py +++ b/core/vendors/__init__.py @@ -1,6 +1,6 @@ import json from contextlib import suppress -from math import ceil +from math import ceil, log10 from django.db import IntegrityError @@ -174,10 +174,36 @@ class AbstractVendor: @staticmethod def round_price_marketologically(price: float) -> float: - up_int = ceil(price) - s = str(up_int) - s = (s[:-1] if len(s) > 1 else "0") + "9" - return float(f"{int(s):.2f}") + """ + Marketological rounding with no cents: + + - Prices < 1: leave exactly as-is. + - Prices ≥ 1: drop any fractional part, then + bump to the next 'psychological' threshold + at the correct order of magnitude and subtract 1. + + E.g. 2.34 → 2 → 3 – 1 = 2 + 12.34 → 12 → 13 – 1 = 12 + 123.45 → 123 → 130 – 1 = 129 + """ + if price < 1: + # sub-currency prices stay as they are + return round(price, 2) + + # strip off any cents + whole = int(price) + + # figure out the magnitude: + # 10**0 = 1 for [1–9], 10**1 = 10 for [10–99], 10**2 = 100 for [100–999], etc. + magnitude = 10 ** max(int(log10(whole)) - 1, 0) + + # next multiple of that magnitude + next_threshold = ceil(whole / magnitude) * magnitude + + # step back 1 to land on a “9” ending + psychological = next_threshold - 1 + + return float(psychological) def get_vendor_instance(self): try: