From 885192d64eadcf6958902016367ce1fb44a17e83 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Mon, 29 Sep 2025 15:45:04 +0200 Subject: [PATCH 01/10] Introduce the payment section in the booking details screen --- .../bookings/compose/BookingPaymentSection.kt | 133 ++++++++++++++++++ .../bookings/details/BookingDetailsScreen.kt | 7 + .../details/BookingDetailsViewState.kt | 7 + WooCommerce/src/main/res/values/strings.xml | 4 + 4 files changed, 151 insertions(+) create mode 100644 WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt new file mode 100644 index 000000000000..d4af2bf88436 --- /dev/null +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt @@ -0,0 +1,133 @@ +package com.woocommerce.android.ui.bookings.compose + +import androidx.annotation.StringRes +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import com.woocommerce.android.R +import com.woocommerce.android.ui.compose.component.WCColoredButton +import com.woocommerce.android.ui.compose.component.WCOutlinedButton +import com.woocommerce.android.ui.compose.preview.LightDarkThemePreviews +import com.woocommerce.android.ui.compose.theme.WooThemeWithBackground + +@Composable +fun BookingPaymentSection( + model: BookingPaymentDetailsModel, + onMarkAsPaid: () -> Unit, + onViewOrder: () -> Unit, + modifier: Modifier = Modifier, +) { + Column(modifier = modifier) { + BookingSectionHeader(R.string.booking_payment_header) + HorizontalDivider(thickness = 0.5.dp) + Column( + verticalArrangement = Arrangement.spacedBy(16.dp), + modifier = Modifier + .background(color = MaterialTheme.colorScheme.surfaceContainer) + .padding(vertical = 16.dp) + ) { + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) { + PaymentRow(label = R.string.booking_payment_label_service, value = model.service) + PaymentRow(label = R.string.tax, value = model.tax) + PaymentRow(label = R.string.discount, value = model.discount) + PaymentRow(label = R.string.total, value = model.total, fontWeight = FontWeight.Medium) + } + HorizontalDivider( + thickness = 0.5.dp, + modifier = Modifier.padding(start = 16.dp) + ) + WCColoredButton( + onClick = onMarkAsPaid, + text = stringResource(id = R.string.booking_payment_mark_as_paid), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) + WCOutlinedButton( + onClick = onViewOrder, + colors = ButtonDefaults.outlinedButtonColors( + contentColor = MaterialTheme.colorScheme.onSurface + ), + text = stringResource(id = R.string.booking_payment_view_order), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) + } + } +} + +@Composable +private fun PaymentRow( + @StringRes label: Int, + value: String, + fontWeight: FontWeight = FontWeight.Normal, +) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + ) { + PaymentText(stringResource(label), fontWeight = fontWeight) + PaymentText(value, modifier = Modifier.padding(start = 8.dp), fontWeight = fontWeight) + } +} + +@Composable +private fun PaymentText( + text: String, + fontWeight: FontWeight, + modifier: Modifier = Modifier, +) { + Text( + text = text, + style = MaterialTheme.typography.bodyMedium.copy(fontWeight = fontWeight), + color = MaterialTheme.colorScheme.onSurface, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = modifier + ) +} + +data class BookingPaymentDetailsModel( + val service: String, + val tax: String, + val discount: String, + val total: String +) + +@LightDarkThemePreviews +@Composable +private fun BookingPaymentSectionPreview() { + WooThemeWithBackground { + BookingPaymentSection( + model = BookingPaymentDetailsModel( + service = "$55.00", + tax = "$4.50", + discount = "-", + total = "$59.50" + ), + onMarkAsPaid = {}, + onViewOrder = {}, + modifier = Modifier.fillMaxWidth() + ) + } +} diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt index 255e7504ead3..60a74c57d35c 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt @@ -26,6 +26,7 @@ import com.woocommerce.android.ui.bookings.compose.BookingAttendanceSection import com.woocommerce.android.ui.bookings.compose.BookingAttendanceStatus import com.woocommerce.android.ui.bookings.compose.BookingAttendanceStatusBottomSheet import com.woocommerce.android.ui.bookings.compose.BookingCustomerDetails +import com.woocommerce.android.ui.bookings.compose.BookingPaymentSection import com.woocommerce.android.ui.bookings.compose.BookingStatus import com.woocommerce.android.ui.bookings.compose.BookingSummary import com.woocommerce.android.ui.bookings.compose.BookingSummaryModel @@ -96,6 +97,12 @@ fun BookingDetailsScreen( onClick = { showAttendanceSheet.value = true }, modifier = Modifier.fillMaxWidth() ) + BookingPaymentSection( + model = viewState.bookingPaymentDetails, + onMarkAsPaid = {}, + onViewOrder = {}, + modifier = Modifier.fillMaxWidth() + ) } if (showAttendanceSheet.value) { BookingAttendanceStatusBottomSheet( diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt index 3bdb99ff54ff..0bc844399006 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt @@ -3,6 +3,7 @@ package com.woocommerce.android.ui.bookings.details import com.woocommerce.android.ui.bookings.compose.BookingAppointmentDetailsModel import com.woocommerce.android.ui.bookings.compose.BookingAttendanceStatus import com.woocommerce.android.ui.bookings.compose.BookingCustomerDetailsModel +import com.woocommerce.android.ui.bookings.compose.BookingPaymentDetailsModel import com.woocommerce.android.ui.bookings.compose.BookingStatus import com.woocommerce.android.ui.bookings.compose.BookingSummaryModel @@ -32,5 +33,11 @@ data class BookingDetailsViewState( "Montgomery AL 36109", "United States" ) + ), + val bookingPaymentDetails: BookingPaymentDetailsModel = BookingPaymentDetailsModel( + service = "$55.00", + tax = "$4.50", + discount = "-", + total = "$59.50" ) ) diff --git a/WooCommerce/src/main/res/values/strings.xml b/WooCommerce/src/main/res/values/strings.xml index 05a035a1c8a6..02d6a3611695 100644 --- a/WooCommerce/src/main/res/values/strings.xml +++ b/WooCommerce/src/main/res/values/strings.xml @@ -4895,5 +4895,9 @@ The customer arrived and the session took place as planned. The client will no longer be able to attend. The client missed the appointment without canceling in advance. + PAYMENT + Service + Mark as paid + View order From 47d8a8663a7b92060f8008e9abc2dcbbfa57e56e Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Tue, 30 Sep 2025 10:15:18 +0200 Subject: [PATCH 02/10] Show different buttons states in payment status section --- .../bookings/compose/BookingPaymentSection.kt | 51 ++++++++++++++++--- .../bookings/details/BookingDetailsScreen.kt | 2 + WooCommerce/src/main/res/values/strings.xml | 1 + 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt index d4af2bf88436..1dc5348dbb7d 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt @@ -26,7 +26,9 @@ import com.woocommerce.android.ui.compose.theme.WooThemeWithBackground @Composable fun BookingPaymentSection( model: BookingPaymentDetailsModel, + paymentStatus: BookingPaymentStatus, onMarkAsPaid: () -> Unit, + onMarkAsRefunded: () -> Unit, onViewOrder: () -> Unit, modifier: Modifier = Modifier, ) { @@ -54,13 +56,26 @@ fun BookingPaymentSection( thickness = 0.5.dp, modifier = Modifier.padding(start = 16.dp) ) - WCColoredButton( - onClick = onMarkAsPaid, - text = stringResource(id = R.string.booking_payment_mark_as_paid), - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - ) + if (paymentStatus == BookingPaymentStatus.PAID) { + WCOutlinedButton( + onClick = onMarkAsRefunded, + colors = ButtonDefaults.outlinedButtonColors( + contentColor = MaterialTheme.colorScheme.onSurface + ), + text = stringResource(id = R.string.booking_payment_mark_as_refunded), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) + } else { + WCColoredButton( + onClick = onMarkAsPaid, + text = stringResource(id = R.string.booking_payment_mark_as_paid), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) + } WCOutlinedButton( onClick = onViewOrder, colors = ButtonDefaults.outlinedButtonColors( @@ -125,8 +140,30 @@ private fun BookingPaymentSectionPreview() { discount = "-", total = "$59.50" ), + paymentStatus = BookingPaymentStatus.COMPLETE, + onMarkAsPaid = {}, + onViewOrder = {}, + onMarkAsRefunded = {}, + modifier = Modifier.fillMaxWidth() + ) + } +} + +@LightDarkThemePreviews +@Composable +private fun BookingPaymentSectionWithRefundOptionPreview() { + WooThemeWithBackground { + BookingPaymentSection( + model = BookingPaymentDetailsModel( + service = "$55.00", + tax = "$4.50", + discount = "-", + total = "$59.50" + ), + paymentStatus = BookingPaymentStatus.PAID, onMarkAsPaid = {}, onViewOrder = {}, + onMarkAsRefunded = {}, modifier = Modifier.fillMaxWidth() ) } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt index 60a74c57d35c..b977d187fb03 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt @@ -99,8 +99,10 @@ fun BookingDetailsScreen( ) BookingPaymentSection( model = viewState.bookingPaymentDetails, + paymentStatus = viewState.bookingSummary.paymentStatus, onMarkAsPaid = {}, onViewOrder = {}, + onMarkAsRefunded = {}, modifier = Modifier.fillMaxWidth() ) } diff --git a/WooCommerce/src/main/res/values/strings.xml b/WooCommerce/src/main/res/values/strings.xml index 02d6a3611695..4fd0ec8f038e 100644 --- a/WooCommerce/src/main/res/values/strings.xml +++ b/WooCommerce/src/main/res/values/strings.xml @@ -4899,5 +4899,6 @@ Service Mark as paid View order + Mark as refunded From f5356948ada29ef958340e05ebdcccf8a3275a41 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Tue, 30 Sep 2025 11:05:00 +0200 Subject: [PATCH 03/10] Open order from the payment section --- .../bookings/details/BookingDetailsFragment.kt | 8 +++++++- .../ui/bookings/details/BookingDetailsScreen.kt | 16 ++++++++++------ .../bookings/details/BookingDetailsViewState.kt | 1 + .../main/res/navigation/nav_graph_bookings.xml | 9 ++++++++- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsFragment.kt index ca782a6721d3..9153f0739e09 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsFragment.kt @@ -23,7 +23,13 @@ class BookingDetailsFragment : BaseFragment() { return composeView { BookingDetailsScreen( viewModel = viewModel, - onBack = { findNavController().popBackStack() } + onBack = { findNavController().popBackStack() }, + onViewOrder = { orderId -> + findNavController().navigate( + BookingDetailsFragmentDirections + .actionBookingDetailsFragmentToOrderDetailFragment(orderId) + ) + } ) } } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt index b977d187fb03..a996adf764ed 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt @@ -37,7 +37,8 @@ import com.woocommerce.android.ui.compose.theme.WooThemeWithBackground @Composable fun BookingDetailsScreen( viewModel: BookingDetailsViewModel, - onBack: () -> Unit + onBack: () -> Unit, + onViewOrder: (Long) -> Unit ) { val viewState by viewModel.state.observeAsState() @@ -46,7 +47,8 @@ fun BookingDetailsScreen( viewState = it, onBack = onBack, onCancelBooking = viewModel::onCancelBooking, - onAttendanceStatusSelected = viewModel::onAttendanceStatusSelected + onAttendanceStatusSelected = viewModel::onAttendanceStatusSelected, + onViewOrder = onViewOrder ) } } @@ -56,7 +58,8 @@ fun BookingDetailsScreen( viewState: BookingDetailsViewState, onBack: () -> Unit, onCancelBooking: () -> Unit, - onAttendanceStatusSelected: (BookingAttendanceStatus) -> Unit + onAttendanceStatusSelected: (BookingAttendanceStatus) -> Unit, + onViewOrder: (Long) -> Unit ) { val showAttendanceSheet = remember { mutableStateOf(false) } Scaffold( @@ -99,9 +102,9 @@ fun BookingDetailsScreen( ) BookingPaymentSection( model = viewState.bookingPaymentDetails, - paymentStatus = viewState.bookingSummary.paymentStatus, + paymentStatus = viewState.bookingSummary.status, onMarkAsPaid = {}, - onViewOrder = {}, + onViewOrder = { onViewOrder(viewState.orderId) }, onMarkAsRefunded = {}, modifier = Modifier.fillMaxWidth() ) @@ -143,7 +146,8 @@ private fun BookingDetailsPreview() { ), onBack = {}, onCancelBooking = {}, - onAttendanceStatusSelected = {} + onAttendanceStatusSelected = {}, + onViewOrder = {} ) } } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt index 0bc844399006..30902145f8a4 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt @@ -9,6 +9,7 @@ import com.woocommerce.android.ui.bookings.compose.BookingSummaryModel data class BookingDetailsViewState( val toolbarTitle: String = "", + val orderId: Long = 0L, val bookingSummary: BookingSummaryModel = BookingSummaryModel( date = "05/07/2025, 11:00 AM", name = "Women’s Haircut", diff --git a/WooCommerce/src/main/res/navigation/nav_graph_bookings.xml b/WooCommerce/src/main/res/navigation/nav_graph_bookings.xml index 3ef6a3e1729a..a109327019b1 100644 --- a/WooCommerce/src/main/res/navigation/nav_graph_bookings.xml +++ b/WooCommerce/src/main/res/navigation/nav_graph_bookings.xml @@ -7,7 +7,7 @@ + android:label="fragment_bookings"> @@ -20,6 +20,13 @@ android:name="bookingId" android:defaultValue="-1L" app:argType="long" /> + + + From 4407afeca3d25f6a632a887621ba96fa4de81601 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Tue, 30 Sep 2025 11:39:13 +0200 Subject: [PATCH 04/10] Handle the onMarkAsPaid and onMarkAsRefunded callbacks --- .../bookings/details/BookingDetailsScreen.kt | 8 +++---- .../details/BookingDetailsViewModel.kt | 24 ++++++++++++++++++- .../details/BookingDetailsViewState.kt | 4 +++- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt index a996adf764ed..b2c0de272b49 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt @@ -48,7 +48,7 @@ fun BookingDetailsScreen( onBack = onBack, onCancelBooking = viewModel::onCancelBooking, onAttendanceStatusSelected = viewModel::onAttendanceStatusSelected, - onViewOrder = onViewOrder + onViewOrder = onViewOrder, ) } } @@ -59,7 +59,7 @@ fun BookingDetailsScreen( onBack: () -> Unit, onCancelBooking: () -> Unit, onAttendanceStatusSelected: (BookingAttendanceStatus) -> Unit, - onViewOrder: (Long) -> Unit + onViewOrder: (Long) -> Unit, ) { val showAttendanceSheet = remember { mutableStateOf(false) } Scaffold( @@ -103,9 +103,9 @@ fun BookingDetailsScreen( BookingPaymentSection( model = viewState.bookingPaymentDetails, paymentStatus = viewState.bookingSummary.status, - onMarkAsPaid = {}, + onMarkAsPaid = viewState.onMarkAsPaid, onViewOrder = { onViewOrder(viewState.orderId) }, - onMarkAsRefunded = {}, + onMarkAsRefunded = viewState.onMarkAsRefunded, modifier = Modifier.fillMaxWidth() ) } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt index 1a9f704a7ad0..3155fb4e3d3a 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.asLiveData import com.woocommerce.android.R import com.woocommerce.android.ui.bookings.compose.BookingAttendanceStatus +import com.woocommerce.android.ui.bookings.compose.BookingStatus import com.woocommerce.android.viewmodel.ResourceProvider import com.woocommerce.android.viewmodel.ScopedViewModel import com.woocommerce.android.viewmodel.navArgs @@ -21,7 +22,12 @@ class BookingDetailsViewModel @Inject constructor( private val navArgs: BookingDetailsFragmentArgs by savedState.navArgs() - private val _state = MutableStateFlow(BookingDetailsViewState()) + private val _state = MutableStateFlow( + BookingDetailsViewState( + onMarkAsPaid = ::onMarkAsPaid, + onMarkAsRefunded = ::onMarkAsRefunded, + ) + ) val state: LiveData = _state.asLiveData() init { @@ -40,6 +46,22 @@ class BookingDetailsViewModel @Inject constructor( } } + private fun onMarkAsPaid() { + _state.update { current -> + current.copy( + bookingSummary = current.bookingSummary.copy(status = BookingStatus.Paid) + ) + } + } + + private fun onMarkAsRefunded() { + _state.update { current -> + current.copy( + bookingSummary = current.bookingSummary.copy(status = BookingStatus.Unpaid) + ) + } + } + fun onCancelBooking() { // TODO Add logic to Cancel booking } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt index 30902145f8a4..2cc0d30099a8 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt @@ -40,5 +40,7 @@ data class BookingDetailsViewState( tax = "$4.50", discount = "-", total = "$59.50" - ) + ), + val onMarkAsPaid: () -> Unit = {}, + val onMarkAsRefunded: () -> Unit = {}, ) From 9acb84291b15a11446b418c89f5848a5281db547 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Tue, 30 Sep 2025 11:41:26 +0200 Subject: [PATCH 05/10] Move onCancelBooking to BookingDetailsViewState --- .../android/ui/bookings/details/BookingDetailsScreen.kt | 5 +---- .../android/ui/bookings/details/BookingDetailsViewModel.kt | 3 ++- .../android/ui/bookings/details/BookingDetailsViewState.kt | 1 + 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt index b2c0de272b49..5410a871a534 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt @@ -46,7 +46,6 @@ fun BookingDetailsScreen( BookingDetailsScreen( viewState = it, onBack = onBack, - onCancelBooking = viewModel::onCancelBooking, onAttendanceStatusSelected = viewModel::onAttendanceStatusSelected, onViewOrder = onViewOrder, ) @@ -57,7 +56,6 @@ fun BookingDetailsScreen( fun BookingDetailsScreen( viewState: BookingDetailsViewState, onBack: () -> Unit, - onCancelBooking: () -> Unit, onAttendanceStatusSelected: (BookingAttendanceStatus) -> Unit, onViewOrder: (Long) -> Unit, ) { @@ -86,7 +84,7 @@ fun BookingDetailsScreen( ) BookingAppointmentDetails( model = viewState.bookingsAppointmentDetails, - onCancelBooking = onCancelBooking, + onCancelBooking = viewState.onCancelBooking, modifier = Modifier.fillMaxWidth() ) BookingCustomerDetails( @@ -145,7 +143,6 @@ private fun BookingDetailsPreview() { ) ), onBack = {}, - onCancelBooking = {}, onAttendanceStatusSelected = {}, onViewOrder = {} ) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt index 3155fb4e3d3a..78fb921a17c9 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt @@ -26,6 +26,7 @@ class BookingDetailsViewModel @Inject constructor( BookingDetailsViewState( onMarkAsPaid = ::onMarkAsPaid, onMarkAsRefunded = ::onMarkAsRefunded, + onCancelBooking = ::onCancelBooking, ) ) val state: LiveData = _state.asLiveData() @@ -62,7 +63,7 @@ class BookingDetailsViewModel @Inject constructor( } } - fun onCancelBooking() { + private fun onCancelBooking() { // TODO Add logic to Cancel booking } } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt index 2cc0d30099a8..b915d3484f67 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt @@ -43,4 +43,5 @@ data class BookingDetailsViewState( ), val onMarkAsPaid: () -> Unit = {}, val onMarkAsRefunded: () -> Unit = {}, + val onCancelBooking: () -> Unit = {}, ) From 2c99833e2a155227b43e63a9fa23ca74eedc9381 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Tue, 30 Sep 2025 11:57:26 +0200 Subject: [PATCH 06/10] Move onAttendanceStatusSelected to BookingDetailsViewState --- .../android/ui/bookings/details/BookingDetailsScreen.kt | 5 +---- .../ui/bookings/details/BookingDetailsViewModel.kt | 3 ++- .../ui/bookings/details/BookingDetailsViewState.kt | 1 + .../ui/bookings/details/BookingDetailsViewModelTest.kt | 9 +++++++++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt index 5410a871a534..192cdf4574ae 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt @@ -46,7 +46,6 @@ fun BookingDetailsScreen( BookingDetailsScreen( viewState = it, onBack = onBack, - onAttendanceStatusSelected = viewModel::onAttendanceStatusSelected, onViewOrder = onViewOrder, ) } @@ -56,7 +55,6 @@ fun BookingDetailsScreen( fun BookingDetailsScreen( viewState: BookingDetailsViewState, onBack: () -> Unit, - onAttendanceStatusSelected: (BookingAttendanceStatus) -> Unit, onViewOrder: (Long) -> Unit, ) { val showAttendanceSheet = remember { mutableStateOf(false) } @@ -110,7 +108,7 @@ fun BookingDetailsScreen( if (showAttendanceSheet.value) { BookingAttendanceStatusBottomSheet( onSelect = { status -> - onAttendanceStatusSelected(status) + viewState.onAttendanceStatusSelected(status) }, onDismiss = { showAttendanceSheet.value = false } ) @@ -143,7 +141,6 @@ private fun BookingDetailsPreview() { ) ), onBack = {}, - onAttendanceStatusSelected = {}, onViewOrder = {} ) } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt index 78fb921a17c9..2ae713b32aab 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt @@ -27,6 +27,7 @@ class BookingDetailsViewModel @Inject constructor( onMarkAsPaid = ::onMarkAsPaid, onMarkAsRefunded = ::onMarkAsRefunded, onCancelBooking = ::onCancelBooking, + onAttendanceStatusSelected = ::onAttendanceStatusSelected, ) ) val state: LiveData = _state.asLiveData() @@ -39,7 +40,7 @@ class BookingDetailsViewModel @Inject constructor( } } - fun onAttendanceStatusSelected(status: BookingAttendanceStatus) { + private fun onAttendanceStatusSelected(status: BookingAttendanceStatus) { _state.update { current -> current.copy( bookingSummary = current.bookingSummary.copy(attendanceStatus = status) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt index b915d3484f67..e4b40a1387f5 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt @@ -44,4 +44,5 @@ data class BookingDetailsViewState( val onMarkAsPaid: () -> Unit = {}, val onMarkAsRefunded: () -> Unit = {}, val onCancelBooking: () -> Unit = {}, + val onAttendanceStatusSelected: (BookingAttendanceStatus) -> Unit = { _ -> } ) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModelTest.kt index 09b6c2268f6d..a71e1e2ca8f7 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModelTest.kt @@ -2,7 +2,11 @@ package com.woocommerce.android.ui.bookings.details import androidx.lifecycle.SavedStateHandle import com.woocommerce.android.R +<<<<<<< HEAD import com.woocommerce.android.ui.bookings.compose.BookingAttendanceStatus +======= +import com.woocommerce.android.util.getOrAwaitValue +>>>>>>> a4e6bd3632f (Move onAttendanceStatusSelected to BookingDetailsViewState) import com.woocommerce.android.viewmodel.BaseUnitTest import com.woocommerce.android.viewmodel.ResourceProvider import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -42,7 +46,12 @@ class BookingDetailsViewModelTest : BaseUnitTest() { val viewModel = createViewModel(savedState, resourceProvider) // When +<<<<<<< HEAD viewModel.onAttendanceStatusSelected(BookingAttendanceStatus.CANCELLED) +======= + val state = viewModel.state.getOrAwaitValue() + state.onAttendanceStatusSelected(com.woocommerce.android.ui.bookings.compose.AttendanceStatus.CANCELLED) +>>>>>>> a4e6bd3632f (Move onAttendanceStatusSelected to BookingDetailsViewState) // Then val updated = viewModel.state.value?.bookingSummary?.attendanceStatus From 874459f00671ce46f22a7c7d56c19b5d1039a0c0 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Wed, 1 Oct 2025 12:42:06 +0200 Subject: [PATCH 07/10] Adjust code after rebasing with trunk --- .../android/ui/bookings/compose/BookingPaymentSection.kt | 8 ++++---- .../android/ui/bookings/details/BookingDetailsScreen.kt | 2 +- .../ui/bookings/details/BookingDetailsViewModelTest.kt | 9 +-------- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt index 1dc5348dbb7d..7e9cd7ac5821 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt @@ -26,7 +26,7 @@ import com.woocommerce.android.ui.compose.theme.WooThemeWithBackground @Composable fun BookingPaymentSection( model: BookingPaymentDetailsModel, - paymentStatus: BookingPaymentStatus, + status: BookingStatus, onMarkAsPaid: () -> Unit, onMarkAsRefunded: () -> Unit, onViewOrder: () -> Unit, @@ -56,7 +56,7 @@ fun BookingPaymentSection( thickness = 0.5.dp, modifier = Modifier.padding(start = 16.dp) ) - if (paymentStatus == BookingPaymentStatus.PAID) { + if (status == BookingStatus.Paid) { WCOutlinedButton( onClick = onMarkAsRefunded, colors = ButtonDefaults.outlinedButtonColors( @@ -140,7 +140,7 @@ private fun BookingPaymentSectionPreview() { discount = "-", total = "$59.50" ), - paymentStatus = BookingPaymentStatus.COMPLETE, + status = BookingStatus.Complete, onMarkAsPaid = {}, onViewOrder = {}, onMarkAsRefunded = {}, @@ -160,7 +160,7 @@ private fun BookingPaymentSectionWithRefundOptionPreview() { discount = "-", total = "$59.50" ), - paymentStatus = BookingPaymentStatus.PAID, + status = BookingStatus.Paid, onMarkAsPaid = {}, onViewOrder = {}, onMarkAsRefunded = {}, diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt index 192cdf4574ae..46c67a44ea51 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt @@ -98,7 +98,7 @@ fun BookingDetailsScreen( ) BookingPaymentSection( model = viewState.bookingPaymentDetails, - paymentStatus = viewState.bookingSummary.status, + status = viewState.bookingSummary.status, onMarkAsPaid = viewState.onMarkAsPaid, onViewOrder = { onViewOrder(viewState.orderId) }, onMarkAsRefunded = viewState.onMarkAsRefunded, diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModelTest.kt index a71e1e2ca8f7..ec2b2d983067 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModelTest.kt @@ -2,11 +2,8 @@ package com.woocommerce.android.ui.bookings.details import androidx.lifecycle.SavedStateHandle import com.woocommerce.android.R -<<<<<<< HEAD import com.woocommerce.android.ui.bookings.compose.BookingAttendanceStatus -======= import com.woocommerce.android.util.getOrAwaitValue ->>>>>>> a4e6bd3632f (Move onAttendanceStatusSelected to BookingDetailsViewState) import com.woocommerce.android.viewmodel.BaseUnitTest import com.woocommerce.android.viewmodel.ResourceProvider import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -46,12 +43,8 @@ class BookingDetailsViewModelTest : BaseUnitTest() { val viewModel = createViewModel(savedState, resourceProvider) // When -<<<<<<< HEAD - viewModel.onAttendanceStatusSelected(BookingAttendanceStatus.CANCELLED) -======= val state = viewModel.state.getOrAwaitValue() - state.onAttendanceStatusSelected(com.woocommerce.android.ui.bookings.compose.AttendanceStatus.CANCELLED) ->>>>>>> a4e6bd3632f (Move onAttendanceStatusSelected to BookingDetailsViewState) + state.onAttendanceStatusSelected(BookingAttendanceStatus.CANCELLED) // Then val updated = viewModel.state.value?.bookingSummary?.attendanceStatus From d6d88ef8946eeeca25ca1ff95f8b07e8a33c69b9 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Thu, 2 Oct 2025 10:06:49 +0200 Subject: [PATCH 08/10] Adjust the spacing beteew two buttons in the booking payment section --- .../android/ui/bookings/compose/BookingPaymentSection.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt index 7e9cd7ac5821..f09f0d44df7b 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt @@ -5,7 +5,9 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.HorizontalDivider @@ -36,7 +38,6 @@ fun BookingPaymentSection( BookingSectionHeader(R.string.booking_payment_header) HorizontalDivider(thickness = 0.5.dp) Column( - verticalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier .background(color = MaterialTheme.colorScheme.surfaceContainer) .padding(vertical = 16.dp) @@ -52,10 +53,12 @@ fun BookingPaymentSection( PaymentRow(label = R.string.discount, value = model.discount) PaymentRow(label = R.string.total, value = model.total, fontWeight = FontWeight.Medium) } + Spacer(modifier = Modifier.height(16.dp)) HorizontalDivider( thickness = 0.5.dp, modifier = Modifier.padding(start = 16.dp) ) + Spacer(modifier = Modifier.height(16.dp)) if (status == BookingStatus.Paid) { WCOutlinedButton( onClick = onMarkAsRefunded, @@ -76,6 +79,7 @@ fun BookingPaymentSection( .padding(horizontal = 16.dp) ) } + Spacer(modifier = Modifier.height(8.dp)) WCOutlinedButton( onClick = onViewOrder, colors = ButtonDefaults.outlinedButtonColors( From 174a412322b0b178b0b741b6966329e769673b05 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Thu, 2 Oct 2025 10:25:06 +0200 Subject: [PATCH 09/10] Rename the `Mark as refunded` button to `Issue refund` --- .../android/ui/bookings/compose/BookingPaymentSection.kt | 3 ++- WooCommerce/src/main/res/values/strings.xml | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt index f09f0d44df7b..499950de8ba9 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/compose/BookingPaymentSection.kt @@ -59,13 +59,14 @@ fun BookingPaymentSection( modifier = Modifier.padding(start = 16.dp) ) Spacer(modifier = Modifier.height(16.dp)) + // TODO Change the logic and use Order info when available if (status == BookingStatus.Paid) { WCOutlinedButton( onClick = onMarkAsRefunded, colors = ButtonDefaults.outlinedButtonColors( contentColor = MaterialTheme.colorScheme.onSurface ), - text = stringResource(id = R.string.booking_payment_mark_as_refunded), + text = stringResource(id = R.string.orderdetail_issue_refund_button), modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp) diff --git a/WooCommerce/src/main/res/values/strings.xml b/WooCommerce/src/main/res/values/strings.xml index 4fd0ec8f038e..02d6a3611695 100644 --- a/WooCommerce/src/main/res/values/strings.xml +++ b/WooCommerce/src/main/res/values/strings.xml @@ -4899,6 +4899,5 @@ Service Mark as paid View order - Mark as refunded From d82dc68b2b99fa3124ec3efc2dffb74065236b88 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Thu, 2 Oct 2025 10:29:18 +0200 Subject: [PATCH 10/10] Use temporary action for payment section buttons --- .../bookings/details/BookingDetailsScreen.kt | 4 ++-- .../details/BookingDetailsViewModel.kt | 19 ------------------- .../details/BookingDetailsViewState.kt | 2 -- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt index 46c67a44ea51..0a5383b4884f 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsScreen.kt @@ -99,9 +99,9 @@ fun BookingDetailsScreen( BookingPaymentSection( model = viewState.bookingPaymentDetails, status = viewState.bookingSummary.status, - onMarkAsPaid = viewState.onMarkAsPaid, + onMarkAsPaid = { onViewOrder(viewState.orderId) }, onViewOrder = { onViewOrder(viewState.orderId) }, - onMarkAsRefunded = viewState.onMarkAsRefunded, + onMarkAsRefunded = { onViewOrder(viewState.orderId) }, modifier = Modifier.fillMaxWidth() ) } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt index 2ae713b32aab..e4ccaba1e0e6 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewModel.kt @@ -5,7 +5,6 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.asLiveData import com.woocommerce.android.R import com.woocommerce.android.ui.bookings.compose.BookingAttendanceStatus -import com.woocommerce.android.ui.bookings.compose.BookingStatus import com.woocommerce.android.viewmodel.ResourceProvider import com.woocommerce.android.viewmodel.ScopedViewModel import com.woocommerce.android.viewmodel.navArgs @@ -24,8 +23,6 @@ class BookingDetailsViewModel @Inject constructor( private val _state = MutableStateFlow( BookingDetailsViewState( - onMarkAsPaid = ::onMarkAsPaid, - onMarkAsRefunded = ::onMarkAsRefunded, onCancelBooking = ::onCancelBooking, onAttendanceStatusSelected = ::onAttendanceStatusSelected, ) @@ -48,22 +45,6 @@ class BookingDetailsViewModel @Inject constructor( } } - private fun onMarkAsPaid() { - _state.update { current -> - current.copy( - bookingSummary = current.bookingSummary.copy(status = BookingStatus.Paid) - ) - } - } - - private fun onMarkAsRefunded() { - _state.update { current -> - current.copy( - bookingSummary = current.bookingSummary.copy(status = BookingStatus.Unpaid) - ) - } - } - private fun onCancelBooking() { // TODO Add logic to Cancel booking } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt index e4b40a1387f5..dab64306c79e 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/details/BookingDetailsViewState.kt @@ -41,8 +41,6 @@ data class BookingDetailsViewState( discount = "-", total = "$59.50" ), - val onMarkAsPaid: () -> Unit = {}, - val onMarkAsRefunded: () -> Unit = {}, val onCancelBooking: () -> Unit = {}, val onAttendanceStatusSelected: (BookingAttendanceStatus) -> Unit = { _ -> } )