[WOOMOB-2450][POS Refunds: M3] Add refund details dialog to POS order details#15502
Conversation
Replace the simple List<String> refund amounts in TotalsBreakdown with a structured RefundRow (label, amount, date, reason). Update RefundInfo to carry RefundRowData preserving the full Refund object for dialog use. Refunds are sorted oldest-first before numbering. Add RefundDetails variant to DialogState and new string resources.
Add ViewRefundDetailsClicked UI event and handle it in the ViewModel by building dialog state from the stored RefundRowData. Add buildLineItemsForSingleRefund to the mapper so the dialog can show per-refund item breakdown. Store current refund rows alongside the selected order for quick dialog construction.
Introduce WooPosRefundDetailsDialog composable showing refunded items, subtotal, tax, and total when "View details" is tapped. Update refund rows in the totals section to display date, reason, and a clickable "View details" link. Wire the dialog into WooPosOrdersScreen.
Generated by 🚫 Danger |
|
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## trunk #15502 +/- ##
============================================
- Coverage 39.54% 39.53% -0.02%
- Complexity 11237 11248 +11
============================================
Files 2251 2252 +1
Lines 129763 130058 +295
Branches 18170 18208 +38
============================================
+ Hits 51318 51415 +97
- Misses 73208 73395 +187
- Partials 5237 5248 +11 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Center the title, make items list scrollable, update divider thickness, and fix TotalRowLine to use consistent text styling.
Handle singular/plural forms correctly (e.g. "1 item" vs "2 items") by switching to getQuantityString.
…ls-of-historical-refunds
There was a problem hiding this comment.
Pull request overview
This PR adds a refund details dialog to the POS order details screen, allowing users to tap on a refund row to view a breakdown that includes refunded items (with images, quantities, and prices), items subtotal, tax, refund total, and payment method. It is part of the M3 milestone for POS Refunds (WOOMOB-2450).
Changes:
- Enriched
RefundInfo/RefundRowDatawith per-refund metadata (label, date, reason, fullRefundobject) and updatedTotalsBreakdown.refundsfromList<String>toList<RefundRow> - Added
WooPosRefundDetailsDialogcomposable and wired the newRefundDetailsdialog state through ViewModel events (ViewRefundDetailsClicked) and screen-level handling - Added
buildLineItemsForSingleRefundtoWooPosOrderDetailsMapperand new state management fields (currentRefundRows,currentOrderForRefunds) in the ViewModel to support showing per-refund line items
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
WooPosRefundInfoBuilder.kt |
Builds RefundRowData per refund with label, date, reason, and amount; changed error handling |
WooPosOrderDetailsMapper.kt |
Added buildLineItemsForSingleRefund for building line items for a single refund |
WooPosOrdersState.kt |
Added RefundRow data class and RefundDetails dialog state |
WooPosOrdersUIEvent.kt |
Added ViewRefundDetailsClicked UI event |
WooPosOrdersViewModel.kt |
Added state management for refund details dialog; new currentRefundRows/currentOrderForRefunds fields |
WooPosOrderDetails.kt |
Refund rows now show label, date, reason, and a "View details" link; whole row is tappable |
WooPosRefundDetailsDialog.kt |
New dialog composable displaying refund item breakdown |
WooPosOrdersScreen.kt |
Wired new RefundDetails dialog state into screen rendering |
strings.xml |
Added string resources for refund label, tax, total, subtotal plurals, and dialog background |
WooPosOrderDetailsMapperTest.kt |
Updated mock for renamed RefundInfo constructor parameter |
WooPosOrdersViewModelTest.kt |
Added formatPrice dependency and updated refund row assertions |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/orders/WooPosOrdersViewModel.kt
Show resolved
Hide resolved
WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/orders/WooPosOrdersViewModel.kt
Show resolved
Hide resolved
...in/kotlin/com/woocommerce/android/ui/woopos/orders/details/refund/WooPosRefundInfoBuilder.kt
Show resolved
Hide resolved
WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/orders/WooPosOrdersViewModel.kt
Outdated
Show resolved
Hide resolved
WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/orders/WooPosOrdersViewModel.kt
Outdated
Show resolved
Hide resolved
...src/main/kotlin/com/woocommerce/android/ui/woopos/orders/details/WooPosOrderDetailsMapper.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
Thanks @samiuelson! I haven't found anything critical, but a couple things worth considering.
- The bottom padding of the last item in the list is always smaller - notice the space between the product image and divider below it is different between the first and second items.
- It is very easy to miss that the content is scrollable - I'd consider adding a shadow on top of the
Totalssection when there is a scroll. We use the same pattern for example in the cart. (P.S. I noticed the same issue in the process refund dialog)
- The centered title feels a bit off - the designs show it centered to the left.
| emptyList() | ||
| } | ||
| RefundInfo(amounts, BigDecimal.ZERO) | ||
| RefundInfo(emptyList(), BigDecimal.ZERO) |
There was a problem hiding this comment.
❓ Seems like previously we showed an error when we failed to load refunds, but now we ignore the error. Is this an intentional change?
There was a problem hiding this comment.
Good catch — this was unintentional. Restored showing the inline error in a86b94d
| private var loadingMoreOrdersJob: Job? = null | ||
| private var sideLoadActionsJob: Job? = null | ||
|
|
||
| private var currentRefundRows: List<RefundRowData> = emptyList() |
There was a problem hiding this comment.
📓 I technically don't see any bug with this approach, but considering we have one VM for everything, with no actual encapsulation (just to be clear, this wasn't introduced in this or previous PR, but over time), I'm worried having multiple independent states that can easily get out of sync is quite risky. Could we somehow make this state dependent on the currently selected order to ensure we don't display refunds for a different order with future code changes? (not necessarily in this PR, but as an maintainability improvement)
There was a problem hiding this comment.
Agreed, having those as independent var fields was fragile. Consolidated currentRefundRows and currentOrderForRefunds into a single CachedRefundData(orderId, rows, order) data class so they can't drift apart → 9162519
| val refundTotal = formatPrice(rowData.refund.amount, order.currency) | ||
|
|
||
| val updatedState = _state.value as? WooPosOrdersState.Content ?: return@launch | ||
| _state.value = updatedState.copy( |
There was a problem hiding this comment.
💡 I'd consider adding a check if still the same order is selected - the coroutine might take a while to start and complete.
Add refundLoadError field to RefundInfo and TotalsBreakdown so the UI can display an inline error message when fetching refunds fails, instead of silently returning empty data.
Replace independent currentRefundRows and currentOrderForRefunds fields with a single CachedRefundData data class that ties the orderId, refund rows, and order together to prevent them from getting out of sync.
Verify the selected order still matches the cached refund data before showing the refund details dialog, preventing stale data from appearing if the user navigated to a different order while the coroutine ran.
…hadow and spacing
|
Thanks for review, Jirka!
Both 1. and 2. were addressed in c8119fa
This is intentional divergence from figma specs, suggested by @kidinov in past, to keep refund-specific dialogs consistent with other dialogs in POS. |
…ls-of-historical-refunds


Description
Fixes WOOMOB-2450
When a refund row is tapped in the POS order details Totals section, a dialog now shows the refund's breakdown: refunded items with images, quantities and prices, items subtotal, tax, refund total, and payment method.
Changes:
RefundRowdata class andRefundDetailsdialog stateRefundInfowith per-refund metadata (label, date, reason, fullRefundobject)WooPosRefundDetailsDialogcomposable usingWooPosDialogWrapperTest Steps
Images/gif
RELEASE-NOTES.txtif necessary. Use the "[Internal]" label for non-user-facing changes.