Commit Graph

461 Commits

Author SHA1 Message Date
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 9a1ad1047a test_stripe: Normalize stripe fixtures.
Normalize generated fixtures for exp_month, exp_year and postal code.
2024-09-19 11:26:21 -07:00
Aman Agrawal 4d8e6ba094 stripe: Change stripe email on the upgrade page if available. 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 e5daa3470f audit-log: Move user event types to AuditLogEventType enum.
Event types moved: USER_CREATED, USER_ACTIVATED, USER_DEACTIVATED
USER_REACTIVATED, USER_ROLE_CHANGED, USER_DELETED
USER_DELETED_PRESERVING_MESSAGES
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 4b954a42ef billing: Create LicenseLedger entry for guest user role changes.
As guest users are charged at a different rate on Zulip Cloud, it
makes sense to track these changes in our LicenseLedger table so
that we can have an accurate record of the use of licenses that
a realm has purchased.
2024-09-05 16:11:36 -07:00
Anders Kaseorg 91ade25ba3 python: Simplify with str.removeprefix, str.removesuffix.
These are available in Python ≥ 3.9.
https://docs.python.org/3/library/stdtypes.html#str.removeprefix

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-09-03 12:30:16 -07:00
Aman Agrawal f0668fbaf6 stripe: Remove numeric variation from normalized fixture data.
We only make `id` and `timestamp` field of the fixture unique whose
uniqueness matters to us in the tests. Other fields don't matter, so
we normalized them completely with a constant so that they don't
have different values when generating fixtures repeatedly.
2024-08-30 11:38:47 -07:00
Aman Agrawal 3ea3f48338 test_stripe: Normalize fixtures for upgrade_by_card_to_plus_plan. 2024-08-26 08:37:27 -07:00
Aman Agrawal 2a158cb8d9 test_stripe: Normalize fixtures for test_stripe_billing_portal_urls. 2024-08-20 13:54:48 -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
Mateusz Mandera 4a93149435 settings: Rework how push notifications service is configured.
Instead of the PUSH_NOTIFICATIONS_BOUNCER_URL and
SUBMIT_USAGE_STATISTICS settings, we want servers to configure
individual ZULIP_SERVICE_* settings, while maintaining backward
compatibility with the old settings. Thus, if all the new
ZULIP_SERVICE_* are at their default False value, but the legacy
settings are activated, they need to be translated in computed_settings
to the modern way.
2024-07-17 17:14:06 -07:00
Anders Kaseorg b96feb34f6 ruff: Fix SIM117 Use a single `with` statement with multiple contexts.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-14 13:48:32 -07:00
Anders Kaseorg 48202389b8 ruff: Bump target-version from py38 to py310.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-13 22:28:22 -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 673a01ea0c realm-deactivation: Send email to owners as part of deactivation.
Creates a new "realm_deactivated" email that can be sent to realm
owners as part of `do_deactivate_realm`, via a boolean flag,
`email_owners`.

This flag is set to `False` when `do_deactivate_realm` is used for
realm exports or changing a realm's subdomain, so that the active
organization owners are not emailed in those cases.

This flag is optional for the `deactivate_realm` management command,
but as there is no active user passed in that case, then the email
is sent without referencing who deactivated the realm.

It is passed as `True` for the support analytics view, but the email
that is generated does not include information about the support
admin user who completed the request for organization deactivation.

When an active organization owner deactivates the organization, then
the flag is `True` and an email is sent to them as well as any other
active organization owners, with a slight variation in the email text
for those two cases.

Adds specific tests for when `email_owners` is passed as `True`. All
existing tests for other functionality of `do_deactivate_user` pass
the flag as `False`.

Adds `localize` from django.util.formats as a jinja env filter so
that the dates in these emails are internationlized for the owner's
default language setting in the "realm_deactivated" email templates.

Fixes #24685.
2024-06-26 16:48:18 -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
Mateusz Mandera 27c4e46b30 do_deactivate_realm: Add deactivation_reason kwarg.
It's going to be helpful in the future to record the reason for realm
deactivation.
- For information tracking
- For making a distinction between cases where we can allow realm owners
  to reactivate their realm via a self-serve flow (e.g.
  "owner_request") vs where we can't (ToS abuse).
2024-05-19 23:07:28 -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
Aman Agrawal da675cb641 support: Send demo request emails to sales@ email. 2024-05-02 09:46:59 -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 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
Aman Agrawal 7d1f858273 stripe: Ensure required_plan_tier is set before setting discount. 2024-04-29 17:11:11 -07:00
Anders Kaseorg 96fbe060a6 python: Mark regexes as raw strings.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-26 12:30:31 -07:00
Aman Agrawal 263d1ae38e demo_request: Add form for user to request a demo.
This sends an email to us after user fills out and sends the form.
2024-04-25 13:09:05 -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
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
Aman Agrawal 8715ead8bc stripe: Regenerate stripe fixtures with fixed tests.
Tests were broken since #29221 and #28875 didn't account for
other tests failing due to changed stripe data. Also, there
was a bug where we were not fetching the correct setup intent
and stripe session for the current test, it was fixed by narrowing
the fetch to the current customer.

Also, we now run `invoice_plans` in a `while` loop until
`next_invoice_date` is greater than the provided event_time. It
makes sense to generate all the invoices for a customer that
needs to paid by them when `invoice_plans_as_needed` is called
for a `event_time`.
2024-04-11 21:57:33 -07:00
Anders Kaseorg e5fd761562 test_stripe: Replace deprecated stripe.Event.to_dict_recursive.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-04 11:23:11 -07:00
Anders Kaseorg 040e8aa7f1 test_stripe: Remove unused stripe.util import.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-04 11:20:26 -07:00
Anders Kaseorg ccb95e76dc ruff: Fix RUF007 Prefer `itertools.pairwise()` over `zip()`.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-01 18:32:52 -07:00
Aman Agrawal b86e37a979 stripe: Add period information for generated invoices.
Invoices need to have period to avoid charges being marked as
point-in-time revenue rather than monthly revenue.
2024-03-30 14:56:12 -07:00
Prakhar Pratyush a0cec2c378 stripe: Skip invoice overdue mail for free plans with no next plan.
Earlier, if a free plan (say legacy plan) with no next plan scheduled
was invoiced, we used to send an invoice overdue email if the last
audit log update is stale.

Actually, we don't need this data as the invoice step is just going
to downgrade the current plan. We should not wait for customer to
start uploading data in this case. Skip the email sending step and
invoice the plan to downgrade.
2024-03-28 09:29:23 -07:00
Lauryn Menard 373671080d remote-support: Include billing entity name in internal billing notice.
Adds a line to the top of the internal_billing_notice email with
the billing entity's display name.

Makes sure all internal_billng_notice email subjects also include
the billing entity's display name.

Makes small updates to the notice text for some cases.
2024-03-20 11:58:15 -07:00
Prakhar Pratyush c9d25b2a95 stripe: Redirect to /plans if plans downgraded on /billing page visit.
When a customer with plan's status 'DOWNGRADE_AT_END_OF_FREE_TRIAL'
visits /billing page on the free-trial end date before the invoice
cron runs, the 'make_end_of_cycle_updates_if_needed' downgrades the
plan.

Earlier, when such a customer visited /billing page in this time window
it resulted in an assertion error.

This commit fixes the incorrect behaviour by redirecting to '/plans'
page in such cases.
2024-03-19 09:25:07 -07:00
Aman Agrawal 3b4abc94ee stripe: Revive an old test case for payment method. 2024-03-15 08:39:46 -07:00
Aman Agrawal e10f81197f upgrade: Fix allowed free trails for ended legacy plans on server.
If the remote realm registered after the legacy plan on server
ENDED, we never migrate the plan to the remote realm. So, we need
to check the server of remote realm whenever we are check remote
realm for legacy plan.
2024-03-15 08:38:46 -07:00
Aman Agrawal b26326815a billing: Adjust strings on billing page for invoice payment method. 2024-03-14 16:43:52 -07:00
Aman Agrawal caba57fe1e stripe: Bill manually managed licenses monthly for additional licenses.
Regardless of plan renewal schedule, we try to invoice all plans
monthly with some exceptions like free trial and fixed price plans,
which help us charge users for additional licenses used during
the previous month.
2024-03-14 16:43:52 -07:00