commerce1 payment transaction with empty currency_code crashes migrate

Created on 9 June 2022, over 2 years ago
Updated 14 April 2024, 9 months ago

Problem/Motivation

I have a site that was upgraded from Drupal 6 (Ubercart) to Drupal 7 (Commerce) and now to Drupal 9 (Commerce).

The Drupal 7 source for commerce_payment_transaction has historical records from Drupal 6 with payment methods like "Credit card" (uc_authorizenet, pnref?), "Check", "PayPal".

commerce1_payment does not handle this situation and hard crashes the migration.

Error: Call to a member function getCurrencyCode() on null in /var/www/html/webroot/modules/commerce/modules/payment/src/Entity/Payment.php on line 334
#0 /var/www/html/webroot/core/lib/Drupal/Core/Entity/EntityStorageBase.php(566): Drupal\commerce_payment\Entity\Payment->preSave(Object(Drupal\commerce_payment\PaymentStorage))
#1 /var/www/html/webroot/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(754): Drupal\Core\Entity\EntityStorageBase->doPreSave(Object(Drupal\commerce_payment\Entity\Payment))
#2 /var/www/html/webroot/core/lib/Drupal/Core/Entity/EntityStorageBase.php(521): Drupal\Core\Entity\ContentEntityStorageBase->doPreSave(Object(Drupal\commerce_payment\Entity\Payment))
#3 /var/www/html/webroot/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(802): Drupal\Core\Entity\EntityStorageBase->save(Object(Drupal\commerce_payment\Entity\Payment))
#4 /var/www/html/webroot/core/lib/Drupal/Core/Entity/EntityBase.php(339): Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object(Drupal\commerce_payment\Entity\Payment))
#5 /var/www/html/webroot/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php(247): Drupal\Core\Entity\EntityBase->save()
#6 /var/www/html/webroot/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php(186): Drupal\migrate\Plugin\migrate\destination\EntityContentBase->save(Object(Drupal\commerce_payment\Entity\Payment), Array)
#7 /var/www/html/webroot/core/modules/migrate/src/MigrateExecutable.php(248): Drupal\migrate\Plugin\migrate\destination\EntityContentBase->import(Object(Drupal\migrate\Row), Array)
#8 /var/www/html/vendor/drush/drush/includes/drush.inc(206): Drupal\migrate\MigrateExecutable->import()

Steps to reproduce

  1. Replicate drupal 6 -> drupal 7 data from old payment providers ("Credit card", "Check", "PayPal") where a transaction row contains currency_code of an empty string
  2. Generate a migration configuration
  3. Run migration. commerce1_payment crashes.

Proposed resolution

- A non-code single-currency store workaround is to add the default_value plugin with the preferred default_value.

- A simple resolution would be to add the "default_value" to both amount/currency_code and refunded_amount/currency_code process chains in the commerce1_payment migration (template). This could use a static value defined at the top of that migration that could be changed.

- A complex resolution would be to create a lookup plugin for the default currency code and update the migration (template) above accordingly to use it. There may not be a way to get the most accurate value in a multi-currency store though for an empty record. This might fit a >80% scenario though.

Remaining tasks

User interface changes

API changes

Data model changes

Migration (template) configuration changes

πŸ› Bug report
Status

Needs review

Version

4.0

Component

Drupal Commerce 1.x

Created by

πŸ‡ΊπŸ‡ΈUnited States mradcliffe USA

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States rclemings

    I found a similar error when importing errors. Patch attached. I suppose I could open a new issue but this one seems to be languishing so I'll just add it here for the benefit of future googlers.

  • Status changed to Needs review about 1 year ago
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 9.5.x + Environment: PHP 7.3 & MySQL 5.7
    last update about 1 year ago
    350 pass
  • πŸ‡ΊπŸ‡ΈUnited States rclemings
  • πŸ‡³πŸ‡ΏNew Zealand quietone

    There are two fixes here, one for payment and one for orders. There is also πŸ› Throw SkipRowException in CommercePrice process plugin when there is no currency_code Needs review is changing the CommercePrice process plugin to always throw an exception with the currency code is not available.

    All of these are relates to the same problem of no currency code. Perhaps they should all use the solution from @mradcliffe of using the default currency code?

    @rclemings, the Commerce Migrate project is set at "Minimally maintained', so yes issues sit for a long time.

  • πŸ‡³πŸ‡ΏNew Zealand quietone
  • πŸ‡ΊπŸ‡ΈUnited States rclemings

    @quietone: Understood. I don't think my patch applies any more anyway, and in any case, it just skipped the problem record instead of importing it.

    The real issue turned out to be missing entries for one order in these tables:

    field_revision_commerce_line_items
    field_revision_commerce_total
    field_revision_commerce_order_total
    field_revision_commerce_customer_billing

    I fixed it by populating those fields from their field_data_commerce_* counterparts and now everything works fine.

    (Posting just in case it helps someone else.)

Production build 0.71.5 2024