From 525c3d4321c5496c32a667087c3bd35450e32ae7 Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Tue, 13 Aug 2024 13:34:30 -0700 Subject: [PATCH] migrations: Squash corporate migrations. Generated using manage.py squashmigrations, with some work: - Used my patch to support squashing AddConstraint/RemoveConstraint operations. - Manually removed the add/deletion of cloud_xor_self_hosted, since it didn't squash properly. - Temporarily removed a couple operations from their migration files, and added them back manually both to the original file and the squash file, to allow later operations to squash properly. Specifically, these are the two unsquashed operations documented with comments at the end of the squash migration file. --- ...01_squashed_0044_convert_ids_to_bigints.py | 378 ++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 corporate/migrations/0001_squashed_0044_convert_ids_to_bigints.py diff --git a/corporate/migrations/0001_squashed_0044_convert_ids_to_bigints.py b/corporate/migrations/0001_squashed_0044_convert_ids_to_bigints.py new file mode 100644 index 0000000000..7abea9c36f --- /dev/null +++ b/corporate/migrations/0001_squashed_0044_convert_ids_to_bigints.py @@ -0,0 +1,378 @@ +# Generated by Django 5.0.7 on 2024-08-13 20:29 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + replaces = [ + ("corporate", "0001_initial"), + ("corporate", "0002_customer_default_discount"), + ("corporate", "0003_customerplan"), + ("corporate", "0004_licenseledger"), + ("corporate", "0005_customerplan_invoicing"), + ("corporate", "0006_nullable_stripe_customer_id"), + ("corporate", "0007_remove_deprecated_fields"), + ("corporate", "0008_nullable_next_invoice_date"), + ("corporate", "0009_customer_sponsorship_pending"), + ("corporate", "0010_customerplan_exempt_from_from_license_number_check"), + ("corporate", "0011_move_exempt_from_from_license_number_check_to_customer_model"), + ("corporate", "0012_zulipsponsorshiprequest"), + ("corporate", "0013_alter_zulipsponsorshiprequest_org_website"), + ("corporate", "0014_customerplan_end_date"), + ("corporate", "0015_event_paymentintent_session"), + ("corporate", "0016_customer_add_remote_server_field"), + ( + "corporate", + "0017_rename_exempt_from_from_license_number_check_customer_exempt_from_license_number_check", + ), + ("corporate", "0018_customer_cloud_xor_self_hosted"), + ("corporate", "0019_zulipsponsorshiprequest_expected_total_users_and_more"), + ("corporate", "0020_add_remote_realm_customers"), + ("corporate", "0021_remove_session_payment_intent"), + ("corporate", "0022_session_is_manual_license_management_upgrade_session"), + ("corporate", "0023_zulipsponsorshiprequest_customer"), + ("corporate", "0024_zulipsponsorshiprequest_fill_customer_data"), + ("corporate", "0025_alter_zulipsponsorshiprequest_customer"), + ("corporate", "0026_remove_zulipsponsorshiprequest_realm"), + ("corporate", "0027_alter_zulipsponsorshiprequest_requested_by"), + ("corporate", "0028_zulipsponsorshiprequest_requested_plan"), + ("corporate", "0029_session_tier"), + ("corporate", "0030_alter_zulipsponsorshiprequest_requested_plan"), + ("corporate", "0031_customer_flat_discount_and_more"), + ("corporate", "0032_customer_minimum_licenses"), + ("corporate", "0033_customerplan_invoice_overdue_email_sent"), + ("corporate", "0034_customer_discount_required_tier"), + ("corporate", "0035_update_legacy_plan_next_invoice_date"), + ("corporate", "0036_fix_customer_plans_scheduled_after_legacy_plan"), + ("corporate", "0037_customerplanoffer"), + ("corporate", "0038_customerplanoffer_sent_invoice_id_invoice"), + ("corporate", "0039_backfill_end_date_for_fixed_price_plans"), + ("corporate", "0040_customerplan_reminder_to_review_plan_email_sent"), + ("corporate", "0041_fix_plans_on_free_trial_with_changes_in_schedule"), + ("corporate", "0042_invoice_is_created_for_free_trial_upgrade_and_more"), + ("corporate", "0043_remove_customer_default_discount_and_more"), + ("corporate", "0044_convert_ids_to_bigints"), + ] + + initial = True + + dependencies = [ + ("contenttypes", "0002_remove_content_type_name"), + ("zerver", "0001_initial"), + # Requires RemoteRealm model for foreign keys. + ("zilencer", "0035_remoterealmcount_remote_realm_and_more"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="Customer", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("stripe_customer_id", models.CharField(max_length=255, null=True, unique=True)), + ( + "realm", + models.OneToOneField( + null=True, on_delete=django.db.models.deletion.CASCADE, to="zerver.realm" + ), + ), + ("sponsorship_pending", models.BooleanField(default=False)), + ("exempt_from_license_number_check", models.BooleanField(default=False)), + ( + "remote_server", + models.OneToOneField( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="zilencer.remotezulipserver", + ), + ), + ( + "remote_realm", + models.OneToOneField( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="zilencer.remoterealm", + ), + ), + ("flat_discount", models.IntegerField(default=2000)), + ("flat_discounted_months", models.IntegerField(default=0)), + ("minimum_licenses", models.PositiveIntegerField(null=True)), + ("required_plan_tier", models.SmallIntegerField(null=True)), + ("annual_discounted_price", models.IntegerField(default=0)), + ("monthly_discounted_price", models.IntegerField(default=0)), + ], + ), + migrations.CreateModel( + name="CustomerPlan", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("automanage_licenses", models.BooleanField(default=False)), + ("charge_automatically", models.BooleanField(default=False)), + ("price_per_license", models.IntegerField(null=True)), + ("fixed_price", models.IntegerField(null=True)), + ("discount", models.TextField(null=True)), + ("billing_cycle_anchor", models.DateTimeField()), + ("billing_schedule", models.SmallIntegerField()), + ("next_invoice_date", models.DateTimeField(db_index=True, null=True)), + ("tier", models.SmallIntegerField()), + ("status", models.SmallIntegerField(default=1)), + ( + "customer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="corporate.customer" + ), + ), + ("invoicing_status", models.SmallIntegerField(default=1)), + ("end_date", models.DateTimeField(null=True)), + ("invoice_overdue_email_sent", models.BooleanField(default=False)), + ("reminder_to_review_plan_email_sent", models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name="CustomerPlanOffer", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("fixed_price", models.IntegerField(null=True)), + ("tier", models.SmallIntegerField()), + ("status", models.SmallIntegerField()), + ( + "customer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="corporate.customer" + ), + ), + ("sent_invoice_id", models.CharField(max_length=255, null=True)), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="Event", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("stripe_event_id", models.CharField(max_length=255)), + ("type", models.CharField(max_length=255)), + ("status", models.SmallIntegerField(default=1)), + ("object_id", models.PositiveIntegerField(db_index=True)), + ("handler_error", models.JSONField(default=None, null=True)), + ( + "content_type", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="contenttypes.contenttype" + ), + ), + ], + ), + migrations.CreateModel( + name="Invoice", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("stripe_invoice_id", models.CharField(max_length=255, unique=True)), + ("status", models.SmallIntegerField()), + ( + "customer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="corporate.customer" + ), + ), + ("is_created_for_free_trial_upgrade", models.BooleanField(default=False)), + ( + "plan", + models.ForeignKey( + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="corporate.customerplan", + ), + ), + ], + ), + migrations.CreateModel( + name="LicenseLedger", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("is_renewal", models.BooleanField(default=False)), + ("event_time", models.DateTimeField()), + ("licenses", models.IntegerField()), + ("licenses_at_next_renewal", models.IntegerField(null=True)), + ( + "plan", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="corporate.customerplan" + ), + ), + ], + ), + migrations.CreateModel( + name="PaymentIntent", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("stripe_payment_intent_id", models.CharField(max_length=255, unique=True)), + ("status", models.SmallIntegerField()), + ("last_payment_error", models.JSONField(default=None, null=True)), + ( + "customer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="corporate.customer" + ), + ), + ], + ), + migrations.CreateModel( + name="Session", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("stripe_session_id", models.CharField(max_length=255, unique=True)), + ("type", models.SmallIntegerField()), + ("status", models.SmallIntegerField(default=1)), + ( + "customer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="corporate.customer" + ), + ), + ( + "is_manual_license_management_upgrade_session", + models.BooleanField(default=False), + ), + ("tier", models.SmallIntegerField(null=True)), + ], + ), + migrations.CreateModel( + name="ZulipSponsorshipRequest", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ( + "org_type", + models.PositiveSmallIntegerField( + choices=[ + (0, "Unspecified"), + (10, "Business"), + (20, "Open-source project"), + (30, "Education (non-profit)"), + (35, "Education (for-profit)"), + (40, "Research"), + (50, "Event or conference"), + (60, "Non-profit (registered)"), + (70, "Government"), + (80, "Political group"), + (90, "Community"), + (100, "Personal"), + (1000, "Other"), + ], + default=0, + ), + ), + ("org_website", models.URLField(blank=True, null=True)), + ("org_description", models.TextField(default="")), + ( + "requested_by", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ("expected_total_users", models.TextField(default="")), + ("paid_users_count", models.TextField(default="")), + ("paid_users_description", models.TextField(default="")), + ( + "customer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="corporate.customer" + ), + ), + ( + "requested_plan", + models.CharField( + choices=[ + ("", "UNSPECIFIED"), + ("Community", "COMMUNITY"), + ("Basic", "BASIC"), + ("Business", "BUSINESS"), + ], + default="", + max_length=50, + ), + ), + ], + ), + # Operation cannot be squashed, because it's a reverse foreign + # key (`LicenseLedger` has a `CustomerPlan` column), and + # squashing it into the CreateModel would require creating a + # dependency loop. + migrations.AddField( + model_name="customerplan", + name="invoiced_through", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="corporate.LicenseLedger", + ), + ), + # Django's squashmigrations tooling seems unable to squash + # this operation into CreateModel. Likely it's possible to do + # so manually, but it's just a single operation. + migrations.AddConstraint( + model_name="customer", + constraint=models.CheckConstraint( + check=models.Q( + ("realm__isnull", False), + ("remote_server__isnull", False), + ("remote_realm__isnull", False), + _connector="OR", + ), + name="has_associated_model_object", + ), + ), + ]