From 5e03f8935c25e4b6d6bdf19beb2c1bb7ae624bed Mon Sep 17 00:00:00 2001 From: Sarah Badr <92681618+sarahbadr17@users.noreply.github.com> Date: Tue, 28 May 2024 23:07:12 +0200 Subject: [PATCH] feat: correctly modify the status of receipt when editing, creating and deleting --- .../screens/BalanceDetailedScreenTest.kt | 41 +++++++++++ .../balance/BalanceDetailedViewModel.kt | 70 +++++++++++++------ .../accounting/balance/BalancePopUpScreen.kt | 6 +- 3 files changed, 92 insertions(+), 25 deletions(-) diff --git a/app/src/androidTest/java/com/github/se/assocify/screens/BalanceDetailedScreenTest.kt b/app/src/androidTest/java/com/github/se/assocify/screens/BalanceDetailedScreenTest.kt index 702fa8931..1abeda74d 100644 --- a/app/src/androidTest/java/com/github/se/assocify/screens/BalanceDetailedScreenTest.kt +++ b/app/src/androidTest/java/com/github/se/assocify/screens/BalanceDetailedScreenTest.kt @@ -1,7 +1,9 @@ package com.github.se.assocify.screens import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsEnabled import androidx.compose.ui.test.assertIsNotDisplayed +import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.assertTextContains import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.junit4.createComposeRule @@ -185,6 +187,8 @@ class BalanceDetailedScreenTest : val onSuccessCallback = firstArg<(List) -> Unit>() onSuccessCallback(receiptList) } + + every { uploadReceipt(any(), any(), any(), any()) } answers {} } lateinit var budgetDetailedViewModel: BudgetDetailedViewModel @@ -561,4 +565,41 @@ class BalanceDetailedScreenTest : onNodeWithText("lots of money").assertIsDisplayed() } } + + /** Tests what happens when you select or not a receipt */ + @Test + fun testReceiptAmountLinkedToBalanceAmount() { + with(composeTestRule) { + onNodeWithTag("createNewItem").performClick() + onNodeWithTag("receiptDropdown").assertIsDisplayed() + // select the receipt r1 + onNodeWithTag("receiptDropdown").performClick() + onNodeWithText("r1").performClick() + onNodeWithTag("editAmount").assertIsNotEnabled() + onNodeWithText("0.28").assertIsDisplayed() // the amount of r1 + assert(!balanceDetailedViewModel.uiState.value.noReceiptSelected) + + // select no receipt + onNodeWithTag("receiptDropdown").performClick() + onNodeWithText("No receipt").performClick() + assert(balanceDetailedViewModel.uiState.value.noReceiptSelected) + onNodeWithTag("editAmount").assertIsEnabled().performTextInput("500") + } + } + + /** Tests that status of the receipt is correctly changed */ + @Test + fun testReceiptStatusLinkedToBalanceStatus() { + with(composeTestRule) { + onNodeWithTag("createNewItem").performClick() + onNodeWithTag("receiptDropdown").assertIsDisplayed() + // select the receipt r1 + onNodeWithTag("receiptDropdown").performClick() + onNodeWithText("r1").performClick() + onNodeWithTag("editDialogColumn").performScrollToNode(hasTestTag("editConfirmButton")) + onNodeWithTag("editStatusDropdown").performClick() + onNodeWithText("Approved").performClick() + onNodeWithTag("editConfirmButton").performClick() + } + } } diff --git a/app/src/main/java/com/github/se/assocify/ui/screens/treasury/accounting/balance/BalanceDetailedViewModel.kt b/app/src/main/java/com/github/se/assocify/ui/screens/treasury/accounting/balance/BalanceDetailedViewModel.kt index e88f1e862..b1fe48d51 100644 --- a/app/src/main/java/com/github/se/assocify/ui/screens/treasury/accounting/balance/BalanceDetailedViewModel.kt +++ b/app/src/main/java/com/github/se/assocify/ui/screens/treasury/accounting/balance/BalanceDetailedViewModel.kt @@ -1,5 +1,6 @@ package com.github.se.assocify.ui.screens.treasury.accounting.balance +import android.util.Log import androidx.compose.material3.SnackbarHostState import androidx.lifecycle.ViewModel import com.github.se.assocify.model.CurrentUser @@ -234,28 +235,7 @@ class BalanceDetailedViewModel( // update the status of the receipt val receipt = _uiState.value.receiptList.find { it.uid == balanceItem.receiptUID } if (receipt != null && receipt.status != balanceItem.status) { - receiptAPI.uploadReceipt( - receipt.copy(status = balanceItem.status), - {}, - { - _uiState.value = - _uiState.value.copy( - receiptList = - _uiState.value.receiptList.map { - if (it.uid == receipt.uid) receipt.copy(status = balanceItem.status) - else it - }) - }, - { receiptFail, _ -> - if (receiptFail) { - CoroutineScope(Dispatchers.Main).launch { - _uiState.value.snackbarState.showSnackbar( - message = "Failed to save status of the receipt", - actionLabel = "Retry", - ) - } - } - }) + modifyReceiptStatus(receipt, balanceItem.status) } balanceApi.updateBalance( @@ -285,6 +265,13 @@ class BalanceDetailedViewModel( } fun deleteBalanceItem(balanceItemUid: String) { + // before deleting, put the status of receipt to pending + val balanceItem = _uiState.value.balanceList.find { it.uid == balanceItemUid } ?: return + val receipt = _uiState.value.receiptList.find { it.uid == balanceItem.receiptUID } + if (receipt != null) { + modifyReceiptStatus(receipt, Status.Pending) + } + balanceApi.deleteBalance( balanceItemUid, { @@ -318,6 +305,12 @@ class BalanceDetailedViewModel( _uiState.value.errorDate != null) { return } + // update the status of the receipt + val receipt = _uiState.value.receiptList.find { it.uid == balanceItem.receiptUID } + if (receipt != null && receipt.status != balanceItem.status) { + modifyReceiptStatus(receipt, balanceItem.status) + } + balanceApi.addBalance( CurrentUser.associationUid!!, balanceItem.subcategoryUID, @@ -416,6 +409,39 @@ class BalanceDetailedViewModel( fun noReceiptSelected(selected: Boolean) { _uiState.value = _uiState.value.copy(noReceiptSelected = selected) } + + /** + * Modify the status receipt + * + * @param receipt the receipt to modify + * @param status the new status of the receipt + */ + fun modifyReceiptStatus(receipt: Receipt, status: Status) { + receiptAPI.uploadReceipt( + receipt.copy(status = status), + {}, + { + _uiState.value = + _uiState.value.copy( + receiptList = + _uiState.value.receiptList.map { + if (it.uid == receipt.uid) { + receipt.copy(status = status) + } else it + }) + Log.d("Receipt", "Receipt status updated") + }, + { receiptFail, _ -> + if (receiptFail) { + CoroutineScope(Dispatchers.Main).launch { + _uiState.value.snackbarState.showSnackbar( + message = "Failed to save status of the receipt", + actionLabel = "Retry", + ) + } + } + }) + } } /** diff --git a/app/src/main/java/com/github/se/assocify/ui/screens/treasury/accounting/balance/BalancePopUpScreen.kt b/app/src/main/java/com/github/se/assocify/ui/screens/treasury/accounting/balance/BalancePopUpScreen.kt index 173fe6055..ed5f2c2cf 100644 --- a/app/src/main/java/com/github/se/assocify/ui/screens/treasury/accounting/balance/BalancePopUpScreen.kt +++ b/app/src/main/java/com/github/se/assocify/ui/screens/treasury/accounting/balance/BalancePopUpScreen.kt @@ -180,7 +180,7 @@ fun BalancePopUpScreen(balanceDetailedViewModel: BalanceDetailedViewModel) { OutlinedTextField( singleLine = true, isError = balanceModel.errorAmount != null, - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(8.dp).testTag("editAmount"), value = amountString, onValueChange = { if (receiptUid == "") { @@ -202,7 +202,7 @@ fun BalancePopUpScreen(balanceDetailedViewModel: BalanceDetailedViewModel) { ExposedDropdownMenuBox( expanded = balanceTvaExpanded, onExpandedChange = { balanceTvaExpanded = !balanceTvaExpanded }, - modifier = Modifier.testTag("categoryDropdown").padding(8.dp)) { + modifier = Modifier.testTag("editTVADropdown").padding(8.dp)) { OutlinedTextField( value = "$tvaString%", onValueChange = {}, @@ -280,7 +280,7 @@ fun BalancePopUpScreen(balanceDetailedViewModel: BalanceDetailedViewModel) { ExposedDropdownMenuBox( expanded = statusExpanded, onExpandedChange = { statusExpanded = !statusExpanded }, - modifier = Modifier.testTag("categoryDropdown").padding(8.dp)) { + modifier = Modifier.testTag("editStatusDropdown").padding(8.dp)) { OutlinedTextField( value = mutableStatus.name, onValueChange = {},