diff --git a/enterprise_subsidy/apps/subsidy/migrations/0022_backfill_initial_deposits.py b/enterprise_subsidy/apps/subsidy/migrations/0022_backfill_initial_deposits.py index 121c0678..598cbe3d 100644 --- a/enterprise_subsidy/apps/subsidy/migrations/0022_backfill_initial_deposits.py +++ b/enterprise_subsidy/apps/subsidy/migrations/0022_backfill_initial_deposits.py @@ -7,18 +7,23 @@ Note this has no reverse migration logic. Attempts to rollback the deployment which includes this PR will not delete (un-backfill) the deposits created during the forward migration. """ +import logging + import django.utils.timezone from django.db import migrations from enterprise_subsidy.apps.subsidy.migration_utils import find_legacy_initial_transactions from enterprise_subsidy.apps.subsidy.models import SubsidyReferenceChoices +logger = logging.getLogger(__name__) + def forwards_func(apps, schema_editor): """ The core logic of this migration. """ # We get the models from the versioned app registry; if we directly import it, it'll be the wrong version. + Ledger = apps.get_model("openedx_ledger", "Ledger") Transaction = apps.get_model("openedx_ledger", "Transaction") Deposit = apps.get_model("openedx_ledger", "Deposit") HistoricalDeposit = apps.get_model("openedx_ledger", "HistoricalDeposit") @@ -44,12 +49,22 @@ def forwards_func(apps, schema_editor): deposits_to_backfill = [] historical_deposits_to_backfill = [] for tx in legacy_initial_transactions: + sales_contract_reference_id = None + sales_contract_reference_provider = None + try: + sales_contract_reference_id = tx.ledger.subsidy.reference_id + sales_contract_reference_provider = sales_contract_reference_providers[tx.ledger.subsidy.reference_type] + except Ledger.subsidy.RelatedObjectDoesNotExist: + logger.warning( + "Found a ledger (%s) without a related subsidy, so the initial deposit will not have a sales contract.", + tx.ledger.uuid, + ) deposit_fields = { "ledger": tx.ledger, "transaction": tx, "desired_deposit_quantity": tx.quantity, - "sales_contract_reference_id": tx.ledger.subsidy.reference_id, - "sales_contract_reference_provider": sales_contract_reference_providers[tx.ledger.subsidy.reference_type], + "sales_contract_reference_id": sales_contract_reference_id, + "sales_contract_reference_provider": sales_contract_reference_provider, } deposit = Deposit(**deposit_fields) historical_deposit = HistoricalDeposit( diff --git a/enterprise_subsidy/apps/subsidy/tests/test_migrations.py b/enterprise_subsidy/apps/subsidy/tests/test_migrations.py index 6add9813..591581b0 100644 --- a/enterprise_subsidy/apps/subsidy/tests/test_migrations.py +++ b/enterprise_subsidy/apps/subsidy/tests/test_migrations.py @@ -11,15 +11,22 @@ @pytest.mark.django_db @pytest.mark.parametrize( - "initial_deposit_exists,subsidy_reference_id", + "initial_deposit_exists,subsidy_exists,subsidy_reference_id", [ - (False, None), - (False, "abc123"), - (True, None), - (True, "abc123"), + (False, False, None), + (False, True, None), + (False, True, "abc123"), + (True, False, None), + (True, True, None), + (True, True, "abc123"), ], ) -def test_migration_0022_backfill_initial_deposits(migrator, initial_deposit_exists, subsidy_reference_id): +def test_migration_0022_backfill_initial_deposits( + migrator, + initial_deposit_exists, + subsidy_exists, + subsidy_reference_id, +): """ Test Backfilling initial deposits via data migration. """ @@ -36,23 +43,27 @@ def test_migration_0022_backfill_initial_deposits(migrator, initial_deposit_exis SalesContractReferenceProvider = old_state.apps.get_model("openedx_ledger", "SalesContractReferenceProvider") ledger = Ledger.objects.create() - subsidy = Subsidy.objects.create( - ledger=ledger, - starting_balance=100, - reference_id=subsidy_reference_id, - enterprise_customer_uuid=uuid.uuid4(), - ) + subsidy = None + if subsidy_exists: + subsidy = Subsidy.objects.create( + ledger=ledger, + starting_balance=100, + reference_id=subsidy_reference_id, + enterprise_customer_uuid=uuid.uuid4(), + ) transaction = Transaction.objects.create( ledger=ledger, idempotency_key=INITIAL_DEPOSIT_TRANSACTION_SLUG, - quantity=subsidy.starting_balance, + quantity=subsidy.starting_balance if subsidy_exists else 100, state=TransactionStateChoices.COMMITTED ) if initial_deposit_exists: - sales_contract_reference_provider = SalesContractReferenceProvider.objects.create( - slug=subsidy.reference_type, - name="Foo Bar", - ) + sales_contract_reference_provider = None + if subsidy_exists: + sales_contract_reference_provider = SalesContractReferenceProvider.objects.create( + slug=subsidy.reference_type, + name="Foo Bar", + ) Deposit.objects.create( ledger=ledger, desired_deposit_quantity=transaction.quantity, @@ -83,14 +94,23 @@ def test_migration_0022_backfill_initial_deposits(migrator, initial_deposit_exis # Finally check that all the deposit values are correct. assert Deposit.objects.first().ledger.uuid == ledger.uuid - assert Deposit.objects.first().desired_deposit_quantity == subsidy.starting_balance + assert Deposit.objects.first().desired_deposit_quantity == 100 assert Deposit.objects.first().transaction.uuid == transaction.uuid - assert Deposit.objects.first().sales_contract_reference_id == subsidy_reference_id - assert Deposit.objects.first().sales_contract_reference_provider.slug == subsidy.reference_type + if subsidy_exists: + assert Deposit.objects.first().sales_contract_reference_id == subsidy_reference_id + assert Deposit.objects.first().sales_contract_reference_provider.slug == subsidy.reference_type + else: + assert Deposit.objects.first().sales_contract_reference_id is None + assert Deposit.objects.first().sales_contract_reference_provider is None + assert HistoricalDeposit.objects.first().ledger.uuid == ledger.uuid - assert HistoricalDeposit.objects.first().desired_deposit_quantity == subsidy.starting_balance + assert HistoricalDeposit.objects.first().desired_deposit_quantity == 100 assert HistoricalDeposit.objects.first().transaction.uuid == transaction.uuid - assert HistoricalDeposit.objects.first().sales_contract_reference_id == subsidy_reference_id - assert HistoricalDeposit.objects.first().sales_contract_reference_provider.slug == subsidy.reference_type + if subsidy_exists: + assert HistoricalDeposit.objects.first().sales_contract_reference_id == subsidy_reference_id + assert HistoricalDeposit.objects.first().sales_contract_reference_provider.slug == subsidy.reference_type + else: + assert HistoricalDeposit.objects.first().sales_contract_reference_id is None + assert HistoricalDeposit.objects.first().sales_contract_reference_provider is None assert HistoricalDeposit.objects.first().history_type == "+" assert HistoricalDeposit.objects.first().history_change_reason == "Data migration to backfill initial deposits"