fix: anchor hwid pricing to paid period

This commit is contained in:
3252a8
2026-05-27 18:13:27 +03:00
parent 1c9e55d797
commit f2fc335221
2 changed files with 54 additions and 3 deletions
@@ -87,9 +87,9 @@ class HwidDeviceMixin:
full_price = float(package.price_for_period(period_months))
period_start = self._as_aware_utc(getattr(sub, "start_date", None))
period_end = self._as_aware_utc(getattr(sub, "end_date", None)) or valid_until
if not period_start or period_start >= period_end:
period_start = valid_from
period_end = valid_until
inferred_period_start = add_months(period_end, -period_months)
if not period_start or period_start >= period_end or period_start < inferred_period_start:
period_start = inferred_period_start
basis_seconds = max(1.0, (period_end - period_start).total_seconds())
billable_start = max(now, valid_from)
+51
View File
@@ -222,6 +222,57 @@ class HwidDeviceTopupBehaviourTests(unittest.IsolatedAsyncioTestCase):
self.assertEqual(quote["price"], 50)
self.assertAlmostEqual(quote["proration_ratio"], 0.5)
async def test_quote_uses_last_paid_duration_when_start_date_is_stale(self):
with tempfile.TemporaryDirectory() as tmpdir:
settings = _make_settings(
tmpdir,
_tariffs_config_payload(
hwid_device_packages={
"rub": [
{
"count": 1,
"price": 50,
"prices": {"3": 150},
}
],
"stars": [],
}
),
)
service = _make_service(settings)
sub = _make_sub()
sub.duration_months = 3
sub.start_date = datetime(2098, 7, 1, tzinfo=timezone.utc)
sub.end_date = datetime(2099, 1, 1, tzinfo=timezone.utc)
user = _make_user()
with (
patch(
"bot.services.subscription_service_impl.devices.user_dal.get_user_by_id",
AsyncMock(return_value=user),
),
patch(
"bot.services.subscription_service_impl.devices.subscription_dal.get_active_subscription_by_user_id",
AsyncMock(return_value=sub),
),
patch(
"bot.services.subscription_service_impl.devices.tariff_dal.get_hwid_device_entitlement_summary",
AsyncMock(return_value={"active_devices": 0, "active_until": None}),
),
):
quote = await service.quote_hwid_device_topup(
session=AsyncMock(),
user_id=42,
device_count=1,
tariff_key="standard",
currency="rub",
now=datetime(2098, 10, 1, tzinfo=timezone.utc),
)
self.assertIsNotNone(quote)
self.assertEqual(quote["price"], 150)
self.assertAlmostEqual(quote["proration_ratio"], 1.0)
async def test_unlimited_subscriber_returns_noop_payload(self):
# hwid_device_limit == 0 means unlimited — top-up makes no sense and must skip.
with tempfile.TemporaryDirectory() as tmpdir: