Commit Graph

768 Commits

Author SHA1 Message Date
Aman Agrawal cd7893b1bf sponsorship: Use `organization_type` as field name for simplification. 2023-11-29 19:04:32 -08:00
Mateusz Mandera 2765c63f56 remote_billing: Add flow for legacy servers. 2023-11-29 14:40:27 -08:00
Prakhar Pratyush 44d8dc66d2 send_email: Update 'from_name' for non user-facing emails.
This commit performs a minor update in 'from_name' text for
'support' and 'sponsorship' emails.

Removes capitalization and adds a comment specifying that the
emails are not user-facing.
2023-11-29 14:20:01 -08:00
Alex Vandiver 61fc838179 python: Switch mocking of timezone_now to time_machine. 2023-11-28 15:10:39 -08:00
Alex Vandiver f4cbb494ac test_remote_counts: Insert in date order.
Inserting these in order means that they have dates which ascend with
their ids and remote_ids, for a more accurate simulation.
2023-11-28 09:46:48 -08:00
Aman Agrawal e8fed998ce test_stripe: Add method to better mock stripe invoice creation. 2023-11-28 08:58:19 -08:00
Aman Agrawal 28a49be161 get_initial_upgrade_context: Use tier passed as part of request. 2023-11-28 08:58:19 -08:00
Alya Abbott fcd0783202 upgrade: Simplify free trial upgrade page. 2023-11-28 08:57:27 -08:00
Alya Abbott 9788e7514f billing: Edit text of free trial upgrade page. 2023-11-27 14:17:18 -08:00
Aman Agrawal b35a792623 billing: Allow free trial orgs to switch billing frequency.
Fixes #27855
2023-11-27 14:17:18 -08:00
Aman Agrawal 1f8d3fc48f stripe: Extract method to get next billing cycle. 2023-11-27 14:17:18 -08:00
Aman Agrawal 482b5d8871 upgrade: Minor text changes to free trial page.
Fixes #27684
2023-11-27 14:17:18 -08:00
Aman Agrawal fe1a40279c billing: Downgrade realm at the end of free trial.
Fixes #27875

Instead of immediately ending the free trial, we end the free trial
at the end of the cycle.
2023-11-27 14:17:18 -08:00
Aman Agrawal 22c333d135 stripe: Don't allow free trial users to have paid plan states.
Free trial users can only switch to `ACTIVE` or `ENDED`
as possible states. To switch to any other state, they need to
be `ACTIVE` first.
2023-11-27 14:17:18 -08:00
Aman Agrawal d43a60eb9d models: Add status text for some plan status states. 2023-11-27 14:17:18 -08:00
Tim Abbott 7de061cf10 billing: Inline is_realm_on_paid_plan.
This helps simplify the BillingSession interface to have less
realm-specific functions outside RealmBillingSesssion.
2023-11-27 09:01:56 -08:00
Prakhar Pratyush f8b0e16ff2 stripe: Add get_sponsorship_request_context method to BillingSession.
This commit refactors 'sponsorship_request' view and adds
'BillingSession.get_sponsorship_request' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_Server customers.
2023-11-27 09:01:56 -08:00
Prakhar Pratyush 1b17626327 stripe: Add 'is_sponsored' method to 'BillingSession' class.
This prep commit adds a 'is_sponsored' method as we need
to explicitly check this in 'event_status' view.
2023-11-27 09:01:56 -08:00
Prakhar Pratyush 29f77bfd31 stripe: Add 'get_event_status' method to the 'BillingSession' class.
This commit refactors 'event_status' view and adds
'BillingSession.get_event_status' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_server customers.
2023-11-27 09:01:56 -08:00
Aman Agrawal 20cae359d1 sponsorship: Show correct plan for sponsored without CustomerPlan.
For users on limited plan, if approved for full sponsorship
via support page, we don't create a CustomerPlan for them, but
they are fully sponsored.
2023-11-27 08:23:36 -08:00
Aman Agrawal 3615fa4745 sponsorship: Use customer instead of realm to store sponsorship data.
Since Customer already stores the realm it is linked to and
customer is always created to store sponsorship request, we directly
use customer to link to the sponsorship data for the realm.
2023-11-27 08:23:36 -08:00
Aman Agrawal ede73fc2c6 decorator: Add wrapper to directly pass remote_realm to view_func. 2023-11-26 20:23:24 -08:00
Aman Agrawal 354330d81b decorator: Move self_hosting_management_endpoint wrapper to corporate. 2023-11-26 20:23:24 -08:00
Mateusz Mandera c79d116f8c tests: Add basic tests for remote billing auth flow. 2023-11-26 19:57:12 -08:00
Lauryn Menard b167eeff08 corporate: Create change plan tier function for BillingSession.
Moves and generalizes `switch_realm_from_standard_to_plus_plan`
in stripe.py to be a more general function for changing a
CustomerPlan to a new and valid tier, `do_change_plan_to_new_tier`.

Adds a helper function with the previous function name to be used
for the support view and management command for changing a realm
from the Standard plan tier to the Plus plan tier.
2023-11-26 19:39:52 -08:00
Lauryn Menard a00e687d02 corporate: Update stripe create_balance_transaction description. 2023-11-26 19:39:52 -08:00
Lauryn Menard 1f1f1b913b corporate: Simplify initial plan tier switch check.
Simplifies the initial check for switching a customer plan tier
for an existing and active plan, so that it is more generic.
2023-11-26 19:39:52 -08:00
Lauryn Menard 39bfab0ec4 corporate: Move plan tier change to separate helper function.
Renames CustomerPlan.SWITCH_NOW_FROM_STANDARD_TO_PLUS to be more
generic, CustomerPlan.SWITCH_PLAN_TIER_NOW.

Because the plan tier change is immediate, moves the code to end
the current plan with the old tier and create the new plan with
the new tier from `make_end_of_cycle_updates_if_needed` to instead
be in a separate helper function, `switch_plan_tier`.
2023-11-26 19:39:52 -08:00
Lauryn Menard 30f0005799 corporate: Extract calculation of amount to credit for tier change. 2023-11-26 19:39:52 -08:00
Aman Agrawal 3cfcd0efee remote_upgrade_page: Add /upgrade URL for self hosted realms. 2023-11-24 09:22:02 -08:00
Aman Agrawal caf2b7da26 stripe: Use remote_billing_url for redirecting to sponsorship page.
The will make redirects to sponsorship page work for all
BillingSession child classes.
2023-11-24 09:22:02 -08:00
Aman Agrawal 6ad9217fbf stripe: Set discount to None for 0 discount. 2023-11-24 09:22:02 -08:00
Aman Agrawal 6040ffb94b stripe: Verify context via TypedDict for upgrade page. 2023-11-24 09:22:02 -08:00
Aman Agrawal e3abd57dce stripe: Rename update_context_initial_upgrade. 2023-11-24 09:22:02 -08:00
Aman Agrawal 053f30ca25 stripe: Sort upgrade page context keys.
This will help us verify changes easily.
2023-11-24 09:22:02 -08:00
Aman Agrawal 4844ef9810 upgrade: Pass customer_name instead of realm object to upgrade context.
This will help simplify things for remote realms.
2023-11-24 09:22:02 -08:00
Aman Agrawal ace14e5a7d remote_billing_page: Extract method to get RemoteBillingIdentityDict.
This will likely be used in other files.
2023-11-24 09:22:02 -08:00
Aman Agrawal f006be0cdf initial_upgrade: Rename to upgrade_page.
Replaced for "(initial_upgrade)", " initial_upgrade"
`'initial_upgrade'` and `"initial_upgrade"`.
2023-11-24 09:22:02 -08:00
Aman Agrawal 95f5d8bdb8 billing: Note applied discount on upgrade and billing pages.
Fixes #27526
2023-11-23 10:32:39 -08:00
Aman Agrawal 07d29126fd sponsorship: Improve page for sponsorship pending orgs.
Fixes #27686
2023-11-23 10:32:39 -08:00
Aman Agrawal 003b29ba14 billing_page: Redirect orgs on paid plans with sponsorship pending.
Redirect sponsorship pending realms on a paid plan to billing page
with banner which reflects the current status of their request.
2023-11-23 10:32:39 -08:00
Aman Agrawal 74d8a050e4 billing_page: Extract method to check if realm is on paid plan. 2023-11-23 10:32:39 -08:00
Aman Agrawal 5422dd3661 sponsorship: Improve sponsorship page for sponsored realms. 2023-11-23 10:32:39 -08:00
Prakhar Pratyush 51b39cb682 stripe: Add 'do_update_plan' method to the 'BillingSession' class.
This commit moves a major portion of the 'update_plan`
view to a new shared 'BillingSession.do_update_plan' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_server customers.
2023-11-23 09:01:45 -08:00
Tim Abbott efa423395f billing: Make support_session an explicit parameter. 2023-11-23 09:01:45 -08:00
Mateusz Mandera 3958743b33 corporate: Add prototype authentication system for self-hosters.
This makes it possible for a self-hosted realm administrator to
directly access a logged-page on the push notifications bouncer
service, enabling billing, support contacts, and other administrator
for enterprise customers to be managed without manual setup.
2023-11-22 17:03:47 -08:00
Aman Agrawal d82efbd503 free_trial: Remove extra onboarding flow.
We still redirect free trial users to upgrade page on first
signup but no longer pass the onboarding param.
2023-11-22 08:06:22 -08:00
Aman Agrawal 2218c49244 billing: Minor changes to text for free trial.
Fixes #27685
2023-11-22 08:06:22 -08:00
Prakhar Pratyush 476b44ae67 stripe: Use 'get_price_per_license' in 'get_initial_upgrade_context'.
This commit updates the 'get_initial_upgrade_context' method
to use 'get_price_per_license' for determining 'annual_price'
and 'monthly_price' based on tier and discount instead of hardcoding.

Also, removed the 'percent_off' page_params as
'get_price_per_license' already performs the price calculation
taking discount into consideration.
2023-11-21 23:39:18 -08:00
Aman Agrawal de267b964c event_status: Return user back to same license management after session.
If the update / add card session is successful, return user to
manual license management page if user was on it before clicking
the add / update card button.
2023-11-21 11:44:04 -08:00
Aman Agrawal 69d8442ab4 billing: Allow user to switch between billing frequencies. 2023-11-21 10:42:12 -08:00
Tim Abbott e3a3f36225 billing: Rename do_initial_upgrade.
This function gets context without doing anything, and so deserves a
name that hints that.
2023-11-20 12:04:56 -08:00
Aman Agrawal 09009ab03a upgrade: Separate add card and purchase upgrade flow.
We now let user add / update card in a separate session and then
charge users after clicking on the purchase button.
2023-11-20 12:04:56 -08:00
Prakhar Pratyush 26c5149d31 stripe: Add 'do_initial_upgrade' method to the 'BillingSession' class.
This commit moves a major portion of the 'initial_upgrade`
view to a new shared 'BillingSession.do_initial_upgrade' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_server customers.
2023-11-20 08:00:05 -08:00
Lauryn Menard 11cb37c9a4 billing: Add prototype remote billing sessions.
These new models are incomplete and totally untested, but merging this
will provide valuable scaffolding for doing smaller PRs working on
individual gaps, and reveals a clear set of TODOs/refactoring/model
changes needed to support where want to end up.

Co-authored-by: Tim Abbott <tabbott@zulip.com>
2023-11-17 12:58:37 -08:00
Tim Abbott f916385cab corporate: Adjust models for RemoteRealm customers. 2023-11-17 12:58:37 -08:00
Tim Abbott c5940bd68f zilencer: Make plan types less weird. 2023-11-17 12:58:37 -08:00
Prakhar Pratyush 135d7c03cc stripe: Add 'get_billing_page_context' method to 'BillingSession'.
This commit moves the main context creation part of the
'billing_home` view to a new shared
'BillingSession.get_billing_page_context' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_server customers.
2023-11-16 09:48:43 -08:00
Mateusz Mandera 1819b85b85 management: Allow changing is_billing_admin using change_user_role. 2023-11-15 18:36:07 -08:00
Anders Kaseorg f4e7a11c35 requirements: Upgrade Python requirements.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-11-15 15:27:54 -08:00
Anders Kaseorg 7a4ca3135d stripe: Prepare to switch to stripe inline annotations.
https://github.com/stripe/stripe-python/wiki/Inline-type-annotations

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-11-15 15:27:54 -08:00
Prakhar Pratyush f8a0035215 stripe: Move `make_end_of_cycle_updates_if_needed` to BillingSession.
Moves the 'make_end_of_cycle_updates_if_needed' function to
the 'BillingSession' abstract class.

This refactoring will help in minimizing duplicate code while
supporting both realm and remote_server customers.

Since the function is called from our main daily billing cron job
as well, we have changed 'RealmBillingSession' to accept 'user=None'
(our convention for automated system jobs).
2023-11-15 09:26:41 -08:00
Aman Agrawal 27ffcc6576 bililng: Fix incorrect price per license on billing page.
There is a discrepancy between price per license shown on billing
and upgrade page for annual billing frequency due to difference
in methods used to calculate the amount.

To fix it, we use the same method on both the pages.

I didn't use the helpers.format_money directly here since that would
create a visual delay in showing the price per license which will
not be nice considering that will be the only thing on this page
being updated that way.

The stripe fixture used is same as
free_trial_upgrade_by_card--Customer.retrieve.3.json
2023-11-15 15:59:26 +05:30
Prakhar Pratyush fb9e258a65 stripe: Add 'do_upgrade' method to the 'BillingSession' class.
This commit moves a major portion of the 'upgrade`
view to a new shared 'BillingSession.do_upgrade' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_server customers.
2023-11-14 12:07:26 -08:00
Aman Agrawal 67bddb3d72 billing: Show success message for license change after page reload. 2023-11-13 10:35:39 -08:00
Aman Agrawal 2997c269e1 billing: Show breakdown of renewal amount if not fixed_price. 2023-11-13 10:35:39 -08:00
Aman Agrawal 775a90771e stripe: Modify error message for less than min licenses. 2023-11-13 10:35:39 -08:00
Aman Agrawal 5f0969f52b session: Remove unnecessary has_request_variables wrapper. 2023-11-13 10:35:39 -08:00
Aman Agrawal 2570f7ce23 upgrade: Control automatic / manual license management via URL. 2023-11-13 10:35:39 -08:00
Aman Agrawal 395cafcf46 sponsorship: Add extra input fields to get more org info.
Fixes #27600
2023-11-13 08:52:13 -08:00
Prakhar Pratyush b5a6742adc stripe: Move `process_initial_upgrade` to BillingSession.
Moves the 'process_initial_upgrade' function to the
'BillingSession' abstract class.

This refactoring will help in minimizing duplicate code while
supporting both realm and remote_server customers.
2023-11-13 08:11:27 -08:00
Lauryn Menard 928cb7e09e corporate: Pass plan_tier parameter to process_initial_upgrade.
Updates `process_initial_upgrade` to take a plan_tier parameter,
so that information can be specific to the type of BillingSession.

Note that ideally the plan tier would be passed as metadata to the
stripe.checkout.Session, but in order to do so, we need to be able
to update the generated stripe fixtures for tests. So for now, we
set the plan tier directly in the stripe event handler code.
2023-11-10 11:26:18 -08:00
Lauryn Menard 3e550364c6 corporate: Use plan.name for stripe.Invoice statement descriptor.
Instead of hard coding the string for the stripe.InvoiceItem and
stripe.Invoice statement_descriptor, we use the name of the plan
that was just created.
2023-11-10 11:26:18 -08:00
Lauryn Menard d29c454e80 corporate: Make BillingSession abstract method for changing plan type.
Creates `do_change_plan_type` as a BillingSession abstract method
as an alias for updating the plan_type for a realm (and eventually
remote server).

This removes the last direct reference to a customer's realm in
`process_initial_upgrade`.
2023-11-10 11:26:18 -08:00
Lauryn Menard 26ad2e29c6 corporate: Make BillingSession alias for latest seat count.
Creates `current_count_for_billed_licenses` as an abstract method
in BillingSession class, to get the latest seat count for the realm
(and eventually remote server) connected to the customer.
2023-11-10 11:26:18 -08:00
Prakhar Pratyush 31f048d054 stripe: Move `setup_upgrade_checkout_session_and...` to BillingSession.
Moves the 'setup_upgrade_checkout_session_and_payment_intent'
function to the 'BillingSession' abstract class.

This refactoring will help in minimizing duplicate code while
supporting both realm and remote_server customers.
2023-11-10 09:15:10 -08:00
Aman Agrawal b0fb5c33e9 test_stripe: Fix tests related to text changes on billing page. 2023-11-10 05:17:52 +05:30
Aman Agrawal 9a186ac8d5 billing_page: Redirect users on free plan to `/plans`.
Fixes #27379
2023-11-10 05:17:52 +05:30
Aman Agrawal 56eec2734c billing_page: Add capitalization format of various common cards. 2023-11-10 05:17:52 +05:30
Aman Agrawal f85bd0234a billing: Minor changes. 2023-11-10 05:17:52 +05:30
Aman Agrawal caa40ad2c6 billing_page: Remove unused context. 2023-11-10 05:17:52 +05:30
Aman Agrawal 2f532e49d1 billing: Add field to show billing frequency. 2023-11-10 05:17:52 +05:30
Aman Agrawal 5b97eb0445 billing: Modify title. 2023-11-10 05:17:52 +05:30
Lauryn Menard 6a53005074 corporate: Update generated stripe fixtures for test_stripe.
Generated with both parellel=1 and generate-stripe-fixtures params
on test-backend locally.

Note that the previous series of commits need these test fixtures
to pass CI. If those are changed, then this commit should be updated
or dropped and replaced with a commit that updates the fixtures
based on the new changes.
2023-11-09 12:03:33 -08:00
Lauryn Menard 717d40475e corporate: Use the stripe checkout session metadata for free trials.
Instead of using the data from the stripe.SetupIntent for processing
an initial upgrade for the free trial session types, use the metadata
from the stripe.checkout.Session that was returned.

The metadata is the same for both the checkout session and the setup
intent.
2023-11-09 12:03:33 -08:00
Lauryn Menard c09bfc136e corporate: Update generate stripe fixtures to not use test cc numbers.
Updates generate stripe fixtures to use test credit card strings from
Stripe, instead of creating fake stripe.PaymentMethods for the tests
with the test credit card numbers provided by Stripe.
2023-11-09 12:03:33 -08:00
Lauryn Menard 1f28837bd7 corporate: Update create_stripe_customer to not attach payment method.
According to stripe's documentation for attaching payment methods to
customers (see https://stripe.com/docs/api/payment_methods/attach),
payment methods should be attached to customers through a SetupIntent
or PaymentIntent, which is what we do as we process new customers
and accounts.

Updates create_stripe_customer so that it is clear that the payment
method should not be added when we directly create a new  stripe
customer.
2023-11-09 12:03:33 -08:00
Lauryn Menard 4dd6f105a0 coporate: Change statement descriptor for Zulip Cloud Credit.
There is a 22 char limit on the stripe.Invoice.statement_descriptor
field. The current value for that field in this error case, "Zulip
Cloud Standard Credit" is 27 chars.

Updates the value for this error case to be "Cloud Standard Credit".
2023-11-09 12:03:33 -08:00
Mateusz Mandera 3cafdbdc1e counts: Add function compute_max_monthly_messages for remote servers.
This calculates the largest amount of messages sent within a month for
the last 3 months. The query is targeted for the specific use-case in
this function - for finding the count for a specific server. For
calculating this in bulk for a large number of remote server an
adapted, bulk query will be needed - rather than running this one in a
loop, which would likely be very inefficient.
2023-11-08 09:45:49 -08:00
Lauryn Menard 2da1b3307a corporate: Rename billable_user variables to billing_session in tests. 2023-11-07 12:57:20 -08:00
Lauryn Menard b6fa00d4fd corporate: Set realm strings for test of downgrade small realms.
Instead of randomly generating an integer for the realm string_id
and realm name use a counter to increment the string ids by one.
This way if a particular realm fails the test, it will be easier
to identify which one failed.

Also, removes unused Customer objects that were being returned on
realm creation in the test, as these were not being checked/used
in the test.
2023-11-07 12:57:20 -08:00
Lauryn Menard c3fd7d837b corporate: Add billing admin check to approve sponsorship test.
In commit a3093fad9, we made Hamlet a billing admin for testing.

Because the approve sponsorship flow sends messages from the
notification bot to both organization owners and billing admins,
we need to update that test to cover both of those user types.
2023-11-07 09:13:50 -08:00
Aman Agrawal 0012a52e88 billing: Don't redirect to sponsorship page for orgs on paid plan. 2023-11-06 14:55:14 -08:00
Aman Agrawal 0ffa207118 sponsorship: Use this organization instead of your organization. 2023-11-06 14:55:14 -08:00
Aman Agrawal a3093fad97 billing: Show sponsorship status on /sponsorship page.
We redirect users from billing and upgrade page to sponsorship page if the
org has requested for sponsorship or is already sponsored.
2023-11-06 14:55:14 -08:00
Aman Agrawal 00df9c6c18 urls: Show sponsorship page on a new URL.
Fixes #27377

Replaced #sponsorship links with sponsorship/ links and in other
places liking gear menu.
2023-11-06 14:55:14 -08:00
Lauryn Menard 6f7b75c9a3 corporate: Add `create_stripe_payment_intent` to BillingSession class.
Adds `create_stripe_payment_intent` to the BillingSession abstract
class for the initial upgrade process, which is used only in
`setup_upgrade_checkout_session_and_payment_intent`.

Adds a helper dataclass for the data used to create the stripe
payment intent, StripePaymentIntentData, for the implementation of
more than one child class of BillingSession.

Also adds two abstract helper functions for getting the above stripe
payment intent data as well as updating that data for a stripe
checkout session that is associated with a payment intent:
update_data_for_checkout_session_and_payment_intent,
get_data_for_stripe_payment_intent.
2023-11-06 14:39:36 -08:00
Lauryn Menard 600fea23bb corporate: Add create_stripe_checkout_session to BillingSession class.
Adds `create_stripe_checkout_session` to BillingSession abstract
class, which is then used in all places where a stripe.checkout.Session
and Session were created: start_retry_payment_intent_session,
start_card_update_stripe_session, and
setup_upgrade_checkout_session_and_payment_intent.

Adds a `billing_session_url`  abstract property to the BillingSession
abstract class and for the RealmBillingSession child class sets that
value to `self.realm.uri`.
2023-11-06 14:39:36 -08:00
Lauryn Menard 227645ab65 corporate: Update setup upgrade checkout to only get price per license.
setup_upgrade_checkout_session_and_payment_intent was not using the
datetime values that were being returned by compute_plan_parameters,
so just get the price per license directly.
2023-11-06 14:39:36 -08:00
Lauryn Menard ec2b00e8c4 corporate: Move `update_billing_method...` to BillingSession class.
Moves `update_billing_method_of_current_plan` to the BillingSession
abstract class.

Adds a helper function for support views for the realm case:
`update_realm_billing_method`.
2023-11-04 17:20:49 -07:00
Lauryn Menard 5d07666362 corporate: Move `update_sponsorship_status` to BillingSession class.
Moves `update_sponsorship_status` to BillingSession abstract class
as `update_customer_sponsorship_status`.

Updates the support views to have a helper for updating this on a
realm: `update_realm_sponsorship_status`.
2023-11-04 17:20:49 -07:00
Lauryn Menard d06062c179 corporate: Move `approve_sponsorship` to BillingSession class.
Makes `approve_sponshorship` an abstract method in BillingSession
abstract base class and moves the implementation for realms to the
RealmBillingSession child class.

Adds `approve_realm_sponsorship` helper function that's used in
the support view and initiates the billing session.
2023-11-04 17:20:49 -07:00
Lauryn Menard c8021925c8 corporate: Create AuditLogEventType enum for BillingSession audit logs.
Creates an enum class, AuditLogEventType, and an abstract method in
BillingSession, get_audit_log_event, so that we have an abstraction
for getting the audit log event type since it might be different for
Customer objects with a realm vs a remote_server.
2023-11-04 17:20:49 -07:00
Lauryn Menard ee19a9c274 corporate: Move `attach_realm_discount` to BillingSession class.
This moves the logic for `attach_realm_discount`, which is used in
the support view, to be in the BillingSession class.

Updates the function name to be `attach_discount_to_customer` so
that the context is generalized vs realm specific.

Updates RealmBillingSession implementation to account for actions
that are initiated by a support admin user.

Also moves the helper function `get_discount_for_realm` that is
only used in support views to `corporate/lib/support.py`.
2023-11-04 17:20:49 -07:00
Lauryn Menard 63abf063b7 corporate: Use StripeCustomerData dataclass to create stripe Customer.
So that all child classes of BillingSession generate the same data
structure for customers that are created in Stripe, revise
`get_data_for_stripe_customer` to return a specific dataclass:
StripeCustomerData.
2023-11-04 17:20:49 -07:00
Lauryn Menard ce6f1f8c18 stripe: Create BillingSession class for different customer types.
So that `update_or_create_stripe_customer` can work for Customer
objects with either a realm or remote_server, we create an abstract
base class, BillingSession, and implement a child class for the
current implementation of Customer objects with a realm.

Refactoring `update_or_create_stripe_customer` also moves
`create_stripe_customer` and `replace_payment_method` to the
BillingSession class.
2023-11-04 17:20:49 -07:00
Lauryn Menard d1e2e2d857 corporate: Check for no CustomerPlan on Customer instead of Realm.
In ensure_customer_does_not_have_active_plan, we were already going
through the Customer table to get/check for an active CustomerPlan.

Now we directly get/check for an active CustomerPlan with via the
Customer, which allows for reusing this function for Customer
objects without a Realm set.
2023-10-30 16:09:52 -07:00
Lauryn Menard 85ab5b70e9 corporate: Update string for Customer model.
Update the string method on the Customer model to account for the
realm possibly being None.
2023-10-30 16:09:52 -07:00
Lauryn Menard 37b70a8e24 corporate: Exclude non-realm Customer objects in downgrade small realms.
Updates query in downgrade_small_realms_behind_on_payments_as_needed
to exclude Customer objects with realm=None.
2023-10-30 10:09:17 -07:00
Lauryn Menard c996bb3c19 corporate: Move functions for realm installation data to new file.
Moves two functions in corporate/lib/stripe.py that are used to
get data for the main installation activity analytics page to a
separate file: corporate/lib/analytics.py.

Also, updates these functions for the possibility of realm being
None for a Customer object.
2023-10-30 10:08:45 -07:00
Anders Kaseorg a50eb2e809 mypy: Enable new error explicit-override.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-10-12 12:28:41 -07:00
Aman Agrawal b8b7938eb9 portico: Remove orgs who haven't set their own description. 2023-10-12 09:58:47 -07:00
Aman Agrawal 4ebbd68749 portico: Show limited filters on communities page. 2023-10-12 09:58:47 -07:00
Mateusz Mandera 4fc2b54eed stripe: Set .api_version to make integration work again.
Upgrading stripe to 6.0.0 in e32366638a
breaks our Stripe integration due to API version change making us fail
to finalize creating an invoice and charge the customer.

For the upstream details see:
60ab6ac7d7/CHANGELOG.md (600---2023-08-16)

6.0.0 uses 2023-08-16 Stripe API version unless specified otherwise. We
want to use 2020-08-27.

Setting stripe.api_version in corporate/lib/stripe.py is sufficient for
it to be set everywhere else. This is supported by the fact that we also
only set stripe.api_key in that file.
2023-10-10 16:44:28 -07:00
Mateusz Mandera 07e99eace9 billing: Fix license counting in exempt_from_license_number_check case.
Fixes two bugs involving organization with
exempt_from_license_number_check enabled:
1. If the organization had e.g. 100 users and upgraded their plan,
   specifying 50 licenses, the generated LicenseLedger and thus the
   corresponding invoice was still for 100 users.
2. The organization was unable to use the billing/plan endpoint (update
   plan endpoint) to make their number of licenses less than the current
   number of users.

Organizations with exempt_from_license_number_check are supposed to be
able to declare whatever license number they want, as this attribute
allows having pricing schemes where an organization only pays us for a
subset of their users.
2023-09-26 09:59:15 -07:00
Anders Kaseorg 28597365da python: Delete superfluous parens.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-09-13 13:40:19 -07:00
Alex Vandiver b94402152d models: Always search Messages with a realm_id or id limit.
Unless there is a limit on `id`, always provide a `realm_id` limit as
well.  We also notate which index is expected to be used in each
query.
2023-09-11 15:00:37 -07:00
Mateusz Mandera 18b0e58831 billing: Rename a few confusing references to "Zulip Limited".
We call this Zulip Free on the /plans page.
2023-09-07 17:52:04 -07:00
Ujjawal Modi 2e59b1f30e tests: Use function to create realm rather than django ORM.
This commit makes changes in backend tests to use
`do_create_realm` function to create realm.
2023-09-07 14:21:01 -07:00
Zixuan James Li 30495cec58 migration: Rename extra_data_json to extra_data in audit log models.
This migration applies under the assumption that extra_data_json has
been populated for all existing and coming audit log entries.

- This removes the manual conversions back and forth for extra_data
throughout the codebase including the orjson.loads(), orjson.dumps(),
and str() calls.

- The custom handler used for converting Decimal is removed since
DjangoJSONEncoder handles that for extra_data.

- We remove None-checks for extra_data because it is now no longer
nullable.

- Meanwhile, we want the bouncer to support processing RealmAuditLog entries for
remote servers before and after the JSONField migration on extra_data.

- Since now extra_data should always be a dict for the newer remote
server, which is now migrated, the test cases are updated to create
RealmAuditLog objects by passing a dict for extra_data before
sending over the analytics data. Note that while JSONField allows for
non-dict values, a proper remote server always passes a dict for
extra_data.

- We still test out the legacy extra_data format because not all
remote servers have migrated to use JSONField extra_data.
This verifies that support for extra_data being a string or None has not
been dropped.

Co-authored-by: Siddharth Asthana <siddharthasthana31@gmail.com>
Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2023-08-16 17:18:14 -07:00
Anders Kaseorg 562a79ab76 ruff: Fix PERF401 Use a list comprehension to create a transformed list.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-08-07 17:23:55 -07:00
Anders Kaseorg 3b09197fdf ruff: Fix RUF015 Prefer `next(...)` over single element slice.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-07-23 15:20:53 -07:00
Anders Kaseorg 143baa4243 python: Convert translated positional {} fields to {named} fields.
Translators benefit from the extra information in the field names, and
need the reordering freedom that isn’t available with multiple
positional fields.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-07-18 15:19:07 -07:00
Anders Kaseorg db6323b2c4 python: Remove unused arguments for translated format strings.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-07-18 10:38:46 -07:00
Anders Kaseorg c09e7d6407 codespell: Correct “requestor” to “requester”.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-06-20 16:17:55 -07:00
Zixuan Li e39e04c3ce
migration: Add `extra_data_json` for audit log models.
Note that we use the DjangoJSONEncoder so that we have builtin support
for parsing Decimal and datetime.

During this intermediate state, the migration that creates
extra_data_json field has been run. We prepare for running the backfilling
migration that populates extra_data_json from extra_data.

This change implements double-write, which is important to keep the
state of extra data consistent. For most extra_data usage, this is
handled by the overriden `save` method on `AbstractRealmAuditLog`, where
we either generates extra_data_json using orjson.loads or
ast.literal_eval.

While backfilling ensures that old realm audit log entries have
extra_data_json populated, double-write ensures that any new entries
generated will also have extra_data_json set. So that we can then safely
rename extra_data_json to extra_data while ensuring the non-nullable
invariant.

For completeness, we additionally set RealmAuditLog.NEW_VALUE for
the USER_FULL_NAME_CHANGED event. This cannot be handled with the
overridden `save`.

This addresses: https://github.com/zulip/zulip/pull/23116#discussion_r1040277795

Note that extra_data_json at this point is not used yet. So the test
cases do not need to switch to testing extra_data_json. This is later
done after we rename extra_data_json to extra_data.

Double-write for the remote server audit logs is special, because we only
get the dumped bytes from an external source. Luckily, none of the
payload carries extra_data that is not generated using orjson.dumps for
audit logs of event types in SYNC_BILLING_EVENTS. This can be verified
by looking at:

`git grep -A 6 -E "event_type=.*(USER_CREATED|USER_ACTIVATED|USER_DEACTIVATED|USER_REACTIVATED|USER_ROLE_CHANGED|REALM_DEACTIVATED|REALM_REACTIVATED)"`

Therefore, we just need to populate extra_data_json doing an
orjson.loads call after a None-check.

Co-authored-by: Zixuan James Li <p359101898@gmail.com>
2023-06-07 12:14:43 -07:00
Anders Kaseorg b5e5728112 coverage: Clean up coverage configuration.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-05-31 13:53:04 -07:00
Anders Kaseorg 19dee5450d corporate: Replace unused accessors with database constraint.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-05-31 13:53:04 -07:00
Anders Kaseorg 13545ff885 stripe: Fix invoice_plans_as_needed default value.
Python evaluates default values once when the function is defined, not
when it is called.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-04-27 16:43:33 -07:00
Alya Abbott 977bec25ba portico: Add Atolio case study. 2023-04-26 14:33:30 -07:00
Mateusz Mandera ef42065cec billing: Allow exempt_from_license_number_check any number of licenses.
exempt_from_license_number_check was initially added allowing
organizations with it enabled to invite new users above their number of
licenses.

However, an organization with this permission enabled,
cannot upgrade if they weren't on a plan already - because when choosing
Manual license management, you cannot enter a number of licenses lower
than the current seat count. However, an organization like that probably
already has some users that they get free of charge - and thus they need
to be able to enter a lower number of licenses in order to upgrade.
2023-04-13 15:26:44 -07:00
Mateusz Mandera be208f73f7 billing: Fix exempt_from_from_license_number_check column name.
exempt_from_from_license_number_check was clearly not intended.
2023-04-13 15:26:44 -07:00
Anders Kaseorg 0a3dc8a944 ruff: Fix DJ012 Order of model's inner classes, methods, and fields.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-04-12 17:32:38 -07:00
Tim Abbott 50b91fe5c7 portico: Fix incorrect fallback contributors data type.
Previously, using this without having run fetch-contributors-data
would throw an exception trying to call .filter on an empty
dictionary.
2023-03-27 22:33:54 -07:00
Anders Kaseorg 2976d2c2fa stripe: Fix non-translatable computed string.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-03-27 17:14:46 -07:00
Mateusz Mandera 42de31c2e8 billing: Tweak "contact support" links on billing page.
This is nicer than putting the raw email in the message.
2023-03-27 10:15:21 -07:00
Mateusz Mandera f482fc2a73 billing: Add hint about support on the sponsorship pending page.
This just replaces the billing/upgrade with the statement that
"Your organization has requested sponsored or discounted hosting.", so
it should include an obvious contact in case the customer wants to amend
something or just bump a request that may have gotten missed.
2023-03-27 10:15:21 -07:00
Mateusz Mandera 684430faa2 billing: Add sponsorship request form to the billing page.
Previously this was only available on the upgrade page - meaning an
organization that already bought a plan wouldn't be able to request a
sponsorship to get a discount or such, even if qualified.
2023-03-27 10:15:21 -07:00
Alex Vandiver ab7ff6b582 web: Save a 301 redirect from /billing to /billing/. 2023-03-24 14:51:01 -07:00
Alex Vandiver c686c5ed0f web: Save a needless 301 redirect from /plans to /plans/. 2023-03-24 14:51:01 -07:00
Alex Vandiver 5967dda35d web: Save a needless 301 redirect from /upgrade to /upgrade/. 2023-03-24 14:51:01 -07:00
Alya Abbott e660ffbe07 portico: Add End Point Dev case study page. 2023-03-21 16:20:30 -07:00
Alya Abbott 005ca2b033 portico: Add landing page about trying Zulip by visiting chat.zulip.org. 2023-03-14 13:21:09 -07:00
Anders Kaseorg 2d9b2a2a05 models: Remove type prefixes from __str__ values.
The Django convention is for __repr__ to include the type and __str__
to omit it.  In fact its default __repr__ implementation for models
automatically adds a type prefix to __str__, which has resulted in the
type being duplicated:

    >>> UserProfile.objects.first()
    <UserProfile: <UserProfile: emailgateway@zulip.com <Realm: zulipinternal 1>>>

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-03-08 22:56:55 -08:00
Mateusz Mandera 89a72c92ea stripe: Change realm.plan_type when upgrading a realm to Plus plan. 2023-02-08 10:28:13 -08:00
Anders Kaseorg 59eca10a43 ruff: Fix G004 Logging statement uses f-string.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-02-04 16:36:20 -08:00
Anders Kaseorg da3cf5ea7a ruff: Fix RSE102 Unnecessary parentheses on raised exception.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-02-04 16:34:55 -08:00
Anders Kaseorg df001db1a9 black: Reformat with Black 23.
Black 23 enforces some slightly more specific rules about empty line
counts and redundant parenthesis removal, but the result is still
compatible with Black 22.

(This does not actually upgrade our Python environment to Black 23
yet.)

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-02-02 10:40:13 -08:00
Lauryn Menard 6b2d531dfd notification-bot: Update message for approved full sponsorship.
Updates the message sent by the notification bot when an
organization is approved for full sponsorship on Zulip
Cloud Standard to include a request to list and link to
Zulip on any acknowledgement or sponsorship pages.
2023-01-27 12:40:22 -08:00
Anders Kaseorg 25346bde98 ruff: Fix SIM118 Use `k in d` instead of `k in d.keys()`.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-01-23 11:18:36 -08:00
Anders Kaseorg ff1971f5ad ruff: Fix SIM105 Use `contextlib.suppress` instead of try-except-pass.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-01-23 11:18:36 -08:00
Anders Kaseorg bd884c88ed Fix typos caught by typos.
https://github.com/crate-ci/typos

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-01-03 11:09:50 -08:00
Alex Vandiver 7613928e8a apps: Fix redirect from /apps -> https://zulip.com/apps/.
When this code was moved from being in zerver in 21a2fd482e, it kept
the `if ZILENCER_ENABLED` blocks.  Since ZILENCER and CORPORATE are
generally either both on or both off, the if statement became
mostly-unnecessary.

However, because tests cannot easily remove elements from
INSTALLED_APPS and re-determine URL resolution, we switch to checking
`if CORPORATE_ENABLED` as a guard, and leave these in-place.

The other side effect of this is that with e54ded49c4, most Zulip
deployments started to 404 requests for `/apps` instead of redirecting
them to `https://zulip.com/apps/` since they no longer had any path
configured for `/apps`.  Unfortunately, this URL is in widespread use
in the app (e.g. in links from the Welcome Bot), so we should ensure
that it does successfully redirect.

Add the `/apps` path to `zerver`, but only if not CORPORATE_ENABLED,
so the URLs do not overlap.
2022-12-30 17:47:16 -08:00
Alex Vandiver 13ad9e8323 corporate: CORPORATE_ENABLED is always true in corporate.views.portico.
This is a holdover from when the portico was moved from zerver in
21a2fd482e.
2022-12-30 17:44:23 -08:00
Anders Kaseorg 73c4da7974 ruff: Fix N818 exception name should be named with an Error suffix.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-11-17 16:52:00 -08:00
Anders Kaseorg 46955da3a0 ruff: Fix ANN204 missing return type annotation for __init__.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-11-16 09:29:11 -08:00
Alya Abbott 9ce484e267 portico: Add a page about our values. 2022-11-07 12:27:09 -08:00
Lauryn Menard a3f6220fe4 analytics: Add summary statistic for guest users in realm.
Adds the count of users with the role of guest to the stats view
`page_params` via a database query. This information is then added
to the summary statistics section of the analytics page after being
formatted by `stats.js`.

Creates Bassanio as a guest user in the database for the analytics
realm.

Fixes #20162.
2022-10-17 11:53:59 -07:00
Lauryn Menard 2e23318872 communities: Include orgs without invite or email domain restrictions.
Updates the organizations listed in the open communities directory
to also include organizations that do not require an invite and do
not restrict email domains for new users to join the organization.
2022-10-13 10:11:07 -07:00
Anders Kaseorg 5e1ebf2861 python: Fix __dict__ mutation abuse.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-10-10 08:33:08 -07:00
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