Problem/Motivation
I am migrating from Drupal 7 + Commerce 1.x to Drupal 9 + Commerce 2.x. All my payments have the decimal point in the wrong place. This is not a problem with prices.
Steps to reproduce
Migrate from Drupal 7 to Drupal 9. Then check the databases.
I need to skip some values that were not migrated. My D7 database:
MySQL [drupal]> SELECT transaction_id, order_id, payment_method, amount
-> FROM commerce_payment_transaction
-> WHERE transaction_id > 171 LIMIT 0,5;
+----------------+----------+----------------+--------+
| transaction_id | order_id | payment_method | amount |
+----------------+----------+----------------+--------+
| 172 | 215 | authnet_aim | 22467 |
| 173 | 219 | authnet_aim | 59500 |
| 174 | 222 | authnet_aim | 18752 |
| 179 | 231 | authnet_aim | 14595 |
| 180 | 231 | authnet_aim | 14595 |
+----------------+----------+----------------+--------+
5 rows in set (0.00 sec)
And my D9 database:
MySQL [default]> SELECT payment_id, order_id, amount__number
-> FROM commerce_payment LIMIT 0,5;
+------------+----------+----------------+
| payment_id | order_id | amount__number |
+------------+----------+----------------+
| 172 | 215 | 22467.0000 |
| 173 | 219 | 59500.000000 |
| 174 | 222 | 18752.000000 |
| 179 | 231 | 14595.000000 |
| 180 | 231 | 14595.000000 |
+------------+----------+----------------+
5 rows in set (0.000 sec)
In Drupal 9, all those values should have two more digits after the decimal point.
Proposed resolution
Divide by 100 in the prepareRow() method of the migration source.
This works for my use case. We might have to work harder to handle all cases.
Remaining tasks
Add test coverage.
User interface changes
None
API changes
None
Data model changes
None
Comments
Comment #2
benjifisherThe attached patch works for me.
Comment #4
benjifisherThe failing tests are not a surprise:
and
My site is happier with the patch in #2.
I asked on the #commerce channel in Drupal Slack: am I just not finding the configuration option where you say how many decimal points the payments should be? I was told that I am not missing anything. Based on that, I think I am right and the automated tests are wrong.
Comment #5
tonytheferg commented@benjifisher I am using this as a process plugin as a work around:
Comment #6
rclemings commentedI've seen the same thing but not consistently. I haven't been able to discern any pattern as to when it happens.
Comment #7
travis-bradbury commentedTo support other currencies, we should use
Drupal\commerce_price\MinorUnitConverter::fromMinorUnitsinstead of assuming it should be divided by 100.Comment #8
benstallings commentedAn alternative approach is taken by https://www.drupal.org/project/commerce_migrate/issues/3262612 , which allows the CommercePrice process plugin to be used with these values by passing it array of amount and currency_code.
Comment #9
tkiehne commentedComment #10
damienmckennaI'm seeing the data showing as it does in the issue summary - commerce_payment.amount_number values show as e.g. "572.0000". I suspect the patch should resolve the problem, but I suspect #8 is probably the best approach.
That said, here's some test coverage.
Comment #11
damienmckennaI thought so - the balance_number needed to be changed too.
Comment #12
damienmckennaComment #13
damienmckennaThis moves over the amount/currency logic from #3262612 and adds the test coverage from here, but doesn't include Benji's original change.
Comment #14
damienmckennaThe logic from #3262612 doesn't help :-\
Comment #15
damienmckennaGoing back to the original solution, this should fix the second payment record.
Comment #16
damienmckennaLet's add test coverage for the third successful order that's migrated.
Comment #17
tkiehne commented#16 works on my test sandbox and on my live test data with > 30,000 payments
Comment #18
damienmckennaA tests-only version of patch #16.
Comment #19
damienmckennaMost of the test failures are because of incompatibilities with PHP 8.1, so I opened #3270534.
Comment #20
joekersI've tested the patch in #16 and it's working great for me - thanks!
Comment #21
benstallings commentedsetting to RTBC
Comment #22
quietone commentedThanks for finding and fixing this and providing a test. Just one point.
This is assuming that the currency uses two fraction digits. It would be more robust to get the actual fraction digits for the currency and use that, like the ShippingFlatRate source plugin.
Something like this,
Comment #23
brianlp commentedPatch in #16 worked for me as well, thanks! (Currencies used here have two fraction digits.)
Comment #24
quietone commentedAdding in the suggestion from #22
Comment #26
rishi.kulshreshthaThe patch provided by @quietone works without any issues.
Comment #27
damienmckennaComment #29
quietone commentedI am going to commit #24 because it didn't modify the tests and they still passed. The same way of handling the currency fraction digits is used in the CommercePrice process plugin and the ShippingFlatRate source plugin.
Thanks everyone for working on this problem
Comment #30
quietone commented