From f062d817724ff72b9840a9d01c69ccf8cdca9dcd Mon Sep 17 00:00:00 2001 From: Dev Aggarwal Date: Mon, 15 Jul 2024 03:18:00 +0530 Subject: [PATCH] move txn migration to a separate script --- ...nsaction_plan_appusertransaction_reason.py | 32 ------------------- .../0019_alter_appusertransaction_reason.py | 18 +++++++++++ scripts/migrate_txn_reason.py | 21 ++++++++++++ 3 files changed, 39 insertions(+), 32 deletions(-) create mode 100644 app_users/migrations/0019_alter_appusertransaction_reason.py create mode 100644 scripts/migrate_txn_reason.py diff --git a/app_users/migrations/0018_appusertransaction_plan_appusertransaction_reason.py b/app_users/migrations/0018_appusertransaction_plan_appusertransaction_reason.py index ca77e5e45..a4568a7e5 100644 --- a/app_users/migrations/0018_appusertransaction_plan_appusertransaction_reason.py +++ b/app_users/migrations/0018_appusertransaction_plan_appusertransaction_reason.py @@ -3,32 +3,6 @@ from django.db import migrations, models -def forwards_func(apps, schema_editor): - from payments.plans import PricingPlan - from app_users.models import TransactionReason - - # We get the model from the versioned app registry; - # if we directly import it, it'll be the wrong version - AppUserTransaction = apps.get_model("app_users", "AppUserTransaction") - db_alias = schema_editor.connection.alias - objects = AppUserTransaction.objects.using(db_alias) - - for transaction in objects.filter(amount__gt=0): - # For old transactions, we didn't have a subscription field. - # It just so happened that all monthly subscriptions we offered had - # different amounts from the one-time purchases. - # This uses that heuristic to determine whether a transaction - # was a subscription payment or a one-time purchase. - transaction.reason = TransactionReason.ADDON - for plan in PricingPlan: - if ( - transaction.amount == plan.credits - and transaction.charged_amount == plan.monthly_charge * 100 - ): - transaction.plan = plan.db_value - transaction.reason = TransactionReason.SUBSCRIBE - break - transaction.save(update_fields=["reason", "plan"]) class Migration(migrations.Migration): @@ -48,10 +22,4 @@ class Migration(migrations.Migration): name='reason', field=models.IntegerField(choices=[(1, 'Deduct'), (2, 'Addon'), (3, 'Subscribe'), (4, 'Sub-Create'), (5, 'Sub-Cycle'), (6, 'Sub-Update'), (7, 'Auto-Recharge')], default=1, help_text='The reason for this transaction.

Deduct: Credits deducted due to a run.
Addon: User purchased an add-on.
Subscribe: Applies to subscriptions where no distinction was made between create, update and cycle.
Sub-Create: A subscription was created.
Sub-Cycle: A subscription advanced into a new period.
Sub-Update: A subscription was updated.
Auto-Recharge: Credits auto-recharged due to low balance.'), ), - migrations.RunPython(forwards_func, migrations.RunPython.noop), - migrations.AlterField( - model_name='appusertransaction', - name='reason', - field=models.IntegerField(choices=[(1, 'Deduct'), (2, 'Addon'), (3, 'Subscribe'), (4, 'Sub-Create'), (5, 'Sub-Cycle'), (6, 'Sub-Update'), (7, 'Auto-Recharge')], help_text='The reason for this transaction.

Deduct: Credits deducted due to a run.
Addon: User purchased an add-on.
Subscribe: Applies to subscriptions where no distinction was made between create, update and cycle.
Sub-Create: A subscription was created.
Sub-Cycle: A subscription advanced into a new period.
Sub-Update: A subscription was updated.
Auto-Recharge: Credits auto-recharged due to low balance.'), - ), ] diff --git a/app_users/migrations/0019_alter_appusertransaction_reason.py b/app_users/migrations/0019_alter_appusertransaction_reason.py new file mode 100644 index 000000000..e2d04c62e --- /dev/null +++ b/app_users/migrations/0019_alter_appusertransaction_reason.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.7 on 2024-07-14 21:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app_users', '0018_appusertransaction_plan_appusertransaction_reason'), + ] + + operations = [ + migrations.AlterField( + model_name='appusertransaction', + name='reason', + field=models.IntegerField(choices=[(1, 'Deduct'), (2, 'Addon'), (3, 'Subscribe'), (4, 'Sub-Create'), (5, 'Sub-Cycle'), (6, 'Sub-Update'), (7, 'Auto-Recharge')], help_text='The reason for this transaction.

Deduct: Credits deducted due to a run.
Addon: User purchased an add-on.
Subscribe: Applies to subscriptions where no distinction was made between create, update and cycle.
Sub-Create: A subscription was created.
Sub-Cycle: A subscription advanced into a new period.
Sub-Update: A subscription was updated.
Auto-Recharge: Credits auto-recharged due to low balance.'), + ), + ] diff --git a/scripts/migrate_txn_reason.py b/scripts/migrate_txn_reason.py new file mode 100644 index 000000000..f06f2d95e --- /dev/null +++ b/scripts/migrate_txn_reason.py @@ -0,0 +1,21 @@ +from app_users.models import TransactionReason, AppUserTransaction +from payments.plans import PricingPlan + + +def run(): + for transaction in AppUserTransaction.objects.filter(amount__gt=0): + # For old transactions, we didn't have a subscription field. + # It just so happened that all monthly subscriptions we offered had + # different amounts from the one-time purchases. + # This uses that heuristic to determine whether a transaction + # was a subscription payment or a one-time purchase. + transaction.reason = TransactionReason.ADDON + for plan in PricingPlan: + if ( + transaction.amount == plan.credits + and transaction.charged_amount == plan.monthly_charge * 100 + ): + transaction.plan = plan.db_value + transaction.reason = TransactionReason.SUBSCRIBE + break + transaction.save(update_fields=["reason", "plan"])