Commit Graph

473 Commits

Author SHA1 Message Date
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
Lauryn Menard 3ebc507ddb signups: Move logic for realm admin notification to corporate app.
As we would like to send similar notifications for other billing
state changes (for all BillingSession types), it makes sense to
move the logic for creating and sending these admin realm internal
messages to the BillingSession framework in the corporate app.

In the case that a channel with the specified name does not exist,
we now send direct messages to the admin realm administrators with
the channel, topic and message so that the information is not lost
and so that the channel for these messages can be created.
2024-11-05 08:56:24 -08:00
Prakhar Pratyush f351f94827 do_change_plan_type: Mark the transaction to not create savepoints.
This commit adds 'savepoint=False' to the transaction.atomic
decorators of do_change_plan_type as we don't intend to create
savepoints when the function is called inside an outer transaction.
2024-11-01 16:41:15 -07:00
Prakhar Pratyush c4f74f470d remote_server_post_analytics: Add durable=True to outermost transaction.
This commit adds 'durable=True' to the outermost transaction
in 'remote_server_post_analytics'.

It also adds 'savepoint=False' to inner transaction.atomic
decorator to avoid creating savepoint.

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

* 'savepoint=True' is used in special cases.
2024-11-01 16:41:15 -07:00
Prakhar Pratyush 0fb5657131 transaction: Add durable=True to outermost transaction.atomic decorator.
This commit adds 'durable=True' to the outermost transactions
of the following functions:
* do_create_multiuse_invite_link
* do_revoke_user_invite
* do_revoke_multi_use_invite
* sync_ldap_user_data
* do_reactivate_remote_server
* do_deactivate_remote_server
* bulk_handle_digest_email
* handle_customer_migration_from_server_to_realm
* add_reaction
* remove_reaction
* deactivate_user_group

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 decorators with either 'savepoint=False' or
'durable=True' as required.

* 'savepoint=True' is used in special cases.
2024-11-01 16:41:15 -07:00
Lauryn Menard cac4adac5f billing: Keep stripe_customer_id when migrating to legacy plan.
The removal of the stripe_customer_id when creating a legacy plan
actually disconnects any existing information in Stripe about a
customer, who may have previously had a paid plan, so we don't
want that removal to happen. Instead we get or create the customer
associated with the billing session entity.

Also, updates some of the code comments in the function for legacy
plan migrations to be clearer.
2024-09-27 11:55:07 -07:00
Aman Agrawal 790d5c44a1 stripe: Allow customer to switch license management type.
Fixes #28633

Added a button to switch license management type on billing page.

Tested that the plan switch works correctly.

Tested that when switching from manual to automatic license
management, customer is only billed for billable users for the
next billing cycle.
2024-09-26 16:13:28 -07:00
Anders Kaseorg 5e62903d29 corporate: Use Literal types for upgrade parameters.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-09-24 18:18:26 -07:00
Lauryn Menard 137f4fccde billing: Highlight manual license management errors for admins.
In the billing portal UI for manual license management, limit
decreasing the number of licenses for the next billing period to
be less than the currently used licenses. If the customer is exempt
from license number checks, then this limit is not applied.

Also, visually highlight manual license management errors so that
the billing admin is aware of potential issues.

As of these changes, current licenses can be under the seat count
when a guest user is changed to a non-guest user. And next billing
period licenses can be under the seat cout when a user joins with a
currently available, purchased license after a billing admin has
decreased the number of licenses set for the next billing period.
2024-09-20 12:02:39 -07:00
Lauryn Menard b02cf53d5e billing: Validate license management at end of billing cycle.
For plans where we're enforcing correct manual license management,
before we create the renewal entry for the licenses ledger at the
end of a billing cycle, we should check that the current count of
billed licenses is not higher than what the renewal license count
would be.

Co-authored-by: Aman Agrawal <amanagr@zulip.com>
2024-09-20 12:02:39 -07:00
Aman Agrawal 4d8e6ba094 stripe: Change stripe email on the upgrade page if available. 2024-09-19 11:26:21 -07:00
Aman Agrawal 9a4a07d933 stripe: Allow user to update email for sending invoice. 2024-09-19 11:26:21 -07:00
Lauryn Menard 2e394f3913 billing: Check minimum for plan tier for stale license count check. 2024-09-18 09:40:42 -07:00
Lauryn Menard 0147578de6 corporate: Make initial upgrade license checks more robust.
In cases where the seat count for automated license management is
stale when the upgrade process is initiated and the user has chosen
automated license management, we should get the current billable
license count when doing the initial payment/charge.

Also, makes the post-payment check for inconsistencies more robust
in that we check for both under and over billing cases. In the case
where the customer may have been overbilled, an email is sent to
the billing support team so that manual investigation can happen.
2024-09-11 11:16:55 -07:00
Lauryn Menard aad93e149e audit-log: Move remote server event types to AuditLogEventType enum.
Event types moved: REMOTE_SERVER_DEACTIVATED, REMOTE_SERVER_REACTIVATED
REMOTE_SERVER_PLAN_TYPE_CHANGED, REMOTE_SERVER_DISCOUNT_CHANGED
REMOTE_SERVER_SPONSORSHIP_APPROVED, REMOTE_SERVER_BILLING_MODALITY_CHANGED
REMOTE_SERVER_SPONSORSHIP_PENDING_STATUS_CHANGED, REMOTE_SERVER_CREATED
2024-09-09 11:50:13 -07:00
Lauryn Menard f7e07e91a2 audit-log: Move customer event types to AuditLogEventType enum.
Event types moved: CUSTOMER_CREATED, CUSTOMER_PLAN_CREATED
CUSTOMER_SWITCHED_FROM_MONTHLY_TO_ANNUAL_PLAN,
CUSTOMER_SWITCHED_FROM_ANNUAL_TO_MONTHLY_PLAN,
CUSTOMER_PROPERTY_CHANGED, CUSTOMER_PLAN_PROPERTY_CHANGED
2024-09-09 11:50:13 -07:00
Lauryn Menard bf4a650999 audit-log: Move stripe event types to AuditLogEventType enum.
Event types moved: STRIPE_CUSTOMER_CREATED, STRIPE_CARD_CHANGED
STRIPE_PLAN_CHANGED, STRIPE_PLAN_QUANTITY_RESET
2024-09-09 11:50:13 -07:00
Lauryn Menard d2c32f23db audit-log: Move realm event types to AuditLogEventType enum.
Event types moved: REALM_DEACTIVATED, REALM_REACTIVATED, REALM_SCRUBBED
REALM_PLAN_TYPE_CHANGED, REALM_LOGO_CHANGED, REALM_EXPORTED
REALM_PROPERTY_CHANGED, REALM_ICON_SOURCE_CHANGED, REALM_DISCOUNT_CHANGED
REALM_SPONSORSHIP_APPROVED, REALM_BILLING_MODALITY_CHANGED
REALM_REACTIVATION_EMAIL_SENT, REALM_SPONSORSHIP_PENDING_STATUS_CHANGED
REALM_SUBDOMAIN_CHANGED
2024-09-09 11:50:13 -07:00
Lauryn Menard c0100a3c4c billing: Rename AuditLogEventType to BillingSessionEventType.
This enum class is used only in billing code for mapping billing
actions to audit log event types, so the class name should clearly
reflect that.
2024-09-09 11:50:13 -07:00
Lauryn Menard 44e73eecc1 support: Add basic information about realm.
Adds non-form section to Zulip Cloud support view with some basic
realm information: organization type, plan type, non-guest user
count and guest user count.

Uses a shared template for the basic realm data and adds a shared
support context dict for variables that are used in both remote
and Zulip Cloud support views.
2024-08-26 20:52:38 -07:00
Lauryn Menard b52b1bcca8 support: Consolidate sponsorship forms for remote and Zulip Cloud views.
In the Zulip Cloud support view, adds a "Realm management" section
for support actions that are specific to that view, (e.g., changing
an organization's type or deactivating an organization).

Moves the note about emailing organization owners when a full
sponsorship is approved for Zulip Cloud Standard to the success
message for that action, which mirrors the remote server/realm
support view.
2024-08-20 09:45:49 -07:00
Lauryn Menard 3d58a7ec04 remote-support: Add ability to configure temporary courtesy plan.
Expands section for scheduling plans in the remote support view to
have a form to create a temporary courtesy plan (aka our legacy
plan for remote servers and realms).

Form is not shown if there is a current plan for the remote billing
entity, and would raise a SupportRequestError in that case as well.
2024-08-16 16:40:18 -07:00
Alex Vandiver 8e1582d82e support: Reject attempts to approve sponsorship for deactivated orgs. 2024-08-13 20:29:02 -07:00
Anders Kaseorg 818bad300e corporate: Set assume_scheme="https" for django.forms.URLField.
The previous default of "http" is deprecated and will change to
"https" in Django 6.0.

https://docs.djangoproject.com/en/5.0/releases/5.0/#id2
https://docs.djangoproject.com/en/5.0/ref/forms/fields/#django.forms.URLField.assume_scheme

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-16 13:40:59 -07:00
Anders Kaseorg 1e9b6445a9 ruff: Fix PLR6104 Use `+=` to perform an augmented assignment directly.
This is a preview rule, not yet enabled by default.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-14 13:49:51 -07:00
Anders Kaseorg 1464009fae ruff: Fix UP038 Use `X | Y` in `isinstance` call instead of `(X, Y)`.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-13 22:28:22 -07:00
Anders Kaseorg 0fa5e7f629 ruff: Fix UP035 Import from `collections.abc`, `typing` instead.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-13 22:28:22 -07:00
Anders Kaseorg 531b34cb4c ruff: Fix UP007 Use `X | Y` for type annotations.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-13 22:28:22 -07:00
Anders Kaseorg e08a24e47f ruff: Fix UP006 Use `list` instead of `List` for type annotation.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-13 22:28:22 -07:00
Lauryn Menard 1969698cf6 stripe: Use comma for collection method Literal values. 2024-06-10 16:10:42 -07:00
Lauryn Menard 4fcf7945b0 support: Show annual revenue for active fixed price plans.
In the activity and support views, we want to see the annual
revenue for fixed price plans. While on billing pages, we do
not display this information as these plans are renegotiated
annually.

Adds get_annual_recurring_revenue_for_support_data function
to BillingSession class, so that we can get the fixed price
plan data for these views without changing the logic for
what is displayed on the billing pages.
2024-05-22 15:57:59 -07:00
Anders Kaseorg b545abe1e2 typos: Fix typos caught by mwic.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-05-20 13:55:00 -07:00
Aman Agrawal 7203661d99 support: Set discounted price instead percentage for customers.
This allows us to set the price of a plan exactly as discussed with
the customer.
2024-05-16 02:18:43 -07:00
Vector73 8ab526a25a models: Replace realm.uri with realm.url.
In #23380, we are changing all occurrences of uri with url in order to
follow the latest URL standard. Previous PRs #25038 and #25045 has
replaced the occurences of uri that has no direct relation with realm.

This commit changes just the model property, which has no API
compatibility concerns.
2024-05-08 11:12:43 -07:00
Anders Kaseorg 31c7b2bfd7 stripe: Add assertions to fix errors flagged by mypy 1.10.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-30 13:58:24 -07:00
Anders Kaseorg b195dc5a89 stripe: Add missing stripe_customer_id assertions.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-30 13:58:24 -07:00
Anders Kaseorg 7b2a4304fc stripe: Stringify invoice metadata.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-30 13:58:24 -07:00
Anders Kaseorg 385cd038b0 stripe: Pass ids, not objects, to pagination API.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-30 13:58:24 -07:00
Anders Kaseorg 9ca64b21f3 stripe: Properly convert Period object to CreateParamsPeriod dict.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-30 13:58:24 -07:00
Anders Kaseorg 228ade86be stripe: Use absent days_until_due rather than invalid None.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-30 13:58:24 -07:00
Anders Kaseorg 0af62519a1 stripe: Isolate ignored error for undocumented Invoice.list usage.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-30 13:58:24 -07:00
Anders Kaseorg e7a3d743d1 stripe: Use more specific type annotations.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-30 13:58:24 -07:00
Aman Agrawal 7d1f858273 stripe: Ensure required_plan_tier is set before setting discount. 2024-04-29 17:11:11 -07:00
Aman Agrawal 2d824e85cc stripe: Remove invalid comment.
We use `error_description` in upgrade.ts to determine if the error was
related to customer's card. Doesn't seem like there is any harm
in doing so since we are explicitly handling "stripe.CardError" and
raising these errors with "card error" description.
2024-04-22 09:20:17 -07:00
Aman Agrawal 42bbeb6247 stripe: Change pricing for plus plan.
This also now allows user to upgrade to plus plan from pricing page.

Note that since we don't pass customer_plan on pages like self-hosting
and for/business, `Current plan` status is not displayed on these pages.
2024-04-19 09:57:43 -07:00
Mateusz Mandera 4a2a9176c2 realms: Add caching to the get_seat_count calculation for upload limit.
For simiplicty's sake, we can avoid trying to do cache invalidation in
the variety of events that can cause the seat count to change - since
having an up to 1 day delay between users being added and the upload
limit going up is quite reasonable.
2024-04-15 15:08:56 -07:00
Mateusz Mandera 4eacd25ad5 stripe: Rename CustomerPlan.is_paid.
This might not be the most meaningful change of phrasing, but .is_paid()
sounds like it's a check for whether the customer has already paid their
invoice. is_a_paid_plan() reflects better the meaning that it's whether
it's a plan of a "paid" type.
2024-04-15 15:08:56 -07:00
Aman Agrawal 8a807949df stripe: Disable free trial for customer with any plan in the past. 2024-04-11 21:57:33 -07:00
Aman Agrawal ed2de77895 stripe: Send invoice to customer at the start of free trial.
We send customer an invoice at the start of free trial, if customer
pays we upgrade them to the active plan at the end of free trial,
else we downgrade them and show a custom message on the upgrade
page regarding the current status.
2024-04-11 21:57:33 -07:00