Problem/Motivation
Like #2790545: Add $payment->getBalance(), Order entities needs a getBalance() method. The problem is we don't want commerce_order to depend on commerce_payment but order->getBalance() will need access to any payments made.
Proposed Resolution
Find a way for orders to be able to discover any payments made for an order without requiring a hard dependency on the commerce_payment module.
Remaining Tasks
Discuss: How do we accomplish this? Balance will be order total unless we have a payment service? Then we try to see if there are any payments for the order? Or commerce_order subscribes to commerce_payment events?
Follow PR on GitHub: https://github.com/drupalcommerce/commerce/pull/508
Comment | File | Size | Author |
---|---|---|---|
#33 | commerce-add-order-balance-2804227-32.patch | 14.56 KB | zerolab |
| |||
#31 | commerce-add-order-balance-2804227-31.patch | 14.5 KB | zerolab |
#27 | interdiff-2804227-25-27.txt | 3.74 KB | edaa |
#27 | 2804227-27.patch | 13.79 KB | edaa |
| |||
#25 | 2804227-23-25-interdiff.txt | 753 bytes | flocondetoile |
Comments
Comment #2
mglamanThe best solution, I can think of, is to pass the Order to a Balance service in the Commerce Payment module. This returns the balance of the order.
Comment #3
bojanz CreditAttribution: bojanz at Centarro commentedI was thinking of a $order->paid_total that gets updated from commerce_payment when a payment gets captured or refunded.
Comment #4
agoradesign CreditAttribution: agoradesign commentedI like bojanz' idea more. So you'd always have the field and the getBalance() function, no matter if you enable the Payment module or not. Sounds more right
Comment #5
mglamanSo we'd acknowledge that orders have a "balance", via a method, but no property? Or would order provide the property, too. Or would it be an untyped method and just a base field payment adds?
Comment #6
bojanz CreditAttribution: bojanz at Centarro commentedThe order tracks its paid_total. getBalance() then subtracts the paid_total from the total.
I think it makes sense for an order to have this concept regardless of commerce_payment.
Comment #7
agoradesign CreditAttribution: agoradesign commentedExactly.. Doing this will allow us to ask the order directly for its balance, not a service instead. + you could theoretically implement a very custom payment extension, that doesn't rely on commerce_payment at all, but still have the paid_total field and the getBalance() function.
And last but not least it makes conceptually sense. The order always knows, whether and how much was paid, no matter what module actually does payments
Comment #8
steveoliver CreditAttribution: steveoliver commentedSounds good. I'll work on this today.
Comment #9
steveoliver CreditAttribution: steveoliver commentedFirst pass.
Comment #10
steveoliver CreditAttribution: steveoliver commentedAdd github PR link.
Comment #11
steveoliver CreditAttribution: steveoliver commentedAdded passing tests for the order::getBalance and related methods: https://github.com/drupalcommerce/commerce/pull/508/files#diff-a708b62f9....
Comment #12
vasikei think we need an update to add the "total_paid" field.
here is patch that could be added to the PR
Comment #13
jackbravo CreditAttribution: jackbravo commentedThis is a reroll of previous patch, adding also the commerce_order_post_update_6() function proposed in #12. There is already a PR in github with number [508](https://github.com/drupalcommerce/commerce/pull/508), but here is the udpated one: https://github.com/drupalcommerce/commerce/pull/786
IMO, If the tests pass I think the patch should be good to go and needing only another developer review to mark as RTBC.
Comment #14
jackbravo CreditAttribution: jackbravo commentedThis is the latest patch. I believe tests are passing now.
Comment #15
jackbravo CreditAttribution: jackbravo commentedI realized that asking for the PR.patch gives you this nice format that's more like an interdiff with every commit neatly separated. And if you ask for github's PR.diff, then you get what we generally expect to post here as a patch, which is just one big patch which shows the differences between current dev branch and the change we want. So I'm posting that here also.
Comment #16
jackbravo CreditAttribution: jackbravo commentedI added one more change. Now when we calculate the balance, we consider the payment status. The tests are also updated for this. So I think this is now RTBC, but will wait for someone else to review it.
Here is the diff and the interdiff (the .patch file is like an interdiff right?).
Comment #17
steveoliver CreditAttribution: steveoliver commented@jackbravo-
The patch looks great. Good call on the check of payment state! Super minor nitpick: In OrderInterface.php: "Gets the remaining amount unpaid on the order." I'd remove the word "remaining" -- it seems redundant.
If I didn't work on this, I'd RTBC it, but +1 for RTBC!
Comment #18
jackbravo CreditAttribution: jackbravo commentedSounds good. This is a new patch, changing the getBalance() description. Also a re-roll because there where some conflicts in modules/order/commerce_order.post_update.php.
The PR is also up to date.
Comment #19
flocondetoilePatch #18 doesn't apply well on commerce 2.2, especially for the order tests.
Rerolled Patch #18 on commerce 2.2 and updated the tests.
Comment #21
flocondetoileOups
Comment #23
flocondetoileShould pass.
Comment #25
flocondetoileAgain...
Comment #26
edaa CreditAttribution: edaa commentedNeed to check payment state before subtracting:
Comment #27
edaa CreditAttribution: edaa commentedAs per comment #26
Comment #28
bojanz CreditAttribution: bojanz at Centarro commentedhttps://github.com/drupalcommerce/commerce/pull/855 might have unmerged changes.
Comment #29
Jaesin CreditAttribution: Jaesin at Chapter Three commented+1 for this. I'm working around it for the time being.
Comment #30
bojanz CreditAttribution: bojanz at Centarro commentedThe main question here is what to do with existing orders:
1) Initialize paid_total to 0.
2) Initialize paid_total to the total_price (treat all previous orders as fully paid).
3) Have an update hook that resaves all orders (potentially 10s of thousands).
Comment #31
zerolab CreditAttribution: zerolab at Torchbox commentedAttaching a re-rolled patch with a couple of minor tweaks.
May need to update the tests further.
Note that this does not tackle the questions in #30 yet.
Best,
Dan
editmoved the patch for duplicate payment to #3003832: PaymentProcess needs to take the order balance into account
Comment #33
zerolab CreditAttribution: zerolab at Torchbox commentedMissed a line. The patch combines #27 with updated tests from https://github.com/drupalcommerce/commerce/pull/855
Providing an interdiff is rather fiddly.
Comment #34
bojanz CreditAttribution: bojanz at Centarro commentedI'm wrapping up the final iteration of this patch.
Here are the problems I noticed in #33:
New fields should be added in update hooks, not post update hooks.
It is odd to have addPayment/setPayment methods that do not accept a payment.
Since this calculation logic is insufficient anyway (more on that down below), we should remove these methods and just rely on the regular setter.
$this->getStore()->getDefaultCurrencyCode() is probably from a time when we did the same in other order methods, but it proved to be buggy in multicurrency scenarios. If the field is empty, we should be returning NULL, no fallback.
We need to rewrite this docblock to say how the order balance is calculated, and that it can be negative if the order was overpaid.
In general, we need a service that will recalculate an order's total paid price. That will allow people to update all existing orders if desired. We won't do it ourselves, cause we assume that sites have potentially too many orders to update from update.php, making it better to do it from a Drush/Console command. It will also allow us to heal existing orders that are getting payment updates (if an order with a NULL total_paid gets a refund, the total_paid field can't become negative, we need to recalculate from scratch).
Comment #35
bojanz CreditAttribution: bojanz at Centarro for Torchbox commentedUpdating issue credits. Final test run on Travis.
Comment #36
bojanz CreditAttribution: bojanz at Centarro for Torchbox commentedComment #38
bojanz CreditAttribution: bojanz at Centarro for Torchbox commentedThanks everyone! This took a while :)