Commit Graph

458 Commits

Author SHA1 Message Date
Anders Kaseorg ad2795698b models: Remove explicit id fields.
With django-stubs, these explicit copies of Django’s implicit id
fields are no longer needed for type checking.  An exception is the
BigAutoField AbstractUserMessage.id, which is left alone.

This reverts commit c08ee904d8 (#15641).

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-10-06 13:49:11 -07:00
Anders Kaseorg 47c5deeccd python: Mark dict parameters with defaults as read-only.
Found by semgrep 0.115 more accurately applying the rule added in
commit 0d6c771baf (#15349).

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-10-06 13:48:28 -07:00
Zixuan James Li 4c3c976174 models: Implicitly type model fields with django-stubs.
Previously, we type the model fields with explicit type annotations
manually with the approximate types. This was because the lack of types
for Django.

django-stubs provides more specific types for all these fields that
incompatible with our previous approximate annotations. So now we can
remove the inline type annotations and rely on the types defined in the
stubs. This allows mypy to infer the types of the model fields for us.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-10-05 16:15:56 -07:00
Aman Agrawal cdb1db156f portico: Change display name of non-profit org type.
In the left sidebar, remove `registered` word from the
non-profit category name.
2022-09-13 10:40:16 -07:00
Lauryn Menard 5a7aa8228a urls: Extend documentation URL redirects system to corporate landing pages.
Extends the URL redirect system used for documentation pages to corporate
landing pages. This makes it easier and consistent for contributors who
work on both areas to create new URL redirects when needed.
2022-08-31 15:01:29 -07:00
Aman Agrawal 379c6acbea portico: Add page to list open organizations.
Fixes #22020
2022-08-30 16:02:06 -07:00
Tim Abbott 15977da6f8 demo orgs: Adjust additional hunks involves upgrade string.
Introduced during final editing of
5925ce16b1.
2022-08-29 12:17:09 -07:00
Eeshan Garg 5925ce16b1 demo-orgs: Disable billing and upgrade for demo organizations.
Disables submit buttons on billing / upgrade page for demo
organizations since they will need to become permanent
organizations before upgrading to Zulip Cloud Standard.

Also creates an alert banner on the same page that links to
the help center article on demo organizations.

Updates sub-headers on demo organizations help center
article to match link text and to follow general convention
of using imperative verb forms in help center subheaders.

Part of #19523.

Co-authored by: Lauryn Menard <lauryn@zulip.com>
2022-08-29 11:43:45 -07:00
Aman Agrawal ef21f9107c urls: Move /hello files to the corporate folder. 2022-08-22 15:53:43 -07:00
Aman Agrawal 07f0104714 urls: Move /security files to the corporate folder. 2022-08-22 15:53:43 -07:00
Aman Agrawal 8da5368529 url: Move /self-hosting pages to the corporate folder. 2022-08-22 15:53:43 -07:00
Aman Agrawal c908c9b497 urls: Move /why-zulip pages to the corporate folder. 2022-08-22 15:53:43 -07:00
Aman Agrawal d15158e76b urls: Move /history files to the corporate folder. 2022-08-22 15:53:43 -07:00
Aman Agrawal c9ac233911 urls: Move /team files to the corporate folder. 2022-08-22 15:53:43 -07:00
Aman Agrawal 349bac4751 urls: Move /attribution files to the corporate folder. 2022-08-22 15:53:43 -07:00
Aman Agrawal 7cd8bcd004 urls: Move /development-community files to corporate folder. 2022-08-22 15:53:43 -07:00
Aman Agrawal 9ce7a784e7 urls: Move /apps files to corporate folder. 2022-08-22 15:53:43 -07:00
Aman Agrawal 4a9b4fb91b urls: Move /features files to corporate folder. 2022-08-22 15:53:43 -07:00
Aman Agrawal a5d7a334c4 urls: Move /plans files to corporate folder. 2022-08-22 15:53:43 -07:00
Aman Agrawal afd31b739d templates: Move case-studies and /for pages to corporate folder.
Since these pages don't belong in a self-hosted server.
2022-08-22 15:53:43 -07:00
Aman Agrawal 21a2fd482e portico: Move to corporate folder.
Since the URLs that use these function are present in corporate/urls,
this file belongs in the corporate folder.
2022-08-22 15:53:43 -07:00
Aman Agrawal e54ded49c4 urls: Move URLs that don't belong on self-hosted servers to corporate URLs.
Use absolute URLs for these links in files which will be served
to self-hosted servers.
2022-08-22 15:53:43 -07:00
Mateusz Mandera 2c693f3bd9 billing: Fix licenses amount check during user signup/invitation.
Our seat count calculation is different for guest user than normal users
(a number of initial guests are free, and additional marginal guests are
worth 1/5 of a seat) - so these checks we apply when a user is being
invited or signing up need to know whether it's a guest or non-guest
being added.
2022-08-18 11:56:54 -07:00
Mateusz Mandera a41cecb695 billing: Extract get_seat_count function.
This is a simple generalization of get_latest_seat_count and is useful
for calculating "what will be the realm's license count if this
number of (guest) users is added?" without duplicating any of the math
logic. Will be used in the next commits.
2022-08-18 11:56:54 -07:00
Mateusz Mandera 6582a002e7 billing: Add comment about the calculation in get_latest_seat_count.
Our billing FAQ says:
"For an organization with N other users, 5*N guest users are included at
no extra charge. After that, you will be charged at 1/5 of your regular
per-user pricing for each additional guest.".

It wasn't quite intuitive to me that
max(non_guests, math.ceil(guests / 5)) achieves that pricing, so it's
worth mentioning in a comment that it does and that that's why that
formula is used.
2022-08-18 11:56:54 -07:00
Zixuan James Li ad17096c9c realm_audit_log: Explicitly stringify dict before insertion.
`extra_data` as a `TextField` expects a `str`, but we had been passing
`dict` instead. This is a temporary solution before #18391 to fix the
type annotation.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-26 09:48:33 -07:00
Zixuan James Li 6277f09296 corporate: Fix type annotations for payment failed handler.
When being called, the wrapped function is passed `PaymentIntent`
(the `content_object` of `Event`). With that, since `customer` can be
`None`, an assertion is also required.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-15 14:56:22 -07:00
Zixuan James Li a81fab46e3 webhook: Do not allow None default for headers.
Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-15 14:00:56 -07:00
Zixuan James Li 8a9f06d5bc test_stripe: Remove realm from upgrade.
This is an unused argument. We removed it so that we don't
need to create a `TypedDict` and unpack it when calling
the test client methods.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-06-28 16:12:00 -07:00
Zixuan James Li fd9a0f4274 typing: Apply trivial none-checks with assertions as necessary.
Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-06-23 19:25:48 -07:00
Zixuan James Li 4cf3ba5744 typing: Fix typical typing typos.
Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-06-23 19:25:48 -07:00
Anders Kaseorg df69e1d979 mypy: Enable truthy-bool errors.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-06-23 19:22:12 -07:00
Zixuan James Li 426f8ce385 tests: Replace `HttpResponse` with `TestHttpResponse.`
Since `HttpResponse` is an inaccurate representation of the
monkey-patched response object returned by the Django test client, we
replace it with `_MonkeyPatchedWSGIResponse` as `TestHttpResponse`.

This replaces `HttpResponse` in zerver/tests, analytics/tests, coporate/tests,
zerver/lib/test_classes.py, and zerver/lib/test_helpers.py with
`TestHttpResponse`. Several files in zerver/tests are excluded
from this substitution.

This commit is auto-generated by a script, with manual adjustments on certain
files squashed into it.

This is a part of the django-stubs refactorings.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-06-08 11:25:03 -07:00
Zixuan James Li a142fbff85 tests: Refactor away result.json() calls with helpers.
Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-06-06 23:06:00 -07:00
Zixuan James Li c572d9be5a typing: Add none-checks for db queries.
Signed-off-by: Zixuan James Li <359101898@qq.com>
2022-05-31 09:43:55 -07:00
Zixuan James Li 4a5043dd6e typing: Add none-checks for miscellaneous cases.
Signed-off-by: Zixuan James Li <359101898@qq.com>
2022-05-31 09:43:55 -07:00
Zixuan James Li c34ac1fcd4 typing: Access url via key "Location" instead of attribute "url".
This is a part of #18777.

Signed-off-by: Zixuan James Li <359101898@qq.com>
2022-05-30 11:59:47 -07:00
Anders Kaseorg 0043c0b6b2 django: Use HttpRequest.headers.
Fixes #14769.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-05-13 20:42:20 -07:00
Anders Kaseorg fd16f97d6b python: Excise None from pointlessly nullable booleans.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-04-27 12:40:14 -07:00
Anders Kaseorg e01faebd7e actions: Split out zerver.actions.create_realm.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-04-14 17:14:37 -07:00
Anders Kaseorg 59f6b090c7 actions: Split out zerver.actions.realm_settings.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-04-14 17:14:37 -07:00
Anders Kaseorg cbad5739ab actions: Split out zerver.actions.create_user.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-04-14 17:14:35 -07:00
Anders Kaseorg 975066e3f0 actions: Split out zerver.actions.message_send.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-04-14 17:14:34 -07:00
Anders Kaseorg d7981dad62 actions: Split out zerver.actions.users.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-04-14 17:14:34 -07:00
Zixuan James Li b1fbba0577 stripe: Strengthen decorator types using ParamSpec.
Signed-off-by: Zixuan James Li <359101898@qq.com>
2022-04-14 12:44:35 -07:00
Anders Kaseorg f21842e920 requirements: Upgrade Python requirements.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-03-16 10:43:23 -07:00
Anders Kaseorg 21cd1c10b3 docs: Add missing space in “time zone”.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-02-24 14:05:12 -08:00
Anders Kaseorg 1629d6bfb3 python: Reformat with Black 22 (stable).
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-02-18 18:03:13 -08:00
Aman Agrawal 197843af31 stripe: Replace "Zulip standard" with "Zulip Cloud Standard".
Case sensitive replace.
2022-02-09 11:00:24 -08:00
Aman Agrawal 7614f2203a pricing: Replace "Zulip Standard" with "Zulip Cloud Standard".
Case sensitive replace.
2022-02-09 11:00:24 -08:00
Anders Kaseorg b0ce4f1bce docs: Fix many spelling mistakes.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-02-07 18:51:06 -08:00
Lauryn Menard 3be622ffa7 backend: Add request as parameter to json_success.
Adds request as a parameter to json_success as a refactor towards
making `ignored_parameters_unsupported` functionality available
for all API endpoints.

Also, removes any data parameters that are an empty dict or
a dict with the generic success response values.
2022-02-04 15:16:56 -08:00
Anders Kaseorg 8d9fe9cfb0 mypy: Add types-stripe.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-01-23 22:47:30 -08:00
Anders Kaseorg de1df81ef6 test_stripe: Convert "".format to Python 3.6 f-string.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-01-23 22:17:02 -08:00
Eeshan Garg 0b5324f345 corporate: Add helper for deactivating remote server registrations. 2022-01-03 14:02:48 -08:00
Mateusz Mandera c5c3ab66d6 remote_server: Migrate RemoteZulipServer.uuid to be UUIDField.
Given that these values are uuids, it's better to use UUIDField which is
meant for exactly that, rather than an arbitrary CharField.

This requires modifying some tests to use valid uuids.
2021-12-28 10:11:34 -08:00
Anders Kaseorg b73a6b7b06 test_stripe: What even is how to code I don’t know help.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-12-28 09:31:55 -08:00
Eeshan Garg 79e9ba13e2 billing: Add do_change_remote_server_plan_type.
This is a part of the plumbing we need to support billing for
self-hosted customers.

With documentation changes from tabbott.
2021-12-07 10:25:37 -08:00
Eeshan Garg 2cdaae681d actions: Rename do_change_plan_type -> do change_realm_plan_type.
We will soon be adding an equivalent function for RemoteZulipServer,
so it makes sense to rename this function to be more descriptive.
2021-12-06 16:18:53 -08:00
Eeshan Garg 7c9f587563 billing: Stop using UserProfile.delivery_email in Stripe handler.
Now that we pass in the UserProfile.id in the metadata to Stripe's
PaymentIntent objects, we no longer need to retrieve the user via
delivery_email. It makes more sense to just fetch the user by ID
and then get the latest delivery_email directly.

Note that an update to Stripe's fixtures is not necessary here
since a previous commit already modified the metadata passed to
both stripe.Session/PaymentIntent objects.
2021-12-03 14:57:30 -08:00
Eeshan Garg 88fd399bec billing: Use UserProfile.id to ascertain customer's email.
Previously, our Stripe webhook event handler code retrieved the
user's email from Stripe using the stripe.Customer.email attribute.
This led to situations such that whenever the email that Stripe had
did not correspond to a UserProfile in Zulip, the payment flow
failed since we couldn't find a UserProfile associated with the
given email.

Now, we pass in the UserProfile.id in the metadata to Stripe's
checkout Session object, so that we can fetch the correct email
in future Stripe requests.
2021-12-03 14:57:30 -08:00
Eeshan Garg a3095331eb corporate/models: Modify Customer to accommodate self-hosted customers.
This is a part of our efforts to introduce billing for our on-premise
customers.
2021-11-30 15:20:33 -08:00
Eeshan Garg 075ad5470a corporate: Update fixtures for switching from Standard to Plus.
After the Stripe migration to the hosted checkout page, we were
missing one fixture for the test for switching from Standard to
Plus. This commit updates the fixtures for that particular test.
2021-11-05 17:23:10 -07:00
Vishnu KS 585d98d5a9 billing: Enforce the Stripe API version is in sync with billing system. 2021-11-05 17:23:10 -07:00
Vishnu KS 6c06858e02 billing: Migrate to Stripe hosted checkout page. 2021-11-05 17:23:10 -07:00
Vishnu KS 1a1b9b28ff corporate: Store the Stripe API version. 2021-11-05 17:23:10 -07:00
Eeshan Garg f60b8ccedc corporate: Improve testing for switching from Standard to Plus.
This is a follow-up to #19752. The tests in that PR did not verify
that the financial math involved worked properly. This commit
improves the existing tests and adds new fixtures to make sure
that the financial math works as expected.
2021-10-31 17:50:16 -07:00
Eeshan Garg b325a4f1be realm: Rename plan type constants to be more descriptive.
It is confusing to have the plan type constants not be namespaced
by the thing they represent. We already have a namespacing
convention in place for constants, so we should use it for
Realm.plan_type as well.
2021-10-19 12:20:39 -07:00
Vishnu KS fcab2ea5f7 billing: Add command for switching plans from Standard to Plus. 2021-10-15 17:27:50 -07:00
Vishnu KS 87c1b9e3bc billing: Simplify start_of_next_billing_cycle function. 2021-10-15 17:27:50 -07:00
Vishnu KS a86ab18a7b billing: Use plan.name in invoice description instead of Zulip Standard. 2021-10-15 17:27:50 -07:00
Vishnu KS 194258a721 billing: Make compute_plan_paramaters support Plus as a tier.
compute_plan_parameters assumed that the value of
tier is always CustomerPlan.STANDARD. We change that behavior
to make the function handle CustomerPlan.PLUS as well.
2021-10-15 17:27:50 -07:00
Vishnu KS 641402856d billing: Make compute_plan_paramaters take tier as arg.
This is a prep commit to add support for switching the plan
type from Standard to Plus.
2021-10-15 17:27:50 -07:00
Vishnu KS 9585486905 billing: Fix incorrect variable names in test_compute_plan_parameters.
Seems to have introduced in e883567146
2021-10-15 17:27:50 -07:00
Tim Abbott 0cd68b895c test_stripe: Fix broken test in previous commit. 2021-10-01 17:37:27 -07:00
Eeshan Garg 763b3c27d6 corporate: Add contact support page. 2021-10-01 17:30:01 -07:00
Anders Kaseorg 949bfac40c test_stripe: Avoid deprecated TestCase method aliases.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-09-22 14:59:42 -07:00
PIG208 7386918539 typing: Use accurate type hints for dictionaries.
This fixes the mypy errors related to dictionaries with django-stubs.
2021-08-20 06:02:28 -07:00
Eeshan Garg a808f02a22 billing/sponsorship: Allow blank organization URLs.
We ran into a bug in production caused by two issues:
- Some users came from orgs that didn't have a website and since
  the URL field was required, they submitted invalid URLs.
- We didn't properly respond to invalid form submissions, which
  led to UnboundLocalError exceptions in another part of the
  code.

This commit solves this by doing the following:
- We now allow blank URLs and have a convenient placeholder text
  label that tells users that they may leave the URL field blank.
- This commit refactors the code such that invalid form submissions
  result in an informative error message about what exactly went
  wrong.
2021-08-19 03:08:17 -07:00
Anders Kaseorg 4206e5f00b python: Remove locally dead code.
These changes are all independent of each other; I just didn’t feel
like making dozens of commits for them.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-08-19 01:51:37 -07:00
PIG208 bf86649f4d billing: Refactor initial_upgrade to use REQ. 2021-08-08 17:11:18 -07:00
PIG208 6a61dc2de2 billing: Refactor billing_home to use REQ. 2021-08-08 17:11:18 -07:00
Anders Kaseorg 9756ac0db7 test_stripe: Convert NamedTuple to dataclass.
The locally defined NamedTuple was triggering a mypy caching bug
(https://github.com/python/mypy/issues/10913), and we don’t use the
tuple behavior anyway.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-08-02 21:43:51 -07:00
Anders Kaseorg ad5f0c05b5 python: Remove default "utf8" argument for encode(), decode().
Partially generated by pyupgrade.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-08-02 15:53:52 -07:00
Anders Kaseorg 3665deb93a python: Remove unnecessary intermediate lists.
Generated automatically by pyupgrade.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-08-02 15:53:52 -07:00
Mateusz Mandera ce4eb6f203 bots: Pass realm to get_system_bot calls in registration.py. 2021-07-26 15:33:13 -07:00
Mateusz Mandera a3cd3d6865 bots: Pass realm to get_system_bot calls in stripe. 2021-07-26 15:33:13 -07:00
PIG208 91de2cbe03 typing: Avoid scoped redefinition of different types.
Mypy doesn't allow redefinition of a variable using a different type
within the same scope.
https://github.com/python/mypy/issues/1174
2021-07-26 15:09:07 -07:00
PIG208 d2af20eb2a typing: Do explicit type conversion when appropriate.
When calling some functions or assigning values to certain attributes,
the arguments/right operand do not match the exact type that the
functions/attributes expect, and thus we fix that by converting types
beforehand.
2021-07-26 15:09:07 -07:00
PIG208 7d1c475f69 typing: Use assertions for function arguments.
Utilize the assert_is_not_None helper to eliminate errors of
'Argument x to "Foo" has incompatible type "Optional[Bar]"...'
2021-07-26 14:48:45 -07:00
PIG208 66b1a4e7ca backend: Add None-checks with assertions and if-elses.
This fixes a batch of mypy errors of the following format:
'Item "None" of "Optional[Something]" has no attribute "abc"'
2021-07-24 15:00:21 -07:00
PIG208 de2678a319 tests: Fix missed mypy errors in tests.
This fixes a batch of mypy errors of the following format:
'Item "None" of "Optional[Something]" has no attribute "abc"
as a follow-up for 9892951703.
2021-07-24 14:59:19 -07:00
Tim Abbott 01ce58319d mypy: Fix most AnonymousUser type errors.
This commit fixes several mypy errors with Django stubs, by telling
mypy that we know in a given code path that the user is authenticated.
2021-07-24 14:55:46 -07:00
PIG208 495a8476be tests: Use assertion to enforce None-checks in tests.
This fixes a batch of mypy errors of the following format:
'Item "None" of "Optional[Something]" has no attribute "abc"

Since we have already been recklessly using these attritbutes
in the tests, adding assertions beforehand is justified presuming
that they oughtn't to be None.
2021-07-24 09:54:21 -07:00
Vishnu KS 158cec84ec stripe: Upgrade stripe API to 2020-08-27 version.
This upgrades the Stripe API to the most recent version. Going through
the Git history, it looks like our current API version is at 2019-03-14.

The API version should be manually changed in Stripe dashboard at the same
time as the commit is deployed in production.

Backward incompatible changes that are relevant to our codebase between
(2019-03-14, 2020-08-27].
* 2020-08-27 - The `sources` property on Customers is no longer included by
  default.
* 2020-03-02 - Nothing applicable
* 2019-12-03 - The `id` field of all invoice line items have changed and are
  now prefixed
  with `il_`. We only rely on this while we normalize the fixtures.
* 2019-11-05 - Nothing applicable
* 2019-10-17 - The `billing` attribute on invoices, subscriptions, and
  subscription schedules is renamed to`collection_method`. The invoice
  change is the one that is relevant to us.
* The customer object’s `account_balance` value has been renamed to
  `balance`. Only used for the stubs at the moment.
* 2019-10-08 - Nothing applicable
* 2019-09-09 - Nothing applicable
* 2019-08-14 - Nothing applicable
* 2019-05-16 - Nothing applicable

https://stripe.com/docs/upgrades

Also normalize the following IDs in stripe fixtures

* price_[A-Za-z0-9]{24}
* prod_[A-Za-z0-9]{14}
* pi_[A-Za-z0-9]{24}
* il_[A-Za-z0-9]{24}
2021-07-23 21:44:41 -07:00
Vishnu KS 50950de24c billing: Void open invoices of small realms without an active plan.
Previously, we only downgraded and voided small organizations behind
payments only if they had an active plan.

This left us with a bunch of invoices from small realms which used to
have an active plan. It doesn't make much sense for us to get these
realms to pay the invoices so we have decided to just void them. This
commit voids the open invoices of all the small realms without an active
plan and has the last invoice open. Unlike, the realms with an active
plan we don't email them about us voiding the invoice. It's not super
obvious whether Stripe sends an email to the customer when the Invoice
is voided. But they do get the message that the invoice is voided if
they try to pay the invoice through the hosted invoice page.
2021-07-22 17:56:35 -07:00
Vishnu KS b3d3539306 billing: Only fetch customers with stripe customer id in autodowngrade.
The customers without a value for stripe_customer_id never had an active
plan. So we don't have to consider them for autodowngrade.
2021-07-22 17:56:35 -07:00
Vishnu KS 7e51fe31f3 tests: Generate invoices inside create_realm helper function.
To minimize the code duplication.
2021-07-22 17:56:35 -07:00
Vishnu KS 292932f3a4 tests: Use expected values list for avoiding duplicate code.
This avoid some duplicate code as well as improve the readability since
before we were checking for the expected values far away from the
definition of realm. Now we define the expected values right after the
realm definition which improves the code readability.
Also, this get removes the postfixing of realm variable names with numbers.
The postfixing is kind of mess since if we want add any new realm in between
the realms we need to renumber a lot of realm variables.
2021-07-22 17:56:35 -07:00
Vishnu KS eee02a3403 billing: Create customer_has_last_n_invoices_open function.
An additional check for whether customer.stripe_customer_id is
None is added to the function. That check was not really required before
since all the customers with a plan also have a valid value for
stripe_customer_id. So all the calls to stripe.Invoice.list would have
non None value for customer argument.

Even though that is the case, mypy should still have complained about
the possibility of customer.stripe_customer_id being None when passed to
stripe.Invoice.list as customer paramater since mypy don't know that
customers with a plan will always have a non empty value for
stripe_customer_id. Our stripe stubs expect a non empty value for
the customer parameter of stripe.Invoice.list. This is despite the
fact that stripe.Invoice.list can actually be called with customer set
to None. This returns the invoices from the entire organization.
Though, we still decided to ensure that the value of customer should be
non empty since there is no reason for us to ever call this function
with customer set to None. You can just call the function wuthout the
customer argument instead. So this requirement of a non None customer
paramater is useful for catching bugs.

The reason mypy didn't complain was because the type of
Customer.objects.all() is Any and not QuerySet[Customer]. So mypy has no
idea that customer.stripe_customer_id can be theoratically None even
though it was not possible in this [articular case as explained before.
I verified that this was the reason mypy didn't complain by using the
reveal_type function on Customer.objects.all() and the customer object.
After the refactoring it's super to obvious to mypy that the type of the
customer is Customer since it's mentioned in the function defintion. So it
was able to complain about the possibility of customer.stripe_customer_id
being None after the refactoring.
2021-07-22 17:56:35 -07:00