From ead08c6deb6cd2ee7fbed1001324a073e0e2033b Mon Sep 17 00:00:00 2001 From: Rooney Date: Wed, 15 May 2024 17:12:35 -0400 Subject: [PATCH 01/22] Title --- .../ChangeDueCalculatorFragment.kt | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index 832ccaa33e6..d488c2f42c2 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.MaterialTheme import androidx.compose.material.Text @@ -17,6 +18,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.fragment.app.DialogFragment import androidx.fragment.app.viewModels @@ -44,26 +46,30 @@ class ChangeDueCalculatorFragment : DialogFragment() { modifier = Modifier .fillMaxSize() .padding(16.dp), - verticalArrangement = Arrangement.Center, + verticalArrangement = Arrangement.Top, horizontalAlignment = Alignment.CenterHorizontally ) { - // Display dynamic content based on UI state when (uiState) { is ChangeDueCalculatorViewModel.UiState.Loading -> { - Text(text = stringResource(R.string.loading), style = MaterialTheme.typography.h5) + Text(text = stringResource(R.string.loading), style = MaterialTheme.typography.h6) } - is ChangeDueCalculatorViewModel.UiState.Success -> { val state = uiState as ChangeDueCalculatorViewModel.UiState.Success Text( text = stringResource(R.string.cash_payments_take_payment_title, state.amountDue), - style = MaterialTheme.typography.h5, - modifier = Modifier.padding(bottom = 16.dp) + style = MaterialTheme.typography.h4, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.dp), + textAlign = TextAlign.Center + ) + Text( + text = "TODO...", + style = MaterialTheme.typography.body1 ) } - is ChangeDueCalculatorViewModel.UiState.Error -> { - Text(text = stringResource(R.string.error_generic), style = MaterialTheme.typography.h5) + Text(text = stringResource(R.string.error_generic), style = MaterialTheme.typography.h6) } } } From ad2f326462a6bd7163d07294783984818b2f2122 Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 14:28:28 -0400 Subject: [PATCH 02/22] Base fragment with title bar --- .../ChangeDueCalculatorFragment.kt | 75 +++++++++++-------- 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index d488c2f42c2..f37c5e03d2e 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -7,10 +7,12 @@ import android.view.ViewGroup import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.MaterialTheme +import androidx.compose.material.Scaffold import androidx.compose.material.Text +import androidx.compose.material.TopAppBar +import androidx.compose.material.primarySurface import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -18,15 +20,14 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.fragment.app.DialogFragment import androidx.fragment.app.viewModels import com.woocommerce.android.R +import com.woocommerce.android.ui.base.BaseFragment import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint -class ChangeDueCalculatorFragment : DialogFragment() { +class ChangeDueCalculatorFragment : BaseFragment() { private val viewModel: ChangeDueCalculatorViewModel by viewModels() @@ -42,36 +43,48 @@ class ChangeDueCalculatorFragment : DialogFragment() { fun ChangeDueCalculatorScreen() { val uiState by viewModel.uiState.collectAsState() - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp), - verticalArrangement = Arrangement.Top, - horizontalAlignment = Alignment.CenterHorizontally - ) { - when (uiState) { - is ChangeDueCalculatorViewModel.UiState.Loading -> { - Text(text = stringResource(R.string.loading), style = MaterialTheme.typography.h6) + Scaffold( + topBar = { + when (uiState) { + is ChangeDueCalculatorViewModel.UiState.Success -> { + val successState = uiState as ChangeDueCalculatorViewModel.UiState.Success + TopAppBar( + title = { + Text(text = stringResource(R.string.cash_payments_take_payment_title, successState.amountDue)) + }, + backgroundColor = MaterialTheme.colors.primarySurface + ) + } + else -> { + TopAppBar( + title = { Text(text = stringResource(id = R.string.cash_payments_take_payment_title)) }, + backgroundColor = MaterialTheme.colors.primarySurface + ) + } } - is ChangeDueCalculatorViewModel.UiState.Success -> { - val state = uiState as ChangeDueCalculatorViewModel.UiState.Success - Text( - text = stringResource(R.string.cash_payments_take_payment_title, state.amountDue), - style = MaterialTheme.typography.h4, - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 8.dp), - textAlign = TextAlign.Center - ) - Text( - text = "TODO...", - style = MaterialTheme.typography.body1 - ) - } - is ChangeDueCalculatorViewModel.UiState.Error -> { - Text(text = stringResource(R.string.error_generic), style = MaterialTheme.typography.h6) + } + ) { paddingValues -> + Column( + modifier = Modifier + .padding(paddingValues) + .fillMaxSize() + .padding(16.dp), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.CenterHorizontally + ) { + when (uiState) { + is ChangeDueCalculatorViewModel.UiState.Loading -> { + Text(text = stringResource(R.string.loading), style = MaterialTheme.typography.h6) + } + is ChangeDueCalculatorViewModel.UiState.Success -> { + Text("TODO...", style = MaterialTheme.typography.body1) + } + is ChangeDueCalculatorViewModel.UiState.Error -> { + Text(text = stringResource(R.string.error_generic), style = MaterialTheme.typography.h6) + } } } } } } + From 27a04ed64410cb6a2d906e9d1425660db3e1a7c7 Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 14:43:47 -0400 Subject: [PATCH 03/22] Add back button --- .../ChangeDueCalculatorFragment.kt | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index f37c5e03d2e..c28a43cd9db 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -6,22 +6,30 @@ import android.view.View import android.view.ViewGroup import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.material.Icon +import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold import androidx.compose.material.Text import androidx.compose.material.TopAppBar -import androidx.compose.material.primarySurface +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.fragment.app.viewModels +import androidx.navigation.fragment.findNavController import com.woocommerce.android.R import com.woocommerce.android.ui.base.BaseFragment import dagger.hilt.android.AndroidEntryPoint @@ -50,15 +58,30 @@ class ChangeDueCalculatorFragment : BaseFragment() { val successState = uiState as ChangeDueCalculatorViewModel.UiState.Success TopAppBar( title = { - Text(text = stringResource(R.string.cash_payments_take_payment_title, successState.amountDue)) + Text( + text = stringResource( + R.string.cash_payments_take_payment_title, + successState.amountDue + ), + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center + ) }, - backgroundColor = MaterialTheme.colors.primarySurface + backgroundColor = Color.White, // Set the background color to white + navigationIcon = { + IconButton(onClick = { findNavController().navigateUp() }) { + Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back") + } + }, + actions = { + // Keep an empty action to center the title text + Spacer(modifier = Modifier.weight(1f)) + } ) } else -> { TopAppBar( title = { Text(text = stringResource(id = R.string.cash_payments_take_payment_title)) }, - backgroundColor = MaterialTheme.colors.primarySurface ) } } @@ -87,4 +110,3 @@ class ChangeDueCalculatorFragment : BaseFragment() { } } } - From b0c1b3427964e8bf78c95377f0c7e084c23cd27b Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 14:50:33 -0400 Subject: [PATCH 04/22] Detekt --- .../ChangeDueCalculatorFragment.kt | 65 ++++++++++--------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index c28a43cd9db..5b5d149efb6 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -53,38 +53,41 @@ class ChangeDueCalculatorFragment : BaseFragment() { Scaffold( topBar = { - when (uiState) { - is ChangeDueCalculatorViewModel.UiState.Success -> { - val successState = uiState as ChangeDueCalculatorViewModel.UiState.Success - TopAppBar( - title = { - Text( - text = stringResource( - R.string.cash_payments_take_payment_title, - successState.amountDue - ), - modifier = Modifier.fillMaxWidth(), - textAlign = TextAlign.Center - ) - }, - backgroundColor = Color.White, // Set the background color to white - navigationIcon = { - IconButton(onClick = { findNavController().navigateUp() }) { - Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back") - } - }, - actions = { - // Keep an empty action to center the title text - Spacer(modifier = Modifier.weight(1f)) - } - ) + TopAppBar( + backgroundColor = Color.White, + navigationIcon = { + // Back button + IconButton(onClick = { findNavController().navigateUp() }) { + Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back") + } + }, + title = { + // Adjust text based on state within the AppBar directly + if (uiState is ChangeDueCalculatorViewModel.UiState.Success) { + val successState = uiState as ChangeDueCalculatorViewModel.UiState.Success + Text( + text = stringResource( + R.string.cash_payments_take_payment_title, + successState.amountDue + ), + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center + ) + } else { + Text( + text = stringResource(id = R.string.cash_payments_take_payment_title), + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center + ) + } + }, + actions = { + // This is required to center the title when there are no actual actions + if (uiState !is ChangeDueCalculatorViewModel.UiState.Success) { + Spacer(modifier = Modifier.weight(1f)) + } } - else -> { - TopAppBar( - title = { Text(text = stringResource(id = R.string.cash_payments_take_payment_title)) }, - ) - } - } + ) } ) { paddingValues -> Column( From 082ec61535f30ade87b0a95fedc7a2a401dc597f Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 14:53:48 -0400 Subject: [PATCH 05/22] Remove comments --- .../ui/payments/methodselection/ChangeDueCalculatorFragment.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index 5b5d149efb6..207f3fcd95e 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -56,13 +56,11 @@ class ChangeDueCalculatorFragment : BaseFragment() { TopAppBar( backgroundColor = Color.White, navigationIcon = { - // Back button IconButton(onClick = { findNavController().navigateUp() }) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back") } }, title = { - // Adjust text based on state within the AppBar directly if (uiState is ChangeDueCalculatorViewModel.UiState.Success) { val successState = uiState as ChangeDueCalculatorViewModel.UiState.Success Text( @@ -82,7 +80,6 @@ class ChangeDueCalculatorFragment : BaseFragment() { } }, actions = { - // This is required to center the title when there are no actual actions if (uiState !is ChangeDueCalculatorViewModel.UiState.Success) { Spacer(modifier = Modifier.weight(1f)) } From 5d5f917cf6a320ff5284f69527c87784aaa5bef5 Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 15:08:11 -0400 Subject: [PATCH 06/22] Background color --- .../ui/payments/methodselection/ChangeDueCalculatorFragment.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index 207f3fcd95e..b51fce9e075 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -25,6 +25,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @@ -54,7 +55,7 @@ class ChangeDueCalculatorFragment : BaseFragment() { Scaffold( topBar = { TopAppBar( - backgroundColor = Color.White, + backgroundColor = colorResource(id = R.color.color_toolbar), navigationIcon = { IconButton(onClick = { findNavController().navigateUp() }) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back") From 5fe03fdc8dc00cedf4f895a3d436b94744d1ed3e Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 15:16:15 -0400 Subject: [PATCH 07/22] Left align title --- .../ChangeDueCalculatorFragment.kt | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index b51fce9e075..9255e55e015 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -6,9 +6,7 @@ import android.view.View import android.view.ViewGroup import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.Icon import androidx.compose.material.IconButton @@ -23,11 +21,9 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController @@ -65,25 +61,15 @@ class ChangeDueCalculatorFragment : BaseFragment() { if (uiState is ChangeDueCalculatorViewModel.UiState.Success) { val successState = uiState as ChangeDueCalculatorViewModel.UiState.Success Text( - text = stringResource( - R.string.cash_payments_take_payment_title, - successState.amountDue - ), - modifier = Modifier.fillMaxWidth(), - textAlign = TextAlign.Center + text = stringResource(R.string.cash_payments_take_payment_title, successState.amountDue), + modifier = Modifier.padding(start = 16.dp) ) } else { Text( text = stringResource(id = R.string.cash_payments_take_payment_title), - modifier = Modifier.fillMaxWidth(), - textAlign = TextAlign.Center + modifier = Modifier.padding(start = 16.dp) ) } - }, - actions = { - if (uiState !is ChangeDueCalculatorViewModel.UiState.Success) { - Spacer(modifier = Modifier.weight(1f)) - } } ) } From a649a1b37589b5bad05b982459a19a80cd8ea483 Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 15:16:36 -0400 Subject: [PATCH 08/22] Detekt --- .../payments/methodselection/ChangeDueCalculatorFragment.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index 9255e55e015..c2222543a8e 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -61,7 +61,10 @@ class ChangeDueCalculatorFragment : BaseFragment() { if (uiState is ChangeDueCalculatorViewModel.UiState.Success) { val successState = uiState as ChangeDueCalculatorViewModel.UiState.Success Text( - text = stringResource(R.string.cash_payments_take_payment_title, successState.amountDue), + text = stringResource( + R.string.cash_payments_take_payment_title, + successState.amountDue + ), modifier = Modifier.padding(start = 16.dp) ) } else { From a5c184b35e2313419d35d96d01e679b62bcb1cfb Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 15:24:56 -0400 Subject: [PATCH 09/22] Format order total --- .../ChangeDueCalculatorViewModel.kt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModel.kt index bf441e9620d..ac2da99205d 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModel.kt @@ -1,18 +1,24 @@ package com.woocommerce.android.ui.payments.methodselection import androidx.lifecycle.SavedStateHandle +import com.woocommerce.android.tools.SelectedSite import com.woocommerce.android.ui.orders.details.OrderDetailRepository +import com.woocommerce.android.util.CurrencyFormatter import com.woocommerce.android.viewmodel.ScopedViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch +import org.wordpress.android.fluxc.store.WooCommerceStore import java.math.BigDecimal import javax.inject.Inject @HiltViewModel class ChangeDueCalculatorViewModel @Inject constructor( + private val selectedSite: SelectedSite, + private val currencyFormatter: CurrencyFormatter, savedStateHandle: SavedStateHandle, + private val wooCommerceStore: WooCommerceStore, private val orderDetailRepository: OrderDetailRepository ) : ScopedViewModel(savedStateHandle) { @@ -21,7 +27,7 @@ class ChangeDueCalculatorViewModel @Inject constructor( sealed class UiState { data object Loading : UiState() - data class Success(val amountDue: BigDecimal, val change: BigDecimal) : UiState() + data class Success(val amountDue: String, val change: BigDecimal) : UiState() data object Error : UiState() } @@ -35,7 +41,12 @@ class ChangeDueCalculatorViewModel @Inject constructor( private fun loadOrderDetails() { launch { val order = orderDetailRepository.getOrderById(orderId)!! - _uiState.value = UiState.Success(amountDue = order.total, 0.00.toBigDecimal()) + _uiState.value = UiState.Success(amountDue = formatOrderTotal(order.total), 0.00.toBigDecimal()) } } + + private fun formatOrderTotal(total: BigDecimal): String { + val currencyCode = wooCommerceStore.getSiteSettings(selectedSite.get())?.currencyCode ?: "" + return currencyFormatter.formatCurrency(total, currencyCode) + } } From ca20407e951b08c44c37be212ea9122dfe94f529 Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 15:53:45 -0400 Subject: [PATCH 10/22] Test success class --- .../ChangeDueCalculatorViewModelTest.kt | 95 +++++++++++++++++-- 1 file changed, 86 insertions(+), 9 deletions(-) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt index 9f0fca75621..911c515148c 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt @@ -1,33 +1,110 @@ package com.woocommerce.android.ui.payments.methodselection +import androidx.lifecycle.SavedStateHandle +import com.woocommerce.android.model.Order +import com.woocommerce.android.tools.NetworkStatus +import com.woocommerce.android.tools.SelectedSite +import com.woocommerce.android.ui.orders.details.OrderDetailRepository +import com.woocommerce.android.util.CurrencyFormatter import com.woocommerce.android.viewmodel.BaseUnitTest import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runBlockingTest +import org.junit.Before import org.junit.Test +import org.mockito.kotlin.any +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever +import org.wordpress.android.fluxc.model.OrderEntity +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.fluxc.store.WCOrderStore +import org.wordpress.android.fluxc.store.WooCommerceStore +import java.math.BigDecimal +import kotlin.test.assertEquals + +private const val PAYMENT_URL = "paymentUrl" +private const val ORDER_TOTAL = "100$" @ExperimentalCoroutinesApi class ChangeDueCalculatorViewModelTest : BaseUnitTest() { + + private val site: SiteModel = mock { + on { name }.thenReturn("siteName") + } + private val order: Order = mock { + on { paymentUrl }.thenReturn(PAYMENT_URL) + on { total }.thenReturn(BigDecimal(1L)) + on { id }.thenReturn(1L) + on { currency }.thenReturn("USD") + } + private val orderEntity: OrderEntity = mock() + + private val selectedSite: SelectedSite = mock { + on { get() }.thenReturn(site) + } + private val orderStore: WCOrderStore = mock { + onBlocking { getOrderByIdAndSite(any(), any()) }.thenReturn(orderEntity) + on { getOrderStatusForSiteAndKey(any(), any()) }.thenReturn(mock()) + } + private val networkStatus: NetworkStatus = mock() + private val currencyFormatter: CurrencyFormatter = mock { + on { formatCurrency(any(), any(), any()) }.thenReturn(ORDER_TOTAL) + } + private val wooCommerceStore: WooCommerceStore = mock { + on { getSiteSettings(site) }.thenReturn(mock()) + } + + private val orderDetailRepository: OrderDetailRepository = mock() + + private val savedStateHandle: SavedStateHandle = mock() + + + private lateinit var viewModel: ChangeDueCalculatorViewModel + + @Before + fun setup() { + viewModel = initViewModel() + + } + @Test - fun `given valid order id, when order details are requested, then success state is emitted`() = testBlocking { + fun `given valid order details, when order details are requested, then success state is emitted`() = runBlockingTest { // GIVEN - // TODO val viewModel: ChangeDueCalculatorViewModel = mock() - // TODO + val expectedAmountDue = "100.00" + val expectedChange = BigDecimal("20.00") + whenever(orderDetailRepository.getOrderById(1)).thenReturn(order) // WHEN - // TODO + //viewModel.fetchOrderDetails() // Your actual function call to load the data + viewModel = initViewModel() // THEN - // TODO + val uiState = viewModel.uiState.value // Assuming uiState is how the ViewModel exposes the current state + assert(uiState is ChangeDueCalculatorViewModel.UiState.Success) + uiState as ChangeDueCalculatorViewModel.UiState.Success + assertEquals(expectedAmountDue, uiState.amountDue) + assertEquals(expectedChange, uiState.change) } @Test - fun `given order details retrieval failure, when order details are loaded, then error state is emitted`() = testBlocking { + fun `given order details retrieval failure, when order details are loaded, then error state is emitted`() = runBlockingTest { // GIVEN - // TODO val viewModel: ChangeDueCalculatorViewModel = mock() + //whenever(repository.getOrderDetails()).thenThrow(RuntimeException("Error fetching order details")) // WHEN - // TODO + //viewModel.fetchOrderDetails() // THEN - // TODO assertThat(viewModel.uiState.value).isEqualTo(ChangeDueCalculatorViewModel.UiState.Error) + //val uiState = viewModel.uiState.value + //assert(uiState is ChangeDueCalculatorViewModel.UiState.Error) + } + + private fun initViewModel(): ChangeDueCalculatorViewModel { + return ChangeDueCalculatorViewModel( + selectedSite, + currencyFormatter, + savedStateHandle, + wooCommerceStore, + orderDetailRepository + ) } } From 43a4af9d3140db537c9bcac2c966c6cf38a19fd2 Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 15:54:46 -0400 Subject: [PATCH 11/22] Detekt --- .../ChangeDueCalculatorViewModelTest.kt | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt index 911c515148c..25b0fc5cfc3 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt @@ -2,7 +2,6 @@ package com.woocommerce.android.ui.payments.methodselection import androidx.lifecycle.SavedStateHandle import com.woocommerce.android.model.Order -import com.woocommerce.android.tools.NetworkStatus import com.woocommerce.android.tools.SelectedSite import com.woocommerce.android.ui.orders.details.OrderDetailRepository import com.woocommerce.android.util.CurrencyFormatter @@ -14,9 +13,7 @@ import org.junit.Test import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.whenever -import org.wordpress.android.fluxc.model.OrderEntity import org.wordpress.android.fluxc.model.SiteModel -import org.wordpress.android.fluxc.store.WCOrderStore import org.wordpress.android.fluxc.store.WooCommerceStore import java.math.BigDecimal import kotlin.test.assertEquals @@ -36,16 +33,10 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { on { id }.thenReturn(1L) on { currency }.thenReturn("USD") } - private val orderEntity: OrderEntity = mock() private val selectedSite: SelectedSite = mock { on { get() }.thenReturn(site) } - private val orderStore: WCOrderStore = mock { - onBlocking { getOrderByIdAndSite(any(), any()) }.thenReturn(orderEntity) - on { getOrderStatusForSiteAndKey(any(), any()) }.thenReturn(mock()) - } - private val networkStatus: NetworkStatus = mock() private val currencyFormatter: CurrencyFormatter = mock { on { formatCurrency(any(), any(), any()) }.thenReturn(ORDER_TOTAL) } @@ -57,13 +48,11 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { private val savedStateHandle: SavedStateHandle = mock() - private lateinit var viewModel: ChangeDueCalculatorViewModel @Before fun setup() { viewModel = initViewModel() - } @Test @@ -74,11 +63,11 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { whenever(orderDetailRepository.getOrderById(1)).thenReturn(order) // WHEN - //viewModel.fetchOrderDetails() // Your actual function call to load the data + // viewModel.fetchOrderDetails() viewModel = initViewModel() // THEN - val uiState = viewModel.uiState.value // Assuming uiState is how the ViewModel exposes the current state + val uiState = viewModel.uiState.value assert(uiState is ChangeDueCalculatorViewModel.UiState.Success) uiState as ChangeDueCalculatorViewModel.UiState.Success assertEquals(expectedAmountDue, uiState.amountDue) @@ -88,14 +77,14 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { @Test fun `given order details retrieval failure, when order details are loaded, then error state is emitted`() = runBlockingTest { // GIVEN - //whenever(repository.getOrderDetails()).thenThrow(RuntimeException("Error fetching order details")) + // whenever(repository.getOrderDetails()).thenThrow(RuntimeException("Error fetching order details")) // WHEN - //viewModel.fetchOrderDetails() + // viewModel.fetchOrderDetails() // THEN - //val uiState = viewModel.uiState.value - //assert(uiState is ChangeDueCalculatorViewModel.UiState.Error) + // val uiState = viewModel.uiState.value + // assert(uiState is ChangeDueCalculatorViewModel.UiState.Error) } private fun initViewModel(): ChangeDueCalculatorViewModel { From e1cc2a625e983cd4521f1126c1ee38b44092d4f4 Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 15:56:30 -0400 Subject: [PATCH 12/22] Detekt --- .../methodselection/ChangeDueCalculatorViewModelTest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt index 25b0fc5cfc3..01c35014869 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt @@ -7,7 +7,7 @@ import com.woocommerce.android.ui.orders.details.OrderDetailRepository import com.woocommerce.android.util.CurrencyFormatter import com.woocommerce.android.viewmodel.BaseUnitTest import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest +import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.mockito.kotlin.any @@ -56,7 +56,7 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { } @Test - fun `given valid order details, when order details are requested, then success state is emitted`() = runBlockingTest { + fun `given valid order details, when order details are requested, then success state is emitted`() = runTest { // GIVEN val expectedAmountDue = "100.00" val expectedChange = BigDecimal("20.00") @@ -75,7 +75,7 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { } @Test - fun `given order details retrieval failure, when order details are loaded, then error state is emitted`() = runBlockingTest { + fun `given order details retrieval failure, when order details are loaded, then error state is emitted`() = runTest { // GIVEN // whenever(repository.getOrderDetails()).thenThrow(RuntimeException("Error fetching order details")) From 11d9d067ab29d082ab3f53d5e22d950537768631 Mon Sep 17 00:00:00 2001 From: Rooney Date: Thu, 16 May 2024 16:17:04 -0400 Subject: [PATCH 13/22] Fix my test --- .../ChangeDueCalculatorViewModelTest.kt | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt index 01c35014869..e5e13199e66 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt @@ -18,20 +18,14 @@ import org.wordpress.android.fluxc.store.WooCommerceStore import java.math.BigDecimal import kotlin.test.assertEquals -private const val PAYMENT_URL = "paymentUrl" -private const val ORDER_TOTAL = "100$" +private const val ORDER_TOTAL = "100.00" @ExperimentalCoroutinesApi class ChangeDueCalculatorViewModelTest : BaseUnitTest() { - private val site: SiteModel = mock { - on { name }.thenReturn("siteName") - } + private val site: SiteModel = mock() private val order: Order = mock { - on { paymentUrl }.thenReturn(PAYMENT_URL) on { total }.thenReturn(BigDecimal(1L)) - on { id }.thenReturn(1L) - on { currency }.thenReturn("USD") } private val selectedSite: SelectedSite = mock { @@ -52,15 +46,16 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { @Before fun setup() { - viewModel = initViewModel() + // TODO } @Test fun `given valid order details, when order details are requested, then success state is emitted`() = runTest { // GIVEN val expectedAmountDue = "100.00" - val expectedChange = BigDecimal("20.00") - whenever(orderDetailRepository.getOrderById(1)).thenReturn(order) + val expectedChange = BigDecimal("0.0") + whenever(orderDetailRepository.getOrderById(1L)).thenReturn(order) + whenever(savedStateHandle.get("orderId")).thenReturn(1L) // WHEN // viewModel.fetchOrderDetails() From 59fe1f8eac920c7ed16a85535747dac84efde803 Mon Sep 17 00:00:00 2001 From: Rooney Date: Fri, 17 May 2024 11:28:01 -0400 Subject: [PATCH 14/22] Back string --- .../methodselection/ChangeDueCalculatorFragment.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index c2222543a8e..90e1f936dff 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -54,7 +54,12 @@ class ChangeDueCalculatorFragment : BaseFragment() { backgroundColor = colorResource(id = R.color.color_toolbar), navigationIcon = { IconButton(onClick = { findNavController().navigateUp() }) { - Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back") + Icon( + Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = stringResource( + R.string.back + ) + ) } }, title = { From 7e05f2771f2ede4149a1b75c6fd70be0fd836c0a Mon Sep 17 00:00:00 2001 From: Rooney Date: Fri, 17 May 2024 14:48:05 -0400 Subject: [PATCH 15/22] Use smart cast --- .../ChangeDueCalculatorFragment.kt | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index 90e1f936dff..0cfb5fcdacd 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -46,7 +46,7 @@ class ChangeDueCalculatorFragment : BaseFragment() { @Composable fun ChangeDueCalculatorScreen() { - val uiState by viewModel.uiState.collectAsState() + val uiState = viewModel.uiState.collectAsState().value Scaffold( topBar = { @@ -63,21 +63,16 @@ class ChangeDueCalculatorFragment : BaseFragment() { } }, title = { - if (uiState is ChangeDueCalculatorViewModel.UiState.Success) { - val successState = uiState as ChangeDueCalculatorViewModel.UiState.Success - Text( - text = stringResource( + val titleText = when (uiState) { + is ChangeDueCalculatorViewModel.UiState.Success -> { + stringResource( R.string.cash_payments_take_payment_title, - successState.amountDue - ), - modifier = Modifier.padding(start = 16.dp) - ) - } else { - Text( - text = stringResource(id = R.string.cash_payments_take_payment_title), - modifier = Modifier.padding(start = 16.dp) - ) + uiState.amountDue + ) + } + else -> stringResource(id = R.string.cash_payments_take_payment_title) } + Text(text = titleText, modifier = Modifier.padding(start = 16.dp)) } ) } From 1e62af0d7a953c871c3bc192fa1f7ce080dddd9a Mon Sep 17 00:00:00 2001 From: Rooney Date: Fri, 17 May 2024 14:51:01 -0400 Subject: [PATCH 16/22] Remove commented out code --- .../methodselection/ChangeDueCalculatorFragment.kt | 1 - .../ChangeDueCalculatorViewModelTest.kt | 13 +++---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index 0cfb5fcdacd..b8e351c108d 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -18,7 +18,6 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt index e5e13199e66..475f2aa58b8 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt @@ -44,11 +44,6 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { private lateinit var viewModel: ChangeDueCalculatorViewModel - @Before - fun setup() { - // TODO - } - @Test fun `given valid order details, when order details are requested, then success state is emitted`() = runTest { // GIVEN @@ -58,7 +53,6 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { whenever(savedStateHandle.get("orderId")).thenReturn(1L) // WHEN - // viewModel.fetchOrderDetails() viewModel = initViewModel() // THEN @@ -72,14 +66,13 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { @Test fun `given order details retrieval failure, when order details are loaded, then error state is emitted`() = runTest { // GIVEN - // whenever(repository.getOrderDetails()).thenThrow(RuntimeException("Error fetching order details")) + // TODO // WHEN - // viewModel.fetchOrderDetails() + // TODO // THEN - // val uiState = viewModel.uiState.value - // assert(uiState is ChangeDueCalculatorViewModel.UiState.Error) + // TODO } private fun initViewModel(): ChangeDueCalculatorViewModel { From d09a6c80d1171b52d1ca5e144e296975414e7c9f Mon Sep 17 00:00:00 2001 From: Rooney Date: Fri, 17 May 2024 14:52:31 -0400 Subject: [PATCH 17/22] Detekt --- .../payments/methodselection/ChangeDueCalculatorViewModelTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt index 475f2aa58b8..d4489b348dd 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt @@ -8,7 +8,6 @@ import com.woocommerce.android.util.CurrencyFormatter import com.woocommerce.android.viewmodel.BaseUnitTest import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest -import org.junit.Before import org.junit.Test import org.mockito.kotlin.any import org.mockito.kotlin.mock From 3275df8c64318d78cf6b35a2bb9646cdecc7920e Mon Sep 17 00:00:00 2001 From: Rooney Date: Fri, 17 May 2024 15:24:59 -0400 Subject: [PATCH 18/22] Create new compose class --- .../ChangeDueCalculatorScreen.kt | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt new file mode 100644 index 00000000000..a09f805ea33 --- /dev/null +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt @@ -0,0 +1,76 @@ +package com.woocommerce.android.ui.payments.methodselection + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Scaffold +import androidx.compose.material.Text +import androidx.compose.material.TopAppBar +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.woocommerce.android.R + +@Composable +fun ChangeDueCalculatorScreen( + uiState: ChangeDueCalculatorViewModel.UiState, + onNavigateUp: () -> Unit +) { + Scaffold( + topBar = { + TopAppBar( + title = { Text(text = getTitleText(uiState)) }, + navigationIcon = { + IconButton(onClick = onNavigateUp) { + Icon( + Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = stringResource(R.string.back) + ) + } + }, + backgroundColor = colorResource(id = R.color.color_toolbar), + ) + } + ) { paddingValues -> + Column( + modifier = Modifier + .padding(paddingValues) + .fillMaxSize() + .padding(16.dp), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.CenterHorizontally + ) { + when (uiState) { + is ChangeDueCalculatorViewModel.UiState.Loading -> Text( + "Loading...", + style = MaterialTheme.typography.h6 + ) + is ChangeDueCalculatorViewModel.UiState.Success -> Text( + "Amount Due: ${uiState.amountDue}", + style = MaterialTheme.typography.body1 + ) + is ChangeDueCalculatorViewModel.UiState.Error -> Text("Error", style = MaterialTheme.typography.h6) + } + } + } +} + +@Composable +private fun getTitleText(uiState: ChangeDueCalculatorViewModel.UiState): String { + return when (uiState) { + is ChangeDueCalculatorViewModel.UiState.Success -> stringResource( + R.string.cash_payments_take_payment_title, + uiState.amountDue + ) + else -> stringResource(id = R.string.cash_payments_take_payment_title) + } +} From 7d6d9e3bdfc247e1372fd3201a42e11ad84aa3c2 Mon Sep 17 00:00:00 2001 From: Rooney Date: Fri, 17 May 2024 15:29:58 -0400 Subject: [PATCH 19/22] Detekt --- .../ChangeDueCalculatorFragment.kt | 79 +------------------ .../ChangeDueCalculatorScreen.kt | 18 ++++- 2 files changed, 18 insertions(+), 79 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt index b8e351c108d..67766074d00 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorFragment.kt @@ -4,29 +4,11 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Scaffold -import androidx.compose.material.Text -import androidx.compose.material.TopAppBar -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier +import androidx.compose.runtime.getValue import androidx.compose.ui.platform.ComposeView -import androidx.compose.ui.res.colorResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController -import com.woocommerce.android.R import com.woocommerce.android.ui.base.BaseFragment import dagger.hilt.android.AndroidEntryPoint @@ -38,63 +20,8 @@ class ChangeDueCalculatorFragment : BaseFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { return ComposeView(requireContext()).apply { setContent { - ChangeDueCalculatorScreen() - } - } - } - - @Composable - fun ChangeDueCalculatorScreen() { - val uiState = viewModel.uiState.collectAsState().value - - Scaffold( - topBar = { - TopAppBar( - backgroundColor = colorResource(id = R.color.color_toolbar), - navigationIcon = { - IconButton(onClick = { findNavController().navigateUp() }) { - Icon( - Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource( - R.string.back - ) - ) - } - }, - title = { - val titleText = when (uiState) { - is ChangeDueCalculatorViewModel.UiState.Success -> { - stringResource( - R.string.cash_payments_take_payment_title, - uiState.amountDue - ) - } - else -> stringResource(id = R.string.cash_payments_take_payment_title) - } - Text(text = titleText, modifier = Modifier.padding(start = 16.dp)) - } - ) - } - ) { paddingValues -> - Column( - modifier = Modifier - .padding(paddingValues) - .fillMaxSize() - .padding(16.dp), - verticalArrangement = Arrangement.Top, - horizontalAlignment = Alignment.CenterHorizontally - ) { - when (uiState) { - is ChangeDueCalculatorViewModel.UiState.Loading -> { - Text(text = stringResource(R.string.loading), style = MaterialTheme.typography.h6) - } - is ChangeDueCalculatorViewModel.UiState.Success -> { - Text("TODO...", style = MaterialTheme.typography.body1) - } - is ChangeDueCalculatorViewModel.UiState.Error -> { - Text(text = stringResource(R.string.error_generic), style = MaterialTheme.typography.h6) - } - } + val uiState by viewModel.uiState.collectAsState() + ChangeDueCalculatorScreen(uiState = uiState, onNavigateUp = { findNavController().navigateUp() }) } } } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt index a09f805ea33..8d12ced2a0f 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt @@ -51,14 +51,25 @@ fun ChangeDueCalculatorScreen( ) { when (uiState) { is ChangeDueCalculatorViewModel.UiState.Loading -> Text( - "Loading...", + stringResource( + R.string.loading, + ), style = MaterialTheme.typography.h6 ) + is ChangeDueCalculatorViewModel.UiState.Success -> Text( - "Amount Due: ${uiState.amountDue}", + stringResource( + R.string.cash_payments_take_payment_title, + uiState.amountDue + ), style = MaterialTheme.typography.body1 ) - is ChangeDueCalculatorViewModel.UiState.Error -> Text("Error", style = MaterialTheme.typography.h6) + + is ChangeDueCalculatorViewModel.UiState.Error -> Text( + stringResource( + R.string.error_generic, + ), style = MaterialTheme.typography.h6 + ) } } } @@ -71,6 +82,7 @@ private fun getTitleText(uiState: ChangeDueCalculatorViewModel.UiState): String R.string.cash_payments_take_payment_title, uiState.amountDue ) + else -> stringResource(id = R.string.cash_payments_take_payment_title) } } From ff6c1cee7f2f40f07546e32df2ddd60ca394297e Mon Sep 17 00:00:00 2001 From: Rooney Date: Fri, 17 May 2024 15:37:12 -0400 Subject: [PATCH 20/22] Update test --- .../payments/methodselection/ChangeDueCalculatorScreen.kt | 3 ++- .../methodselection/ChangeDueCalculatorViewModelTest.kt | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt index 8d12ced2a0f..c724f14bb53 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt @@ -68,7 +68,8 @@ fun ChangeDueCalculatorScreen( is ChangeDueCalculatorViewModel.UiState.Error -> Text( stringResource( R.string.error_generic, - ), style = MaterialTheme.typography.h6 + ), + style = MaterialTheme.typography.h6 ) } } diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt index d4489b348dd..ca344049342 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt @@ -8,6 +8,7 @@ import com.woocommerce.android.util.CurrencyFormatter import com.woocommerce.android.viewmodel.BaseUnitTest import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import org.assertj.core.api.Assertions.assertThat import org.junit.Test import org.mockito.kotlin.any import org.mockito.kotlin.mock @@ -15,7 +16,6 @@ import org.mockito.kotlin.whenever import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.store.WooCommerceStore import java.math.BigDecimal -import kotlin.test.assertEquals private const val ORDER_TOTAL = "100.00" @@ -56,10 +56,10 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { // THEN val uiState = viewModel.uiState.value - assert(uiState is ChangeDueCalculatorViewModel.UiState.Success) + assertThat(uiState).isInstanceOf(ChangeDueCalculatorViewModel.UiState.Success::class.java) uiState as ChangeDueCalculatorViewModel.UiState.Success - assertEquals(expectedAmountDue, uiState.amountDue) - assertEquals(expectedChange, uiState.change) + assertThat(uiState.change).isEqualTo(expectedChange) + assertThat(uiState.amountDue).isEqualTo(expectedAmountDue) } @Test From db640f80e8244520606d8512913998744b4aadac Mon Sep 17 00:00:00 2001 From: Rooney Date: Fri, 17 May 2024 16:05:49 -0400 Subject: [PATCH 21/22] Add compose preview --- .../methodselection/ChangeDueCalculatorScreen.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt index c724f14bb53..e57f5a17280 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp import com.woocommerce.android.R @@ -87,3 +88,15 @@ private fun getTitleText(uiState: ChangeDueCalculatorViewModel.UiState): String else -> stringResource(id = R.string.cash_payments_take_payment_title) } } + +@Composable +@PreviewLightDark() +fun ChangeDueCalculatorScreenSuccessPreview() { + ChangeDueCalculatorScreen( + uiState = ChangeDueCalculatorViewModel.UiState.Success( + amountDue = "$100.00", + change = 0.00.toBigDecimal() + ), + onNavigateUp = {} + ) +} From ab5e7036e03fbfb14eceb1532c930f0e1a1f41e8 Mon Sep 17 00:00:00 2001 From: Rooney Date: Fri, 17 May 2024 16:21:01 -0400 Subject: [PATCH 22/22] Additional test case --- .../ChangeDueCalculatorViewModelTest.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt index ca344049342..9a9903acc18 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/payments/methodselection/ChangeDueCalculatorViewModelTest.kt @@ -43,6 +43,18 @@ class ChangeDueCalculatorViewModelTest : BaseUnitTest() { private lateinit var viewModel: ChangeDueCalculatorViewModel + @Test + fun `when ViewModel is initialized, then initial state is loading`() { + // GIVEN + whenever(savedStateHandle.get("orderId")).thenReturn(1L) + + // WHEN + viewModel = initViewModel() + + // THEN + assertThat(viewModel.uiState.value).isInstanceOf(ChangeDueCalculatorViewModel.UiState.Loading::class.java) + } + @Test fun `given valid order details, when order details are requested, then success state is emitted`() = runTest { // GIVEN