mirror of https://github.com/zulip/zulip.git
billing: Update next_renewal_date to take an event_time.
Also changes a < into a <= in add_plan_renewal_to_license_ledger_if_needed.
This commit is contained in:
parent
7c11fe819a
commit
83a7595feb
|
@ -79,14 +79,14 @@ def next_month(billing_cycle_anchor: datetime, dt: datetime) -> datetime:
|
|||
'billing_cycle_anchor: %s, dt: %s' % (billing_cycle_anchor, dt))
|
||||
|
||||
# TODO take downgrade into account
|
||||
def next_renewal_date(plan: CustomerPlan) -> datetime:
|
||||
def next_renewal_date(plan: CustomerPlan, event_time: datetime) -> datetime:
|
||||
months_per_period = {
|
||||
CustomerPlan.ANNUAL: 12,
|
||||
CustomerPlan.MONTHLY: 1,
|
||||
}[plan.billing_schedule]
|
||||
periods = 1
|
||||
dt = plan.billing_cycle_anchor
|
||||
while dt <= plan.billed_through:
|
||||
while dt <= event_time:
|
||||
dt = add_months(plan.billing_cycle_anchor, months_per_period * periods)
|
||||
periods += 1
|
||||
return dt
|
||||
|
@ -191,14 +191,14 @@ def do_replace_payment_source(user: UserProfile, stripe_token: str) -> stripe.Cu
|
|||
# TODO handle downgrade
|
||||
def add_plan_renewal_to_license_ledger_if_needed(plan: CustomerPlan, event_time: datetime) -> LicenseLedger:
|
||||
last_ledger_entry = LicenseLedger.objects.filter(plan=plan).order_by('-id').first()
|
||||
plan_renewal_date = next_renewal_date(plan)
|
||||
if plan_renewal_date < event_time:
|
||||
if not LicenseLedger.objects.filter(
|
||||
plan=plan, event_time=plan_renewal_date, is_renewal=True).exists():
|
||||
return LicenseLedger.objects.create(
|
||||
plan=plan, is_renewal=True, event_time=plan_renewal_date,
|
||||
licenses=last_ledger_entry.licenses_at_next_renewal,
|
||||
licenses_at_next_renewal=last_ledger_entry.licenses_at_next_renewal)
|
||||
last_renewal = LicenseLedger.objects.filter(plan=plan, is_renewal=True) \
|
||||
.order_by('-id').first().event_time
|
||||
plan_renewal_date = next_renewal_date(plan, last_renewal)
|
||||
if plan_renewal_date <= event_time:
|
||||
return LicenseLedger.objects.create(
|
||||
plan=plan, is_renewal=True, event_time=plan_renewal_date,
|
||||
licenses=last_ledger_entry.licenses_at_next_renewal,
|
||||
licenses_at_next_renewal=last_ledger_entry.licenses_at_next_renewal)
|
||||
return last_ledger_entry
|
||||
|
||||
# Returns Customer instead of stripe_customer so that we don't make a Stripe
|
||||
|
|
|
@ -403,7 +403,8 @@ class StripeTest(ZulipTestCase):
|
|||
self.assertEqual('/billing/', response.url)
|
||||
|
||||
# Check /billing has the correct information
|
||||
response = self.client_get("/billing/")
|
||||
with patch('corporate.views.timezone_now', return_value=self.now):
|
||||
response = self.client_get("/billing/")
|
||||
self.assert_not_in_success_response(['Pay annually'], response)
|
||||
for substring in [
|
||||
'Zulip Standard', str(self.seat_count),
|
||||
|
@ -485,7 +486,8 @@ class StripeTest(ZulipTestCase):
|
|||
self.assertEqual('/billing/', response.url)
|
||||
|
||||
# Check /billing has the correct information
|
||||
response = self.client_get("/billing/")
|
||||
with patch('corporate.views.timezone_now', return_value=self.now):
|
||||
response = self.client_get("/billing/")
|
||||
self.assert_not_in_success_response(['Pay annually', 'Update card'], response)
|
||||
for substring in [
|
||||
'Zulip Standard', str(123),
|
||||
|
@ -950,12 +952,11 @@ class LicenseLedgerTest(ZulipTestCase):
|
|||
self.assertEqual(LicenseLedger.objects.count(), 1)
|
||||
plan = CustomerPlan.objects.get()
|
||||
# Plan hasn't renewed yet
|
||||
add_plan_renewal_to_license_ledger_if_needed(plan, self.next_year)
|
||||
add_plan_renewal_to_license_ledger_if_needed(plan, self.next_year - timedelta(days=1))
|
||||
self.assertEqual(LicenseLedger.objects.count(), 1)
|
||||
# Plan needs to renew
|
||||
# TODO: do_deactivate_user for a user, so that licenses_at_next_renewal != licenses
|
||||
ledger_entry = add_plan_renewal_to_license_ledger_if_needed(
|
||||
plan, self.next_year + timedelta(seconds=1))
|
||||
ledger_entry = add_plan_renewal_to_license_ledger_if_needed(plan, self.next_year)
|
||||
self.assertEqual(LicenseLedger.objects.count(), 2)
|
||||
ledger_params = {
|
||||
'plan': plan, 'is_renewal': True, 'event_time': self.next_year,
|
||||
|
@ -963,7 +964,7 @@ class LicenseLedgerTest(ZulipTestCase):
|
|||
for key, value in ledger_params.items():
|
||||
self.assertEqual(getattr(ledger_entry, key), value)
|
||||
# Plan needs to renew, but we already added the plan_renewal ledger entry
|
||||
add_plan_renewal_to_license_ledger_if_needed(plan, self.next_year + timedelta(seconds=1))
|
||||
add_plan_renewal_to_license_ledger_if_needed(plan, self.next_year + timedelta(days=1))
|
||||
self.assertEqual(LicenseLedger.objects.count(), 2)
|
||||
|
||||
def test_update_license_ledger_if_needed(self) -> None:
|
||||
|
|
|
@ -168,11 +168,12 @@ def billing_home(request: HttpRequest) -> HttpResponse:
|
|||
CustomerPlan.STANDARD: 'Zulip Standard',
|
||||
CustomerPlan.PLUS: 'Zulip Plus',
|
||||
}[plan.tier]
|
||||
last_ledger_entry = add_plan_renewal_to_license_ledger_if_needed(plan, timezone_now())
|
||||
now = timezone_now()
|
||||
last_ledger_entry = add_plan_renewal_to_license_ledger_if_needed(plan, now)
|
||||
# TODO: this is not really correct; need to give the situation as of the "fillstate"
|
||||
licenses = last_ledger_entry.licenses
|
||||
# Should do this in javascript, using the user's timezone
|
||||
renewal_date = '{dt:%B} {dt.day}, {dt.year}'.format(dt=next_renewal_date(plan))
|
||||
renewal_date = '{dt:%B} {dt.day}, {dt.year}'.format(dt=next_renewal_date(plan, now))
|
||||
renewal_cents = renewal_amount(plan)
|
||||
# TODO: this is the case where the plan doesn't automatically renew
|
||||
if renewal_cents is None: # nocoverage
|
||||
|
|
Loading…
Reference in New Issue