Skip to content

Comments

feat: Add outcome tracking and unify transaction display#20

Merged
ufebri merged 6 commits intomasterfrom
development
Nov 29, 2025
Merged

feat: Add outcome tracking and unify transaction display#20
ufebri merged 6 commits intomasterfrom
development

Conversation

@ufebri
Copy link
Owner

@ufebri ufebri commented Nov 23, 2025

This commit introduces a new feature for tracking outcomes (expenses) and refactors the existing transaction display to create a unified and reusable component structure.

Features

  • Outcome Tracking:
    • UI: Added a new "Outcome" screen accessible from the bottom navigation to display a list of expenses.
    • Data Model: Introduced OutcomeData and related mappers to handle expense information.
    • Use Cases: Implemented use cases for creating, reading, updating, and fetching outcome data (SubmitOutcomeUseCase, ReadOutcomeTransactionUseCase, etc.).
    • ViewModel: Created OutcomeViewModel to manage the state and logic for the outcome screen.

Refactor

  • Unified Entry Components:

    • Renamed HistoryItemCard to EntryItemCard to serve as a generic card for both income (orders) and outcomes.
    • Created EntryItem as a unified data class to represent items in a list, distinguishing between INCOME and OUTCOME types.
    • Introduced DateHeader as a reusable composable for sectioning entries by date.
    • HistoryScreenView and the new OutcomeScreenView now use these shared components (DateHeader, EntryItemCard) for a consistent look and feel.
  • Code Structure and Error Handling:

    • Use Case Segregation: Moved income-related use cases (e.g., GetOrderUseCase, SubmitOrderUseCase) into an income subpackage to separate them from the new outcome use cases.
    • Centralized Error Handling: Created GSheetRepositoryErrorHandling and UseCaseErrorHandling objects to standardize error messages and logic across the data and domain layers.
    • Bottom Navigation: Replaced the "Inventory" tab with "Outcome". The BottomNavItem now uses string resources for titles.
  • CI/CD Enhancements:

    • SonarCloud Integration: Added SonarCloud analysis to the CI pipeline for static code analysis and quality checks.
    • Coveralls: Configured the workflow to upload code coverage reports to Coveralls.
    • Secrets Management: Added SonarCloud secrets to the GitHub Actions workflow.

This commit introduces a new feature for tracking outcomes (expenses) and refactors the existing transaction display to create a unified and reusable component structure.

### Features
- **Outcome Tracking**:
    - **UI**: Added a new "Outcome" screen accessible from the bottom navigation to display a list of expenses.
    - **Data Model**: Introduced `OutcomeData` and related mappers to handle expense information.
    - **Use Cases**: Implemented use cases for creating, reading, updating, and fetching outcome data (`SubmitOutcomeUseCase`, `ReadOutcomeTransactionUseCase`, etc.).
    - **ViewModel**: Created `OutcomeViewModel` to manage the state and logic for the outcome screen.

### Refactor
- **Unified Entry Components**:
    - Renamed `HistoryItemCard` to `EntryItemCard` to serve as a generic card for both income (orders) and outcomes.
    - Created `EntryItem` as a unified data class to represent items in a list, distinguishing between `INCOME` and `OUTCOME` types.
    - Introduced `DateHeader` as a reusable composable for sectioning entries by date.
    - `HistoryScreenView` and the new `OutcomeScreenView` now use these shared components (`DateHeader`, `EntryItemCard`) for a consistent look and feel.

- **Code Structure and Error Handling**:
    - **Use Case Segregation**: Moved income-related use cases (e.g., `GetOrderUseCase`, `SubmitOrderUseCase`) into an `income` subpackage to separate them from the new `outcome` use cases.
    - **Centralized Error Handling**: Created `GSheetRepositoryErrorHandling` and `UseCaseErrorHandling` objects to standardize error messages and logic across the data and domain layers.
    - **Bottom Navigation**: Replaced the "Inventory" tab with "Outcome". The `BottomNavItem` now uses string resources for titles.

- **CI/CD Enhancements**:
    - **SonarCloud Integration**: Added SonarCloud analysis to the CI pipeline for static code analysis and quality checks.
    - **Coveralls**: Configured the workflow to upload code coverage reports to Coveralls.
    - **Secrets Management**: Added SonarCloud secrets to the GitHub Actions workflow.
@ufebri ufebri self-assigned this Nov 23, 2025
@ufebri ufebri added the enhancement New feature or request label Nov 23, 2025
This commit introduces complete Create, Read, Update, and Delete (CRUD) functionality for outcomes. It adds a dedicated bottom sheet for creating and editing expenses, refactors shared components, and enhances the `OutcomeViewModel` to manage the entire lifecycle.

### Features
- **Outcome CRUD in UI**:
    - **Add/Edit Bottom Sheet**: A new `OutcomeBottomSheet` is implemented, allowing users to add new outcomes or edit existing ones. It is displayed using a `ModalBottomSheetLayout` in `OutcomeScreenView`.
    - **Floating Action Button (FAB)**: Added an FAB to the `OutcomeScreenView` to trigger the "Add Outcome" flow.
    - **Edit Flow**: Tapping on an existing outcome item now opens the bottom sheet with the item's data pre-filled, enabling updates.

### Refactor
- **Shared Components**:
    - **`DatePickerField`**: A new, reusable `DatePickerField` Composable has been created to provide a consistent date picker experience across the app. This component uses the older `DatePickerDialog` for broader compatibility and is now used in both the Order and Outcome bottom sheets.
    - **`DropdownMenuField`**: A generic `DropdownMenuField` has been extracted for reuse.
    - **`EntryItemCard`**: The card is now clickable, passing an `onClick` lambda to handle user interactions like editing.

- **ViewModel and State Management (`OutcomeViewModel`)**:
    - The ViewModel now manages the full state for both creating and editing outcomes, including `isEditMode`, form field values (`name`, `price`, `date`, etc.), and submission status.
    - New functions like `onPurposeChanged`, `onPriceChanged`, `onDateChanged`, `prepareNewOutcome`, `buildOutcomeDataForSubmit`, and `buildOutcomeDataForUpdate` have been added to handle user input and data preparation.
    - Logic has been added to `submitOutcome` and `updateOutcome` to refresh the outcome list and show a confirmation Snackbar upon completion.
    - The `onOutcomeEditClick` function now fetches the outcome data and populates the UI state for editing.

- **Domain and Data**:
    - **`PaymentType` Enum**: A `PaymentType` enum was created to manage payment methods (`QRIS`, `CASH`, `PERSONAL`) and their descriptions in a type-safe way.
    - **UI State (`OutcomeUiState`)**: Added `isSubmitEnabled` and `isUpdateEnabled` computed properties to control button states based on form validity.

### Style and Build
- **Date Picker Theme**: A custom theme (`Theme_LaundryHub_DatePicker`) was created to style the Android `DatePickerDialog`.
- **UI Colors**: Updated primary and secondary colors in the app's theme (`Theme.kt`, `colors.xml`) to use a consistent purple (`#6750A4`).
- **Dependencies**: Removed unused `materialui_version` from `build.gradle`.
- **Testing**: Added new unit tests for `readPackageData` and `readOtherPackage` in `GoogleSheetRepositoryImplTest`.
This commit introduces a pull-to-refresh feature on the "Outcome" screen for a better user experience. It also significantly improves the testing suite by adding comprehensive unit tests for `OutcomeUseCases`, enhancing repository tests, and refining the JaCoCo configuration for more accurate code coverage reports.

### Features
- **Pull-to-Refresh**: Implemented pull-to-refresh functionality on the Outcome screen, allowing users to easily refresh the list of expenses.
    - `OutcomeScreenView` now uses `pullRefresh` and `PullRefreshIndicator`.
    - `OutcomeViewModel` includes a `refreshOutcomeList()` function to handle the refresh logic.

### Testing
- **OutcomeUseCases Tests**: Added `OutcomeUseCasesTest.kt` to provide full unit test coverage for all outcome-related use cases (`Read`, `Submit`, `Update`, `GetById`, `GetLastId`), including success and failure scenarios.
- **Repository Test Enhancements**: Expanded `GoogleSheetRepositoryImplTest` with new tests for:
    - `readSummaryTransaction` (success, empty, and error cases).
    - `getLastOrderId` (success and error cases).
- **Error Handling**: Standardized repository error handling by replacing generic exceptions with centralized handlers (`GSheetRepositoryErrorHandling`).

### Build & CI
- **JaCoCo Configuration**:
    - Upgraded JaCoCo to version `0.8.11`.
    - Refined the `jacocoTestReport` task in `app/build.gradle` to be more precise in locating class files and execution data, ensuring more reliable and accurate code coverage reporting.
    - Excluded the main application class (`LaundryHubApp`) from coverage reports.

### Minor UI Fixes
- Replaced Material icons with their `autoMirrored` versions (`Send`, `List`) to better support right-to-left layouts.
This commit introduces an "Inventory" screen accessible from the Profile page and adds comprehensive unit tests for the `OutcomeViewModel`.

### Features
- **Inventory Screen**:
    - An "Inventory" option has been added to the "Profile" screen, allowing users to navigate to a new screen for managing inventory.
    - A new composable `InventoryScreenView` has been created for this feature (though the implementation details are not in this diff).
    - Navigation has been set up to handle the transition from the Profile screen to the Inventory screen.

### Testing
- **OutcomeViewModel Tests**:
    - Added a new test class `OutcomeViewModelTest` to ensure the reliability of the outcome management feature.
    - The tests cover key functionalities:
        - ViewModel initialization and initial data fetching.
        - Refreshing the outcome list.
        - Handling the "edit" action for an existing outcome.
        - Validating data before submission.
        - Verifying the state after a successful submission.

### Build
- **JaCoCo Configuration**:
    - Updated the JaCoCo test report task to depend on Kotlin and Java compilation tasks, ensuring accurate code coverage reports.
This commit refactors the unit tests to use centralized dummy data, improving test consistency and maintainability. It also fixes an issue in the CI configuration and improves a utility function.

### Refactor
- **Centralized Dummy Data**:
    - Replaced hardcoded test data in `HomeViewModelTest`, `HistoryViewModelTest`, `InventoryViewModelTest`, and `ProfileViewModelTest` with shared dummy data objects (e.g., `DUMMY_UNPAID_ORDER_ITEM_EMY`, `dummyHistoryUiState`).
    - This change centralizes test data, making tests more readable and easier to manage.

### Fix
- **CI Test Execution**:
    - Updated the `cicd.yaml` workflow to run `./gradlew testDebugUnitTest` instead of `test`. This ensures the correct test variant is executed, fixing test failures in the CI pipeline.
- **Rupiah Formatting**:
    - In `TextUtil.kt`, the `toRupiahFormat` function was updated to use `Locale.Builder` for creating the Indonesian locale, which is the modern and recommended approach.

### Chore
- **Gradle Configuration**:
    - Removed a redundant `.findAll` closure in `app/build.gradle` for Jacoco's class directories configuration, which was causing warnings.
This commit refactors the UI by introducing a shared `SubmitUpdateButton` composable to reduce code duplication in the `OrderBottomSheetScreen` and `OutcomeBottomSheet`. It also enhances testing across the application by adding new unit tests for `OutcomeUiState`, `EntryItem`, and covering more scenarios in existing view model and UI state tests.

### Refactor
- **`SubmitUpdateButton` Component**:
    - Created a new reusable `SubmitUpdateButton` composable to handle the logic for displaying a "Submit" or "Update" button based on an `isEditMode` flag.
    - The component manages its enabled state, displays a `CircularProgressIndicator` during submission, and is now used in `OrderBottomSheetScreen` and `OutcomeBottomSheet`.
    - Added new string resources for `Submit` and `Update` to support this component.

### Testing
- **New Test Suites**:
    - Added `OutcomeUiStateTest.kt` to verify the logic for `isSubmitEnabled` and `isUpdateEnabled`.
    - Added `EntryItemTest.kt` to test the mapping from `OutcomeData` to `EntryItemUI` and the grouping logic in `toDateListUiItems`.
- **ViewModel Test Enhancements**:
    - Expanded `OutcomeViewModelTest.kt` to cover error handling for submit/update actions, edit clicks, and data fetching. It also now tests the `buildOutcomeData` and `resetForm` methods.
    - Added tests to `HomeViewModelTest.kt` to ensure the `isLoading` state is correctly handled when use cases return `Resource.Loading`.
- **UI State Test Improvements**:
    - Simplified and improved tests in `OrderUiStateTest.kt` and `UserItemTest.kt` for better clarity and focus.

### Minor
- Added a `@Preview` to the `DatePickerField.kt` component for easier visualization in Android Studio.
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@ufebri ufebri merged commit 79b5830 into master Nov 29, 2025
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant