Commit Graph

521 Commits

Author SHA1 Message Date
Aman Agrawal
3cdda91afe 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.
2025-05-14 13:45:35 -07:00
Aman Agrawal
6fb7a21cef stripe: Update plan in database outside for loop.
Since we are not doing an early return here and the updated information
is not immediately used, we can skip updating the plan in database
till the end of for loop.
2025-05-14 13:45:35 -07:00
Aman Agrawal
ba9d183721 stripe: Only create flat discounts for renewal invoices.
If we only created invoice for additional licenses, we don't need
to add discount to the invoice.

Changes haven't been tested in this commit. It is just for easy
verification of changes.
2025-05-14 13:45:35 -07:00
Aman Agrawal
cfa7458797 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.
2025-05-14 13:45:35 -07:00
Aman Agrawal
af4cee9479 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.
2025-05-14 13:45:35 -07:00
Aman Agrawal
fbec6ab123 stripe: Only attempt payment if invoice is not paid.
Since it is possible that invoice can be paid before we reach here,
so only attempt payment if the invoice is not marked as 'paid'.

Fixes invoice already paid error from stripe when running tests.
2025-05-14 13:45:35 -07:00
Lauryn Menard
4d1bfe6537 demo-orgs: Disable corporate upgrade and sponsorship pages.
Use a shared error template for demo organizations when rendering
the upgrade or sponsorship pages.

Demo organizations must be converted into a permanent organization,
i.e., not be automatically scheduled for deletion, to either apply
for a sponsorship/discount or upgrade to a paid plan.
2025-04-23 09:23:24 -07:00
Lauryn Menard
b074288bac upgrade: Remove demo_organization_scheduled_deletion_date page param.
The demo_organization_scheduled_deletion_date has never been used
on the upgrade page, and currently raises a Zod error as what is
being sent for the value of that page param is a datetime object,
and not the datetime object converted to an integer.

We really only need the boolean value that checks if the demo
organization scheduled deletion date is not None for the upgrade
page logic, which is set in the context dict for that page, but
not in the page params.
2025-04-17 10:49:02 -07:00
Ethan Mayer
c12b94aea4 models: Refactor corporate/models.py into models package.
Fixes #34318.

Seperated models file into a package with component files.
2025-04-08 10:16:35 -07:00
Lauryn Menard
ec89e5afd2 billing: Improve error handling when invoicing plans as needed.
When we're unable to process an invoice for a customer due to a billing
or assertion error, we log the error and add the customer ID to a set
of failed customer IDs. This allows us to continuing invoicing other
customers, and at the same time not invoice any other pending plans
attached to a customer we failed to invoice.
2025-03-27 12:51:52 -07:00
Lauryn Menard
10fff6a691 billing: Extract helper for invoicing check of remote server audit log.
Extracts the logic for making sure that, for self-hosted plans, the
remote server audit log data is current before invoicing an active
plan.
2025-03-27 12:51:52 -07:00
Lauryn Menard
0f567a1a66 billing: Extract helper for sending invoice overdue email.
Extracts the logic for sending an email to billing support when
a remote server's audit log data is stale and there is an active
CustomerPlan that needs to be invoiced.
2025-03-27 12:51:52 -07:00
Lauryn Menard
10a02142dc billing: Extract helper for sending fixed price plan renewal email.
Extracts the logic for sending a reminder email about the end of a
fixed price plan to billing support into a separate function.
2025-03-27 12:51:52 -07:00
Vector73
c049259d07 user: Remove is_billing_admin user property.
Removed `is_billing_admin` user property as it is no longer used since
billing permissions are now determined by `can_manage_billing_group`
realm setting.
2025-03-10 09:36:30 -07:00
Vector73
158fd58cde settings: Add "can_manage_billing_group" realm setting.
Added "can_manage_billing_group" realm group permission setting
to control who can manage billing and plans in the organization.

Fixes #32745.
2025-03-10 09:36:30 -07:00
Lauryn Menard
c4e3ccafa2 stripe: Delete fixed price plan offer if customer on comp access plan.
Updates delete_fixed_price_plan to use the same structure as
configure_fixed_price_plan. If there is a customer plan and it's
billable, then we delete the configured CustomerPlan object. If
there is no customer plan or it's a complimentary access plan, we
delete the configured CustomerPlanOffer object.
2025-02-28 17:42:04 -08:00
Lauryn Menard
add58e3795 billing: Use customer.minimum_licenses for minimum plan check.
Allow for manually setting a minimum_licenses value on a customer
to return that for min_licenses_for_plan in cases where we wanted
to override the general plan minimum for a particular case.
2025-02-20 14:17:25 -08:00
Aman Agrawal
b549562a4d sponsorship: Ask user how they plan to use Zulip.
This will help avoid some back-and-forth on sponsorship requests.
2025-01-22 09:22:52 -08:00
Aman Agrawal
6e1bb56519 stripe: Check for min_licenses when switching plan tier.
When we are upgrading a customer to a different plan tier, we should
check if switching plans would lead to different licenses due to
different minimum license requirement between plans.
2025-01-21 15:53:53 -08:00
Lauryn Menard
261333c37f corporate: Clean up code remaining comments with "legacy plan".
Replaces documentation in billing code and tests to use
"complimentary access plan" instead of "legacy plan".
2025-01-21 15:40:27 -08:00
Lauryn Menard
bc20a0f086 support: Update "temporary courtesy" to "complimentary access".
Updates support actions for "temporary courtesy" plans to instead
use "complimentary access" to refer to these plans and actions.

Prep for implementing a complimentary access plan for Zulip Cloud.
2025-01-21 15:40:27 -08:00
Lauryn Menard
d3bc9bec1d billing: Rename migrate_customer_to_legacy_plan.
Renames migrate_customer_to_legacy_plan to
create_complimentary_access_plan for how this
function is currently used.

Prep for adding a complimentary access plan
for Zulip Cloud.
2025-01-21 15:40:27 -08:00
Aman Agrawal
b870faec5a stripe: Require 10 minimum licenses for cloud plus plan. 2025-01-16 11:32:03 -08:00
Aman Agrawal
e0767b23ed stripe: Validate licenses for the correct plan.
Since licenses are being created for the `new_plan` we need to
check licenses for the new plan here.
2025-01-16 11:32:03 -08:00
Lauryn Menard
e963d5eaa9 billing: Fix deleting next fixed-price plan via support.
If the customer has a current fixed-price plan and a support admin
configures a fixed-price plan for the upcoming billing year, then
a CustomerPlan object is created and not a CustomerPlanOffer.

Fix the support action for deleting a configured fixed-price next
plan.

Updates the success strings for these actions to be specify if the
deleted object was a plan offer or a scheduled plan.
2025-01-15 11:23:24 -08:00
Anders Kaseorg
653b0b0436 ruff: Partially reformat Python with Ruff 0.9 (2025 style).
These are the changes that are backwards compatible with the 2024
style.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2025-01-14 09:42:16 -08:00
Anders Kaseorg
58822372d5 typos: Fix typos caught by typos and mwic.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-12-24 19:15:36 -08:00
Aman Agrawal
0b063e73fe stripe: Fix error on visiting /customer_portal without parameters.
Now visiting `/customer_portal` will correctly take you to the stripe
customer portal corresponding to the customer for editing.

There is no reason for us to block access to this page.
2024-12-17 10:33:22 -08:00
Aman Agrawal
bb8a0ea1f4 stripe: Create customer if one doesn't exist.
Since this function can only be called by billing admins, it
is okay to allow them to create a customer if one doesn't exist.
2024-12-17 10:33:22 -08:00
Lauryn Menard
a1121b39ad stripe: Rename should_schedule_upgrade_for_legacy_remote_server param.
Renames should_schedule_upgrade_for_legacy_remote_server parameter
to upgrade_when_complimentary_access_plan_ends in both
process_initial_upgrade and compute_plan_parameters, as well as
associated variable names and relevant code comments.
2024-12-15 09:15:07 -08:00
Lauryn Menard
1f2f0af257 stripe: Rename remote_server_legacy_plan param in initial upgrade.
Renames the remote_server_legacy_plan parameter in
process_initial_upgrade to instead be complimentary_access_plan,
as well as some relevant code comments in that function.
2024-12-15 09:15:07 -08:00
Lauryn Menard
7a0626aede stripe: Rename get_remote_server_legacy_plan.
Renames get_remote_server_legacy_plan to
get_complimentary_access_plan, as well as
associated variable names.
2024-12-15 09:15:07 -08:00
Lauryn Menard
20352aff9e stripe: Rename get_legacy_remote_server_next_plan.
Renames get_legacy_remote_server_next_plan to
get_complimentary_access_next_plan, as well as
associated variable names.
2024-12-15 09:15:07 -08:00
Lauryn Menard
b6f8c20772 stripe: Rename get_legacy_remote_server_next_plan_name.
Rename get_legacy_remote_server_next_plan_name to
get_complimentary_access_next_plan_name, as well as all
associated variables.
2024-12-15 09:15:07 -08:00
Lauryn Menard
713bef6ff5 stripe: Rename get_formatted_remote_server_legacy_plan_end_date.
Renames get_formatted_remote_server_legacy_plan_end_date to
get_formatted_complimentary_plan_end_date and associated
variable names.
2024-12-15 09:15:07 -08:00
Lauryn Menard
984fdf3eb9 upgrade: Update context variables to use "complimentary_access". 2024-12-15 09:15:07 -08:00
Lauryn Menard
f63e5c9242 billing: Update context variables to use "complimentary_access". 2024-12-15 09:15:07 -08:00
Lauryn Menard
36210c1ff3 billing: Replace legacy plan languagae with complimentary access.
Replaces the billing context variable for billing entities on a
temporary courtesy plan to use 'complimentary access' instead of
'legacy'.
2024-12-12 11:04:23 -08:00
Lauryn Menard
a6ca968a29 corporate: Add and use CustomerPlan.COMPLIMENTARY_PLAN_TIERS.
Adds COMPLIMENTARY_PLAN_TIERS to the CustomerPlan model so that
we start transitioning from the "legacy plan" language in the
billing system code. Adds a helper function that checks if the
plan tier is in COMPLIMENTARY_PLAN_TIERS.

Updates the sponsorship page context to use that helper function
and updates the relevant template for the updated user-facing
terminology.
2024-12-12 11:04:23 -08:00
Lauryn Menard
e1ae7dba18 stripe: Rename add_sponsorship_info_to_context to clarify function.
Renames add_sponsorship_info_to_context to instead be
add_org_type_data_to_sponsorship_context since this function for
all billing entities is adding information about the organization
type for the sponsorship request form.
2024-12-12 11:04:23 -08:00
Lauryn Menard
18686e06bb sponsorship: Remove free_trial from sponsorship page context.
Being on a free trial also means that the billing entity is on a
paid plan.

If they are on a sponsored plan, then they are not on a free trial.
If they have a pending sponsorship request, then they will be
redirected to the billing page. Otherwise, they will be shown the
form to request a sponsored/discounted plan, which does not use
the free_trial boolean.
2024-12-12 11:04:23 -08:00
Lauryn Menard
710f36cade stripe: Refactor function for getting sponsorship page context.
Reorders the logic in get_sponsorship_request_context so that the
early return for billing entities with a pending sponsorship request
that are also on a current paid plan is clearer.
2024-12-12 11:04:23 -08:00
Lauryn Menard
a0562593b3 stripe: Update next_invoice_date for current logic of monthly invoices.
Updates next_invoice_date since, as of commit caba57fe1e, we no
longer consider the plan's billing schedule (annual or monthly)
when invoicing for additional licenses.
2024-12-03 10:17:28 -08:00
Lauryn Menard
a0bbc62f2b support: Add fixed-price plan configuration to Cloud support view.
Adds ability to configure a fixed-price plan and to delete a
configured fixed-price plan in the Cloud support view.

Updates the invoice processing to send reminder emails to the
billing support email for these Cloud fixed-price plans about
renewals since we now are able to configure them via our support
panel.

Updates function to get the billing session for stripe webhook
events to handle an intial upgrade for a custom generated invoice
for a fixed-price plan for a Cloud organization, which won't have
a user_id in the invoice metadata.
2024-11-26 12:42:39 -08:00
Lauryn Menard
89b5e850b2 support: Implement setting a current plan end date for Cloud support.
Prep for implementing fixed-price plan offers in Cloud support view.
2024-11-26 12:42:39 -08:00
Prakhar Pratyush
c5b3d2e434 custom_check: Add rule to avoid creating savepoints.
This commit adds a custom rule to check python files
and raise lint error if they have transaction.atomic used
without any argument or savepoint=True is used.

It helps to avoid creating unintended savepoints in the future.
2024-11-21 14:55:15 -08:00
Lauryn Menard
cd55488487 billing: Link customer stripe ID for manual fixed-price plan invoices.
For cases where a customer is created in Stripe first for the manual
invoice, we want to connect that customer information to our Customer
object in the database. That way the customer can access the billing
page once the invoice is paid.
2024-11-21 10:34:33 -08:00
Anders Kaseorg
9e9e951a4a corporate: Fix misuse of timezone_now() as parameter default.
Python parameter defaults are only evaluated once at the function
definition site, not at each call site.  So these defaults were
incorrectly evaluating to the server’s startup time rather than the
current time.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-11-10 19:14:32 -08:00
Prakhar Pratyush
75edce59c1 process_downgrade: Add savepoint=False to avoid creating savepoint.
'process_downgrade' is used inside an outer db transaction
created in 'remote_server_post_analytics'.

`transaction.atomic()` block in 'process_downgrade' resulted in
savepoint creation.

This commit adds `savepoint=False` to avoid that.
2024-11-05 17:58:47 -08:00
Prakhar Pratyush
9c9866461a transaction: Add durable=True to the outermost db transactions.
This commit adds `durable=True` to the outermost db transactions
created in the following:
* confirm_email_change
* handle_upload_pre_finish_hook
* deliver_scheduled_emails
* restore_data_from_archive
* do_change_realm_subdomain
* do_create_realm
* do_deactivate_realm
* do_reactivate_realm
* do_delete_user
* do_delete_user_preserving_messages
* create_stripe_customer
* process_initial_upgrade
* do_update_plan
* request_sponsorship
* upload_message_attachment
* register_remote_server
* do_soft_deactivate_users
* maybe_send_batched_emails

It helps to avoid creating unintended savepoints in the future.

This is as a part of our plan to explicitly mark all the
transaction.atomic calls with either 'savepoint=False' or
'durable=True' as required.

* 'savepoint=True' is used in special cases.
2024-11-05 17:58:47 -08:00