mirror of
https://github.com/zulip/zulip.git
synced 2025-10-29 02:53:52 +00:00
stripe: Link InvoiceItem to Invoice.
This is required for upgrading to the basil version of stripe. Changes haven't been tested in this commit. It is just for easy verification of changes.
This commit is contained in:
@@ -3216,25 +3216,32 @@ class BillingSession(ABC):
|
|||||||
licenses_base = plan.invoiced_through.licenses
|
licenses_base = plan.invoiced_through.licenses
|
||||||
invoiced_through_id = plan.invoiced_through.id
|
invoiced_through_id = plan.invoiced_through.id
|
||||||
|
|
||||||
|
# Invoice Variables
|
||||||
|
stripe_invoice: stripe.Invoice | None = None
|
||||||
|
need_to_invoice = False
|
||||||
|
|
||||||
# Track if we added renewal invoice item which is possibly eligible for discount.
|
# Track if we added renewal invoice item which is possibly eligible for discount.
|
||||||
renewal_invoice_period: stripe.InvoiceItem.CreateParamsPeriod | None = None
|
renewal_invoice_period: stripe.InvoiceItem.CreateParamsPeriod | None = None
|
||||||
for ledger_entry in LicenseLedger.objects.filter(
|
for ledger_entry in LicenseLedger.objects.filter(
|
||||||
plan=plan, id__gt=invoiced_through_id, event_time__lte=event_time
|
plan=plan, id__gt=invoiced_through_id, event_time__lte=event_time
|
||||||
).order_by("id"):
|
).order_by("id"):
|
||||||
price_args: PriceArgs = {}
|
# InvoiceItem variables.
|
||||||
|
invoice_item_params = stripe.InvoiceItem.CreateParams(
|
||||||
|
customer=plan.customer.stripe_customer_id
|
||||||
|
)
|
||||||
|
|
||||||
if ledger_entry.is_renewal:
|
if ledger_entry.is_renewal:
|
||||||
if plan.fixed_price is not None:
|
if plan.fixed_price is not None:
|
||||||
amount_due = get_amount_due_fixed_price_plan(
|
amount_due = get_amount_due_fixed_price_plan(
|
||||||
plan.fixed_price, plan.billing_schedule
|
plan.fixed_price, plan.billing_schedule
|
||||||
)
|
)
|
||||||
price_args = {"amount": amount_due}
|
invoice_item_params["amount"] = amount_due
|
||||||
else:
|
else:
|
||||||
assert plan.price_per_license is not None # needed for mypy
|
assert plan.price_per_license is not None # needed for mypy
|
||||||
price_args = {
|
invoice_item_params["unit_amount"] = plan.price_per_license
|
||||||
"unit_amount": plan.price_per_license,
|
invoice_item_params["quantity"] = ledger_entry.licenses
|
||||||
"quantity": ledger_entry.licenses,
|
invoice_item_params["description"] = f"{plan.name} - renewal"
|
||||||
}
|
need_to_invoice = True
|
||||||
description = f"{plan.name} - renewal"
|
|
||||||
elif (
|
elif (
|
||||||
plan.fixed_price is None
|
plan.fixed_price is None
|
||||||
and licenses_base is not None
|
and licenses_base is not None
|
||||||
@@ -3260,19 +3267,34 @@ class BillingSession(ABC):
|
|||||||
plan_renewal_or_end_date - ledger_entry.event_time
|
plan_renewal_or_end_date - ledger_entry.event_time
|
||||||
) / (billing_period_end - last_renewal)
|
) / (billing_period_end - last_renewal)
|
||||||
unit_amount = int(plan.price_per_license * proration_fraction + 0.5)
|
unit_amount = int(plan.price_per_license * proration_fraction + 0.5)
|
||||||
price_args = {
|
invoice_item_params["unit_amount"] = unit_amount
|
||||||
"unit_amount": unit_amount,
|
invoice_item_params["quantity"] = ledger_entry.licenses - licenses_base
|
||||||
"quantity": ledger_entry.licenses - licenses_base,
|
invoice_item_params["description"] = "Additional license ({} - {})".format(
|
||||||
}
|
|
||||||
description = "Additional license ({} - {})".format(
|
|
||||||
ledger_entry.event_time.strftime("%b %-d, %Y"),
|
ledger_entry.event_time.strftime("%b %-d, %Y"),
|
||||||
plan_renewal_or_end_date.strftime("%b %-d, %Y"),
|
plan_renewal_or_end_date.strftime("%b %-d, %Y"),
|
||||||
)
|
)
|
||||||
|
need_to_invoice = True
|
||||||
|
|
||||||
if price_args:
|
if stripe_invoice is None and need_to_invoice:
|
||||||
plan.invoiced_through = ledger_entry
|
if plan.charge_automatically:
|
||||||
plan.invoicing_status = CustomerPlan.INVOICING_STATUS_STARTED
|
collection_method: Literal["charge_automatically", "send_invoice"] = (
|
||||||
plan.save(update_fields=["invoicing_status", "invoiced_through"])
|
"charge_automatically"
|
||||||
|
)
|
||||||
|
days_until_due = None
|
||||||
|
else:
|
||||||
|
collection_method = "send_invoice"
|
||||||
|
days_until_due = DEFAULT_INVOICE_DAYS_UNTIL_DUE
|
||||||
|
invoice_params = stripe.Invoice.CreateParams(
|
||||||
|
auto_advance=True,
|
||||||
|
collection_method=collection_method,
|
||||||
|
customer=plan.customer.stripe_customer_id,
|
||||||
|
statement_descriptor=plan.name,
|
||||||
|
)
|
||||||
|
if days_until_due is not None:
|
||||||
|
invoice_params["days_until_due"] = days_until_due
|
||||||
|
stripe_invoice = stripe.Invoice.create(**invoice_params)
|
||||||
|
|
||||||
|
if invoice_item_params.get("description") is not None:
|
||||||
invoice_period = stripe.InvoiceItem.CreateParamsPeriod(
|
invoice_period = stripe.InvoiceItem.CreateParamsPeriod(
|
||||||
start=datetime_to_timestamp(ledger_entry.event_time),
|
start=datetime_to_timestamp(ledger_entry.event_time),
|
||||||
end=datetime_to_timestamp(
|
end=datetime_to_timestamp(
|
||||||
@@ -3283,22 +3305,28 @@ class BillingSession(ABC):
|
|||||||
if ledger_entry.is_renewal:
|
if ledger_entry.is_renewal:
|
||||||
renewal_invoice_period = invoice_period
|
renewal_invoice_period = invoice_period
|
||||||
|
|
||||||
stripe.InvoiceItem.create(
|
invoice_item_params["currency"] = "usd"
|
||||||
currency="usd",
|
invoice_item_params["discountable"] = False
|
||||||
customer=plan.customer.stripe_customer_id,
|
invoice_item_params["period"] = invoice_period
|
||||||
description=description,
|
invoice_item_params["idempotency_key"] = get_idempotency_key(ledger_entry)
|
||||||
discountable=False,
|
assert stripe_invoice is not None
|
||||||
period=invoice_period,
|
assert stripe_invoice.id is not None
|
||||||
idempotency_key=get_idempotency_key(ledger_entry),
|
invoice_item_params["invoice"] = stripe_invoice.id
|
||||||
**price_args,
|
stripe.InvoiceItem.create(**invoice_item_params)
|
||||||
)
|
|
||||||
# Update license base per ledger_entry.
|
# Update license base per ledger_entry.
|
||||||
licenses_base = ledger_entry.licenses
|
licenses_base = ledger_entry.licenses
|
||||||
plan.invoiced_through = ledger_entry
|
plan.invoiced_through = ledger_entry
|
||||||
|
|
||||||
if renewal_invoice_period is not None:
|
flat_discount, flat_discounted_months = self.get_flat_discount_info(plan.customer)
|
||||||
flat_discount, flat_discounted_months = self.get_flat_discount_info(plan.customer)
|
if stripe_invoice is not None:
|
||||||
if plan.fixed_price is None and flat_discounted_months > 0:
|
# Only apply discount if this invoice contains renewal of the plan.
|
||||||
|
if (
|
||||||
|
renewal_invoice_period is not None
|
||||||
|
and plan.fixed_price is None
|
||||||
|
and flat_discounted_months > 0
|
||||||
|
):
|
||||||
|
assert stripe_invoice.id is not None
|
||||||
num_months = (
|
num_months = (
|
||||||
12 if plan.billing_schedule == CustomerPlan.BILLING_SCHEDULE_ANNUAL else 1
|
12 if plan.billing_schedule == CustomerPlan.BILLING_SCHEDULE_ANNUAL else 1
|
||||||
)
|
)
|
||||||
@@ -3307,6 +3335,7 @@ class BillingSession(ABC):
|
|||||||
plan.customer.flat_discounted_months -= flat_discounted_months
|
plan.customer.flat_discounted_months -= flat_discounted_months
|
||||||
plan.customer.save(update_fields=["flat_discounted_months"])
|
plan.customer.save(update_fields=["flat_discounted_months"])
|
||||||
stripe.InvoiceItem.create(
|
stripe.InvoiceItem.create(
|
||||||
|
invoice=stripe_invoice.id,
|
||||||
currency="usd",
|
currency="usd",
|
||||||
customer=plan.customer.stripe_customer_id,
|
customer=plan.customer.stripe_customer_id,
|
||||||
description=f"${cents_to_dollar_string(flat_discount)}/month new customer discount",
|
description=f"${cents_to_dollar_string(flat_discount)}/month new customer discount",
|
||||||
@@ -3315,23 +3344,6 @@ class BillingSession(ABC):
|
|||||||
period=renewal_invoice_period,
|
period=renewal_invoice_period,
|
||||||
)
|
)
|
||||||
|
|
||||||
if plan.charge_automatically:
|
|
||||||
collection_method: Literal["charge_automatically", "send_invoice"] = (
|
|
||||||
"charge_automatically"
|
|
||||||
)
|
|
||||||
days_until_due = None
|
|
||||||
else:
|
|
||||||
collection_method = "send_invoice"
|
|
||||||
days_until_due = DEFAULT_INVOICE_DAYS_UNTIL_DUE
|
|
||||||
invoice_params = stripe.Invoice.CreateParams(
|
|
||||||
auto_advance=True,
|
|
||||||
collection_method=collection_method,
|
|
||||||
customer=plan.customer.stripe_customer_id,
|
|
||||||
statement_descriptor=plan.name,
|
|
||||||
)
|
|
||||||
if days_until_due is not None:
|
|
||||||
invoice_params["days_until_due"] = days_until_due
|
|
||||||
stripe_invoice = stripe.Invoice.create(**invoice_params)
|
|
||||||
stripe.Invoice.finalize_invoice(stripe_invoice)
|
stripe.Invoice.finalize_invoice(stripe_invoice)
|
||||||
|
|
||||||
plan.invoicing_status = CustomerPlan.INVOICING_STATUS_DONE
|
plan.invoicing_status = CustomerPlan.INVOICING_STATUS_DONE
|
||||||
|
|||||||
Reference in New Issue
Block a user