mirror of https://github.com/zulip/zulip.git
billing: Adding invoicing fields to CustomerPlan.
This commit is contained in:
parent
fe280fc38c
commit
421cda0e34
|
@ -231,10 +231,10 @@ def compute_plan_parameters(
|
|||
if discount is not None:
|
||||
# There are no fractional cents in Stripe, so round down to nearest integer.
|
||||
price_per_license = int(float(price_per_license * (1 - discount / 100)) + .00001)
|
||||
next_billing_date = period_end
|
||||
next_invoice_date = period_end
|
||||
if automanage_licenses:
|
||||
next_billing_date = add_months(billing_cycle_anchor, 1)
|
||||
return billing_cycle_anchor, next_billing_date, period_end, price_per_license
|
||||
next_invoice_date = add_months(billing_cycle_anchor, 1)
|
||||
return billing_cycle_anchor, next_invoice_date, period_end, price_per_license
|
||||
|
||||
# Only used for cloud signups
|
||||
@catch_stripe_errors
|
||||
|
@ -251,7 +251,7 @@ def process_initial_upgrade(user: UserProfile, licenses: int, automanage_license
|
|||
"Customer {} trying to upgrade, but has an active subscription".format(customer))
|
||||
raise BillingError('subscribing with existing subscription', BillingError.TRY_RELOADING)
|
||||
|
||||
billing_cycle_anchor, next_billing_date, period_end, price_per_license = compute_plan_parameters(
|
||||
billing_cycle_anchor, next_invoice_date, period_end, price_per_license = compute_plan_parameters(
|
||||
automanage_licenses, billing_schedule, customer.default_discount)
|
||||
# The main design constraint in this function is that if you upgrade with a credit card, and the
|
||||
# charge fails, everything should be rolled back as if nothing had happened. This is because we
|
||||
|
@ -294,15 +294,16 @@ def process_initial_upgrade(user: UserProfile, licenses: int, automanage_license
|
|||
customer=customer,
|
||||
# Deprecated, remove
|
||||
licenses=-1,
|
||||
billed_through=billing_cycle_anchor,
|
||||
next_billing_date=next_billing_date,
|
||||
next_invoice_date=next_invoice_date,
|
||||
**plan_params)
|
||||
LicenseLedger.objects.create(
|
||||
ledger_entry = LicenseLedger.objects.create(
|
||||
plan=plan,
|
||||
is_renewal=True,
|
||||
event_time=billing_cycle_anchor,
|
||||
licenses=billed_licenses,
|
||||
licenses_at_next_renewal=billed_licenses)
|
||||
plan.invoiced_through = ledger_entry
|
||||
plan.save(update_fields=['invoiced_through'])
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm, acting_user=user, event_time=billing_cycle_anchor,
|
||||
event_type=RealmAuditLog.CUSTOMER_PLAN_CREATED,
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.18 on 2019-01-28 13:04
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('corporate', '0004_licenseledger'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='customerplan',
|
||||
old_name='next_billing_date',
|
||||
new_name='next_invoice_date',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='customerplan',
|
||||
name='billed_through',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='customerplan',
|
||||
name='invoiced_through',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='corporate.LicenseLedger'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='customerplan',
|
||||
name='invoicing_status',
|
||||
field=models.SmallIntegerField(default=1),
|
||||
),
|
||||
]
|
|
@ -39,9 +39,12 @@ class CustomerPlan(models.Model):
|
|||
MONTHLY = 2
|
||||
billing_schedule = models.SmallIntegerField() # type: int
|
||||
|
||||
# This is like analytic's FillState, but for billing
|
||||
billed_through = models.DateTimeField() # type: datetime.datetime
|
||||
next_billing_date = models.DateTimeField(db_index=True) # type: datetime.datetime
|
||||
next_invoice_date = models.DateTimeField(db_index=True) # type: datetime.datetime
|
||||
invoiced_through = models.ForeignKey(
|
||||
'LicenseLedger', null=True, on_delete=CASCADE, related_name='+') # type: Optional[LicenseLedger]
|
||||
DONE = 1
|
||||
STARTED = 2
|
||||
invoicing_status = models.SmallIntegerField(default=DONE) # type: int
|
||||
|
||||
STANDARD = 1
|
||||
PLUS = 2 # not available through self-serve signup
|
||||
|
|
|
@ -392,8 +392,8 @@ class StripeTest(StripeTestCase):
|
|||
plan = CustomerPlan.objects.get(
|
||||
customer=customer, automanage_licenses=True,
|
||||
price_per_license=8000, fixed_price=None, discount=None, billing_cycle_anchor=self.now,
|
||||
billing_schedule=CustomerPlan.ANNUAL, billed_through=self.now,
|
||||
next_billing_date=self.next_month, tier=CustomerPlan.STANDARD,
|
||||
billing_schedule=CustomerPlan.ANNUAL, invoiced_through=LicenseLedger.objects.first(),
|
||||
next_invoice_date=self.next_month, tier=CustomerPlan.STANDARD,
|
||||
status=CustomerPlan.ACTIVE)
|
||||
LicenseLedger.objects.get(
|
||||
plan=plan, is_renewal=True, event_time=self.now, licenses=self.seat_count,
|
||||
|
@ -477,8 +477,8 @@ class StripeTest(StripeTestCase):
|
|||
plan = CustomerPlan.objects.get(
|
||||
customer=customer, automanage_licenses=False, charge_automatically=False,
|
||||
price_per_license=8000, fixed_price=None, discount=None, billing_cycle_anchor=self.now,
|
||||
billing_schedule=CustomerPlan.ANNUAL, billed_through=self.now,
|
||||
next_billing_date=self.next_year, tier=CustomerPlan.STANDARD,
|
||||
billing_schedule=CustomerPlan.ANNUAL, invoiced_through=LicenseLedger.objects.first(),
|
||||
next_invoice_date=self.next_year, tier=CustomerPlan.STANDARD,
|
||||
status=CustomerPlan.ACTIVE)
|
||||
LicenseLedger.objects.get(
|
||||
plan=plan, is_renewal=True, event_time=self.now, licenses=123, licenses_at_next_renewal=123)
|
||||
|
|
Loading…
Reference in New Issue