mirror of
https://github.com/zulip/zulip.git
synced 2025-11-07 15:33:30 +00:00
billing: Document model fields that are not self explanatory.
This commit is contained in:
@@ -22,8 +22,10 @@ class Customer(models.Model):
|
|||||||
default_discount: Optional[Decimal] = models.DecimalField(
|
default_discount: Optional[Decimal] = models.DecimalField(
|
||||||
decimal_places=4, max_digits=7, null=True
|
decimal_places=4, max_digits=7, null=True
|
||||||
)
|
)
|
||||||
# Some non-profit organizations on manual license management pay only for their paid employees.
|
# Some non-profit organizations on manual license management pay
|
||||||
# We don't prevent these organizations from adding more users than the number of licenses they purchased.
|
# only for their paid employees. We don't prevent these
|
||||||
|
# organizations from adding more users than the number of licenses
|
||||||
|
# they purchased.
|
||||||
exempt_from_from_license_number_check: bool = models.BooleanField(default=False)
|
exempt_from_from_license_number_check: bool = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
@@ -57,18 +59,39 @@ class CustomerPlan(models.Model):
|
|||||||
# Discount that was applied. For display purposes only.
|
# Discount that was applied. For display purposes only.
|
||||||
discount: Optional[Decimal] = models.DecimalField(decimal_places=4, max_digits=6, null=True)
|
discount: Optional[Decimal] = models.DecimalField(decimal_places=4, max_digits=6, null=True)
|
||||||
|
|
||||||
|
# Initialized with the time of plan creation. Used for calculating
|
||||||
|
# start of next billing cycle, next invoice date etc. This value
|
||||||
|
# should never be modified. The only exception is when we change
|
||||||
|
# the status of the plan from free trial to active and reset the
|
||||||
|
# billing_cycle_anchor.
|
||||||
billing_cycle_anchor: datetime.datetime = models.DateTimeField()
|
billing_cycle_anchor: datetime.datetime = models.DateTimeField()
|
||||||
|
|
||||||
ANNUAL = 1
|
ANNUAL = 1
|
||||||
MONTHLY = 2
|
MONTHLY = 2
|
||||||
billing_schedule: int = models.SmallIntegerField()
|
billing_schedule: int = models.SmallIntegerField()
|
||||||
|
|
||||||
|
# The next date the billing system should go through ledger
|
||||||
|
# entries and create invoices for additional users or plan
|
||||||
|
# renewal. Since we use a daily cron job for invoicing, the
|
||||||
|
# invoice will be generated the first time the cron job runs after
|
||||||
|
# next_invoice_date.
|
||||||
next_invoice_date: Optional[datetime.datetime] = models.DateTimeField(db_index=True, null=True)
|
next_invoice_date: Optional[datetime.datetime] = models.DateTimeField(db_index=True, null=True)
|
||||||
|
|
||||||
|
# On next_invoice_date, we go through ledger entries that were
|
||||||
|
# created after invoiced_through and process them by generating
|
||||||
|
# invoices for any additional users and/or plan renewal. Once the
|
||||||
|
# invoice is generated, we update the value of invoiced_through
|
||||||
|
# and set it to the last ledger entry we processed.
|
||||||
invoiced_through: Optional["LicenseLedger"] = models.ForeignKey(
|
invoiced_through: Optional["LicenseLedger"] = models.ForeignKey(
|
||||||
"LicenseLedger", null=True, on_delete=CASCADE, related_name="+"
|
"LicenseLedger", null=True, on_delete=CASCADE, related_name="+"
|
||||||
)
|
)
|
||||||
|
|
||||||
DONE = 1
|
DONE = 1
|
||||||
STARTED = 2
|
STARTED = 2
|
||||||
INITIAL_INVOICE_TO_BE_SENT = 3
|
INITIAL_INVOICE_TO_BE_SENT = 3
|
||||||
|
# This status field helps ensure any errors encountered during the
|
||||||
|
# invoicing process do not leave our invoicing system in a broken
|
||||||
|
# state.
|
||||||
invoicing_status: int = models.SmallIntegerField(default=DONE)
|
invoicing_status: int = models.SmallIntegerField(default=DONE)
|
||||||
|
|
||||||
STANDARD = 1
|
STANDARD = 1
|
||||||
@@ -87,7 +110,8 @@ class CustomerPlan(models.Model):
|
|||||||
NEVER_STARTED = 12
|
NEVER_STARTED = 12
|
||||||
status: int = models.SmallIntegerField(default=ACTIVE)
|
status: int = models.SmallIntegerField(default=ACTIVE)
|
||||||
|
|
||||||
# TODO maybe override setattr to ensure billing_cycle_anchor, etc are immutable
|
# TODO maybe override setattr to ensure billing_cycle_anchor, etc
|
||||||
|
# are immutable.
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
@@ -147,10 +171,21 @@ class LicenseLedger(models.Model):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
plan: CustomerPlan = models.ForeignKey(CustomerPlan, on_delete=CASCADE)
|
plan: CustomerPlan = models.ForeignKey(CustomerPlan, on_delete=CASCADE)
|
||||||
|
|
||||||
# Also True for the initial upgrade.
|
# Also True for the initial upgrade.
|
||||||
is_renewal: bool = models.BooleanField(default=False)
|
is_renewal: bool = models.BooleanField(default=False)
|
||||||
|
|
||||||
event_time: datetime.datetime = models.DateTimeField()
|
event_time: datetime.datetime = models.DateTimeField()
|
||||||
|
|
||||||
|
# The number of licenses ("seats") purchased by the the organization at the time of ledger
|
||||||
|
# entry creation. Normally, to add a user the organization needs at least one spare license.
|
||||||
|
# Once a license is purchased, it is valid till the end of the billing period, irrespective
|
||||||
|
# of whether the license is used or not. So the value of licenses will never decrease for
|
||||||
|
# subsequent LicenseLedger entries in the same billing period.
|
||||||
licenses: int = models.IntegerField()
|
licenses: int = models.IntegerField()
|
||||||
# None means the plan does not automatically renew.
|
|
||||||
# This cannot be None if plan.automanage_licenses.
|
# The number of licenses the organization needs in the next billing cycle. The value of
|
||||||
|
# licenses_at_next_renewal can increase or decrease for subsequent LicenseLedger entries in
|
||||||
|
# the same billing period. For plans on automatic license management this value is usually
|
||||||
|
# equal to the number of activated users in the organization.
|
||||||
licenses_at_next_renewal: Optional[int] = models.IntegerField(null=True)
|
licenses_at_next_renewal: Optional[int] = models.IntegerField(null=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user