Commit Graph

987 Commits

Author SHA1 Message Date
bedo db5c272f82 billing: Migrate to @typed_endpoint.
migrate update_plan(), update_plan_for_remote_realm(),
and update_plan_for_remote_server() to @typed_endpoint.
2024-07-05 10:32:57 -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
Kenneth Rodrigues 8970884837 coporate: Convert to typed_endpoint.
Convert `installation_activity` and `support` to `typed_endpoint`.
2024-06-25 11:07:03 -07:00
Lauryn Menard 1969698cf6 stripe: Use comma for collection method Literal values. 2024-06-10 16:10:42 -07:00
Alex Vandiver 50c3dd88e6 models: Migrate ids of all non-Message-related tables to bigint.
Migrate all `ids` of anything which does not have a foreign key from
the Message or UserMessage table (and would thus require walking
those) to be `bigint`.  This is done by removing explicit
`BigAutoField`s, trading them for explicit `AutoField`s on the tables
to not be migrated, while updating `DEFAULT_AUTO_FIELD` to the new
default.

In general, the tables adjusted in this commit are small tables -- at
least compared to Messages and UserMessages.

Many-to-many tables without their own model class are adjusted by a
custom Operation, since they do not automatically pick up migrations
when `DEFAULT_AUTO_FIELD` changes[^1].

Note that this does multiple scans over tables to update foreign
keys[^2].  Large installs may wish to hand-optimize this using the
output of `./manage.py sqlmigrate` to join multiple `ALTER TABLE`
statements into one, to speed up the migration.  This is unfortunately
not possible to do generically, as constraint names may differ between
installations.

This leaves the following primary keys as non-`bigint`:
- `auth_group.id`
- `auth_group_permissions.id`
- `auth_permission.id`
- `django_content_type.id`
- `django_migrations.id`
- `otp_static_staticdevice.id`
- `otp_static_statictoken.id`
- `otp_totp_totpdevice.id`
- `two_factor_phonedevice.id`
- `zerver_archivedmessage.id`
- `zerver_client.id`
- `zerver_message.id`
- `zerver_realm.id`
- `zerver_recipient.id`
- `zerver_userprofile.id`

[^1]: https://code.djangoproject.com/ticket/32674
[^2]: https://code.djangoproject.com/ticket/24203
2024-06-05 11:48:27 -07:00
Aman Agrawal 96dee2b987 portico_error_pages: Collect zerver error pages into a folder.
Tested `link_does_not_exist.html`, `404.html` and `unsupported_browser`
pages render correctly.
2024-06-05 09:06:44 -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
Lauryn Menard 37afad038c support: Add link to stripe customer dashboard.
Adds a link to the stripe customer dashboard if the Customer
object for an active plan has a stripe_customer_id. If there
is no stripe ID to link to, then the icon is shown without
a link, which is the case for remote server/realm sponsorships
and legacy plans.
2024-05-22 11:32:46 -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
Sahil Batra 7b42c802b1 invites: Add include_realm_default_subscriptions parameter.
This commit adds include_realm_default_subscriptions parameter
to the invite endpoints and the corresponding field in
PreregistrationUser and MultiuseInvite objects. This field will
be used to subscribe the new users to the default streams at the
time of account creation and not to the streams that were default
when sending the invite.
2024-05-14 14:20:07 -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
Tim Abbott 7d3877f69a support: Rate limit demo form requests. 2024-05-04 07:36:16 -07:00
Anders Kaseorg eb45eca57b support: Replace common.copy_data_attribute_value with clipboard.js.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-05-03 12:45:46 -07:00
Alex Vandiver d863aa56de invites: Lock the realm when determining invitation counts.
This prevents users from hammering the invitation endpoint, causing
races, and inviting more users than they should otherwise be allowed
to.

Doing this requires that we not raise InvitationError when we have
partially succeeded; that behaviour is left to the one callsite of
do_invite_users.

Reported by Lakshit Agarwal (@chiekosec).
2024-05-02 14:23:04 -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 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 04638ffaee stripe: Add required plan tier for cloud realms on support page. 2024-04-29 17:11:11 -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 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
Prakhar Pratyush 14415dfa90 invoice_paid_event: Verify invoice before activating fixed-price plan.
Earlier, we were not verifying that the invoice which got paid is
for the fixed-price plan.

That could result in a bug where another support invoice with
collection_method = "send_invoice" got paid while a fixed-price
plam is already configured. The fixed-price plan would be falsely
activated.

This commit verifies the invoice before activating the fixed-price
plan.
2024-04-16 09:49:04 -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
Lauryn Menard 4e5c62527c activity: Update installation total row for moving referrer column.
Updates the total row so that the ARR and user counts align with
the column updates in commit 971123565f.
2024-04-15 10:52:41 -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
Aman Agrawal a2e0c84a7e stripe: Remove unused parameter. 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
Prakhar Pratyush e3f8c62e34 registration: Send a group DM to admins when no spare licenses left.
Earlier, when adding a new user failed due to no spare licenses
available, a message was sent to the "New user announcements"
stream.

We plan to disable the stream by default as a part of improving
onboarding experience.

Now, we send a group DM to admins when adding a new user fails
due to no spare licenses available. It makes it independent of
the "New user announcements" setting. These warning messages
are important and shouldn't be missed.
2024-04-03 12:28:05 -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
Anders Kaseorg ae47de36c9 python: Add missing TypeAlias annotations.
See commit c2c96eb0cf (#26405).

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-01 16:19:56 -07:00
Aman Agrawal d21f5c9b75 registration: Ask user how they found Zulip. 2024-04-01 12:44:12 -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
Mateusz Mandera 374178903e remote_billing: Move stripe_customer_id from server to realm if needed.
As explained in the comment, when we're moving the server plan to the
remote realm's Customer object, the realm Customer may not have
stripe_customer_id set and therefore that value needs to get moved from
the server Customer.
2024-03-29 16:27:03 -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
Mateusz Mandera c3caa3ecc8 stripe: Rename @error_handler decorator.
This decorator, among other things, transforms the "event" argument
passed when calling the decorated functions into actually passing
event.content_object.

So e.g. despite having a (before the decorator is applied) signature:

```
def handle_invoice_paid_event(stripe_invoice: stripe.Invoice, invoice: Invoice) -> None:
```

these are called passing an `Event` in the second arg when calling
`handle_invoice_paid_event`:

```
handle_invoice_paid_event(stripe_invoice, event)
```

I found that kind of confusing because the @error_handler decorator
didn't sound like something that would intervene in the arguments like
that. So it feels helpful to rename it something with a less modest
name, that makes it sound like it does more than just pure
error-handling.
2024-03-28 09:10:09 -07:00
Anders Kaseorg a1a341f0ae ruff: Fix UP032 Use f-string instead of `format` call.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-03-21 08:59:17 -07:00