-
Notifications
You must be signed in to change notification settings - Fork 116
[Woo POS] [Receipts] Set order metadata with the formatted change due amount string when a cash payment is made #15559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Woo POS] [Receipts] Set order metadata with the formatted change due amount string when a cash payment is made #15559
Conversation
…`updateOrder` and `updatePOSOrder`.
…tOfSaleOrderController` to `POSOrderService` to avoid having to update `OrderAction.updateOrder` that implies a lot more unnecessary changes from existing usage.
…ore logic is moved to the service.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works well; a question inline about whether we should send the change even when it's 0
let fieldsToUpdate: [OrderUpdateField] = [ | ||
.status, | ||
.paymentMethodID, | ||
.paymentMethodTitle] | ||
let updatedOrder = order.copy(status: .completed, | ||
paymentMethodID: PaymentGateway.Constants.cashOnDeliveryGatewayID, | ||
paymentMethodTitle: Localization.cashPaymentMethodTitle) | ||
|
||
let _ = try await withCheckedThrowingContinuation { continuation in | ||
let action = OrderAction.updateOrder(siteID: siteID, | ||
order: updatedOrder, | ||
giftCard: nil, | ||
fields: fieldsToUpdate, | ||
onCompletion: { [weak self] result in | ||
guard let self = self else { return } | ||
switch result { | ||
case .success: | ||
self.celebrate() | ||
case .failure: | ||
analytics.track(.pointOfSaleCashPaymentFailed) | ||
} | ||
continuation.resume(with: result) | ||
}) | ||
stores.dispatch(action) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice tidying up, this should definitely be in the service
func collectCashPayment(changeDueAmount: String?) async throws { | ||
try await orderController.collectCashPayment(changeDueAmount: changeDueAmount) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why make this optional? There's always a change amount for cash payments, it's just that sometimes it's $0. There's potentially value in specifically knowing that the app calculated the change as zero... are there other reasons not to send it in that case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question, it's optional not only for 0 change due amount but also for unexpected scenarios like when it cannot parse the currency and input text:
woocommerce-ios/WooCommerce/Classes/POS/ViewHelpers/CollectCashViewHelper.swift
Lines 24 to 25 in 4db63d3
guard let orderDecimal = parseCurrency(orderTotal), | |
let inputDecimal = parseCurrency(textFieldAmountInput) else { |
I agree that 0 change due amount can be shown on the receipt as well. The zero case was skipped before just because it was following the logic where the UI doesn't show a message for 0 change due amount. From Perplexity:
If the change due is zero, many POS systems will omit displaying or printing the change due amount, often configurable by the user or store settings.
I also checked a few receipt examples and a bunch of them do show 0 change due amount. I believe the best UX is for the app to set the order metadata for all >= 0 change due amount, and the backend can decide whether to show it or not (we will show it by default for Basic POS) like based on a POS configuration in the future.
Updated in bcf0589 and ready for another check!

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me 👍 thanks!
Another thought (sorry, should have come up with this yesterday):
Why send the formatted value? The API doesn't send us formatted values, it sends a currency code and an unformatted string for the amount. Perhaps we should reply in the same way?
We don't really support multicurrency well, but we shouldn't make it harder for ourselves – relying on the currency set on the order is reasonable. We can throw an error in the app if someone tries to give change in a different currency to the order – I don't think that'll even come up yet though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great thought, better late than never! I was sending the formatted value just so that the backend can just display it right away. I just checked the order API response including other metadata like from WooPayments, the amounts are not formatted. Let me try making it work in core first, then I will update the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the currency symbol in 7111d68. Can be tested with woocommerce/woocommerce#57734 that displays the formatted change due amount.
…ue-amount-for-pos-cash-payment
…ue-amount-for-pos-cash-payment
Version |
…ue-amount-for-pos-cash-payment
@joshheald I updated the PR to send the cash payment change due amount without the currency symbol, if you'd like to take another look. This can be tested with woocommerce/woocommerce#57734 that displays the formatted change due amount with the order currency symbol. |
…ue-amount-for-pos-cash-payment
Merging as the core work woocommerce/woocommerce#57734 was merged. |
Generated by 🚫 Danger |
Closes: WOOMOB-378
Just one reviewer is required.
✅⚠️ for author: potential merge conflicts with #15557.
Description
This pull request sends the change amount from each cash payment in POS in the order's metadata
_cash_change_amount
field. The most important changes involve adding functionality for encoding and passing the cash payment change due amount, updating relevant protocols and controllers, and adding comprehensive test coverage. There was a small refactoring to replaceOrderAction.updateOrder
inPointOfSaleOrderController
with a newPOSOrderServiceProtocol.markOrderAsCompletedWithCashPayment
, so that we don't have to change many of the existingOrderAction.updateOrder
use cases for the new parameter.POS Cash Payment Enhancements:
cashPaymentChangeDueAmount
to theupdateOrder
andupdatePOSOrder
methods inOrdersRemote
to encode and pass cash payment change amounts.POSOrdersRemoteProtocol
to include thecashPaymentChangeDueAmount
parameter in theupdatePOSOrder
method.PointOfSaleOrderControllerProtocol
and its implementations to handle thechangeDueAmount
parameter when collecting cash payments. The core order update logic was moved toPOSOrderServiceProtocol.markOrderAsCompletedWithCashPayment
so that order update actions can call the async/awaitOrdersRemote.updatePOSOrder
with the cash payment change due amount parameter there.UI and View Model Updates:
PointOfSaleCollectCashView
to calculate and pass the change due amount using a helper method.CollectCashViewHelper
with methods to compute and format the change due amount.Test Coverage:
OrdersRemoteTests
to verify encoding of cash payment change amounts and ensure no metadata is included when the parameter is absent.PointOfSaleOrderControllerTests
to validate the behavior ofcollectCashPayment
with and without a change due amount, and to ensure proper error handling and analytics tracking.POSOrderServiceTests
for the new functionmarkOrderAsCompletedWithCashPayment
with the core order update logic with change due amount.Steps to reproduce
No change due amount
Cash payment
and enter the exact order amount, then mark payment as complete --> should hear a cha-chingmeta_data
value should have an entry with key_cash_change_amount
with the zero formatted change due amount as its value. In the response,payment_method
should becod
andpayment_method_title
should be the localized version of "Pay in Person", just like beforeNon-zero change due amount
Cash payment
and enter a higher amount than the order amount, note the change due amount, then mark payment as complete --> should hear a cha-chingmeta_data
value should have an entry with key_cash_change_amount
with the formatted change due amount as its value. The amount string should be formatted with the store currency settings but does not include the currency symbol. In the response,payment_method
should becod
andpayment_method_title
should be the localized version of "Pay in Person", just like beforeScreenshots
Example request body:
RELEASE-NOTES.txt
if necessary.Reviewer (or Author, in the case of optional code reviews):
Please make sure these conditions are met before approving the PR, or request changes if the PR needs improvement: