From 3782fd0d6f1dc21334d95768fd15fa183e69c4db Mon Sep 17 00:00:00 2001 From: Sk Niyaj Ali Date: Wed, 6 Nov 2024 20:52:46 +0530 Subject: [PATCH] Merge kmm-impl into dev (#1813) * Feat: KMP Library Setup (#1766) * Migrating from hilt to koin (This) (#1764) * Migrating from hilt to koin * Fixed Instance creation error * refactor: Removed Hilt and migrated to Koin This commit removes Hilt and migrates the project to Koin for dependency injection. The following changes were made: - Removed the `AndroidHiltConventionPlugin`. - Added the `AndroidKoinConventionPlugin`. - Updated dependencies to use Koin. - Updated KSP configuration for Koin. - Updated feature modules to use Koin. - Updated common modules to use Koin . - Removed Hilt annotations and replaced them with Koin annotations. - Updated ViewModels to use Koin for dependency injection. - Updated modules to use Koin for dependency injection. * Formatted Dependencies * migrating from hilt to koin clean up commit * Revert "migrating from hilt to koin clean up commit" This reverts commit bb63058e49299a23d4397ef8ed2ff6236418bd7e. --------- Co-authored-by: Sk Niyaj Ali * Feat: KMP Library Setup --------- Co-authored-by: Nagarjuna <99315689+Nagarjuna0033@users.noreply.github.com> * Feat: [:core:model] - Migrated to KMM (#1770) * Feat: [:core:common] KMP Migration (#1768) * Feat: [:core:common] KMP Migration * Updated Usage Declaration * Feat: [:core:datastore] - Migrated to KMP (#1769) * Feat: [:core:network] - Migrated to KMP (#1772) * Feat: [:core:network] - Migrated to KMP * Feat: [:core:data] - Migrated to KMP Library * Feat: [:core:designsystem] - Migrated to KMP with CMP Library (#1774) * Feat: [:core:ui] - Migrated to KMP with CMP Library (#1775) * Feat: [:feature:auth] - Migrated to Kotlin Multiplatform (#1782) * Feat: [:feature:auth] - Migrated to Kotlin Multiplatform * Added Support For Web * Feat: Migrated Passcode Module to KMP (#1783) * Feat: Migrated Home Module to KMP (#1784) * Feat: Migrated Edit Password Module to KMP (#1787) * Feat: Migrated FAQ module to kmp (#1786) * Feat: Migrated Settings Module to KMP (#1785) * Feat: Migrated Profile Module to KMP (#1788) * Feat: Migrated History Module to KMP (#1790) * Feat: Migrated Payments Module to KMP (#1791) * Feat: Migrated Finance Module to KMP (#1792) * Feat: Migrated Accounts Module to KMP (#1793) * Feat: Migrated Accounts Module to KMP * Updated README.md * Update README.md * Feat: Migrated Invoices Module to KMP (#1794) * Feat: Migrated KYC Module to KMP (#1798) * Migrated Notification Module to KMP (#1799) * Feat: Migrated KYC Module to KMP * Feat: Migrated Notification Module to KMP * Feat: Migrated Saved Card Module to KMP (#1800) * Feat: Migrated Receipt Module to KMP (#1801) * fix: Ios Build (#1802) * Feat: Migrated SI Module to KMP (#1803) * Feat: Migrated Request Money Module to KMP (#1807) * Feat: Migrated Send Money Module to KMP (#1808) * Feat: Migrated Make Transfer Module to KMP (#1809) * Feat: Migrated QR Module to KMP (#1810) * Feat: Migrated UPI Setup Module to KMP (#1811) * Feat: Final Clean-up For KMP (#1812) * Feat: Final Cleanup For KMP * Update README.md * Update EditPassword README.md * Update FAQ README.md * Update Finance README.md * Update History README.md * Update Home README.md * Update Invoice README.md * Update KYC README.md * Update Make Transfer README.md * Update Notification README.md * Update Payments README.md * Update Profile README.md * Update Saved Card README.md * Update Send Money README.md * Update Settings README.md * Update SI README.md * Migrating from hilt to koin (This) (#1764) * Migrating from hilt to koin * Fixed Instance creation error * refactor: Removed Hilt and migrated to Koin This commit removes Hilt and migrates the project to Koin for dependency injection. The following changes were made: - Removed the `AndroidHiltConventionPlugin`. - Added the `AndroidKoinConventionPlugin`. - Updated dependencies to use Koin. - Updated KSP configuration for Koin. - Updated feature modules to use Koin. - Updated common modules to use Koin . - Removed Hilt annotations and replaced them with Koin annotations. - Updated ViewModels to use Koin for dependency injection. - Updated modules to use Koin for dependency injection. * Formatted Dependencies * migrating from hilt to koin clean up commit * Revert "migrating from hilt to koin clean up commit" This reverts commit bb63058e49299a23d4397ef8ed2ff6236418bd7e. --------- Co-authored-by: Sk Niyaj Ali * Profile UI redesign (#1767) * Refactor Profile UI * Fixed Build Issue * Profile UI Bug Fix & Improvement * added placeholder for when uri is null cleanup fix spotless test failure * Fix - CI Build Issue --------- Co-authored-by: Sk Niyaj Ali * refactor: Redesign payment screen (#1773) * refactor: Redesign payment screen * resolved detekt error * refactor : changed current theme instead of using NewUi * resolved spotless errors * refactor: Redesign finance screen (#1777) * refactor: Redesign payment screen * resolved detekt error * refactor : changed current theme instead of using NewUi * resolved spotless errors * refactor: Redesign finance screen UI * resolved spotless errors * resolved conflicts * changed structure of accounts screen * refactor padding values in finance screen * fix: dark theme colors (#1789) * fix: dark theme colors * fixed edit icon tint * Fix invoice api (#1797) * Redesign requeset screen UI * fix MissingKoinDefinitionException * removed comments and fixed share qr code bug * fix: Invoice APIs * update readme file (#1804) * update readme file * update readme file * update readme file with how to contribute * Add branch policy (#1805) * update readme file * update readme file * update readme file with how to contribute * update readme file with how to contribute * update readme file with branch Policy --------- Co-authored-by: Rajan Maurya * Migrating from hilt to koin (This) (#1764) * Migrating from hilt to koin * Fixed Instance creation error * refactor: Removed Hilt and migrated to Koin This commit removes Hilt and migrates the project to Koin for dependency injection. The following changes were made: - Removed the `AndroidHiltConventionPlugin`. - Added the `AndroidKoinConventionPlugin`. - Updated dependencies to use Koin. - Updated KSP configuration for Koin. - Updated feature modules to use Koin. - Updated common modules to use Koin . - Removed Hilt annotations and replaced them with Koin annotations. - Updated ViewModels to use Koin for dependency injection. - Updated modules to use Koin for dependency injection. * Formatted Dependencies * migrating from hilt to koin clean up commit * Revert "migrating from hilt to koin clean up commit" This reverts commit bb63058e49299a23d4397ef8ed2ff6236418bd7e. --------- Co-authored-by: Sk Niyaj Ali * Merge kmm-impl to dev --------- Co-authored-by: Nagarjuna <99315689+Nagarjuna0033@users.noreply.github.com> Co-authored-by: Rajan Maurya Co-authored-by: Pronay Sarker Co-authored-by: kapmaurya <152150716+kapmaurya@users.noreply.github.com> --- .github/workflows/feature_branch_ci.yml | 32 - .github/workflows/master_dev_ci.yml | 11 +- .run/mifospay-android.run.xml | 70 + .run/mifospay-desktop.run.xml | 24 + .run/mifospay-web-js.run.xml | 24 + .run/mifospay-web-wasm.run.xml | 24 + README.md | 93 +- build-logic/convention/build.gradle.kts | 56 +- .../AndroidApplicationConventionPlugin.kt | 2 - ...roidApplicationFirebaseConventionPlugin.kt | 39 - .../kotlin/AndroidFeatureConventionPlugin.kt | 66 - .../AndroidLibraryComposeConventionPlugin.kt | 19 - .../kotlin/AndroidLintConventionPlugin.kt | 37 - .../kotlin/AndroidRoomConventionPlugin.kt | 29 - .../kotlin/AndroidTestConventionPlugin.kt | 21 - .../main/kotlin/CMPFeatureConventionPlugin.kt | 55 + .../main/kotlin/JvmLibraryConventionPlugin.kt | 15 - ...onPlugin.kt => KMPKoinConventionPlugin.kt} | 16 +- ...lugin.kt => KMPLibraryConventionPlugin.kt} | 34 +- .../src/main/kotlin/org/mifospay/Detekt.kt | 2 - .../main/kotlin/org/mifospay/KotlinAndroid.kt | 42 +- .../org/mifospay/KotlinMultiplatform.kt | 40 + build.gradle.kts | 2 +- ci-prepush.bat | 6 +- ci-prepush.sh | 6 +- core/analytics/build.gradle.kts | 22 +- core/analytics/proguard-rules.pro | 21 - .../kotlin}/AndroidManifest.xml | 0 .../mifospay/core/analytics/AnalyticsEvent.kt | 0 .../core/analytics/AnalyticsHelper.kt | 0 .../core/analytics/NoOpAnalyticsHelper.kt | 0 .../core/analytics/StubAnalyticsHelper.kt | 0 .../org/mifospay/core/analytics/UiHelpers.kt | 0 .../core/analytics/di/AnalyticsModule.kt | 0 .../analytics/di/FirebaseAnalyticsHelper.kt | 0 core/common/build.gradle.kts | 52 +- core/common/proguard-rules.pro | 21 - .../{main => androidMain}/AndroidManifest.xml | 0 .../core/common/CurrencyFormatter.android.kt | 26 + .../core/common/FileUtils.android.kt} | 5 +- .../org/mifospay/core/common/Parcelize.kt | 29 + .../common/di/DispatchersModule.android.kt} | 13 +- .../org/mifospay/core}/common/Constants.kt | 2 +- .../mifospay/core/common/CurrencyFormatter.kt | 13 +- .../org/mifospay/core/common/DataState.kt | 39 + .../core/common/DataStateExtensions.kt | 105 + .../org/mifospay/core/common/DateHelper.kt | 353 ++ .../org/mifospay/core/common/DebugUtil.kt | 16 +- .../org/mifospay/core/common/FileUtils.kt | 39 + .../mifospay/core/common}/MifosDispatchers.kt | 3 +- .../mifospay/core}/common/NavArgsConstants.kt | 2 +- .../org/mifospay/core/common/Parcelize.kt | 41 + .../core/common/di/DispatchersModule.kt} | 13 +- .../core/common/utils/StringExtensions.kt | 33 + .../core/common/CurrencyFormatter.jvm.kt | 26 + .../org/mifospay/core/common/FileUtils.jvm.kt | 13 + .../org/mifospay/core/common/Parcelize.kt | 46 + .../common/di/DispatchersModule.desktop.kt | 22 + .../core/common/CurrencyFormatter.js.kt | 36 + .../org/mifospay/core/common/FileUtils.js.kt | 7 +- .../org/mifospay/core/common/Parcelize.kt | 46 + .../core/common/di/DispatchersModule.js.kt | 22 + .../org/mifospay/common/CreditCardUtils.kt | 39 - .../kotlin/org/mifospay/common/DebugUtil.kt | 26 - .../kotlin/org/mifospay/common/FileUtils.kt | 36 - .../main/kotlin/org/mifospay/common/Utils.kt | 47 - .../core/common/CurrencyFormatter.native.kt | 28 + .../mifospay/core/common/FileUtils.native.kt | 45 + .../org/mifospay/core/common/Parcelize.kt | 46 + .../common/di/DispatchersModule.native.kt | 22 + .../core/common/CurrencyFormatter.js.kt | 35 + .../org/mifospay/core/common/FileUtils.js.kt} | 4 +- .../org/mifospay/core/common/Parcelize.kt | 46 + .../core/common/di/DispatchersModule.js.kt | 22 + core/data/build.gradle.kts | 44 +- .../{main => androidMain}/AndroidManifest.xml | 0 .../di/AndroidPlatformDependentDataModule.kt | 32 + .../core/data/di/AndroidPlatformModule.kt | 47 + .../util/ConnectivityManagerNetworkMonitor.kt | 20 +- .../data/util/TimeZoneBroadcastMonitor.kt} | 12 +- .../res/values/strings.xml | 0 .../{main => commonMain}/assets/banks.json | 0 .../{main => commonMain}/assets/cities.json | 0 .../assets/countriesToCities.json | 0 .../data/di/PlatformDependentDataModule.kt | 24 + .../mifospay/core/data/di/RepositoryModule.kt | 105 + .../core/data/mapper/AccountMapper.kt | 32 + .../core/data/mapper/ClientDetailsMapper.kt | 106 + .../core/data/mapper/SavingAccountMapper.kt | 60 + .../data/mapper/SearchedEntitiesMapper.kt | 26 + .../core/data/mapper/TransactionMapper.kt | 39 + .../mifospay/core/data/mapper/UserMapper.kt | 59 + .../core/data/repository/AccountRepository.kt | 30 + .../repository/AuthenticationRepository.kt | 9 +- .../data/repository/BeneficiaryRepository.kt | 32 + .../core/data/repository/ClientRepository.kt | 42 + .../data/repository/DocumentRepository.kt | 48 + .../core/data/repository/InvoiceRepository.kt | 31 + .../data/repository/KycLevelRepository.kt | 28 + .../data/repository/LocalAssetRepository.kt | 20 + .../repository/NotificationRepository.kt} | 14 +- .../data/repository/RegistrationRepository.kt | 20 + .../data/repository/RunReportRepository.kt} | 21 +- .../data/repository/SavedCardRepository.kt | 27 + .../repository/SavingsAccountRepository.kt | 55 + .../core/data/repository/SearchRepository.kt} | 15 +- .../data/repository/SelfServiceRepository.kt | 65 + .../StandingInstructionRepository.kt | 42 + .../ThirdPartyTransferRepository.kt | 22 + .../repository/TwoFactorAuthRepository.kt | 23 + .../core/data/repository/UserRepository.kt | 33 + .../repositoryImp/AccountRepositoryImpl.kt | 77 + .../AuthenticationRepositoryImpl.kt | 38 + .../BeneficiaryRepositoryImpl.kt | 77 + .../repositoryImp/ClientRepositoryImpl.kt | 132 + .../repositoryImp/DocumentRepositoryImpl.kt | 125 + .../repositoryImp/InvoiceRepositoryImpl.kt | 88 + .../repositoryImp/KycLevelRepositoryImpl.kt | 67 + .../repositoryImp/LocalAssetRepositoryImpl.kt | 64 + .../NotificationRepositoryImpl.kt | 32 + .../RegistrationRepositoryImpl.kt | 45 + .../repositoryImp/RunReportRepositoryImpl.kt | 37 + .../repositoryImp/SavedCardRepositoryImpl.kt | 86 + .../SavingsAccountRepositoryImpl.kt | 146 + .../repositoryImp/SearchRepositoryImpl.kt | 39 + .../SelfServiceRepositoryImpl.kt | 227 ++ .../StandingInstructionRepositoryImpl.kt | 109 + .../ThirdPartyTransferRepositoryImpl.kt | 38 + .../TwoFactorAuthRepositoryImpl.kt | 39 + .../data/repositoryImp/UserRepositoryImpl.kt | 96 + .../org/mifospay/core/data/util/Constants.kt | 10 +- .../mifospay/core/data/util/NetworkMonitor.kt | 0 .../mifospay/core/data/util/SampleCurrency.kt | 160 + .../mifospay/core/data/util/SampleLocale.kt | 700 ++++ .../core/data/util/TimeZoneMonitor.kt | 14 +- .../core/data/util/UpiQrCodeProcessor.kt | 148 + .../data/JsPlatformDependentDataModule.kt | 31 + .../di/PlatformDependentDataModule.jvm.kt | 11 +- .../data/JsPlatformDependentDataModule.kt | 31 + .../di/PlatformDependentDataModule.jvm.kt | 22 + .../org/mifospay/core/data/base/TaskLooper.kt | 62 - .../core/data/base/ThreadPoolQueue.kt | 24 - .../org/mifospay/core/data/base/UseCase.kt | 45 - .../mifospay/core/data/base/UseCaseFactory.kt | 33 - .../mifospay/core/data/base/UseCaseHandler.kt | 65 - .../core/data/base/UseCaseScheduler.kt | 28 - .../data/base/UseCaseThreadPoolScheduler.kt | 59 - .../org/mifospay/core/data/di/DataModule.kt | 214 -- .../usecase/account/BlockUnblockCommand.kt | 46 - .../account/DownloadTransactionReceipt.kt | 45 - .../domain/usecase/account/FetchAccount.kt | 66 - .../account/FetchAccountTransaction.kt | 62 - .../account/FetchAccountTransactions.kt | 53 - .../usecase/account/FetchAccountTransfer.kt | 40 - .../domain/usecase/account/FetchAccounts.kt | 55 - .../domain/usecase/account/FetchMerchants.kt | 53 - .../domain/usecase/account/TransferFunds.kt | 275 -- .../domain/usecase/client/CreateClient.kt | 54 - .../domain/usecase/client/FetchClientData.kt | 75 - .../usecase/client/FetchClientDetails.kt | 44 - .../domain/usecase/client/FetchClientImage.kt | 45 - .../domain/usecase/client/SearchClient.kt | 55 - .../domain/usecase/client/UpdateClient.kt | 55 - .../usecase/history/TransactionsHistory.kt | 44 - .../domain/usecase/invoice/FetchInvoice.kt | 62 - .../domain/usecase/invoice/FetchInvoices.kt | 49 - .../usecase/kyc/FetchKYCLevel1Details.kt | 47 - .../usecase/kyc/UpdateKYCLevel1Details.kt | 51 - .../data/domain/usecase/kyc/UploadKYCDocs.kt | 57 - .../usecase/kyc/UploadKYCLevel1Details.kt | 50 - .../notification/FetchNotifications.kt | 46 - .../data/domain/usecase/savedcards/AddCard.kt | 43 - .../domain/usecase/savedcards/DeleteCard.kt | 43 - .../domain/usecase/savedcards/EditCard.kt | 44 - .../usecase/savedcards/FetchSavedCards.kt | 48 - .../CreateStandingTransaction.kt | 206 -- .../DeleteStandingInstruction.kt | 47 - .../FetchStandingInstruction.kt | 46 - .../GetAllStandingInstructions.kt | 51 - .../UpdateStandingInstruction.kt | 89 - .../usecase/twofactor/FetchDeliveryMethods.kt | 45 - .../domain/usecase/twofactor/RequestOTP.kt | 42 - .../domain/usecase/twofactor/ValidateOTP.kt | 43 - .../domain/usecase/user/AuthenticateUser.kt | 45 - .../data/domain/usecase/user/CreateUser.kt | 51 - .../data/domain/usecase/user/DeleteUser.kt | 42 - .../domain/usecase/user/FetchUserDetails.kt | 42 - .../data/domain/usecase/user/FetchUsers.kt | 51 - .../data/domain/usecase/user/RegisterUser.kt | 45 - .../data/domain/usecase/user/UpdateUser.kt | 52 - .../data/domain/usecase/user/VerifyUser.kt | 44 - .../fineract/entity/mapper/AccountMapper.kt | 35 - .../entity/mapper/ClientDetailsMapper.kt | 34 - .../fineract/entity/mapper/CurrencyMapper.kt | 23 - .../fineract/entity/mapper/FetchAccount.kt | 62 - .../entity/mapper/SearchedEntitiesMapper.kt | 33 - .../entity/mapper/TransactionMapper.kt | 60 - .../fineract/repository/FineractRepository.kt | 327 -- .../auth/AuthenticationUserRepository.kt | 35 - .../data/repository/local/LocalRepository.kt | 33 - .../local/MifosLocalAssetRepository.kt | 47 - .../core/data/util/ErrorJsonMessageHelper.kt | 36 - .../data/NativePlatformDependentDataModule.kt | 31 + .../di/PlatformDependentDataModule.native.kt | 22 + .../mobilewallet/core/ExampleUnitTest.kt | 26 - .../data/JsPlatformDependentDataModule.kt | 31 + .../di/PlatformDependentDataModule.jvm.kt | 22 + core/datastore-proto/build.gradle.kts | 23 +- core/datastore-proto/consumer-rules.pro | 0 core/datastore-proto/proguard-rules.pro | 21 - .../core/datastore/proto/ClientPreferences.kt | 51 + .../core/datastore/proto/RolePreferences.kt | 29 + .../datastore/proto/UserInfoPreferences.kt | 43 + .../core/datastore/proto/client_info.proto | 13 + .../core/datastore/proto/role_info.proto | 11 + .../core/datastore/proto/user_info.proto | 20 + .../user_preferences.proto | 13 - core/datastore/build.gradle.kts | 31 +- core/datastore/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../core/datastore/PreferencesHelper.kt | 0 .../core/datastore/di/CoreDataStoreModule.kt | 0 .../core/datastore/PreferencesMapper.kt | 107 + .../datastore/UserPreferencesDataSource.kt | 175 + .../datastore/UserPreferencesRepository.kt | 46 + .../UserPreferencesRepositoryImpl.kt | 127 + .../core/datastore/di/PreferenceModule.kt | 32 + .../core/datastore/ExampleUnitTest.kt | 25 - core/designsystem/build.gradle.kts | 62 +- .../src/androidMain}/AndroidManifest.xml | 0 .../designsystem/component/PermissionBox.kt | 11 +- .../composeResources}/font/outfit_black.ttf | Bin .../composeResources}/font/outfit_bold.ttf | Bin .../font/outfit_extra_bold.ttf | Bin .../font/outfit_extra_light.ttf | Bin .../composeResources}/font/outfit_light.ttf | Bin .../composeResources}/font/outfit_medium.ttf | Bin .../composeResources}/font/outfit_regular.ttf | Bin .../font/outfit_semi_bold.ttf | Bin .../composeResources}/font/outfit_thin.ttf | Bin .../designsystem/component/AlertDialog.kt | 19 +- .../core/designsystem/component/Background.kt | 23 +- .../designsystem/component/BottomSheet.kt | 21 +- .../core/designsystem/component/Button.kt | 22 +- .../core/designsystem/component/Card.kt | 0 .../core/designsystem/component/IconBox.kt | 20 +- .../designsystem/component/LoadingWheel.kt | 2 +- .../component/MifosBasicDialog.kt | 142 + .../component/MifosLoadingDialog.kt | 107 + .../designsystem/component/MifosScaffold.kt | 177 + .../core/designsystem/component/MifosTab.kt | 22 +- .../designsystem/component/MifosTopAppBar.kt | 275 ++ .../designsystem/component/MifosTopBar.kt | 9 +- .../core/designsystem/component/Navigation.kt | 63 +- .../core/designsystem/component/TextField.kt | 367 +++ .../designsystem/component/TextUserImage.kt | 3 +- .../core/designsystem/component/TopAppBar.kt | 41 +- .../component/scrollbar/AppScrollbars.kt | 246 ++ .../scrollbar/LazyScrollbarUtilities.kt | 81 + .../component/scrollbar/Scrollbar.kt | 412 +++ .../component/scrollbar/ScrollbarExt.kt | 227 ++ .../component/scrollbar/ThumbExt.kt | 82 + .../core/designsystem/icon/MifosIcons.kt | 46 +- .../designsystem/theme/BackgroundTheme.kt | 0 .../mifospay/core/designsystem/theme/Color.kt | 6 +- .../core/designsystem/theme/GradientColors.kt | 0 .../core/designsystem/theme/MifosTextStyle.kt | 0 .../mifospay/core/designsystem/theme/Theme.kt | 2 +- .../core/designsystem/theme/TintTheme.kt | 0 .../mifospay/core/designsystem/theme/Type.kt | 72 +- .../designsystem/utils/ExpirationDateMask.kt | 0 .../core/designsystem/utils/ModifierExt.kt | 85 + .../designsystem/component/MifosScaffold.kt | 66 - .../component/OutlineTextField.kt | 79 - .../core/designsystem/component/TextField.kt | 339 -- {mifospay => core/domain}/.gitignore | 0 core/domain/README.md | 3 + core/domain/build.gradle.kts | 26 + core/{network => domain}/proguard-rules.pro | 11 +- .../org/mifospay/core/domain/LoginUseCase.kt | 78 + .../mifospay/core/domain/di/DomainModule.kt | 26 + core/model/build.gradle.kts | 17 +- core/model/consumer-rules.pro | 0 core/model/proguard-rules.pro | 21 - .../mifospay/core/model/account/Account.kt | 27 + .../core/model/account/AccountContent.kt | 20 + .../model/account/AccountTransferPayload.kt | 35 + .../model/account/AccountsWithTransactions.kt | 17 + .../core/model/account/DefaultAccount.kt} | 27 +- .../core/model/account}/NewAccount.kt | 17 +- .../org/mifospay/core/model/bank}/Bank.kt | 10 +- .../core/model/bank/BankAccountDetails.kt | 25 + .../core/model/beneficiary/Beneficiary.kt | 35 + .../model/beneficiary/BeneficiaryPayload.kt | 31 + .../beneficiary/BeneficiaryUpdatePayload.kt} | 13 +- .../org/mifospay/core/model/client/Client.kt | 35 + .../core/model/client/ClientAccount.kt} | 9 +- .../core/model/client/ClientAddress.kt} | 20 +- .../core/model/client/ClientStatus.kt} | 14 +- .../core/model/client/ClientTimeline.kt} | 16 +- .../mifospay/core/model/client/NewClient.kt | 23 + .../core/model/client/UpdatedClient.kt | 22 + .../core/model/datatables}/invoice/Invoice.kt | 18 +- .../datatables}/invoice/InvoiceEntity.kt | 2 +- .../core/model/kyc/KYCLevel1Details.kt | 26 + .../core/model/notification/Notification.kt | 33 + .../model/notification/NotificationPayload.kt | 21 + .../core/model/savedcards/CardPayload.kt | 22 + .../core/model/savedcards/SavedCard.kt | 45 + .../core/model/savingsaccount/AccountType.kt | 22 + .../BlockUnblockResponseEntity.kt | 26 + .../savingsaccount/CreateNewSavingEntity.kt | 32 + .../core/model/savingsaccount/Currency.kt | 26 + .../core/model/savingsaccount}/DepositType.kt | 40 +- .../model/savingsaccount/InterestPeriod.kt | 22 + .../model/savingsaccount/PaymentDetailData.kt | 26 + .../core/model/savingsaccount}/PaymentType.kt | 17 +- .../model/savingsaccount/SavingAccount.kt | 31 + .../savingsaccount/SavingAccountDetail.kt | 51 + .../savingsaccount/SavingAccountEntity.kt | 30 + .../savingsaccount/SavingAccountTemplate.kt | 30 + .../core/model/savingsaccount/SavingCharge.kt | 21 + .../savingsaccount/SavingProductOption.kt | 26 + .../SavingsWithAssociationsEntity.kt | 42 + .../core/model/savingsaccount/Status.kt | 32 + .../core/model/savingsaccount/SubStatus.kt | 29 + .../core/model/savingsaccount/Summary.kt | 36 + .../core/model/savingsaccount/Timeline.kt | 31 + .../core/model/savingsaccount/Transaction.kt | 36 + .../model/savingsaccount}/TransactionType.kt | 4 +- .../savingsaccount/TransactionsEntity.kt | 59 + .../core/model/savingsaccount/Transfer.kt | 25 + .../model/savingsaccount/TransferDetail.kt | 97 + .../UpdateSavingAccountEntity.kt} | 18 +- .../core/model/search/AccountResult.kt | 28 + .../core/model/search}/SearchResult.kt | 19 +- .../model/standinginstruction/SITemplate.kt | 120 + .../standinginstruction/SIUpdatePayload.kt} | 23 +- .../StandingInstruction.kt | 75 + .../StandingInstructionPayload.kt | 56 + .../org/mifospay/core/model/user/NewUser.kt | 22 + .../org/mifospay/core/model/user/RoleInfo.kt} | 15 +- .../org/mifospay/core/model/user/UserData.kt | 27 + .../org/mifospay/core/model/user/UserInfo.kt | 16 +- .../mifospay/core/model/utils/CurrencyCode.kt | 33 + .../org/mifospay/core/model/utils/Locale.kt | 34 + .../core/model/utils/PaymentQrData.kt | 61 + .../core/model/domain/BankAccountDetails.kt | 26 - .../mifospay/core/model/domain/Transaction.kt | 41 - .../core/model/domain/client/NewClient.kt | 61 - .../core/model/domain/user/NewUser.kt | 33 - .../mifospay/core/model/entity/Timeline.kt | 30 - .../accounts/SavingAccountsListResponse.kt | 16 - .../model/entity/accounts/savings/Currency.kt | 41 - .../accounts/savings/PaymentDetailData.kt | 39 - .../entity/accounts/savings/SavingAccount.kt | 69 - .../savings/SavingsWithAssociations.kt | 113 - .../model/entity/accounts/savings/Status.kt | 72 - .../model/entity/accounts/savings/Summary.kt | 43 - .../model/entity/accounts/savings/TimeLine.kt | 67 - .../accounts/savings/TransactionType.kt | 69 - .../entity/accounts/savings/Transactions.kt | 72 - .../entity/accounts/savings/TransferDetail.kt | 39 - .../model/entity/beneficary/Beneficiary.kt | 40 - .../entity/beneficary/BeneficiaryPayload.kt | 36 - .../beneficary/BeneficiaryUpdatePayload.kt | 20 - .../core/model/entity/client/Client.kt | 101 - .../core/model/entity/client/Currency.kt | 37 - .../mifospay/core/model/entity/client/Type.kt | 26 - .../core/model/entity/kyc/KYCLevel1Details.kt | 38 - .../core/model/entity/noncore/Document.kt | 25 - .../model/entity/payload/ClientPayload.kt | 68 - .../model/entity/payload/DataTablePayload.kt | 29 - .../payload/StandingInstructionPayload.kt | 40 - .../model/entity/payload/TransferPayload.kt | 54 - .../model/entity/register/RegisterPayload.kt | 38 - .../core/model/entity/register/UserVerify.kt | 20 - .../core/model/entity/savedcards/Card.kt | 35 - .../entity/standinginstruction/SDIResponse.kt | 16 - .../StandingInstruction.kt | 55 - .../entity/templates/account/AccountOption.kt | 39 - .../account/AccountOptionsTemplate.kt | 22 - .../entity/templates/account/AccountType.kt | 26 - .../beneficiary/AccountTypeOption.kt | 26 - .../mifospay/core/model/signup/SignupData.kt | 32 - .../mifospay/core/model/utils/DateHelper.kt | 141 - .../mobilewallet/model/ExampleUnitTest.kt | 25 - core/network/build.gradle.kts | 90 +- core/network/consumer-rules.pro | 2 + .../src/androidMain}/AndroidManifest.xml | 2 +- .../core/network/KtorAndroidHttpClient.kt | 51 + .../{main => commonMain}/assets/banks.json | 0 .../{main => commonMain}/assets/cities.json | 0 .../assets/countries.json | 0 .../assets/countriesToCities.json | 0 .../{main => commonMain}/assets/states.json | 0 .../core/network/FineractApiManager.kt | 47 + .../mifospay/core/network/KtorHttpClient.kt} | 8 +- .../mifospay/core/network/KtorfitClient.kt | 100 + .../core/network/SelfServiceApiManager.kt | 26 + .../mifospay/core/network/di/LocalModule.kt | 6 +- .../mifospay/core/network/di/NetworkModule.kt | 83 + .../org/mifospay/core/network/di/Qualifier.kt | 17 + .../localAssets/JvmLocalAssetManager.kt | 10 +- .../localAssets/LocalAssetDataSource.kt | 6 +- .../network/localAssets/LocalAssetManager.kt | 4 +- .../localAssets/MifosLocalAssetDataSource.kt | 30 +- .../network/model/ClientResponseEntity.kt} | 14 +- .../core/network/model/CommonResponse.kt} | 11 +- .../core/network/model}/GenericResponse.kt | 2 +- .../core/network/model/entity/Page.kt} | 13 +- .../core/network}/model/entity/Role.kt | 8 +- .../network/model/entity/SearchedEntity.kt | 22 + .../core/network}/model/entity/TPTResponse.kt | 13 +- .../core/network/model/entity/Timeline.kt | 43 + .../core/network}/model/entity/UserEntity.kt | 5 +- .../network}/model/entity/UserWithRole.kt | 14 +- .../authentication/AuthenticationPayload.kt | 18 + .../entity/client/ClientAccountsEntity.kt} | 22 +- .../model/entity/client/ClientEntity.kt | 43 + .../network/model/entity/client/Currency.kt | 31 + .../model/entity/client/DepositTypeEntity.kt | 19 + .../model/entity/client/NewClientEntity.kt | 63 + .../network/model/entity/client/Status.kt | 21 + .../core/network/model/entity/client/Type.kt | 19 + .../model/entity/client/UpdateClientEntity.kt | 21 + .../network/model/entity/noncore/Document.kt | 24 + .../model/entity/payload/ClientPayload.kt | 33 + .../model/entity/payload/DataTablePayload.kt | 27 + .../model/entity/payload/PayPayload.kt | 9 +- .../model/entity/payload/PayResponse.kt | 26 + .../model/entity/payload/TransferPayload.kt | 43 + .../model/entity/payload/UpdateVpaPayload.kt | 7 +- .../model/entity/register/RegisterPayload.kt | 24 + .../model/entity/register/UserVerify.kt | 18 + .../core/network/model/entity/signup}/City.kt | 2 +- .../network/model/entity/signup}/Country.kt | 2 +- .../network/model/entity/signup}/State.kt | 2 +- .../entity/templates/account/AccountOption.kt | 23 + .../account/AccountOptionsTemplate.kt | 18 + .../entity/templates/account/AccountType.kt | 19 + .../beneficiary/AccountTypeOption.kt | 19 + .../beneficiary/BeneficiaryTemplate.kt | 17 + .../model/entity/user/NewUserEntity.kt} | 23 +- .../entity}/user/UpdateUserEntityClients.kt | 7 +- .../entity/user/UpdateUserEntityEmail.kt | 17 + .../entity/user/UpdateUserEntityPassword.kt | 30 + .../core/network/model/entity}/user/User.kt | 12 +- .../network/model/twofactor/AccessToken.kt | 19 + .../model}/twofactor/DeliveryMethod.kt | 13 +- .../services/AccountTransfersService.kt | 45 + .../network/services/AuthenticationService.kt | 13 +- .../network/services/BeneficiaryService.kt | 43 + .../core/network/services/ClientService.kt | 69 + .../core/network/services/DocumentService.kt | 64 +- .../core/network/services/InvoiceService.kt | 53 +- .../core/network/services/KYCLevel1Service.kt | 36 +- .../network/services/NotificationService.kt | 16 +- .../network/services/RegistrationService.kt | 16 +- .../core/network/services/RunReportService.kt | 20 +- .../core/network/services/SavedCardService.kt | 52 + .../services/SavingsAccountsService.kt | 71 + .../core/network/services/SearchService.kt | 13 +- .../services/StandingInstructionService.kt | 73 + .../services/ThirdPartyTransferService.kt | 27 + .../network/services/TwoFactorAuthService.kt | 29 + .../core/network/services/UserService.kt | 59 + .../core/network/utils}/ApiEndPoints.kt | 3 +- .../mifospay/core/network/utils/BaseURL.kt | 30 + .../network/utils/FlowConverterFactory.kt | 52 + .../core/network/utils/KtorInterceptor.kt | 89 + .../core/network/KtorJvmHttpClient.kt | 50 + .../mifospay/core/network/KtorJsHttpClient.kt | 50 + .../mifospay/core/network/ApiInterceptor.kt | 39 - .../org/mifospay/core/network/BaseURL.kt | 27 - .../core/network/FineractApiManager.kt | 100 - .../core/network/JvmLocalAssetManager.kt | 37 - .../mifospay/core/network/KtorInterceptor.kt | 48 - .../core/network/MifosWalletOkHttpClient.kt | 93 - .../core/network/SelfServiceApiManager.kt | 43 - .../core/network/TestingApiInterceptor.kt | 41 - .../mifospay/core/network/di/NetworkModule.kt | 247 -- .../org/mifospay/core/network/di/Qualifier.kt | 27 - .../services/AccountTransfersService.kt | 24 - .../network/services/BeneficiaryService.kt | 47 - .../core/network/services/ClientService.kt | 65 - .../services/KtorAuthenticationService.kt | 32 - .../services/KtorSavingsAccountService.kt | 81 - .../core/network/services/SavedCardService.kt | 48 - .../services/StandingInstructionService.kt | 67 - .../services/ThirdPartyTransferService.kt | 30 - .../network/services/TwoFactorAuthService.kt | 32 - .../core/network/services/UserService.kt | 47 - .../core/network/KtorNativeHttpClient.kt | 50 + .../mifospay/network/ExampleUnitTest.kt | 25 - .../mifospay/core/network/KtorJsHttpClient.kt | 50 + core/ui/build.gradle.kts | 55 +- core/ui/consumer-rules.pro | 0 core/ui/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../mifospay/core/ui/JankStatsExtensions.kt | 0 .../core/ui/utils/ShareUtils.android.kt | 105 + .../drawable/arrow_outward.xml | 12 +- .../composeResources}/drawable/artwork.xml | 0 .../drawable/core_ui_info_outline.xml} | 0 .../drawable/core_ui_money_in.png | Bin .../drawable/core_ui_money_out.png | Bin .../feature_receipt_mifospay_round_logo.png | Bin .../composeResources}/values/strings.xml | 2 +- .../kotlin/org/mifospay/core/ui/AvatarBox.kt | 35 +- .../org/mifospay/core/ui/DevicePreviews.kt | 7 +- .../org/mifospay/core/ui/DropdownBox.kt | 162 + .../mifospay/core/ui/EmptyContentScreen.kt | 127 +- .../mifospay/core/ui/ErrorScreenContent.kt | 15 +- .../org/mifospay/core/ui/ExpiryDateInput.kt | 3 +- .../org/mifospay/core/ui/HeadingTitile.kt | 2 +- .../org/mifospay/core/ui/LocalTimeZone.kt | 0 .../org/mifospay/core/ui/MifosDivider.kt | 0 .../mifospay/core/ui/MifosPasswordField.kt | 188 ++ .../org/mifospay/core/ui/MifosSmallChip.kt | 47 + .../org/mifospay/core/ui/MifosUserImage.kt | 30 +- .../core/ui/NavGraphBuilderExtensions.kt | 91 + .../ui/NonLetterColorVisualTransformation.kt | 61 + .../org/mifospay/core/ui/OtpTextField.kt | 2 +- .../core/ui/PasswordStrengthIndicator.kt | 217 ++ .../org/mifospay/core/ui/RevealSwipe.kt | 588 ++++ .../org/mifospay/core/ui/ScrollableTabRow.kt | 13 +- .../core/ui/TransactionHistoryCard.kt | 105 + .../mifospay/core/ui/TransactionItemCard.kt | 197 ++ .../mifospay/core/ui/utility/AddBtnChip.kt | 12 +- .../mifospay/core/ui/utility/DialogState.kt | 0 .../mifospay/core/ui/utility/DialogType.kt | 0 .../mifospay/core/ui/utility/TabContent.kt | 0 .../mifospay/core/ui/utils/BackgroundEvent.kt | 17 + .../mifospay/core/ui/utils/BaseViewModel.kt | 100 + .../mifospay/core/ui/utils/EventsEffect.kt | 42 + .../core/ui/utils/LifecycleEventEffect.kt | 41 + .../mifospay/core/ui/utils/PasswordChecker.kt | 94 + .../core/ui/utils}/PasswordStrength.kt | 14 +- .../ui/utils/PasswordStrengthExtensions.kt | 40 + .../org/mifospay/core/ui/utils/ShareUtils.kt | 13 +- .../org/mifospay/core/ui/utils/Transition.kt | 379 +++ .../core/ui/utils/ShareUtils.desktop.kt | 35 + .../mifospay/core/ui/utils/ShareUtils.js.kt | 35 + .../core/ui/ProfileConcentricImage.kt | 55 - .../mifospay/core/ui/TransactionItemScreen.kt | 116 - core/ui/src/main/res/drawable/checker.webp | Bin 1030 -> 0 bytes .../core/ui/utils/ShareUtils.native.kt | 32 + .../mifospay/ui/ExampleUnitTest.kt | 25 - .../core/ui/utils/ShareUtils.wasmJs.kt | 35 + feature/accounts/README.md | 27 + feature/accounts/build.gradle.kts | 22 +- feature/accounts/consumer-rules.pro | 0 feature/accounts/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../drawable/baseline_check.xml | 15 + .../drawable/baseline_unchecked.xml | 15 + .../drawable/feature_accounts_ic_bank.xml | 0 .../drawable/feature_accounts_logo_axis.png | Bin .../drawable/feature_accounts_logo_hdfc.png | Bin .../drawable/feature_accounts_logo_icici.png | Bin .../drawable/feature_accounts_logo_pnb.png | Bin .../drawable/feature_accounts_logo_rbl.png | Bin .../drawable/feature_accounts_logo_sbi.png | Bin .../feature_accounts_sim_card_selected.xml | 2 +- .../feature_accounts_sim_card_unselected.xml | 2 +- .../composeResources}/values/strings.xml | 4 +- .../feature/accounts/AccountViewModel.kt | 242 ++ .../feature/accounts/AccountsScreen.kt | 613 ++++ .../beneficiary/AddEditBeneficiaryScreen.kt | 296 ++ .../AddEditBeneficiaryViewModel.kt | 299 ++ .../beneficiary/BeneficiaryAddEditType.kt | 29 + .../beneficiary/BeneficiaryNavigation.kt | 80 + .../feature/accounts/di/AccountsModule.kt | 26 + .../AddEditSavingAccountScreen.kt | 542 ++++ .../savingsaccount/AddEditSavingNavigation.kt | 85 + .../savingsaccount/AddEditSavingViewModel.kt | 431 +++ .../savingsaccount/SavingsAddEditType.kt | 29 + .../details/SavingAccountDetailNavigation.kt | 42 + .../details/SavingAccountDetailScreen.kt | 499 +++ .../details/SavingAccountDetailViewModel.kt | 113 + .../feature/bank/accounts/AccountViewModel.kt | 141 - .../feature/bank/accounts/AccountsItem.kt | 74 - .../feature/bank/accounts/AccountsScreen.kt | 231 -- .../choose/sim/ChooseSimDialogSheet.kt | 210 -- .../details/BankAccountDetailScreen.kt | 251 -- .../bank/accounts/di/AccountsModule.kt | 26 - .../accounts/link/LinkBankAccountScreen.kt | 347 -- .../accounts/link/LinkBankAccountViewModel.kt | 106 - ...LinkBankUiStatePreviewParameterProvider.kt | 34 - .../navigation/BankAccountDetailNavigation.kt | 70 - .../navigation/LinkBankAccountNavigation.kt | 31 - .../accounts/src/main/res/values/colors.xml | 15 - feature/auth/build.gradle.kts | 38 +- .../auth/src/androidMain}/AndroidManifest.xml | 0 .../composeResources}/values/strings.xml | 6 +- .../mifospay/feature/auth/di/AuthModule.kt | 22 + .../feature/auth/login/LoginScreen.kt | 235 ++ .../feature/auth/login/LoginViewModel.kt | 154 + .../mobileVerify/MobileVerificationScreen.kt | 291 ++ .../MobileVerificationViewModel.kt | 287 ++ .../auth/navigation/LoginScreenNavigation.kt | 18 +- .../MobileVerificationScreenNavigation.kt | 37 + .../auth/navigation/SignupScreenNavigation.kt | 61 + .../feature/auth/signup/SignupScreen.kt | 309 ++ .../feature/auth/signup/SignupViewModel.kt | 592 ++++ .../socialSignup/SignupMethodNavigation.kt | 34 + .../auth/socialSignup/SignupMethodScreen.kt | 175 + .../mifospay/feature/auth/di/AuthModule.kt | 49 - .../feature/auth/login/LoginScreen.kt | 251 -- .../feature/auth/login/LoginViewModel.kt | 157 - .../mobileVerify/MobileVerificationScreen.kt | 289 -- .../MobileVerificationViewModel.kt | 92 - .../MobileVerificationScreenNavigation.kt | 83 - .../auth/navigation/SignupScreenNavigation.kt | 107 - .../feature/auth/signup/SignupScreen.kt | 531 --- .../feature/auth/signup/SignupViewModel.kt | 294 -- .../socialSignup/SocialSignupMethodScreen.kt | 350 -- feature/editpassword/README.md | 18 + feature/editpassword/build.gradle.kts | 16 +- feature/editpassword/consumer-rules.pro | 0 feature/editpassword/proguard-rules.pro | 21 - .../{main => androidMain}/AndroidManifest.xml | 0 .../composeResources}/values/strings.xml | 0 .../editpassword/EditPasswordScreen.kt | 197 ++ .../editpassword/EditPasswordViewModel.kt | 267 ++ .../editpassword/di/EditPasswordModule.kt | 11 +- .../EditPasswordScreenNavigation.kt | 12 +- .../editpassword/EditPasswordScreen.kt | 225 -- .../editpassword/EditPasswordViewModel.kt | 124 - feature/faq/README.md | 15 + feature/faq/build.gradle.kts | 16 +- feature/faq/consumer-rules.pro | 0 feature/faq/proguard-rules.pro | 21 - .../{main => androidMain}/AndroidManifest.xml | 0 .../composeResources}/values/strings.xml | 2 +- .../kotlin/org/mifospay/feature/faq/FAQ.kt | 7 +- .../org/mifospay/feature/faq/FAQViewModel.kt | 75 + .../org/mifospay/feature/faq/FaqScreen.kt | 123 +- .../org/mifospay/feature/faq/di/FaqModule.kt | 7 +- .../feature/faq/navigation/FAQNavigation.kt | 4 +- .../org/mifospay/feature/faq/FAQViewModel.kt | 34 - .../org/mifospay/feature/faq/FaqScreen.kt | 79 - feature/finance/README.md | 17 + feature/finance/build.gradle.kts | 16 +- feature/finance/consumer-rules.pro | 0 feature/finance/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../mifospay/feature/finance/FinanceScreen.kt | 8 +- .../finance/navigation/FinanceNavigation.kt | 0 feature/history/README.md | 20 + feature/history/build.gradle.kts | 17 +- feature/history/consumer-rules.pro | 0 feature/history/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../drawable/arrow_outward.xml} | 8 +- .../drawable/feature_history_ic_send.xml | 0 .../composeResources}/values/strings.xml | 4 +- .../mifospay/feature/history/HistoryScreen.kt | 134 + .../feature/history/HistoryViewModel.kt | 132 + .../history/components/HistoryScreenFilter.kt | 105 + .../history/components/TransactionDetail.kt | 214 ++ .../history/components/TransactionList.kt | 187 ++ .../history/detail/TransactionDetailScreen.kt | 128 + .../detail/TransactionDetailViewModel.kt | 96 + .../feature/history/di/HistoryModule.kt | 22 + .../history/navigation/HistoryNavigation.kt} | 22 +- .../SpecificTransactionsNavigation.kt | 52 + .../navigation/TransactionDetailNavigation.kt | 41 + .../SpecificTransactionsScreen.kt | 133 + .../SpecificTransactionsViewModel.kt | 133 + .../org/mifospay/feature/di/HistoryModule.kt | 40 - .../mifospay/feature/history/HistoryScreen.kt | 239 -- .../feature/history/HistoryViewModel.kt | 81 - .../SpecificTransactionsScreen.kt | 265 -- .../SpecificTransactionsViewModel.kt | 103 - .../SpecificTransactionsNavigation.kt | 53 - .../detail/TransactionDetailScreen.kt | 208 -- .../detail/TransactionDetailViewModel.kt | 50 - feature/home/README.md | 19 + feature/home/build.gradle.kts | 18 +- feature/home/consumer-rules.pro | 0 feature/home/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../drawable/arrow_backward.xml} | 8 +- .../drawable/arrow_outward.xml | 15 + .../composeResources}/drawable/coin_image.png | Bin .../composeResources}/values/strings.xml | 1 + .../org/mifospay/feature/home/HomeScreen.kt | 611 ++++ .../mifospay/feature/home/HomeViewModel.kt | 198 ++ .../mifospay/feature/home/di/HomeModule.kt | 10 +- .../feature/home/navigation/HomeNavigation.kt | 10 +- .../org/mifospay/feature/home/HomeScreen.kt | 453 --- .../mifospay/feature/home/HomeViewModel.kt | 86 - .../mifospay/feature/home/di/HomeModule.kt | 26 - feature/invoices/README.md | 16 + feature/invoices/build.gradle.kts | 18 +- feature/invoices/consumer-rules.pro | 0 feature/invoices/proguard-rules.pro | 21 - .../androidMain/kotlin}/AndroidManifest.xml | 0 .../composeResources/drawable/ic_check.xml} | 2 +- .../composeResources/drawable/ic_remove.xml} | 0 .../composeResources}/values/strings.xml | 0 .../mifospay/feature/invoices/InvoiceItem.kt | 47 +- .../feature/invoices/InvoiceScreen.kt | 146 + .../feature/invoices/InvoicesViewModel.kt | 93 + .../invoices/details/InvoiceDetailScreen.kt | 243 ++ .../details/InvoiceDetailViewModel.kt | 119 + .../feature/invoices/di/InvoicesModule.kt | 20 + .../invoices/navigation/InvoiceNavigation.kt | 19 +- .../feature/invoices/InvoiceDetailScreen.kt | 292 -- .../invoices/InvoiceDetailViewModel.kt | 66 - .../feature/invoices/InvoiceScreen.kt | 170 - .../feature/invoices/InvoicesViewModel.kt | 69 - .../feature/invoices/di/InvoicesModule.kt | 35 - .../invoices/src/main/res/values/colors.xml | 13 - feature/kyc/README.md | 17 + feature/kyc/build.gradle.kts | 27 +- feature/kyc/consumer-rules.pro | 0 feature/kyc/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../drawable/feature_kyc_ic_error_state.xml | 2 +- .../composeResources}/values/strings.xml | 2 +- .../feature/kyc/KYCDescriptionScreen.kt | 201 ++ .../feature/kyc/KYCDescriptionViewModel.kt | 120 + .../mifospay/feature/kyc/KYCLevel1Screen.kt | 269 ++ .../feature/kyc/KYCLevel1ViewModel.kt | 314 ++ .../mifospay/feature/kyc/KYCLevel2Screen.kt | 315 ++ .../feature/kyc/KYCLevel2ViewModel.kt | 238 ++ .../mifospay/feature/kyc/KYCLevel3Screen.kt | 51 + .../feature/kyc/KYCLevel3ViewModel.kt | 14 + .../org/mifospay/feature/kyc/di/KYCModule.kt | 24 + .../kyc/navigation/KYCLevel1Navigation.kt | 6 +- .../kyc/navigation/KYCLevel2Navigation.kt | 15 +- .../kyc/navigation/KYCLevel3Navigation.kt | 17 +- .../feature/kyc/navigation/KYCNavigation.kt | 0 .../feature/kyc/KYCDescriptionScreen.kt | 355 -- .../feature/kyc/KYCDescriptionViewModel.kt | 80 - .../mifospay/feature/kyc/KYCLevel1Screen.kt | 286 -- .../feature/kyc/KYCLevel1ViewModel.kt | 85 - .../mifospay/feature/kyc/KYCLevel2Screen.kt | 389 --- .../feature/kyc/KYCLevel2ViewModel.kt | 76 - .../mifospay/feature/kyc/KYCLevel3Screen.kt | 111 - .../feature/kyc/KYCLevel3ViewModel.kt | 34 - .../org/mifospay/feature/kyc/di/KYCModule.kt | 50 - feature/kyc/src/main/res/values/colors.xml | 18 - feature/kyc/src/main/res/values/dimens.xml | 25 - feature/make-transfer/README.md | 18 + feature/make-transfer/build.gradle.kts | 16 +- .../{main => androidMain}/AndroidManifest.xml | 0 .../feature_make_transfer_ic_close.xml | 2 +- .../feature_make_transfer_ic_done.xml | 2 +- ...feature_make_transfer_transfer_failure.xml | 0 ...feature_make_transfer_transfer_success.xml | 2 +- .../drawable/process_ring.xml | 52 + .../composeResources}/values/strings.xml | 0 .../make/transfer/MakeTransferScreen.kt | 416 +++ .../make/transfer/MakeTransferViewModel.kt | 264 ++ .../make/transfer/di/MakeTransferModule.kt | 12 +- .../navigation/MakeTransferNavigation.kt | 52 + .../success/TransferSuccessNavigation.kt | 33 + .../transfer/success/TransferSuccessScreen.kt | 85 + .../make/transfer/MakeTransferScreen.kt | 401 --- .../make/transfer/MakeTransferViewModel.kt | 129 - .../navigation/MakeTransferNavigation.kt | 64 - .../merchants/README.md | 0 feature/merchants/build.gradle.kts | 18 +- feature/merchants/consumer-rules.pro | 0 feature/merchants/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../drawable/feature_merchants_ic_bank.xml | 0 .../composeResources}/values/strings.xml | 0 .../merchants/MerchantTransferViewModel.kt | 32 + .../feature/merchants/MerchantViewModel.kt | 72 + .../feature/merchants/di/MerchantsModule.kt | 20 + .../navigation/MerchantTransferNavigation.kt | 0 .../feature/merchants/ui/MerchantScreen.kt | 182 +- .../merchants/ui/MerchantTransferScreen.kt | 148 +- .../feature/merchants/ui/MerchantsItem.kt | 21 +- .../merchants/MerchantTransferViewModel.kt | 146 - .../feature/merchants/MerchantViewModel.kt | 149 - .../feature/merchants/di/MerchantsModule.kt | 38 - feature/notification/README.md | 14 + feature/notification/build.gradle.kts | 18 +- feature/notification/consumer-rules.pro | 0 feature/notification/proguard-rules.pro | 21 - .../{main => androidMain}/AndroidManifest.xml | 0 .../composeResources}/values/strings.xml | 0 .../notification/NotificationNavigation.kt | 17 +- .../notification/NotificationScreen.kt | 206 ++ .../notification/NotificationViewModel.kt | 52 + .../notification/di/NotificationModule.kt | 10 +- .../notification/NotificationScreen.kt | 201 -- .../notification/NotificationViewModel.kt | 70 - feature/payments/README.md | 16 + feature/payments/build.gradle.kts | 16 +- feature/payments/consumer-rules.pro | 0 feature/payments/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../drawable/baseline_content_copy.xml | 15 + .../composeResources}/values/strings.xml | 4 +- .../feature/payments/PaymentNavigation.kt | 0 .../feature/payments/PaymentsScreen.kt | 13 +- .../feature/payments/RequestScreen.kt | 179 + .../feature/payments/TransferViewModel.kt | 69 + .../feature/payments/di/PaymentsModule.kt | 10 +- .../feature/payments/RequestScreen.kt | 138 - .../feature/payments/TransferViewModel.kt | 90 - feature/profile/README.md | 18 + feature/profile/build.gradle.kts | 38 +- feature/profile/consumer-rules.pro | 2 + feature/profile/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../composeResources/drawable/placeholder.png | Bin .../composeResources}/values/strings.xml | 4 +- .../mifospay/feature/profile/ProfileScreen.kt | 204 ++ .../feature/profile/ProfileViewModel.kt | 145 + .../profile/components}/ProfileCard.kt | 42 +- .../profile/components/ProfileImage.kt | 180 + .../feature/profile/di/ProfileModule.kt | 20 + .../feature/profile/edit/EditProfileScreen.kt | 212 ++ .../profile/edit/EditProfileViewModel.kt | 315 ++ .../navigation/EditProfileNavigation.kt | 15 +- .../profile/navigation/ProfileNavigation.kt | 58 + .../mifospay/feature/profile/ProfileScreen.kt | 137 - .../feature/profile/ProfileViewModel.kt | 96 - .../feature/profile/di/ProfileModule.kt | 35 - .../feature/profile/edit/EditProfileScreen.kt | 469 --- .../profile/edit/EditProfileScreenImage.kt | 101 - .../profile/edit/EditProfileViewModel.kt | 118 - feature/qr/README.md | 4 + feature/qr/build.gradle.kts | 50 +- feature/qr/consumer-rules.pro | 2 + feature/qr/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 5 +- .../mifospay/feature/qr/BarcodeAnalyzer.kt | 57 + .../qr/CameraPermissionState.android.kt | 72 + .../org/mifospay/feature/qr/CameraView.kt | 79 + .../feature/qr/QrCodeScanner.android.kt | 27 + .../kotlin/org/mifospay/feature/qr/Utils.kt | 34 + .../composeResources}/values/strings.xml | 0 .../feature/qr/CameraPermissionState.kt | 19 +- .../org/mifospay/feature/qr/CodeType.kt | 17 +- .../org/mifospay/feature/qr/QrCodeScanner.kt | 81 + .../mifospay/feature/qr/ScanQrCodeScreen.kt | 89 + .../mifospay/feature/qr/ScanQrViewModel.kt | 44 + .../org/mifospay/feature/qr/di/QrModule.kt | 11 +- .../feature/qr/navigation/ReadQrNavigation.kt | 33 + .../qr/CameraPermissionState.desktop.kt | 28 + .../feature/qr/QrCodeScanner.desktop.kt | 26 + .../feature/qr/CameraPermissionState.js.kt | 28 + .../mifospay/feature/qr/QrCodeScanner.js.kt | 26 + .../mifospay/feature/read/qr/ReadQrScreen.kt | 257 -- .../feature/read/qr/ReadQrViewModel.kt | 50 - .../mifospay/feature/read/qr/di/QrModule.kt | 24 - .../read/qr/navigation/ReadQrNavigation.kt | 29 - .../feature/read/qr/utils/QrCodeAnalyzer.kt | 73 - .../mifospay/feature/read/qr/utils/ScanQr.kt | 51 - .../qr/CameraPermissionState.native.kt | 68 + .../org/mifospay/feature/qr/CameraView.kt | 228 ++ .../feature/qr/OrientationListener.kt | 52 + .../feature/qr/QrCodeScanner.native.kt | 26 + .../kotlin/org/mifospay/feature/qr/Utls.kt | 40 + .../qr/CameraPermissionState.wasmJs.kt | 28 + .../feature/qr/QrCodeScanner.wasmJs.kt | 26 + feature/receipt/README.md | 178 + feature/receipt/build.gradle.kts | 20 +- feature/receipt/consumer-rules.pro | 0 feature/receipt/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../drawable/feature_receipt_ic_download.xml | 0 .../feature_receipt_mifospay_round_logo.png | Bin .../composeResources}/values/strings.xml | 0 .../mifospay/feature/receipt/ReceiptScreen.kt | 83 + .../feature/receipt/ReceiptViewModel.kt | 40 + .../feature/receipt/di/ReceiptModule.kt | 18 + .../receipt/navigation/ReceiptNavigation.kt} | 19 +- .../mifospay/feature/receipt/ReceiptScreen.kt | 620 ---- .../feature/receipt/ReceiptViewModel.kt | 167 - .../feature/receipt/di/ReceiptModule.kt | 27 - .../receipt/navigation/ReceiptNavigation.kt | 44 - feature/request-money/README.md | 7 + feature/request-money/build.gradle.kts | 20 +- feature/request-money/consumer-rules.pro | 0 feature/request-money/proguard-rules.pro | 21 - .../androidMain/kotlin}/AndroidManifest.xml | 5 +- .../composeResources}/drawable/logo.png | Bin .../composeResources}/values/strings.xml | 2 - .../feature/request/money/SetAmountDialog.kt | 224 ++ .../feature/request/money/ShowQrScreen.kt | 225 ++ .../feature/request/money/ShowQrViewModel.kt | 284 ++ .../request/money/di/RequestMoneyModule.kt | 18 + .../money/navigation/ShowQrNavigation.kt | 22 +- .../feature/request/money/GenerateQr.kt | 284 -- .../request/money/PayVpaMobileScreen.kt | 196 -- .../feature/request/money/SetAmountDialog.kt | 192 -- .../feature/request/money/ShowQrContent.kt | 121 - .../request/money/ShowQrScreenRoute.kt | 211 -- .../feature/request/money/ShowQrViewModel.kt | 71 - .../request/money/di/RequestMoneyModule.kt | 31 - .../feature/request/money/util/ImageUtils.kt | 41 - feature/savedcards/README.md | 21 + feature/savedcards/build.gradle.kts | 19 +- feature/savedcards/consumer-rules.pro | 0 feature/savedcards/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../composeResources/drawable/amex_logo.xml | 28 + .../composeResources/drawable/bg1.xml | 35 + .../composeResources/drawable/bg2.xml | 254 ++ .../composeResources/drawable/bg3.xml | 32 + .../composeResources/drawable/bg4.xml | 29 + .../composeResources/drawable/circle_bg.xml | 63 + .../composeResources/drawable/diner_clubs.xml | 22 + .../drawable/ic_mastercard.xml | 31 + .../composeResources/drawable/ic_visa.xml | 22 + .../composeResources/drawable/maestro.xml | 29 + .../composeResources/drawable/red_bg.xml | 43 + .../composeResources/drawable/rupay_logo.xml | 46 + .../composeResources/drawable/symbol.xml | 23 + .../composeResources/drawable/violet_bg.xml | 38 + .../composeResources}/values/strings.xml | 4 +- .../feature/savedcards/CardsScreen.kt | 335 ++ .../savedcards/CardsScreenViewModel.kt | 222 ++ .../savedcards/components/CardConfig.kt | 31 + .../savedcards/components/CardNumberFilter.kt | 179 + .../savedcards/components/ColorUtils.kt | 90 + .../savedcards/components/CreditCard.kt | 593 ++++ .../createOrUpdate/AddEditCardNavigation.kt | 86 + .../createOrUpdate/AddEditCardScreen.kt | 333 ++ .../createOrUpdate/AddEditCardViewModel.kt | 346 ++ .../createOrUpdate/CardAddEditType.kt | 29 + .../details/CardDetailNavigation.kt | 40 + .../savedcards/details/CardDetailScreen.kt | 248 ++ .../savedcards/details/CardDetailViewModel.kt | 97 + .../feature/savedcards/di/SavedCardsModule.kt | 17 +- .../savedcards/utils/CreditCardUtils.kt | 313 ++ .../feature/savedcards/AddCardDialogSheet.kt | 254 -- .../feature/savedcards/CardsScreen.kt | 495 --- .../savedcards/CardsScreenViewModel.kt | 179 - .../navigation/AddCardNavigation.kt | 38 - feature/search/.gitignore | 1 - .../mifospay/feature/search/SearchScreen.kt | 290 -- .../feature/search/SearchViewModel.kt | 65 - .../feature/search/di/SearchModule.kt | 24 - .../search/src/main/res/values/strings.xml | 14 - feature/send-money/README.md | 18 + feature/send-money/build.gradle.kts | 24 +- .../src/androidMain}/AndroidManifest.xml | 0 .../feature/send/money/PlayScannerModule.kt | 46 + .../feature/send/money/QrScanner.android.kt | 57 + .../composeResources}/values/strings.xml | 10 +- .../mifospay/feature/send/money/QrScanner.kt | 12 +- .../feature/send/money/SendMoneyScreen.kt | 504 +++ .../feature/send/money/SendMoneyViewModel.kt | 255 ++ .../feature/send/money/di/SendMoneyModule.kt | 14 +- .../send/money/navigation/SendNavigation.kt | 62 + .../feature/send/money/QrScanner.desktop.kt | 25 + .../feature/send/money/QrScanner.js.kt | 25 + .../send-money/src/main/AndroidManifest.xml | 11 - .../send/money/SendPaymentViewModel.kt | 105 - .../feature/send/money/SendScreenRoute.kt | 438 --- .../send/money/navigation/SendNavigation.kt | 35 - .../feature/send/money/QrScanner.native.kt | 25 + .../feature/send/money/QrScanner.wasmJs.kt | 25 + feature/settings/README.md | 18 + feature/settings/build.gradle.kts | 19 +- feature/settings/consumer-rules.pro | 0 feature/settings/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../drawable/outline_logout.xml | 15 + .../drawable/outline_password.xml | 15 + .../composeResources/drawable/outline_pin.xml | 21 + .../composeResources}/values/strings.xml | 0 .../feature/settings/SettingsScreen.kt | 245 ++ .../feature/settings/SettingsViewModel.kt | 189 ++ .../feature/settings/di/SettingsModule.kt | 10 +- .../settings/navigation/SettingsNavigation.kt | 10 +- feature/settings/src/main/AndroidManifest.xml | 13 - .../feature/settings/DialogManager.kt | 49 - .../feature/settings/SettingsScreen.kt | 170 - .../feature/settings/SettingsViewModel.kt | 45 - feature/standing-instruction/README.md | 24 + feature/standing-instruction/build.gradle.kts | 17 +- .../standing-instruction/consumer-rules.pro | 0 .../standing-instruction/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../composeResources}/values/strings.xml | 2 + .../instruction/StandingInstructionScreen.kt | 381 +++ .../StandingInstructionViewModel.kt | 222 ++ .../instruction/components/FrequencyChip.kt | 46 + .../components/InstructionTypeChip.kt | 46 + .../instruction/components/PriorityChip.kt | 49 + .../createOrUpdate/AddEditSINavigation.kt | 83 + .../createOrUpdate/AddEditSIScreen.kt | 863 +++++ .../createOrUpdate/AddEditSIViewModel.kt | 643 ++++ .../createOrUpdate/SIAddEditType.kt | 29 + .../instruction/details/SIDetailViewModel.kt | 103 + .../details/SIDetailsNavigation.kt | 39 + .../instruction/details/SIDetailsScreen.kt | 320 ++ .../di/StandingInstructionModule.kt | 22 + .../standing/instruction/NewSIScreenRoute.kt | 485 --- .../standing/instruction/NewSIViewModel.kt | 107 - .../feature/standing/instruction/SIContent.kt | 76 - .../standing/instruction/SIDetailsScreen.kt | 294 -- .../StandingInstructionDetailsViewModel.kt | 106 - .../StandingInstructionNavigation.kt | 56 - .../instruction/StandingInstructionScreen.kt | 152 - .../StandingInstructionViewModel.kt | 67 - .../di/StandingInstructionModule.kt | 45 - .../upi-setup/README.md | 0 feature/upi-setup/build.gradle.kts | 18 +- feature/upi-setup/consumer-rules.pro | 0 feature/upi-setup/proguard-rules.pro | 21 - .../src/androidMain}/AndroidManifest.xml | 0 .../composeResources}/values/strings.xml | 0 .../feature/upi/setup}/di/UpiSetupModule.kt | 18 +- .../navigation/SetupUpiPinNavigation.kt | 29 +- .../upi/setup}/screens/DebitCardScreen.kt | 10 +- .../setup}/screens/DebitCardScreenContent.kt | 6 +- .../feature/upi/setup}/screens/OtpScreen.kt | 11 +- .../upi/setup}/screens/SetUpUPiPinScreen.kt | 50 +- .../setup}/screens/SetUpUpiScreenContent.kt | 11 +- .../upi/setup}/screens/UpiPinScreen.kt | 20 +- .../setup}/viewmodel/DebitCardViewModal.kt | 2 +- .../upi/setup}/viewmodel/SetUpUpiViewModal.kt | 4 +- .../upi-setup/src/main/AndroidManifest.xml | 13 - gradle.properties | 1 + gradle/libs.versions.toml | 358 +- gradle/wrapper/gradle-wrapper.properties | 2 +- kotlin-js-store/yarn.lock | 2882 +++++++++++++++++ libs/country-code-picker/.gitignore | 1 - libs/country-code-picker/README.md | 5 - libs/country-code-picker/build.gradle.kts | 33 - .../src/main/AndroidManifest.xml | 13 - .../countrycodepicker/CountryCodePicker.kt | 616 ---- .../countrycodepicker/component/Autofill.kt | 52 - .../component/CountryCodeDialog.kt | 162 - .../component/CountryDialog.kt | 291 -- .../countrycodepicker/data/CountryData.kt | 263 -- .../data/utils/CountryCodeUtils.kt | 64 - .../data/utils/CountryNameMap.kt | 258 -- .../data/utils/NumberHintMap.kt | 259 -- .../data/utils/SearchCountryList.kt | 37 - .../data/utils/ValidatePhoneNumber.kt | 31 - .../PhoneNumberTransformation.kt | 119 - .../src/main/res/values-ar/strings.xml | 260 -- .../src/main/res/values-es/strings.xml | 260 -- .../src/main/res/values-fr/strings.xml | 260 -- .../src/main/res/values-hi/strings.xml | 260 -- .../src/main/res/values-it-rIT/strings.xml | 260 -- .../src/main/res/values-nl/strings.xml | 260 -- .../src/main/res/values-ru-rRU/strings.xml | 260 -- .../src/main/res/values-so/strings.xml | 260 -- .../src/main/res/values-tr-rTR/strings.xml | 260 -- .../src/main/res/values-zh/strings.xml | 260 -- .../src/main/res/values/strings.xml | 502 --- libs/material3-navigation/.gitignore | 1 - libs/material3-navigation/README.md | 7 - libs/material3-navigation/build.gradle.kts | 24 - .../src/main/AndroidManifest.xml | 11 - .../material3/navigation/BottomSheet.kt | 59 - .../navigation/BottomSheetNavigator.kt | 286 -- .../BottomSheetNavigatorDestinationBuilder.kt | 56 - .../material3/navigation/NavGraphBuilder.kt | 69 - libs/mifos-passcode/build.gradle.kts | 68 +- .../{main => androidMain}/AndroidManifest.xml | 0 .../lib_mifos_passcode_mifos_logo.jpg | Bin .../font/lib_mifos_passcode_lato_black.ttf | Bin .../font/lib_mifos_passcode_lato_bold.ttf | Bin .../font/lib_mifos_passcode_lato_regular.ttf | Bin .../composeResources}/values/strings.xml | 0 .../mifos/library/passcode/PassCodeScreen.kt | 84 +- .../library/passcode/PasscodeNavigation.kt | 0 .../library/passcode/component/MifosIcon.kt | 7 +- .../passcode/component/PasscodeButton.kt | 13 +- .../passcode/component/PasscodeHeader.kt | 15 +- .../passcode/component/PasscodeKeys.kt | 7 +- .../component/PasscodeMismatchedDialog.kt | 10 +- .../component/PasscodeStepIndicator.kt | 0 .../passcode/component/PasscodeToolbar.kt | 13 +- .../library/passcode/di/PasscodeModule.kt | 21 + .../org/mifos/library/passcode/theme/Color.kt | 0 .../org/mifos/library/passcode/theme/Font.kt | 41 + .../org/mifos/library/passcode/theme/Theme.kt | 2 +- .../org/mifos/library/passcode/theme/Type.kt | 12 - .../library/passcode/utility/Constants.kt | 0 .../passcode/utility/ShakeAnimation.kt | 0 .../mifos/library/passcode/utility/Step.kt | 2 +- .../passcode/viewmodels/PasscodeViewModel.kt | 199 ++ .../library/passcode/data/PasscodeManager.kt | 48 + .../data/PasscodePreferencesDataSource.kt | 66 + .../library/passcode/di/PreferenceModule.kt | 23 + .../model/PasscodePreferencesProto.kt | 22 + .../passcode/passcode_preferences.proto | 8 + .../library/passcode/data/PasscodeManager.kt | 29 - .../passcode/data/PasscodeRepositoryImpl.kt | 28 - .../library/passcode/di/ApplicationModule.kt | 35 - .../org/mifos/library/passcode/theme/Font.kt | 34 - .../passcode/utility/PreferenceManager.kt | 39 - .../passcode/utility/VibrationFeedback.kt | 48 - .../passcode/viewmodels/PasscodeViewModel.kt | 148 - .../lib_mifos_passcode_delete_forever.xml | 15 - .../drawable/lib_mifos_passcode_ic_delete.xml | 20 - libs/pullrefresh/.gitignore | 1 - libs/pullrefresh/README.md | 5 - libs/pullrefresh/build.gradle.kts | 24 - libs/pullrefresh/src/main/AndroidManifest.xml | 11 - .../PullRefresh.kt | 107 - .../PullRefreshIndicator.kt | 236 -- .../PullRefreshIndicatorTransform.kt | 66 - .../PullRefreshState.kt | 229 -- lint/.gitignore | 1 - lint/build.gradle.kts | 37 - lint/lint-baseline.xml | 13 - .../mifospay/lint/MifosPayIssueRegistry.kt | 36 - .../mifospay/lint/TestMethodNameDetector.kt | 119 - .../mifos/mifospay/lint/config/Priorities.kt | 17 - .../lint/designsystem/DesignSystemDetector.kt | 110 - .../lint/designsystem/Material2Detector.kt | 103 - .../org/mifos/mifospay/lint/util/LintUtils.kt | 54 - .../lint/util/OptionLoadingDetector.kt | 25 - .../mifospay/lint/util/StringSetLintOption.kt | 22 - ...ndroid.tools.lint.client.api.IssueRegistry | 1 - .../lint/TestMethodNameDetectorTest.kt | 116 - .../designsystem/DesignSystemDetectorTest.kt | 157 - mifospay-android/.gitignore | 1 + {mifospay => mifospay-android}/README.md | 0 .../build.gradle.kts | 45 +- .../prodReleaseRuntimeClasspath.tree.txt | 2713 ++++++++++++++++ .../prodReleaseRuntimeClasspath.txt | 405 +++ .../google-services.json | 0 .../lint-baseline.xml | 0 .../prodRelease-badging.txt | 17 +- .../proguard-rules.pro | 0 .../release_keystore.keystore | Bin .../org/mifospay/ExampleInstrumentedTest.kt | 0 .../src/main/AndroidManifest.xml | 14 +- .../main/kotlin/org/mifospay/MainActivity.kt | 76 + .../main/kotlin/org/mifospay/MifosPayApp.kt | 16 +- .../src/main/res/drawable/bg_splash.xml | 0 .../src/main/res/drawable/bg_splash_12.xml | 0 .../res/drawable/feature_accounts_ic_bank.xml | 28 + .../feature_receipt_mifospay_round_logo.png | Bin 0 -> 39075 bytes .../src/main/res/drawable/ic_finance.xml | 0 .../src/main/res/drawable/ic_home.xml | 0 .../src/main/res/drawable/ic_person.xml | 0 .../src/main/res/drawable/ic_swap_horiz.xml | 0 .../src/main/res/drawable/logo_axis.png | Bin .../src/main/res/drawable/logo_hdfc.png | Bin .../src/main/res/drawable/logo_icici.png | Bin .../src/main/res/drawable/logo_pnb.png | Bin .../src/main/res/drawable/logo_rbl.png | Bin .../src/main/res/drawable/logo_sbi.png | Bin .../main/res/drawable/mifospay_round_logo.png | Bin 0 -> 39075 bytes .../src/main/res/drawable/money_in.png | Bin .../src/main/res/drawable/money_out.png | Bin .../src/main/res/drawable/splash_icon.png | Bin .../res/drawable/splash_screen_background.xml | 0 .../src/main/res/mipmap/ic_launcher.png | Bin .../src/main/res/mipmap/ic_launcher_round.png | Bin .../src/main/res/values/colors.xml | 0 .../src/main/res/values/splash.xml | 0 .../src/main/res/values/strings.xml | 0 .../src/main/res/xml/provider_paths.xml | 0 mifospay-desktop/.gitignore | 1 + mifospay-desktop/README.md | 1 + .../build.gradle.kts | 18 +- .../src/desktopMain/kotlin/main.kt | 5 +- .../iosApp.xcodeproj/project.pbxproj | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../UserInterfaceState.xcuserstate | Bin .../xcschemes/xcschememanagement.plist | 0 .../xcschemes/iosApp.xcscheme | 0 .../xcschemes/xcschememanagement.plist | 0 .../AccentColor.colorset/Contents.json | 0 .../AppIcon.appiconset/Contents.json | 0 .../iosApp/Assets.xcassets/Contents.json | 0 .../iosApp/ContentView.swift | 2 +- .../Preview Assets.xcassets/Contents.json | 0 .../iosApp/iosAppApp.swift | 2 +- mifospay-shared/build.gradle.kts | 93 + .../composeResources/values/strings.xml | 21 + .../kotlin/org/mifospay/shared/MifosPayApp.kt | 72 + .../org/mifospay/shared/MifosPayViewModel.kt | 25 +- .../org/mifospay/shared/di/KoinModules.kt | 116 + .../shared}/navigation/LoginNavGraph.kt | 33 +- .../shared}/navigation/MifosNavGraph.kt | 2 +- .../shared/navigation/MifosNavHost.kt | 336 ++ .../shared}/navigation/PasscodeNavGraph.kt | 23 +- .../shared}/navigation/RootNavGraph.kt | 13 +- .../org/mifospay/shared}/ui/MifosApp.kt | 224 +- .../org/mifospay/shared}/ui/MifosAppState.kt | 74 +- .../shared/utils}/TopLevelDestination.kt | 32 +- mifospay-web/.gitignore | 1 + mifospay-web/README.md | 3 + mifospay-web/build.gradle.kts | 54 + mifospay-web/src/jsMain/kotlin/Application.kt | 15 + mifospay-web/src/jsMain/resources/index.html | 15 + mifospay-web/src/jsMain/resources/styles.css | 14 + mifospay-web/src/wasmJsMain/kotlin/Main.kt | 22 + .../src/wasmJsMain/resources/index.html | 26 + .../prodReleaseRuntimeClasspath.tree.txt | 2624 --------------- .../prodReleaseRuntimeClasspath.txt | 408 --- .../main/java/org/mifospay/MainActivity.kt | 145 - .../src/main/java/org/mifospay/MifosPayApp.kt | 42 - .../api/services/MifosPayMessagingService.kt | 246 -- .../java/org/mifospay/di/JankStatsModule.kt | 36 - .../main/java/org/mifospay/di/KoinModules.kt | 76 - .../org/mifospay/navigation/MifosNavHost.kt | 305 -- .../org/mifospay/utils/NotificationUtils.kt | 257 -- .../java/org/mifospay/KoinModulesCheck.kt | 77 - scripts/pre-commit.sh | 21 - scripts/pre-push.sh | 24 - settings.gradle.kts | 18 +- shared/build.gradle.kts | 119 - .../org/mifospay/shared/MainActivity.kt | 32 - .../org/mifospay/shared/Platform.android.kt | 22 - .../preferences/DataStoreModule.android.kt | 23 - .../kotlin/org/mifospay/shared/App.kt | 37 - .../kotlin/org/mifospay/shared/Platform.kt | 26 - .../org/mifospay/shared/di/KoinModule.kt | 20 - .../mifospay/shared/modal/domain/Client.kt | 19 - .../org/mifospay/shared/modal/domain/Role.kt | 17 - .../mifospay/shared/modal/domain/UserData.kt | 17 - .../shared/preferences/DataStoreModule.kt | 32 - .../preferences/UserPreferenceRepository.kt | 169 - .../preferences/UserPreferenceSerializer.kt | 33 - .../commonMain/proto/user_preferences.proto | 49 - .../preferences/DataStoreModule.desktop.kt | 25 - .../org/mifospay/shared/MainViewController.kt | 21 - .../org/mifospay/shared/Platform.ios.kt | 20 - .../shared/preferences/DataStoreModule.ios.kt | 33 - 1233 files changed, 48054 insertions(+), 39867 deletions(-) delete mode 100644 .github/workflows/feature_branch_ci.yml create mode 100644 .run/mifospay-android.run.xml create mode 100644 .run/mifospay-desktop.run.xml create mode 100644 .run/mifospay-web-js.run.xml create mode 100644 .run/mifospay-web-wasm.run.xml delete mode 100644 build-logic/convention/src/main/kotlin/AndroidApplicationFirebaseConventionPlugin.kt delete mode 100644 build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt delete mode 100644 build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt delete mode 100644 build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt delete mode 100644 build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt delete mode 100644 build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt create mode 100644 build-logic/convention/src/main/kotlin/CMPFeatureConventionPlugin.kt delete mode 100644 build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt rename build-logic/convention/src/main/kotlin/{AndroidKoinConventionPlugin.kt => KMPKoinConventionPlugin.kt} (50%) rename build-logic/convention/src/main/kotlin/{AndroidLibraryConventionPlugin.kt => KMPLibraryConventionPlugin.kt} (50%) create mode 100644 build-logic/convention/src/main/kotlin/org/mifospay/KotlinMultiplatform.kt delete mode 100644 core/analytics/proguard-rules.pro rename core/analytics/src/{main => androidMain/kotlin}/AndroidManifest.xml (100%) rename core/analytics/src/{main => androidMain}/kotlin/org/mifospay/core/analytics/AnalyticsEvent.kt (100%) rename core/analytics/src/{main => androidMain}/kotlin/org/mifospay/core/analytics/AnalyticsHelper.kt (100%) rename core/analytics/src/{main => androidMain}/kotlin/org/mifospay/core/analytics/NoOpAnalyticsHelper.kt (100%) rename core/analytics/src/{main => androidMain}/kotlin/org/mifospay/core/analytics/StubAnalyticsHelper.kt (100%) rename core/analytics/src/{main => androidMain}/kotlin/org/mifospay/core/analytics/UiHelpers.kt (100%) rename core/analytics/src/{main => androidMain}/kotlin/org/mifospay/core/analytics/di/AnalyticsModule.kt (100%) rename core/analytics/src/{main => androidMain}/kotlin/org/mifospay/core/analytics/di/FirebaseAnalyticsHelper.kt (100%) delete mode 100644 core/common/proguard-rules.pro rename core/common/src/{main => androidMain}/AndroidManifest.xml (100%) create mode 100644 core/common/src/androidMain/kotlin/org/mifospay/core/common/CurrencyFormatter.android.kt rename core/{model/src/main/java/com/mifospay/core/model/domain/client/UpdateClientEntityMobile.kt => common/src/androidMain/kotlin/org/mifospay/core/common/FileUtils.android.kt} (70%) create mode 100644 core/common/src/androidMain/kotlin/org/mifospay/core/common/Parcelize.kt rename core/common/src/{main/kotlin/org/mifospay/core/network/di/DispatchersModule.kt => androidMain/kotlin/org/mifospay/core/common/di/DispatchersModule.android.kt} (61%) rename core/common/src/{main/kotlin/org/mifospay => commonMain/kotlin/org/mifospay/core}/common/Constants.kt (99%) rename feature/search/build.gradle.kts => core/common/src/commonMain/kotlin/org/mifospay/core/common/CurrencyFormatter.kt (58%) create mode 100644 core/common/src/commonMain/kotlin/org/mifospay/core/common/DataState.kt create mode 100644 core/common/src/commonMain/kotlin/org/mifospay/core/common/DataStateExtensions.kt create mode 100644 core/common/src/commonMain/kotlin/org/mifospay/core/common/DateHelper.kt rename shared/src/androidMain/kotlin/org/mifospay/shared/di/AndroidPlatformContextProvider.kt => core/common/src/commonMain/kotlin/org/mifospay/core/common/DebugUtil.kt (52%) create mode 100644 core/common/src/commonMain/kotlin/org/mifospay/core/common/FileUtils.kt rename core/common/src/{main/kotlin/org/mifospay/core/network => commonMain/kotlin/org/mifospay/core/common}/MifosDispatchers.kt (92%) rename core/common/src/{main/kotlin/org/mifospay => commonMain/kotlin/org/mifospay/core}/common/NavArgsConstants.kt (92%) create mode 100644 core/common/src/commonMain/kotlin/org/mifospay/core/common/Parcelize.kt rename core/common/src/{main/kotlin/org/mifospay/core/network/di/CoroutineScopesModule.kt => commonMain/kotlin/org/mifospay/core/common/di/DispatchersModule.kt} (57%) create mode 100644 core/common/src/commonMain/kotlin/org/mifospay/core/common/utils/StringExtensions.kt create mode 100644 core/common/src/desktopMain/kotlin/org/mifospay/core/common/CurrencyFormatter.jvm.kt create mode 100644 core/common/src/desktopMain/kotlin/org/mifospay/core/common/FileUtils.jvm.kt create mode 100644 core/common/src/desktopMain/kotlin/org/mifospay/core/common/Parcelize.kt create mode 100644 core/common/src/desktopMain/kotlin/org/mifospay/core/common/di/DispatchersModule.desktop.kt create mode 100644 core/common/src/jsMain/kotlin/org/mifospay/core/common/CurrencyFormatter.js.kt rename shared/src/androidMain/kotlin/org/mifospay/shared/di/Modules.android.kt => core/common/src/jsMain/kotlin/org/mifospay/core/common/FileUtils.js.kt (76%) create mode 100644 core/common/src/jsMain/kotlin/org/mifospay/core/common/Parcelize.kt create mode 100644 core/common/src/jsMain/kotlin/org/mifospay/core/common/di/DispatchersModule.js.kt delete mode 100644 core/common/src/main/kotlin/org/mifospay/common/CreditCardUtils.kt delete mode 100644 core/common/src/main/kotlin/org/mifospay/common/DebugUtil.kt delete mode 100644 core/common/src/main/kotlin/org/mifospay/common/FileUtils.kt delete mode 100644 core/common/src/main/kotlin/org/mifospay/common/Utils.kt create mode 100644 core/common/src/nativeMain/kotlin/org/mifospay/core/common/CurrencyFormatter.native.kt create mode 100644 core/common/src/nativeMain/kotlin/org/mifospay/core/common/FileUtils.native.kt create mode 100644 core/common/src/nativeMain/kotlin/org/mifospay/core/common/Parcelize.kt create mode 100644 core/common/src/nativeMain/kotlin/org/mifospay/core/common/di/DispatchersModule.native.kt create mode 100644 core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/CurrencyFormatter.js.kt rename core/{network/src/main/kotlin/org/mifospay/core/network/services/SavingsAccountsService.kt => common/src/wasmJsMain/kotlin/org/mifospay/core/common/FileUtils.js.kt} (76%) create mode 100644 core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/Parcelize.kt create mode 100644 core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/di/DispatchersModule.js.kt rename core/data/src/{main => androidMain}/AndroidManifest.xml (100%) create mode 100644 core/data/src/androidMain/kotlin/org/mifospay/core/data/di/AndroidPlatformDependentDataModule.kt create mode 100644 core/data/src/androidMain/kotlin/org/mifospay/core/data/di/AndroidPlatformModule.kt rename core/data/src/{main/java => androidMain/kotlin}/org/mifospay/core/data/util/ConnectivityManagerNetworkMonitor.kt (84%) rename core/data/src/{main/java/org/mifospay/core/data/util/TimeZoneMonitor.kt => androidMain/kotlin/org/mifospay/core/data/util/TimeZoneBroadcastMonitor.kt} (91%) rename core/data/src/{main => androidMain}/res/values/strings.xml (100%) rename core/data/src/{main => commonMain}/assets/banks.json (100%) rename core/data/src/{main => commonMain}/assets/cities.json (100%) rename core/data/src/{main => commonMain}/assets/countriesToCities.json (100%) create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/di/RepositoryModule.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/AccountMapper.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/ClientDetailsMapper.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/SavingAccountMapper.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/SearchedEntitiesMapper.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/TransactionMapper.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/UserMapper.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/AccountRepository.kt rename feature/auth/src/main/kotlin/org/mifospay/feature/auth/utils/ValidateUtil.kt => core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/AuthenticationRepository.kt (56%) create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/BeneficiaryRepository.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/ClientRepository.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/DocumentRepository.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/InvoiceRepository.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/KycLevelRepository.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/LocalAssetRepository.kt rename core/data/src/{main/java/org/mifospay/core/data/repository/auth/UserDataRepository.kt => commonMain/kotlin/org/mifospay/core/data/repository/NotificationRepository.kt} (59%) create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/RegistrationRepository.kt rename core/data/src/{main/java/org/mifospay/core/data/repository/local/LocalAssetRepository.kt => commonMain/kotlin/org/mifospay/core/data/repository/RunReportRepository.kt} (50%) create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SavedCardRepository.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SavingsAccountRepository.kt rename core/data/src/{main/java/org/mifospay/core/data/domain/usecase/history/HistoryContract.kt => commonMain/kotlin/org/mifospay/core/data/repository/SearchRepository.kt} (50%) create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SelfServiceRepository.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/StandingInstructionRepository.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/ThirdPartyTransferRepository.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/TwoFactorAuthRepository.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/UserRepository.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/AccountRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/AuthenticationRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/BeneficiaryRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/ClientRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/DocumentRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/InvoiceRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/KycLevelRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/LocalAssetRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/NotificationRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/RegistrationRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/RunReportRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SavedCardRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SavingsAccountRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SearchRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SelfServiceRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/StandingInstructionRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/ThirdPartyTransferRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/TwoFactorAuthRepositoryImpl.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/UserRepositoryImpl.kt rename core/data/src/{main/java => commonMain/kotlin}/org/mifospay/core/data/util/Constants.kt (90%) rename core/data/src/{main/java => commonMain/kotlin}/org/mifospay/core/data/util/NetworkMonitor.kt (100%) create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/util/SampleCurrency.kt create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/util/SampleLocale.kt rename lint/src/main/kotlin/org/mifos/mifospay/lint/util/LintOption.kt => core/data/src/commonMain/kotlin/org/mifospay/core/data/util/TimeZoneMonitor.kt (51%) create mode 100644 core/data/src/commonMain/kotlin/org/mifospay/core/data/util/UpiQrCodeProcessor.kt create mode 100644 core/data/src/desktopMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt rename shared/src/iosMain/kotlin/org/mifospay/shared/di/Modules.ios.kt => core/data/src/desktopMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt (54%) create mode 100644 core/data/src/jsMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt create mode 100644 core/data/src/jsMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/base/TaskLooper.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/base/ThreadPoolQueue.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/base/UseCase.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/base/UseCaseFactory.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/base/UseCaseHandler.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/base/UseCaseScheduler.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/base/UseCaseThreadPoolScheduler.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/di/DataModule.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/BlockUnblockCommand.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/DownloadTransactionReceipt.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccount.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransaction.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransactions.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransfer.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccounts.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchMerchants.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/TransferFunds.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/CreateClient.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientData.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientDetails.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientImage.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/SearchClient.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/UpdateClient.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/history/TransactionsHistory.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/invoice/FetchInvoice.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/invoice/FetchInvoices.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/FetchKYCLevel1Details.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UpdateKYCLevel1Details.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UploadKYCDocs.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UploadKYCLevel1Details.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/notification/FetchNotifications.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/AddCard.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/DeleteCard.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/EditCard.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/FetchSavedCards.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/CreateStandingTransaction.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/DeleteStandingInstruction.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/FetchStandingInstruction.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/GetAllStandingInstructions.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/UpdateStandingInstruction.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/FetchDeliveryMethods.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/RequestOTP.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/ValidateOTP.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/AuthenticateUser.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/CreateUser.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/DeleteUser.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/FetchUserDetails.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/FetchUsers.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/RegisterUser.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/UpdateUser.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/VerifyUser.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/AccountMapper.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/ClientDetailsMapper.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/CurrencyMapper.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/FetchAccount.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/SearchedEntitiesMapper.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/TransactionMapper.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/fineract/repository/FineractRepository.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/repository/auth/AuthenticationUserRepository.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/repository/local/LocalRepository.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/repository/local/MifosLocalAssetRepository.kt delete mode 100644 core/data/src/main/java/org/mifospay/core/data/util/ErrorJsonMessageHelper.kt create mode 100644 core/data/src/nativeMain/kotlin/org/mifospay/core/data/NativePlatformDependentDataModule.kt create mode 100644 core/data/src/nativeMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.native.kt delete mode 100644 core/data/src/test/java/org/mifospay/mobilewallet/core/ExampleUnitTest.kt create mode 100644 core/data/src/wasmJsMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt create mode 100644 core/data/src/wasmJsMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt delete mode 100644 core/datastore-proto/consumer-rules.pro delete mode 100644 core/datastore-proto/proguard-rules.pro create mode 100644 core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/ClientPreferences.kt create mode 100644 core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/RolePreferences.kt create mode 100644 core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/UserInfoPreferences.kt create mode 100644 core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/client_info.proto create mode 100644 core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/role_info.proto create mode 100644 core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/user_info.proto delete mode 100644 core/datastore-proto/src/main/proto/org.mifospay.core.data/user_preferences.proto delete mode 100644 core/datastore/proguard-rules.pro rename core/{datastore-proto/src/main => datastore/src/androidMain}/AndroidManifest.xml (100%) rename core/datastore/src/{main => androidMain}/java/org/mifospay/core/datastore/PreferencesHelper.kt (100%) rename core/datastore/src/{main => androidMain}/java/org/mifospay/core/datastore/di/CoreDataStoreModule.kt (100%) create mode 100644 core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/PreferencesMapper.kt create mode 100644 core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesDataSource.kt create mode 100644 core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesRepository.kt create mode 100644 core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesRepositoryImpl.kt create mode 100644 core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/di/PreferenceModule.kt delete mode 100644 core/datastore/src/test/java/org/mifospay/core/datastore/ExampleUnitTest.kt rename core/{datastore/src/main => designsystem/src/androidMain}/AndroidManifest.xml (100%) rename core/designsystem/src/{main => androidMain}/kotlin/org/mifospay/core/designsystem/component/PermissionBox.kt (96%) rename core/designsystem/src/{main/res => commonMain/composeResources}/font/outfit_black.ttf (100%) rename core/designsystem/src/{main/res => commonMain/composeResources}/font/outfit_bold.ttf (100%) rename core/designsystem/src/{main/res => commonMain/composeResources}/font/outfit_extra_bold.ttf (100%) rename core/designsystem/src/{main/res => commonMain/composeResources}/font/outfit_extra_light.ttf (100%) rename core/designsystem/src/{main/res => commonMain/composeResources}/font/outfit_light.ttf (100%) rename core/designsystem/src/{main/res => commonMain/composeResources}/font/outfit_medium.ttf (100%) rename core/designsystem/src/{main/res => commonMain/composeResources}/font/outfit_regular.ttf (100%) rename core/designsystem/src/{main/res => commonMain/composeResources}/font/outfit_semi_bold.ttf (100%) rename core/designsystem/src/{main/res => commonMain/composeResources}/font/outfit_thin.ttf (100%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/AlertDialog.kt (80%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/Background.kt (89%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/BottomSheet.kt (87%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/Button.kt (95%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/Card.kt (100%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/IconBox.kt (78%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/LoadingWheel.kt (99%) create mode 100644 core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosBasicDialog.kt create mode 100644 core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosLoadingDialog.kt create mode 100644 core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosScaffold.kt rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/MifosTab.kt (66%) create mode 100644 core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosTopAppBar.kt rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/MifosTopBar.kt (83%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/Navigation.kt (89%) create mode 100644 core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/TextField.kt rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/TextUserImage.kt (97%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/component/TopAppBar.kt (75%) create mode 100644 core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/AppScrollbars.kt create mode 100644 core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt create mode 100644 core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/Scrollbar.kt create mode 100644 core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/ScrollbarExt.kt create mode 100644 core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/ThumbExt.kt rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/icon/MifosIcons.kt (70%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/theme/BackgroundTheme.kt (100%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/theme/Color.kt (96%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/theme/GradientColors.kt (100%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/theme/MifosTextStyle.kt (100%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/theme/Theme.kt (99%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/theme/TintTheme.kt (100%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/theme/Type.kt (65%) rename core/designsystem/src/{main => commonMain}/kotlin/org/mifospay/core/designsystem/utils/ExpirationDateMask.kt (100%) create mode 100644 core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/utils/ModifierExt.kt delete mode 100644 core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosScaffold.kt delete mode 100644 core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/OutlineTextField.kt delete mode 100644 core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/TextField.kt rename {mifospay => core/domain}/.gitignore (100%) create mode 100644 core/domain/README.md create mode 100644 core/domain/build.gradle.kts rename core/{network => domain}/proguard-rules.pro (69%) create mode 100644 core/domain/src/commonMain/kotlin/org/mifospay/core/domain/LoginUseCase.kt create mode 100644 core/domain/src/commonMain/kotlin/org/mifospay/core/domain/di/DomainModule.kt delete mode 100644 core/model/consumer-rules.pro delete mode 100644 core/model/proguard-rules.pro create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/account/Account.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountContent.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountTransferPayload.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountsWithTransactions.kt rename core/model/src/{main/java/com/mifospay/core/model/entity/client/Status.kt => commonMain/kotlin/org/mifospay/core/model/account/DefaultAccount.kt} (51%) rename core/model/src/{main/java/com/mifospay/core/model/domain => commonMain/kotlin/org/mifospay/core/model/account}/NewAccount.kt (56%) rename core/model/src/{main/java/com/mifospay/core/model/domain => commonMain/kotlin/org/mifospay/core/model/bank}/Bank.kt (73%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/bank/BankAccountDetails.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/beneficiary/Beneficiary.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/beneficiary/BeneficiaryPayload.kt rename core/model/src/{main/java/com/mifospay/core/model/domain/Currency.kt => commonMain/kotlin/org/mifospay/core/model/beneficiary/BeneficiaryUpdatePayload.kt} (67%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/client/Client.kt rename core/model/src/{main/java/com/mifospay/core/model/entity/Page.kt => commonMain/kotlin/org/mifospay/core/model/client/ClientAccount.kt} (65%) rename core/model/src/{main/java/com/mifospay/core/model/entity/SearchedEntity.kt => commonMain/kotlin/org/mifospay/core/model/client/ClientAddress.kt} (51%) rename core/model/src/{main/java/com/mifospay/core/model/domain/NotificationPayload.kt => commonMain/kotlin/org/mifospay/core/model/client/ClientStatus.kt} (60%) rename core/model/src/{main/java/com/mifospay/core/model/entity/templates/beneficiary/BeneficiaryTemplate.kt => commonMain/kotlin/org/mifospay/core/model/client/ClientTimeline.kt} (51%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/client/NewClient.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/client/UpdatedClient.kt rename core/model/src/{main/java/com/mifospay/core/model/entity => commonMain/kotlin/org/mifospay/core/model/datatables}/invoice/Invoice.kt (66%) rename core/model/src/{main/java/com/mifospay/core/model/entity => commonMain/kotlin/org/mifospay/core/model/datatables}/invoice/InvoiceEntity.kt (93%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/kyc/KYCLevel1Details.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/notification/Notification.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/notification/NotificationPayload.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savedcards/CardPayload.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savedcards/SavedCard.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/AccountType.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/BlockUnblockResponseEntity.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/CreateNewSavingEntity.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Currency.kt rename core/model/src/{main/java/com/mifospay/core/model/entity/client => commonMain/kotlin/org/mifospay/core/model/savingsaccount}/DepositType.kt (53%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/InterestPeriod.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/PaymentDetailData.kt rename core/model/src/{main/java/com/mifospay/core/model/entity/accounts/savings => commonMain/kotlin/org/mifospay/core/model/savingsaccount}/PaymentType.kt (62%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccount.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountDetail.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountEntity.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountTemplate.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingCharge.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingProductOption.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingsWithAssociationsEntity.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Status.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SubStatus.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Summary.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Timeline.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Transaction.kt rename core/model/src/{main/java/com/mifospay/core/model/domain => commonMain/kotlin/org/mifospay/core/model/savingsaccount}/TransactionType.kt (89%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/TransactionsEntity.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Transfer.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/TransferDetail.kt rename core/model/src/{main/java/com/mifospay/core/model/domain/Account.kt => commonMain/kotlin/org/mifospay/core/model/savingsaccount/UpdateSavingAccountEntity.kt} (60%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/search/AccountResult.kt rename core/model/src/{main/java/com/mifospay/core/model/domain => commonMain/kotlin/org/mifospay/core/model/search}/SearchResult.kt (54%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/standinginstruction/SITemplate.kt rename core/model/src/{main/java/com/mifospay/core/model/domain/client/Client.kt => commonMain/kotlin/org/mifospay/core/model/standinginstruction/SIUpdatePayload.kt} (52%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/standinginstruction/StandingInstruction.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/standinginstruction/StandingInstructionPayload.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/user/NewUser.kt rename core/model/src/{main/java/com/mifospay/core/model/domain/twofactor/AccessToken.kt => commonMain/kotlin/org/mifospay/core/model/user/RoleInfo.kt} (59%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/user/UserData.kt rename shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/User.kt => core/model/src/commonMain/kotlin/org/mifospay/core/model/user/UserInfo.kt (70%) create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/utils/CurrencyCode.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/utils/Locale.kt create mode 100644 core/model/src/commonMain/kotlin/org/mifospay/core/model/utils/PaymentQrData.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/domain/BankAccountDetails.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/domain/Transaction.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/domain/client/NewClient.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/domain/user/NewUser.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/Timeline.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/accounts/SavingAccountsListResponse.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/Currency.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/PaymentDetailData.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/SavingAccount.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/SavingsWithAssociations.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/Status.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/Summary.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/TimeLine.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/TransactionType.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/Transactions.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/TransferDetail.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/beneficary/Beneficiary.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/beneficary/BeneficiaryPayload.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/beneficary/BeneficiaryUpdatePayload.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/client/Client.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/client/Currency.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/client/Type.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/kyc/KYCLevel1Details.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/noncore/Document.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/payload/ClientPayload.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/payload/DataTablePayload.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/payload/StandingInstructionPayload.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/payload/TransferPayload.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/register/RegisterPayload.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/register/UserVerify.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/savedcards/Card.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/standinginstruction/SDIResponse.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/standinginstruction/StandingInstruction.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/templates/account/AccountOption.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/templates/account/AccountOptionsTemplate.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/templates/account/AccountType.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/entity/templates/beneficiary/AccountTypeOption.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/signup/SignupData.kt delete mode 100644 core/model/src/main/java/com/mifospay/core/model/utils/DateHelper.kt delete mode 100644 core/model/src/test/java/com/mifos/mobilewallet/model/ExampleUnitTest.kt rename {feature/savedcards/src/main => core/network/src/androidMain}/AndroidManifest.xml (86%) create mode 100644 core/network/src/androidMain/kotlin/org/mifospay/core/network/KtorAndroidHttpClient.kt rename core/network/src/{main => commonMain}/assets/banks.json (100%) rename core/network/src/{main => commonMain}/assets/cities.json (100%) rename core/network/src/{main => commonMain}/assets/countries.json (100%) rename core/network/src/{main => commonMain}/assets/countriesToCities.json (100%) rename core/network/src/{main => commonMain}/assets/states.json (100%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/FineractApiManager.kt rename core/{model/src/main/java/com/mifospay/core/model/domain/user/UpdateUserEntityEmail.kt => network/src/commonMain/kotlin/org/mifospay/core/network/KtorHttpClient.kt} (75%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/KtorfitClient.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/SelfServiceApiManager.kt rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/di/LocalModule.kt (77%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/di/NetworkModule.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/di/Qualifier.kt rename shared/src/commonMain/kotlin/org/mifospay/shared/Greeting.kt => core/network/src/commonMain/kotlin/org/mifospay/core/network/localAssets/JvmLocalAssetManager.kt (65%) rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/localAssets/LocalAssetDataSource.kt (76%) rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/localAssets/LocalAssetManager.kt (84%) rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/localAssets/MifosLocalAssetDataSource.kt (54%) rename core/{model/src/main/java/com/mifospay/core/model/entity/payload/PayResponse.kt => network/src/commonMain/kotlin/org/mifospay/core/network/model/ClientResponseEntity.kt} (74%) rename core/{model/src/main/java/com/mifospay/core/model/UserData.kt => network/src/commonMain/kotlin/org/mifospay/core/network/model/CommonResponse.kt} (68%) rename core/network/src/{main/kotlin/org/mifospay/core/network => commonMain/kotlin/org/mifospay/core/network/model}/GenericResponse.kt (91%) rename core/{model/src/main/java/com/mifospay/core/model/entity/accounts/savings/Transfer.kt => network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/Page.kt} (64%) rename core/{model/src/main/java/com/mifospay/core => network/src/commonMain/kotlin/org/mifospay/core/network}/model/entity/Role.kt (74%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/SearchedEntity.kt rename core/{model/src/main/java/com/mifospay/core => network/src/commonMain/kotlin/org/mifospay/core/network}/model/entity/TPTResponse.kt (63%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/Timeline.kt rename core/{model/src/main/java/com/mifospay/core => network/src/commonMain/kotlin/org/mifospay/core/network}/model/entity/UserEntity.kt (87%) rename core/{model/src/main/java/com/mifospay/core => network/src/commonMain/kotlin/org/mifospay/core/network}/model/entity/UserWithRole.kt (61%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/authentication/AuthenticationPayload.kt rename core/{model/src/main/java/com/mifospay/core/model/entity/client/ClientAccounts.kt => network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/client/ClientAccountsEntity.kt} (50%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/client/ClientEntity.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/client/Currency.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/client/DepositTypeEntity.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/client/NewClientEntity.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/client/Status.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/client/Type.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/client/UpdateClientEntity.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/noncore/Document.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/payload/ClientPayload.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/payload/DataTablePayload.kt rename core/{model/src/main/java/com/mifospay/core => network/src/commonMain/kotlin/org/mifospay/core/network}/model/entity/payload/PayPayload.kt (79%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/payload/PayResponse.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/payload/TransferPayload.kt rename core/{model/src/main/java/com/mifospay/core => network/src/commonMain/kotlin/org/mifospay/core/network}/model/entity/payload/UpdateVpaPayload.kt (70%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/register/RegisterPayload.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/register/UserVerify.kt rename core/{model/src/main/java/com/mifospay/core/model => network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/signup}/City.kt (90%) rename core/{model/src/main/java/com/mifospay/core/model => network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/signup}/Country.kt (89%) rename core/{model/src/main/java/com/mifospay/core/model => network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/signup}/State.kt (90%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/templates/account/AccountOption.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/templates/account/AccountOptionsTemplate.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/templates/account/AccountType.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/templates/beneficiary/AccountTypeOption.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/templates/beneficiary/BeneficiaryTemplate.kt rename core/{model/src/main/java/com/mifospay/core/model/entity/authentication/AuthenticationPayload.kt => network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/user/NewUserEntity.kt} (52%) rename core/{model/src/main/java/com/mifospay/core/model/domain => network/src/commonMain/kotlin/org/mifospay/core/network/model/entity}/user/UpdateUserEntityClients.kt (71%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/user/UpdateUserEntityEmail.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/entity/user/UpdateUserEntityPassword.kt rename core/{model/src/main/java/com/mifospay/core/model/domain => network/src/commonMain/kotlin/org/mifospay/core/network/model/entity}/user/User.kt (72%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/model/twofactor/AccessToken.kt rename core/{model/src/main/java/com/mifospay/core/model/domain => network/src/commonMain/kotlin/org/mifospay/core/network/model}/twofactor/DeliveryMethod.kt (65%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/services/AccountTransfersService.kt rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/services/AuthenticationService.kt (55%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/services/BeneficiaryService.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/services/ClientService.kt rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/services/DocumentService.kt (73%) rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/services/InvoiceService.kt (57%) rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/services/KYCLevel1Service.kt (52%) rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/services/NotificationService.kt (50%) rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/services/RegistrationService.kt (52%) rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/services/RunReportService.kt (58%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/services/SavedCardService.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/services/SavingsAccountsService.kt rename core/network/src/{main => commonMain}/kotlin/org/mifospay/core/network/services/SearchService.kt (68%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/services/StandingInstructionService.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/services/ThirdPartyTransferService.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/services/TwoFactorAuthService.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/services/UserService.kt rename core/network/src/{main/kotlin/org/mifospay/core/network => commonMain/kotlin/org/mifospay/core/network/utils}/ApiEndPoints.kt (92%) create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/utils/BaseURL.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/utils/FlowConverterFactory.kt create mode 100644 core/network/src/commonMain/kotlin/org/mifospay/core/network/utils/KtorInterceptor.kt create mode 100644 core/network/src/desktopMain/kotlin/org/mifospay/core/network/KtorJvmHttpClient.kt create mode 100644 core/network/src/jsMain/kotlin/org/mifospay/core/network/KtorJsHttpClient.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/ApiInterceptor.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/BaseURL.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/FineractApiManager.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/JvmLocalAssetManager.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/KtorInterceptor.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/MifosWalletOkHttpClient.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/SelfServiceApiManager.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/TestingApiInterceptor.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/di/NetworkModule.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/di/Qualifier.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/services/AccountTransfersService.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/services/BeneficiaryService.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/services/ClientService.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/services/KtorAuthenticationService.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/services/KtorSavingsAccountService.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/services/SavedCardService.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/services/StandingInstructionService.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/services/ThirdPartyTransferService.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/services/TwoFactorAuthService.kt delete mode 100644 core/network/src/main/kotlin/org/mifospay/core/network/services/UserService.kt create mode 100644 core/network/src/nativeMain/kotlin/org/mifospay/core/network/KtorNativeHttpClient.kt delete mode 100644 core/network/src/test/java/org/mifospay/mobilewallet/mifospay/network/ExampleUnitTest.kt create mode 100644 core/network/src/wasmJsMain/kotlin/org/mifospay/core/network/KtorJsHttpClient.kt delete mode 100644 core/ui/consumer-rules.pro delete mode 100644 core/ui/proguard-rules.pro rename core/{designsystem/src/main => ui/src/androidMain}/AndroidManifest.xml (100%) rename core/ui/src/{main => androidMain}/kotlin/org/mifospay/core/ui/JankStatsExtensions.kt (100%) create mode 100644 core/ui/src/androidMain/kotlin/org/mifospay/core/ui/utils/ShareUtils.android.kt rename feature/home/src/main/res/drawable/feature_home_ic_arrow_back_black_24dp.xml => core/ui/src/commonMain/composeResources/drawable/arrow_outward.xml (60%) rename {feature/savedcards/src/main/res => core/ui/src/commonMain/composeResources}/drawable/artwork.xml (100%) rename core/ui/src/{main/res/drawable/core_ui_baseline_info_outline_24.xml => commonMain/composeResources/drawable/core_ui_info_outline.xml} (100%) rename core/ui/src/{main/res => commonMain/composeResources}/drawable/core_ui_money_in.png (100%) rename core/ui/src/{main/res => commonMain/composeResources}/drawable/core_ui_money_out.png (100%) rename {feature/receipt/src/main/res => core/ui/src/commonMain/composeResources}/drawable/feature_receipt_mifospay_round_logo.png (100%) rename core/ui/src/{main/res => commonMain/composeResources}/values/strings.xml (80%) rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/AvatarBox.kt (61%) rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/DevicePreviews.kt (59%) create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/DropdownBox.kt rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/EmptyContentScreen.kt (55%) rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/ErrorScreenContent.kt (84%) rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/ExpiryDateInput.kt (98%) rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/HeadingTitile.kt (97%) rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/LocalTimeZone.kt (100%) rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/MifosDivider.kt (100%) create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/MifosPasswordField.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/MifosSmallChip.kt rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/MifosUserImage.kt (61%) create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/NavGraphBuilderExtensions.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/NonLetterColorVisualTransformation.kt rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/OtpTextField.kt (98%) create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/PasswordStrengthIndicator.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/RevealSwipe.kt rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/ScrollableTabRow.kt (82%) create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/TransactionHistoryCard.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/TransactionItemCard.kt rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/utility/AddBtnChip.kt (85%) rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/utility/DialogState.kt (100%) rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/utility/DialogType.kt (100%) rename core/ui/src/{main => commonMain}/kotlin/org/mifospay/core/ui/utility/TabContent.kt (100%) create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/utils/BackgroundEvent.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/utils/BaseViewModel.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/utils/EventsEffect.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/utils/LifecycleEventEffect.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/utils/PasswordChecker.kt rename core/{model/src/main/java/com/mifospay/core/model/signup => ui/src/commonMain/kotlin/org/mifospay/core/ui/utils}/PasswordStrength.kt (74%) create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/utils/PasswordStrengthExtensions.kt rename libs/mifos-passcode/src/main/kotlin/org/mifos/library/passcode/data/PasscodeRepository.kt => core/ui/src/commonMain/kotlin/org/mifospay/core/ui/utils/ShareUtils.kt (55%) create mode 100644 core/ui/src/commonMain/kotlin/org/mifospay/core/ui/utils/Transition.kt create mode 100644 core/ui/src/desktopMain/kotlin/org/mifospay/core/ui/utils/ShareUtils.desktop.kt create mode 100644 core/ui/src/jsMain/kotlin/org/mifospay/core/ui/utils/ShareUtils.js.kt delete mode 100644 core/ui/src/main/kotlin/org/mifospay/core/ui/ProfileConcentricImage.kt delete mode 100644 core/ui/src/main/kotlin/org/mifospay/core/ui/TransactionItemScreen.kt delete mode 100644 core/ui/src/main/res/drawable/checker.webp create mode 100644 core/ui/src/nativeMain/kotlin/org/mifospay/core/ui/utils/ShareUtils.native.kt delete mode 100644 core/ui/src/test/java/org/mifospay/mobilewallet/mifospay/ui/ExampleUnitTest.kt create mode 100644 core/ui/src/wasmJsMain/kotlin/org/mifospay/core/ui/utils/ShareUtils.wasmJs.kt create mode 100644 feature/accounts/README.md delete mode 100644 feature/accounts/consumer-rules.pro delete mode 100644 feature/accounts/proguard-rules.pro rename {core/model/src/main => feature/accounts/src/androidMain}/AndroidManifest.xml (100%) create mode 100644 feature/accounts/src/commonMain/composeResources/drawable/baseline_check.xml create mode 100644 feature/accounts/src/commonMain/composeResources/drawable/baseline_unchecked.xml rename feature/accounts/src/{main/res => commonMain/composeResources}/drawable/feature_accounts_ic_bank.xml (100%) rename feature/accounts/src/{main/res => commonMain/composeResources}/drawable/feature_accounts_logo_axis.png (100%) rename feature/accounts/src/{main/res => commonMain/composeResources}/drawable/feature_accounts_logo_hdfc.png (100%) rename feature/accounts/src/{main/res => commonMain/composeResources}/drawable/feature_accounts_logo_icici.png (100%) rename feature/accounts/src/{main/res => commonMain/composeResources}/drawable/feature_accounts_logo_pnb.png (100%) rename feature/accounts/src/{main/res => commonMain/composeResources}/drawable/feature_accounts_logo_rbl.png (100%) rename feature/accounts/src/{main/res => commonMain/composeResources}/drawable/feature_accounts_logo_sbi.png (100%) rename feature/accounts/src/{main/res => commonMain/composeResources}/drawable/feature_accounts_sim_card_selected.xml (97%) rename feature/accounts/src/{main/res => commonMain/composeResources}/drawable/feature_accounts_sim_card_unselected.xml (96%) rename feature/accounts/src/{main/res => commonMain/composeResources}/values/strings.xml (91%) create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/AccountViewModel.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/AccountsScreen.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/beneficiary/AddEditBeneficiaryScreen.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/beneficiary/AddEditBeneficiaryViewModel.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/beneficiary/BeneficiaryAddEditType.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/beneficiary/BeneficiaryNavigation.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/di/AccountsModule.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/savingsaccount/AddEditSavingAccountScreen.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/savingsaccount/AddEditSavingNavigation.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/savingsaccount/AddEditSavingViewModel.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/savingsaccount/SavingsAddEditType.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/savingsaccount/details/SavingAccountDetailNavigation.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/savingsaccount/details/SavingAccountDetailScreen.kt create mode 100644 feature/accounts/src/commonMain/kotlin/org/mifospay/feature/accounts/savingsaccount/details/SavingAccountDetailViewModel.kt delete mode 100644 feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/AccountViewModel.kt delete mode 100644 feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/AccountsItem.kt delete mode 100644 feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/AccountsScreen.kt delete mode 100644 feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/choose/sim/ChooseSimDialogSheet.kt delete mode 100644 feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/details/BankAccountDetailScreen.kt delete mode 100644 feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/di/AccountsModule.kt delete mode 100644 feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/link/LinkBankAccountScreen.kt delete mode 100644 feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/link/LinkBankAccountViewModel.kt delete mode 100644 feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/link/LinkBankUiStatePreviewParameterProvider.kt delete mode 100644 feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/navigation/BankAccountDetailNavigation.kt delete mode 100644 feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/navigation/LinkBankAccountNavigation.kt delete mode 100644 feature/accounts/src/main/res/values/colors.xml rename {core/network/src/main => feature/auth/src/androidMain}/AndroidManifest.xml (100%) rename feature/auth/src/{main/res => commonMain/composeResources}/values/strings.xml (91%) create mode 100644 feature/auth/src/commonMain/kotlin/org/mifospay/feature/auth/di/AuthModule.kt create mode 100644 feature/auth/src/commonMain/kotlin/org/mifospay/feature/auth/login/LoginScreen.kt create mode 100644 feature/auth/src/commonMain/kotlin/org/mifospay/feature/auth/login/LoginViewModel.kt create mode 100644 feature/auth/src/commonMain/kotlin/org/mifospay/feature/auth/mobileVerify/MobileVerificationScreen.kt create mode 100644 feature/auth/src/commonMain/kotlin/org/mifospay/feature/auth/mobileVerify/MobileVerificationViewModel.kt rename feature/auth/src/{main => commonMain}/kotlin/org/mifospay/feature/auth/navigation/LoginScreenNavigation.kt (63%) create mode 100644 feature/auth/src/commonMain/kotlin/org/mifospay/feature/auth/navigation/MobileVerificationScreenNavigation.kt create mode 100644 feature/auth/src/commonMain/kotlin/org/mifospay/feature/auth/navigation/SignupScreenNavigation.kt create mode 100644 feature/auth/src/commonMain/kotlin/org/mifospay/feature/auth/signup/SignupScreen.kt create mode 100644 feature/auth/src/commonMain/kotlin/org/mifospay/feature/auth/signup/SignupViewModel.kt create mode 100644 feature/auth/src/commonMain/kotlin/org/mifospay/feature/auth/socialSignup/SignupMethodNavigation.kt create mode 100644 feature/auth/src/commonMain/kotlin/org/mifospay/feature/auth/socialSignup/SignupMethodScreen.kt delete mode 100644 feature/auth/src/main/kotlin/org/mifospay/feature/auth/di/AuthModule.kt delete mode 100644 feature/auth/src/main/kotlin/org/mifospay/feature/auth/login/LoginScreen.kt delete mode 100644 feature/auth/src/main/kotlin/org/mifospay/feature/auth/login/LoginViewModel.kt delete mode 100644 feature/auth/src/main/kotlin/org/mifospay/feature/auth/mobileVerify/MobileVerificationScreen.kt delete mode 100644 feature/auth/src/main/kotlin/org/mifospay/feature/auth/mobileVerify/MobileVerificationViewModel.kt delete mode 100644 feature/auth/src/main/kotlin/org/mifospay/feature/auth/navigation/MobileVerificationScreenNavigation.kt delete mode 100644 feature/auth/src/main/kotlin/org/mifospay/feature/auth/navigation/SignupScreenNavigation.kt delete mode 100644 feature/auth/src/main/kotlin/org/mifospay/feature/auth/signup/SignupScreen.kt delete mode 100644 feature/auth/src/main/kotlin/org/mifospay/feature/auth/signup/SignupViewModel.kt delete mode 100644 feature/auth/src/main/kotlin/org/mifospay/feature/auth/socialSignup/SocialSignupMethodScreen.kt create mode 100644 feature/editpassword/README.md delete mode 100644 feature/editpassword/consumer-rules.pro delete mode 100644 feature/editpassword/proguard-rules.pro rename feature/editpassword/src/{main => androidMain}/AndroidManifest.xml (100%) rename feature/editpassword/src/{main/res => commonMain/composeResources}/values/strings.xml (100%) create mode 100644 feature/editpassword/src/commonMain/kotlin/org/mifospay/feature/editpassword/EditPasswordScreen.kt create mode 100644 feature/editpassword/src/commonMain/kotlin/org/mifospay/feature/editpassword/EditPasswordViewModel.kt rename feature/editpassword/src/{main => commonMain}/kotlin/org/mifospay/feature/editpassword/di/EditPasswordModule.kt (65%) rename feature/editpassword/src/{main => commonMain}/kotlin/org/mifospay/feature/editpassword/navigation/EditPasswordScreenNavigation.kt (74%) delete mode 100644 feature/editpassword/src/main/kotlin/org/mifospay/feature/editpassword/EditPasswordScreen.kt delete mode 100644 feature/editpassword/src/main/kotlin/org/mifospay/feature/editpassword/EditPasswordViewModel.kt create mode 100644 feature/faq/README.md delete mode 100644 feature/faq/consumer-rules.pro delete mode 100644 feature/faq/proguard-rules.pro rename feature/faq/src/{main => androidMain}/AndroidManifest.xml (100%) rename feature/faq/src/{main/res => commonMain/composeResources}/values/strings.xml (96%) rename feature/faq/src/{main => commonMain}/kotlin/org/mifospay/feature/faq/FAQ.kt (73%) create mode 100644 feature/faq/src/commonMain/kotlin/org/mifospay/feature/faq/FAQViewModel.kt rename core/ui/src/main/kotlin/org/mifospay/core/ui/FaqItemScreen.kt => feature/faq/src/commonMain/kotlin/org/mifospay/feature/faq/FaqScreen.kt (54%) rename feature/faq/src/{main => commonMain}/kotlin/org/mifospay/feature/faq/di/FaqModule.kt (83%) rename feature/faq/src/{main => commonMain}/kotlin/org/mifospay/feature/faq/navigation/FAQNavigation.kt (87%) delete mode 100644 feature/faq/src/main/kotlin/org/mifospay/feature/faq/FAQViewModel.kt delete mode 100644 feature/faq/src/main/kotlin/org/mifospay/feature/faq/FaqScreen.kt create mode 100644 feature/finance/README.md delete mode 100644 feature/finance/consumer-rules.pro delete mode 100644 feature/finance/proguard-rules.pro rename {core/ui/src/main => feature/finance/src/androidMain}/AndroidManifest.xml (100%) rename feature/finance/src/{main => commonMain}/kotlin/org/mifospay/feature/finance/FinanceScreen.kt (84%) rename feature/finance/src/{main => commonMain}/kotlin/org/mifospay/feature/finance/navigation/FinanceNavigation.kt (100%) create mode 100644 feature/history/README.md delete mode 100644 feature/history/consumer-rules.pro delete mode 100644 feature/history/proguard-rules.pro rename feature/{accounts/src/main => history/src/androidMain}/AndroidManifest.xml (100%) rename feature/{make-transfer/src/main/res/values/colors.xml => history/src/commonMain/composeResources/drawable/arrow_outward.xml} (52%) rename feature/history/src/{main/res => commonMain/composeResources}/drawable/feature_history_ic_send.xml (100%) rename feature/history/src/{main/res => commonMain/composeResources}/values/strings.xml (84%) create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/HistoryScreen.kt create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/HistoryViewModel.kt create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/components/HistoryScreenFilter.kt create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/components/TransactionDetail.kt create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/components/TransactionList.kt create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/detail/TransactionDetailScreen.kt create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/detail/TransactionDetailViewModel.kt create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/di/HistoryModule.kt rename feature/{profile/src/main/kotlin/org/mifospay/feature/profile/navigation/ProfileNavigation.kt => history/src/commonMain/kotlin/org/mifospay/feature/history/navigation/HistoryNavigation.kt} (52%) create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/navigation/SpecificTransactionsNavigation.kt create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/navigation/TransactionDetailNavigation.kt create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/transactions/SpecificTransactionsScreen.kt create mode 100644 feature/history/src/commonMain/kotlin/org/mifospay/feature/history/transactions/SpecificTransactionsViewModel.kt delete mode 100644 feature/history/src/main/kotlin/org/mifospay/feature/di/HistoryModule.kt delete mode 100644 feature/history/src/main/kotlin/org/mifospay/feature/history/HistoryScreen.kt delete mode 100644 feature/history/src/main/kotlin/org/mifospay/feature/history/HistoryViewModel.kt delete mode 100644 feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/SpecificTransactionsScreen.kt delete mode 100644 feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/SpecificTransactionsViewModel.kt delete mode 100644 feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/navigation/SpecificTransactionsNavigation.kt delete mode 100644 feature/history/src/main/kotlin/org/mifospay/feature/transaction/detail/TransactionDetailScreen.kt delete mode 100644 feature/history/src/main/kotlin/org/mifospay/feature/transaction/detail/TransactionDetailViewModel.kt create mode 100644 feature/home/README.md delete mode 100644 feature/home/consumer-rules.pro delete mode 100644 feature/home/proguard-rules.pro rename feature/{auth/src/main => home/src/androidMain}/AndroidManifest.xml (100%) rename feature/home/src/{main/res/values/colors.xml => commonMain/composeResources/drawable/arrow_backward.xml} (53%) create mode 100644 feature/home/src/commonMain/composeResources/drawable/arrow_outward.xml rename feature/home/src/{main/res => commonMain/composeResources}/drawable/coin_image.png (100%) rename feature/home/src/{main/res => commonMain/composeResources}/values/strings.xml (79%) create mode 100644 feature/home/src/commonMain/kotlin/org/mifospay/feature/home/HomeScreen.kt create mode 100644 feature/home/src/commonMain/kotlin/org/mifospay/feature/home/HomeViewModel.kt rename shared/src/desktopMain/kotlin/org/mifospay/shared/di/Modules.desktop.kt => feature/home/src/commonMain/kotlin/org/mifospay/feature/home/di/HomeModule.kt (64%) rename feature/home/src/{main => commonMain}/kotlin/org/mifospay/feature/home/navigation/HomeNavigation.kt (70%) delete mode 100644 feature/home/src/main/kotlin/org/mifospay/feature/home/HomeScreen.kt delete mode 100644 feature/home/src/main/kotlin/org/mifospay/feature/home/HomeViewModel.kt delete mode 100644 feature/home/src/main/kotlin/org/mifospay/feature/home/di/HomeModule.kt create mode 100644 feature/invoices/README.md delete mode 100644 feature/invoices/consumer-rules.pro delete mode 100644 feature/invoices/proguard-rules.pro rename feature/{finance/src/main => invoices/src/androidMain/kotlin}/AndroidManifest.xml (100%) rename feature/invoices/src/{main/res/drawable/feature_invoices_ic_check_round_black_24dp.xml => commonMain/composeResources/drawable/ic_check.xml} (91%) rename feature/invoices/src/{main/res/drawable/feature_invoices_ic_remove_circle_outline_black_24dp.xml => commonMain/composeResources/drawable/ic_remove.xml} (100%) rename feature/invoices/src/{main/res => commonMain/composeResources}/values/strings.xml (100%) rename feature/invoices/src/{main => commonMain}/kotlin/org/mifospay/feature/invoices/InvoiceItem.kt (70%) create mode 100644 feature/invoices/src/commonMain/kotlin/org/mifospay/feature/invoices/InvoiceScreen.kt create mode 100644 feature/invoices/src/commonMain/kotlin/org/mifospay/feature/invoices/InvoicesViewModel.kt create mode 100644 feature/invoices/src/commonMain/kotlin/org/mifospay/feature/invoices/details/InvoiceDetailScreen.kt create mode 100644 feature/invoices/src/commonMain/kotlin/org/mifospay/feature/invoices/details/InvoiceDetailViewModel.kt create mode 100644 feature/invoices/src/commonMain/kotlin/org/mifospay/feature/invoices/di/InvoicesModule.kt rename feature/invoices/src/{main => commonMain}/kotlin/org/mifospay/feature/invoices/navigation/InvoiceNavigation.kt (62%) delete mode 100644 feature/invoices/src/main/kotlin/org/mifospay/feature/invoices/InvoiceDetailScreen.kt delete mode 100644 feature/invoices/src/main/kotlin/org/mifospay/feature/invoices/InvoiceDetailViewModel.kt delete mode 100644 feature/invoices/src/main/kotlin/org/mifospay/feature/invoices/InvoiceScreen.kt delete mode 100644 feature/invoices/src/main/kotlin/org/mifospay/feature/invoices/InvoicesViewModel.kt delete mode 100644 feature/invoices/src/main/kotlin/org/mifospay/feature/invoices/di/InvoicesModule.kt delete mode 100644 feature/invoices/src/main/res/values/colors.xml create mode 100644 feature/kyc/README.md delete mode 100644 feature/kyc/consumer-rules.pro delete mode 100644 feature/kyc/proguard-rules.pro rename feature/{history/src/main => kyc/src/androidMain}/AndroidManifest.xml (100%) rename feature/kyc/src/{main/res => commonMain/composeResources}/drawable/feature_kyc_ic_error_state.xml (92%) rename feature/kyc/src/{main/res => commonMain/composeResources}/values/strings.xml (97%) create mode 100644 feature/kyc/src/commonMain/kotlin/org/mifospay/feature/kyc/KYCDescriptionScreen.kt create mode 100644 feature/kyc/src/commonMain/kotlin/org/mifospay/feature/kyc/KYCDescriptionViewModel.kt create mode 100644 feature/kyc/src/commonMain/kotlin/org/mifospay/feature/kyc/KYCLevel1Screen.kt create mode 100644 feature/kyc/src/commonMain/kotlin/org/mifospay/feature/kyc/KYCLevel1ViewModel.kt create mode 100644 feature/kyc/src/commonMain/kotlin/org/mifospay/feature/kyc/KYCLevel2Screen.kt create mode 100644 feature/kyc/src/commonMain/kotlin/org/mifospay/feature/kyc/KYCLevel2ViewModel.kt create mode 100644 feature/kyc/src/commonMain/kotlin/org/mifospay/feature/kyc/KYCLevel3Screen.kt create mode 100644 feature/kyc/src/commonMain/kotlin/org/mifospay/feature/kyc/KYCLevel3ViewModel.kt create mode 100644 feature/kyc/src/commonMain/kotlin/org/mifospay/feature/kyc/di/KYCModule.kt rename feature/kyc/src/{main => commonMain}/kotlin/org/mifospay/feature/kyc/navigation/KYCLevel1Navigation.kt (80%) rename feature/kyc/src/{main => commonMain}/kotlin/org/mifospay/feature/kyc/navigation/KYCLevel2Navigation.kt (59%) rename feature/kyc/src/{main => commonMain}/kotlin/org/mifospay/feature/kyc/navigation/KYCLevel3Navigation.kt (56%) rename feature/kyc/src/{main => commonMain}/kotlin/org/mifospay/feature/kyc/navigation/KYCNavigation.kt (100%) delete mode 100644 feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCDescriptionScreen.kt delete mode 100644 feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCDescriptionViewModel.kt delete mode 100644 feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel1Screen.kt delete mode 100644 feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel1ViewModel.kt delete mode 100644 feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel2Screen.kt delete mode 100644 feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel2ViewModel.kt delete mode 100644 feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel3Screen.kt delete mode 100644 feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel3ViewModel.kt delete mode 100644 feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/di/KYCModule.kt delete mode 100644 feature/kyc/src/main/res/values/colors.xml delete mode 100644 feature/kyc/src/main/res/values/dimens.xml create mode 100644 feature/make-transfer/README.md rename feature/make-transfer/src/{main => androidMain}/AndroidManifest.xml (100%) rename feature/make-transfer/src/{main/res => commonMain/composeResources}/drawable/feature_make_transfer_ic_close.xml (91%) rename feature/make-transfer/src/{main/res => commonMain/composeResources}/drawable/feature_make_transfer_ic_done.xml (91%) rename feature/make-transfer/src/{main/res => commonMain/composeResources}/drawable/feature_make_transfer_transfer_failure.xml (100%) rename feature/make-transfer/src/{main/res => commonMain/composeResources}/drawable/feature_make_transfer_transfer_success.xml (91%) create mode 100644 feature/make-transfer/src/commonMain/composeResources/drawable/process_ring.xml rename feature/make-transfer/src/{main/res => commonMain/composeResources}/values/strings.xml (100%) create mode 100644 feature/make-transfer/src/commonMain/kotlin/org/mifospay/feature/make/transfer/MakeTransferScreen.kt create mode 100644 feature/make-transfer/src/commonMain/kotlin/org/mifospay/feature/make/transfer/MakeTransferViewModel.kt rename feature/make-transfer/src/{main => commonMain}/kotlin/org/mifospay/feature/make/transfer/di/MakeTransferModule.kt (62%) create mode 100644 feature/make-transfer/src/commonMain/kotlin/org/mifospay/feature/make/transfer/navigation/MakeTransferNavigation.kt create mode 100644 feature/make-transfer/src/commonMain/kotlin/org/mifospay/feature/make/transfer/success/TransferSuccessNavigation.kt create mode 100644 feature/make-transfer/src/commonMain/kotlin/org/mifospay/feature/make/transfer/success/TransferSuccessScreen.kt delete mode 100644 feature/make-transfer/src/main/kotlin/org/mifospay/feature/make/transfer/MakeTransferScreen.kt delete mode 100644 feature/make-transfer/src/main/kotlin/org/mifospay/feature/make/transfer/MakeTransferViewModel.kt delete mode 100644 feature/make-transfer/src/main/kotlin/org/mifospay/feature/make/transfer/navigation/MakeTransferNavigation.kt rename core/analytics/consumer-rules.pro => feature/merchants/README.md (100%) delete mode 100644 feature/merchants/consumer-rules.pro delete mode 100644 feature/merchants/proguard-rules.pro rename feature/{home/src/main => merchants/src/androidMain}/AndroidManifest.xml (100%) rename feature/merchants/src/{main/res => commonMain/composeResources}/drawable/feature_merchants_ic_bank.xml (100%) rename feature/merchants/src/{main/res => commonMain/composeResources}/values/strings.xml (100%) create mode 100644 feature/merchants/src/commonMain/kotlin/org/mifospay/feature/merchants/MerchantTransferViewModel.kt create mode 100644 feature/merchants/src/commonMain/kotlin/org/mifospay/feature/merchants/MerchantViewModel.kt create mode 100644 feature/merchants/src/commonMain/kotlin/org/mifospay/feature/merchants/di/MerchantsModule.kt rename feature/merchants/src/{main => commonMain}/kotlin/org/mifospay/feature/merchants/navigation/MerchantTransferNavigation.kt (100%) rename feature/merchants/src/{main => commonMain}/kotlin/org/mifospay/feature/merchants/ui/MerchantScreen.kt (60%) rename feature/merchants/src/{main => commonMain}/kotlin/org/mifospay/feature/merchants/ui/MerchantTransferScreen.kt (72%) rename feature/merchants/src/{main => commonMain}/kotlin/org/mifospay/feature/merchants/ui/MerchantsItem.kt (80%) delete mode 100644 feature/merchants/src/main/kotlin/org/mifospay/feature/merchants/MerchantTransferViewModel.kt delete mode 100644 feature/merchants/src/main/kotlin/org/mifospay/feature/merchants/MerchantViewModel.kt delete mode 100644 feature/merchants/src/main/kotlin/org/mifospay/feature/merchants/di/MerchantsModule.kt create mode 100644 feature/notification/README.md delete mode 100644 feature/notification/consumer-rules.pro delete mode 100644 feature/notification/proguard-rules.pro rename feature/notification/src/{main => androidMain}/AndroidManifest.xml (100%) rename feature/notification/src/{main/res => commonMain/composeResources}/values/strings.xml (100%) rename feature/notification/src/{main => commonMain}/kotlin/org/mifospay/feature/notification/NotificationNavigation.kt (54%) create mode 100644 feature/notification/src/commonMain/kotlin/org/mifospay/feature/notification/NotificationScreen.kt create mode 100644 feature/notification/src/commonMain/kotlin/org/mifospay/feature/notification/NotificationViewModel.kt rename feature/notification/src/{main => commonMain}/kotlin/org/mifospay/feature/notification/di/NotificationModule.kt (68%) delete mode 100644 feature/notification/src/main/kotlin/org/mifospay/feature/notification/NotificationScreen.kt delete mode 100644 feature/notification/src/main/kotlin/org/mifospay/feature/notification/NotificationViewModel.kt create mode 100644 feature/payments/README.md delete mode 100644 feature/payments/consumer-rules.pro delete mode 100644 feature/payments/proguard-rules.pro rename feature/{invoices/src/main => payments/src/androidMain}/AndroidManifest.xml (100%) create mode 100644 feature/payments/src/commonMain/composeResources/drawable/baseline_content_copy.xml rename feature/payments/src/{main/res => commonMain/composeResources}/values/strings.xml (74%) rename feature/payments/src/{main => commonMain}/kotlin/org/mifospay/feature/payments/PaymentNavigation.kt (100%) rename feature/payments/src/{main => commonMain}/kotlin/org/mifospay/feature/payments/PaymentsScreen.kt (82%) create mode 100644 feature/payments/src/commonMain/kotlin/org/mifospay/feature/payments/RequestScreen.kt create mode 100644 feature/payments/src/commonMain/kotlin/org/mifospay/feature/payments/TransferViewModel.kt rename feature/payments/src/{main => commonMain}/kotlin/org/mifospay/feature/payments/di/PaymentsModule.kt (69%) delete mode 100644 feature/payments/src/main/kotlin/org/mifospay/feature/payments/RequestScreen.kt delete mode 100644 feature/payments/src/main/kotlin/org/mifospay/feature/payments/TransferViewModel.kt create mode 100644 feature/profile/README.md delete mode 100644 feature/profile/proguard-rules.pro rename feature/{kyc/src/main => profile/src/androidMain}/AndroidManifest.xml (100%) rename core/ui/src/main/res/drawable/core_ui_ic_dp_placeholder.png => feature/profile/src/commonMain/composeResources/drawable/placeholder.png (100%) rename feature/profile/src/{main/res => commonMain/composeResources}/values/strings.xml (90%) create mode 100644 feature/profile/src/commonMain/kotlin/org/mifospay/feature/profile/ProfileScreen.kt create mode 100644 feature/profile/src/commonMain/kotlin/org/mifospay/feature/profile/ProfileViewModel.kt rename feature/profile/src/{main/kotlin/org/mifospay/feature/profile => commonMain/kotlin/org/mifospay/feature/profile/components}/ProfileCard.kt (64%) create mode 100644 feature/profile/src/commonMain/kotlin/org/mifospay/feature/profile/components/ProfileImage.kt create mode 100644 feature/profile/src/commonMain/kotlin/org/mifospay/feature/profile/di/ProfileModule.kt create mode 100644 feature/profile/src/commonMain/kotlin/org/mifospay/feature/profile/edit/EditProfileScreen.kt create mode 100644 feature/profile/src/commonMain/kotlin/org/mifospay/feature/profile/edit/EditProfileViewModel.kt rename feature/profile/src/{main => commonMain}/kotlin/org/mifospay/feature/profile/navigation/EditProfileNavigation.kt (66%) create mode 100644 feature/profile/src/commonMain/kotlin/org/mifospay/feature/profile/navigation/ProfileNavigation.kt delete mode 100644 feature/profile/src/main/kotlin/org/mifospay/feature/profile/ProfileScreen.kt delete mode 100644 feature/profile/src/main/kotlin/org/mifospay/feature/profile/ProfileViewModel.kt delete mode 100644 feature/profile/src/main/kotlin/org/mifospay/feature/profile/di/ProfileModule.kt delete mode 100644 feature/profile/src/main/kotlin/org/mifospay/feature/profile/edit/EditProfileScreen.kt delete mode 100644 feature/profile/src/main/kotlin/org/mifospay/feature/profile/edit/EditProfileScreenImage.kt delete mode 100644 feature/profile/src/main/kotlin/org/mifospay/feature/profile/edit/EditProfileViewModel.kt create mode 100644 feature/qr/README.md delete mode 100644 feature/qr/proguard-rules.pro rename feature/{request-money/src/main => qr/src/androidMain}/AndroidManifest.xml (63%) create mode 100644 feature/qr/src/androidMain/kotlin/org/mifospay/feature/qr/BarcodeAnalyzer.kt create mode 100644 feature/qr/src/androidMain/kotlin/org/mifospay/feature/qr/CameraPermissionState.android.kt create mode 100644 feature/qr/src/androidMain/kotlin/org/mifospay/feature/qr/CameraView.kt create mode 100644 feature/qr/src/androidMain/kotlin/org/mifospay/feature/qr/QrCodeScanner.android.kt create mode 100644 feature/qr/src/androidMain/kotlin/org/mifospay/feature/qr/Utils.kt rename feature/qr/src/{main/res => commonMain/composeResources}/values/strings.xml (100%) rename shared/src/desktopMain/kotlin/org/mifospay/shared/Platform.desktop.kt => feature/qr/src/commonMain/kotlin/org/mifospay/feature/qr/CameraPermissionState.kt (56%) rename core/model/src/main/java/com/mifospay/core/model/domain/user/UpdateUserEntityPassword.kt => feature/qr/src/commonMain/kotlin/org/mifospay/feature/qr/CodeType.kt (62%) create mode 100644 feature/qr/src/commonMain/kotlin/org/mifospay/feature/qr/QrCodeScanner.kt create mode 100644 feature/qr/src/commonMain/kotlin/org/mifospay/feature/qr/ScanQrCodeScreen.kt create mode 100644 feature/qr/src/commonMain/kotlin/org/mifospay/feature/qr/ScanQrViewModel.kt rename core/data/src/main/java/org/mifospay/core/data/di/LocalDataModule.kt => feature/qr/src/commonMain/kotlin/org/mifospay/feature/qr/di/QrModule.kt (65%) create mode 100644 feature/qr/src/commonMain/kotlin/org/mifospay/feature/qr/navigation/ReadQrNavigation.kt create mode 100644 feature/qr/src/desktopMain/kotlin/org/mifospay/feature/qr/CameraPermissionState.desktop.kt create mode 100644 feature/qr/src/desktopMain/kotlin/org/mifospay/feature/qr/QrCodeScanner.desktop.kt create mode 100644 feature/qr/src/jsMain/kotlin/org/mifospay/feature/qr/CameraPermissionState.js.kt create mode 100644 feature/qr/src/jsMain/kotlin/org/mifospay/feature/qr/QrCodeScanner.js.kt delete mode 100644 feature/qr/src/main/kotlin/org/mifospay/feature/read/qr/ReadQrScreen.kt delete mode 100644 feature/qr/src/main/kotlin/org/mifospay/feature/read/qr/ReadQrViewModel.kt delete mode 100644 feature/qr/src/main/kotlin/org/mifospay/feature/read/qr/di/QrModule.kt delete mode 100644 feature/qr/src/main/kotlin/org/mifospay/feature/read/qr/navigation/ReadQrNavigation.kt delete mode 100644 feature/qr/src/main/kotlin/org/mifospay/feature/read/qr/utils/QrCodeAnalyzer.kt delete mode 100644 feature/qr/src/main/kotlin/org/mifospay/feature/read/qr/utils/ScanQr.kt create mode 100644 feature/qr/src/nativeMain/kotlin/org/mifospay/feature/qr/CameraPermissionState.native.kt create mode 100644 feature/qr/src/nativeMain/kotlin/org/mifospay/feature/qr/CameraView.kt create mode 100644 feature/qr/src/nativeMain/kotlin/org/mifospay/feature/qr/OrientationListener.kt create mode 100644 feature/qr/src/nativeMain/kotlin/org/mifospay/feature/qr/QrCodeScanner.native.kt create mode 100644 feature/qr/src/nativeMain/kotlin/org/mifospay/feature/qr/Utls.kt create mode 100644 feature/qr/src/wasmJsMain/kotlin/org/mifospay/feature/qr/CameraPermissionState.wasmJs.kt create mode 100644 feature/qr/src/wasmJsMain/kotlin/org/mifospay/feature/qr/QrCodeScanner.wasmJs.kt create mode 100644 feature/receipt/README.md delete mode 100644 feature/receipt/consumer-rules.pro delete mode 100644 feature/receipt/proguard-rules.pro rename feature/{merchants/src/main => receipt/src/androidMain}/AndroidManifest.xml (100%) rename feature/receipt/src/{main/res => commonMain/composeResources}/drawable/feature_receipt_ic_download.xml (100%) rename mifospay/src/main/res/drawable/mifospay_round_logo.png => feature/receipt/src/commonMain/composeResources/drawable/feature_receipt_mifospay_round_logo.png (100%) rename feature/receipt/src/{main/res => commonMain/composeResources}/values/strings.xml (100%) create mode 100644 feature/receipt/src/commonMain/kotlin/org/mifospay/feature/receipt/ReceiptScreen.kt create mode 100644 feature/receipt/src/commonMain/kotlin/org/mifospay/feature/receipt/ReceiptViewModel.kt create mode 100644 feature/receipt/src/commonMain/kotlin/org/mifospay/feature/receipt/di/ReceiptModule.kt rename feature/{search/src/main/kotlin/org/mifospay/feature/search/SearchNavigation.kt => receipt/src/commonMain/kotlin/org/mifospay/feature/receipt/navigation/ReceiptNavigation.kt} (57%) delete mode 100644 feature/receipt/src/main/kotlin/org/mifospay/feature/receipt/ReceiptScreen.kt delete mode 100644 feature/receipt/src/main/kotlin/org/mifospay/feature/receipt/ReceiptViewModel.kt delete mode 100644 feature/receipt/src/main/kotlin/org/mifospay/feature/receipt/di/ReceiptModule.kt delete mode 100644 feature/receipt/src/main/kotlin/org/mifospay/feature/receipt/navigation/ReceiptNavigation.kt create mode 100644 feature/request-money/README.md delete mode 100644 feature/request-money/consumer-rules.pro delete mode 100644 feature/request-money/proguard-rules.pro rename feature/{standing-instruction/src/main => request-money/src/androidMain/kotlin}/AndroidManifest.xml (63%) rename feature/request-money/src/{main/res => commonMain/composeResources}/drawable/logo.png (100%) rename feature/request-money/src/{main/res => commonMain/composeResources}/values/strings.xml (92%) create mode 100644 feature/request-money/src/commonMain/kotlin/org/mifospay/feature/request/money/SetAmountDialog.kt create mode 100644 feature/request-money/src/commonMain/kotlin/org/mifospay/feature/request/money/ShowQrScreen.kt create mode 100644 feature/request-money/src/commonMain/kotlin/org/mifospay/feature/request/money/ShowQrViewModel.kt create mode 100644 feature/request-money/src/commonMain/kotlin/org/mifospay/feature/request/money/di/RequestMoneyModule.kt rename feature/request-money/src/{main => commonMain}/kotlin/org/mifospay/feature/request/money/navigation/ShowQrNavigation.kt (53%) delete mode 100644 feature/request-money/src/main/kotlin/org/mifospay/feature/request/money/GenerateQr.kt delete mode 100644 feature/request-money/src/main/kotlin/org/mifospay/feature/request/money/PayVpaMobileScreen.kt delete mode 100644 feature/request-money/src/main/kotlin/org/mifospay/feature/request/money/SetAmountDialog.kt delete mode 100644 feature/request-money/src/main/kotlin/org/mifospay/feature/request/money/ShowQrContent.kt delete mode 100644 feature/request-money/src/main/kotlin/org/mifospay/feature/request/money/ShowQrScreenRoute.kt delete mode 100644 feature/request-money/src/main/kotlin/org/mifospay/feature/request/money/ShowQrViewModel.kt delete mode 100644 feature/request-money/src/main/kotlin/org/mifospay/feature/request/money/di/RequestMoneyModule.kt delete mode 100644 feature/request-money/src/main/kotlin/org/mifospay/feature/request/money/util/ImageUtils.kt create mode 100644 feature/savedcards/README.md delete mode 100644 feature/savedcards/consumer-rules.pro delete mode 100644 feature/savedcards/proguard-rules.pro rename feature/{payments/src/main => savedcards/src/androidMain}/AndroidManifest.xml (100%) create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/amex_logo.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/bg1.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/bg2.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/bg3.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/bg4.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/circle_bg.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/diner_clubs.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/ic_mastercard.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/ic_visa.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/maestro.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/red_bg.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/rupay_logo.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/symbol.xml create mode 100644 feature/savedcards/src/commonMain/composeResources/drawable/violet_bg.xml rename feature/savedcards/src/{main/res => commonMain/composeResources}/values/strings.xml (92%) create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/CardsScreen.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/CardsScreenViewModel.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/components/CardConfig.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/components/CardNumberFilter.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/components/ColorUtils.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/components/CreditCard.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/createOrUpdate/AddEditCardNavigation.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/createOrUpdate/AddEditCardScreen.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/createOrUpdate/AddEditCardViewModel.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/createOrUpdate/CardAddEditType.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/details/CardDetailNavigation.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/details/CardDetailScreen.kt create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/details/CardDetailViewModel.kt rename feature/savedcards/src/{main => commonMain}/kotlin/org/mifospay/feature/savedcards/di/SavedCardsModule.kt (59%) create mode 100644 feature/savedcards/src/commonMain/kotlin/org/mifospay/feature/savedcards/utils/CreditCardUtils.kt delete mode 100644 feature/savedcards/src/main/kotlin/org/mifospay/feature/savedcards/AddCardDialogSheet.kt delete mode 100644 feature/savedcards/src/main/kotlin/org/mifospay/feature/savedcards/CardsScreen.kt delete mode 100644 feature/savedcards/src/main/kotlin/org/mifospay/feature/savedcards/CardsScreenViewModel.kt delete mode 100644 feature/savedcards/src/main/kotlin/org/mifospay/feature/savedcards/navigation/AddCardNavigation.kt delete mode 100644 feature/search/.gitignore delete mode 100644 feature/search/src/main/kotlin/org/mifospay/feature/search/SearchScreen.kt delete mode 100644 feature/search/src/main/kotlin/org/mifospay/feature/search/SearchViewModel.kt delete mode 100644 feature/search/src/main/kotlin/org/mifospay/feature/search/di/SearchModule.kt delete mode 100644 feature/search/src/main/res/values/strings.xml create mode 100644 feature/send-money/README.md rename feature/{search/src/main => send-money/src/androidMain}/AndroidManifest.xml (100%) create mode 100644 feature/send-money/src/androidMain/kotlin/org/mifospay/feature/send/money/PlayScannerModule.kt create mode 100644 feature/send-money/src/androidMain/kotlin/org/mifospay/feature/send/money/QrScanner.android.kt rename feature/send-money/src/{main/res => commonMain/composeResources}/values/strings.xml (77%) rename shared/src/commonMain/kotlin/org/mifospay/shared/di/Modules.kt => feature/send-money/src/commonMain/kotlin/org/mifospay/feature/send/money/QrScanner.kt (67%) create mode 100644 feature/send-money/src/commonMain/kotlin/org/mifospay/feature/send/money/SendMoneyScreen.kt create mode 100644 feature/send-money/src/commonMain/kotlin/org/mifospay/feature/send/money/SendMoneyViewModel.kt rename feature/send-money/src/{main => commonMain}/kotlin/org/mifospay/feature/send/money/di/SendMoneyModule.kt (61%) create mode 100644 feature/send-money/src/commonMain/kotlin/org/mifospay/feature/send/money/navigation/SendNavigation.kt create mode 100644 feature/send-money/src/desktopMain/kotlin/org/mifospay/feature/send/money/QrScanner.desktop.kt create mode 100644 feature/send-money/src/jsMain/kotlin/org/mifospay/feature/send/money/QrScanner.js.kt delete mode 100644 feature/send-money/src/main/AndroidManifest.xml delete mode 100644 feature/send-money/src/main/kotlin/org/mifospay/feature/send/money/SendPaymentViewModel.kt delete mode 100644 feature/send-money/src/main/kotlin/org/mifospay/feature/send/money/SendScreenRoute.kt delete mode 100644 feature/send-money/src/main/kotlin/org/mifospay/feature/send/money/navigation/SendNavigation.kt create mode 100644 feature/send-money/src/nativeMain/kotlin/org/mifospay/feature/send/money/QrScanner.native.kt create mode 100644 feature/send-money/src/wasmJsMain/kotlin/org/mifospay/feature/send/money/QrScanner.wasmJs.kt create mode 100644 feature/settings/README.md delete mode 100644 feature/settings/consumer-rules.pro delete mode 100644 feature/settings/proguard-rules.pro rename feature/{profile/src/main => settings/src/androidMain}/AndroidManifest.xml (100%) create mode 100644 feature/settings/src/commonMain/composeResources/drawable/outline_logout.xml create mode 100644 feature/settings/src/commonMain/composeResources/drawable/outline_password.xml create mode 100644 feature/settings/src/commonMain/composeResources/drawable/outline_pin.xml rename feature/settings/src/{main/res => commonMain/composeResources}/values/strings.xml (100%) create mode 100644 feature/settings/src/commonMain/kotlin/org/mifospay/feature/settings/SettingsScreen.kt create mode 100644 feature/settings/src/commonMain/kotlin/org/mifospay/feature/settings/SettingsViewModel.kt rename feature/settings/src/{main => commonMain}/kotlin/org/mifospay/feature/settings/di/SettingsModule.kt (68%) rename feature/settings/src/{main => commonMain}/kotlin/org/mifospay/feature/settings/navigation/SettingsNavigation.kt (79%) delete mode 100644 feature/settings/src/main/AndroidManifest.xml delete mode 100644 feature/settings/src/main/kotlin/org/mifospay/feature/settings/DialogManager.kt delete mode 100644 feature/settings/src/main/kotlin/org/mifospay/feature/settings/SettingsScreen.kt delete mode 100644 feature/settings/src/main/kotlin/org/mifospay/feature/settings/SettingsViewModel.kt create mode 100644 feature/standing-instruction/README.md delete mode 100644 feature/standing-instruction/consumer-rules.pro delete mode 100644 feature/standing-instruction/proguard-rules.pro rename feature/{qr/src/main => standing-instruction/src/androidMain}/AndroidManifest.xml (100%) rename feature/standing-instruction/src/{main/res => commonMain/composeResources}/values/strings.xml (91%) create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/StandingInstructionScreen.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/StandingInstructionViewModel.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/components/FrequencyChip.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/components/InstructionTypeChip.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/components/PriorityChip.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/createOrUpdate/AddEditSINavigation.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/createOrUpdate/AddEditSIScreen.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/createOrUpdate/AddEditSIViewModel.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/createOrUpdate/SIAddEditType.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/details/SIDetailViewModel.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/details/SIDetailsNavigation.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/details/SIDetailsScreen.kt create mode 100644 feature/standing-instruction/src/commonMain/kotlin/org/mifospay/feature/standing/instruction/di/StandingInstructionModule.kt delete mode 100644 feature/standing-instruction/src/main/kotlin/org/mifospay/feature/standing/instruction/NewSIScreenRoute.kt delete mode 100644 feature/standing-instruction/src/main/kotlin/org/mifospay/feature/standing/instruction/NewSIViewModel.kt delete mode 100644 feature/standing-instruction/src/main/kotlin/org/mifospay/feature/standing/instruction/SIContent.kt delete mode 100644 feature/standing-instruction/src/main/kotlin/org/mifospay/feature/standing/instruction/SIDetailsScreen.kt delete mode 100644 feature/standing-instruction/src/main/kotlin/org/mifospay/feature/standing/instruction/StandingInstructionDetailsViewModel.kt delete mode 100644 feature/standing-instruction/src/main/kotlin/org/mifospay/feature/standing/instruction/StandingInstructionNavigation.kt delete mode 100644 feature/standing-instruction/src/main/kotlin/org/mifospay/feature/standing/instruction/StandingInstructionScreen.kt delete mode 100644 feature/standing-instruction/src/main/kotlin/org/mifospay/feature/standing/instruction/StandingInstructionViewModel.kt delete mode 100644 feature/standing-instruction/src/main/kotlin/org/mifospay/feature/standing/instruction/di/StandingInstructionModule.kt rename core/common/consumer-rules.pro => feature/upi-setup/README.md (100%) delete mode 100644 feature/upi-setup/consumer-rules.pro delete mode 100644 feature/upi-setup/proguard-rules.pro rename feature/{receipt/src/main => upi-setup/src/androidMain}/AndroidManifest.xml (100%) rename feature/upi-setup/src/{main/res => commonMain/composeResources}/values/strings.xml (100%) rename feature/upi-setup/src/{main/kotlin/org/mifospay/feature/upiSetup => commonMain/kotlin/org/mifospay/feature/upi/setup}/di/UpiSetupModule.kt (54%) rename feature/upi-setup/src/{main/kotlin/org/mifospay/feature/upiSetup => commonMain/kotlin/org/mifospay/feature/upi/setup}/navigation/SetupUpiPinNavigation.kt (69%) rename feature/upi-setup/src/{main/kotlin/org/mifospay/feature/upiSetup => commonMain/kotlin/org/mifospay/feature/upi/setup}/screens/DebitCardScreen.kt (94%) rename feature/upi-setup/src/{main/kotlin/org/mifospay/feature/upiSetup => commonMain/kotlin/org/mifospay/feature/upi/setup}/screens/DebitCardScreenContent.kt (97%) rename feature/upi-setup/src/{main/kotlin/org/mifospay/feature/upiSetup => commonMain/kotlin/org/mifospay/feature/upi/setup}/screens/OtpScreen.kt (88%) rename feature/upi-setup/src/{main/kotlin/org/mifospay/feature/upiSetup => commonMain/kotlin/org/mifospay/feature/upi/setup}/screens/SetUpUPiPinScreen.kt (74%) rename feature/upi-setup/src/{main/kotlin/org/mifospay/feature/upiSetup => commonMain/kotlin/org/mifospay/feature/upi/setup}/screens/SetUpUpiScreenContent.kt (93%) rename feature/upi-setup/src/{main/kotlin/org/mifospay/feature/upiSetup => commonMain/kotlin/org/mifospay/feature/upi/setup}/screens/UpiPinScreen.kt (89%) rename feature/upi-setup/src/{main/kotlin/org/mifospay/feature/upiSetup => commonMain/kotlin/org/mifospay/feature/upi/setup}/viewmodel/DebitCardViewModal.kt (97%) rename feature/upi-setup/src/{main/kotlin/org/mifospay/feature/upiSetup => commonMain/kotlin/org/mifospay/feature/upi/setup}/viewmodel/SetUpUpiViewModal.kt (86%) delete mode 100644 feature/upi-setup/src/main/AndroidManifest.xml create mode 100644 kotlin-js-store/yarn.lock delete mode 100644 libs/country-code-picker/.gitignore delete mode 100644 libs/country-code-picker/README.md delete mode 100644 libs/country-code-picker/build.gradle.kts delete mode 100644 libs/country-code-picker/src/main/AndroidManifest.xml delete mode 100644 libs/country-code-picker/src/main/kotlin/com/mifos/library/countrycodepicker/CountryCodePicker.kt delete mode 100644 libs/country-code-picker/src/main/kotlin/com/mifos/library/countrycodepicker/component/Autofill.kt delete mode 100644 libs/country-code-picker/src/main/kotlin/com/mifos/library/countrycodepicker/component/CountryCodeDialog.kt delete mode 100644 libs/country-code-picker/src/main/kotlin/com/mifos/library/countrycodepicker/component/CountryDialog.kt delete mode 100644 libs/country-code-picker/src/main/kotlin/com/mifos/library/countrycodepicker/data/CountryData.kt delete mode 100644 libs/country-code-picker/src/main/kotlin/com/mifos/library/countrycodepicker/data/utils/CountryCodeUtils.kt delete mode 100644 libs/country-code-picker/src/main/kotlin/com/mifos/library/countrycodepicker/data/utils/CountryNameMap.kt delete mode 100644 libs/country-code-picker/src/main/kotlin/com/mifos/library/countrycodepicker/data/utils/NumberHintMap.kt delete mode 100644 libs/country-code-picker/src/main/kotlin/com/mifos/library/countrycodepicker/data/utils/SearchCountryList.kt delete mode 100644 libs/country-code-picker/src/main/kotlin/com/mifos/library/countrycodepicker/data/utils/ValidatePhoneNumber.kt delete mode 100644 libs/country-code-picker/src/main/kotlin/com/mifos/library/countrycodepicker/transformation/PhoneNumberTransformation.kt delete mode 100644 libs/country-code-picker/src/main/res/values-ar/strings.xml delete mode 100644 libs/country-code-picker/src/main/res/values-es/strings.xml delete mode 100644 libs/country-code-picker/src/main/res/values-fr/strings.xml delete mode 100644 libs/country-code-picker/src/main/res/values-hi/strings.xml delete mode 100644 libs/country-code-picker/src/main/res/values-it-rIT/strings.xml delete mode 100644 libs/country-code-picker/src/main/res/values-nl/strings.xml delete mode 100644 libs/country-code-picker/src/main/res/values-ru-rRU/strings.xml delete mode 100644 libs/country-code-picker/src/main/res/values-so/strings.xml delete mode 100644 libs/country-code-picker/src/main/res/values-tr-rTR/strings.xml delete mode 100644 libs/country-code-picker/src/main/res/values-zh/strings.xml delete mode 100644 libs/country-code-picker/src/main/res/values/strings.xml delete mode 100644 libs/material3-navigation/.gitignore delete mode 100644 libs/material3-navigation/README.md delete mode 100644 libs/material3-navigation/build.gradle.kts delete mode 100644 libs/material3-navigation/src/main/AndroidManifest.xml delete mode 100644 libs/material3-navigation/src/main/kotlin/com/mifos/library/material3/navigation/BottomSheet.kt delete mode 100644 libs/material3-navigation/src/main/kotlin/com/mifos/library/material3/navigation/BottomSheetNavigator.kt delete mode 100644 libs/material3-navigation/src/main/kotlin/com/mifos/library/material3/navigation/BottomSheetNavigatorDestinationBuilder.kt delete mode 100644 libs/material3-navigation/src/main/kotlin/com/mifos/library/material3/navigation/NavGraphBuilder.kt rename libs/mifos-passcode/src/{main => androidMain}/AndroidManifest.xml (100%) rename libs/mifos-passcode/src/{main/res => commonMain/composeResources}/drawable/lib_mifos_passcode_mifos_logo.jpg (100%) rename libs/mifos-passcode/src/{main/res => commonMain/composeResources}/font/lib_mifos_passcode_lato_black.ttf (100%) rename libs/mifos-passcode/src/{main/res => commonMain/composeResources}/font/lib_mifos_passcode_lato_bold.ttf (100%) rename libs/mifos-passcode/src/{main/res => commonMain/composeResources}/font/lib_mifos_passcode_lato_regular.ttf (100%) rename libs/mifos-passcode/src/{main/res => commonMain/composeResources}/values/strings.xml (100%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/PassCodeScreen.kt (76%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/PasscodeNavigation.kt (100%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/component/MifosIcon.kt (75%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/component/PasscodeButton.kt (77%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/component/PasscodeHeader.kt (84%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/component/PasscodeKeys.kt (96%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/component/PasscodeMismatchedDialog.kt (71%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/component/PasscodeStepIndicator.kt (100%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/component/PasscodeToolbar.kt (79%) create mode 100644 libs/mifos-passcode/src/commonMain/kotlin/org/mifos/library/passcode/di/PasscodeModule.kt rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/theme/Color.kt (100%) create mode 100644 libs/mifos-passcode/src/commonMain/kotlin/org/mifos/library/passcode/theme/Font.kt rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/theme/Theme.kt (97%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/theme/Type.kt (71%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/utility/Constants.kt (100%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/utility/ShakeAnimation.kt (100%) rename libs/mifos-passcode/src/{main => commonMain}/kotlin/org/mifos/library/passcode/utility/Step.kt (90%) create mode 100644 libs/mifos-passcode/src/commonMain/kotlin/org/mifos/library/passcode/viewmodels/PasscodeViewModel.kt create mode 100644 libs/mifos-passcode/src/commonMain/kotlin/proto/org/mifos/library/passcode/data/PasscodeManager.kt create mode 100644 libs/mifos-passcode/src/commonMain/kotlin/proto/org/mifos/library/passcode/data/PasscodePreferencesDataSource.kt create mode 100644 libs/mifos-passcode/src/commonMain/kotlin/proto/org/mifos/library/passcode/di/PreferenceModule.kt create mode 100644 libs/mifos-passcode/src/commonMain/kotlin/proto/org/mifos/library/passcode/model/PasscodePreferencesProto.kt create mode 100644 libs/mifos-passcode/src/commonMain/kotlin/proto/org/mifos/library/passcode/passcode_preferences.proto delete mode 100644 libs/mifos-passcode/src/main/kotlin/org/mifos/library/passcode/data/PasscodeManager.kt delete mode 100644 libs/mifos-passcode/src/main/kotlin/org/mifos/library/passcode/data/PasscodeRepositoryImpl.kt delete mode 100644 libs/mifos-passcode/src/main/kotlin/org/mifos/library/passcode/di/ApplicationModule.kt delete mode 100644 libs/mifos-passcode/src/main/kotlin/org/mifos/library/passcode/theme/Font.kt delete mode 100644 libs/mifos-passcode/src/main/kotlin/org/mifos/library/passcode/utility/PreferenceManager.kt delete mode 100644 libs/mifos-passcode/src/main/kotlin/org/mifos/library/passcode/utility/VibrationFeedback.kt delete mode 100644 libs/mifos-passcode/src/main/kotlin/org/mifos/library/passcode/viewmodels/PasscodeViewModel.kt delete mode 100644 libs/mifos-passcode/src/main/res/drawable/lib_mifos_passcode_delete_forever.xml delete mode 100644 libs/mifos-passcode/src/main/res/drawable/lib_mifos_passcode_ic_delete.xml delete mode 100644 libs/pullrefresh/.gitignore delete mode 100644 libs/pullrefresh/README.md delete mode 100644 libs/pullrefresh/build.gradle.kts delete mode 100644 libs/pullrefresh/src/main/AndroidManifest.xml delete mode 100644 libs/pullrefresh/src/main/kotlin/com.mifos.library.pullrefresh/PullRefresh.kt delete mode 100644 libs/pullrefresh/src/main/kotlin/com.mifos.library.pullrefresh/PullRefreshIndicator.kt delete mode 100644 libs/pullrefresh/src/main/kotlin/com.mifos.library.pullrefresh/PullRefreshIndicatorTransform.kt delete mode 100644 libs/pullrefresh/src/main/kotlin/com.mifos.library.pullrefresh/PullRefreshState.kt delete mode 100644 lint/.gitignore delete mode 100644 lint/build.gradle.kts delete mode 100644 lint/lint-baseline.xml delete mode 100644 lint/src/main/kotlin/org/mifos/mifospay/lint/MifosPayIssueRegistry.kt delete mode 100644 lint/src/main/kotlin/org/mifos/mifospay/lint/TestMethodNameDetector.kt delete mode 100644 lint/src/main/kotlin/org/mifos/mifospay/lint/config/Priorities.kt delete mode 100644 lint/src/main/kotlin/org/mifos/mifospay/lint/designsystem/DesignSystemDetector.kt delete mode 100644 lint/src/main/kotlin/org/mifos/mifospay/lint/designsystem/Material2Detector.kt delete mode 100644 lint/src/main/kotlin/org/mifos/mifospay/lint/util/LintUtils.kt delete mode 100644 lint/src/main/kotlin/org/mifos/mifospay/lint/util/OptionLoadingDetector.kt delete mode 100644 lint/src/main/kotlin/org/mifos/mifospay/lint/util/StringSetLintOption.kt delete mode 100644 lint/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry delete mode 100644 lint/src/test/kotlin/org/mifos/mifospay/lint/TestMethodNameDetectorTest.kt delete mode 100644 lint/src/test/kotlin/org/mifos/mifospay/lint/designsystem/DesignSystemDetectorTest.kt create mode 100644 mifospay-android/.gitignore rename {mifospay => mifospay-android}/README.md (100%) rename {mifospay => mifospay-android}/build.gradle.kts (75%) create mode 100644 mifospay-android/dependencies/prodReleaseRuntimeClasspath.tree.txt create mode 100644 mifospay-android/dependencies/prodReleaseRuntimeClasspath.txt rename {mifospay => mifospay-android}/google-services.json (100%) rename {mifospay => mifospay-android}/lint-baseline.xml (100%) rename {mifospay => mifospay-android}/prodRelease-badging.txt (79%) rename {mifospay => mifospay-android}/proguard-rules.pro (100%) rename {mifospay => mifospay-android}/release_keystore.keystore (100%) rename {mifospay => mifospay-android}/src/androidTest/java/org/mifospay/ExampleInstrumentedTest.kt (100%) rename {mifospay => mifospay-android}/src/main/AndroidManifest.xml (84%) create mode 100644 mifospay-android/src/main/kotlin/org/mifospay/MainActivity.kt rename shared/src/androidMain/kotlin/org/mifospay/shared/MyApplication.kt => mifospay-android/src/main/kotlin/org/mifospay/MifosPayApp.kt (58%) rename {mifospay => mifospay-android}/src/main/res/drawable/bg_splash.xml (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/bg_splash_12.xml (100%) create mode 100644 mifospay-android/src/main/res/drawable/feature_accounts_ic_bank.xml create mode 100644 mifospay-android/src/main/res/drawable/feature_receipt_mifospay_round_logo.png rename {mifospay => mifospay-android}/src/main/res/drawable/ic_finance.xml (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/ic_home.xml (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/ic_person.xml (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/ic_swap_horiz.xml (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/logo_axis.png (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/logo_hdfc.png (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/logo_icici.png (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/logo_pnb.png (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/logo_rbl.png (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/logo_sbi.png (100%) create mode 100644 mifospay-android/src/main/res/drawable/mifospay_round_logo.png rename {mifospay => mifospay-android}/src/main/res/drawable/money_in.png (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/money_out.png (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/splash_icon.png (100%) rename {mifospay => mifospay-android}/src/main/res/drawable/splash_screen_background.xml (100%) rename {mifospay => mifospay-android}/src/main/res/mipmap/ic_launcher.png (100%) rename {mifospay => mifospay-android}/src/main/res/mipmap/ic_launcher_round.png (100%) rename {mifospay => mifospay-android}/src/main/res/values/colors.xml (100%) rename {mifospay => mifospay-android}/src/main/res/values/splash.xml (100%) rename {mifospay => mifospay-android}/src/main/res/values/strings.xml (100%) rename {mifospay => mifospay-android}/src/main/res/xml/provider_paths.xml (100%) create mode 100644 mifospay-desktop/.gitignore create mode 100644 mifospay-desktop/README.md rename {desktop => mifospay-desktop}/build.gradle.kts (69%) rename desktop/src/jvmMain/kotlin/Main.kt => mifospay-desktop/src/desktopMain/kotlin/main.kt (90%) rename {iosApp => mifospay-ios}/iosApp.xcodeproj/project.pbxproj (100%) rename {iosApp => mifospay-ios}/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename {iosApp => mifospay-ios}/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename {iosApp => mifospay-ios}/iosApp.xcodeproj/project.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate (100%) rename {iosApp => mifospay-ios}/iosApp.xcodeproj/project.xcworkspace/xcuserdata/apple.xcuserdatad/xcschemes/xcschememanagement.plist (100%) rename {iosApp => mifospay-ios}/iosApp.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/iosApp.xcscheme (100%) rename {iosApp => mifospay-ios}/iosApp.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/xcschememanagement.plist (100%) rename {iosApp => mifospay-ios}/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json (100%) rename {iosApp => mifospay-ios}/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename {iosApp => mifospay-ios}/iosApp/Assets.xcassets/Contents.json (100%) rename {iosApp => mifospay-ios}/iosApp/ContentView.swift (93%) rename {iosApp => mifospay-ios}/iosApp/Preview Content/Preview Assets.xcassets/Contents.json (100%) rename {iosApp => mifospay-ios}/iosApp/iosAppApp.swift (92%) create mode 100644 mifospay-shared/build.gradle.kts create mode 100644 mifospay-shared/src/commonMain/composeResources/values/strings.xml create mode 100644 mifospay-shared/src/commonMain/kotlin/org/mifospay/shared/MifosPayApp.kt rename mifospay/src/main/java/org/mifospay/MainActivityViewModel.kt => mifospay-shared/src/commonMain/kotlin/org/mifospay/shared/MifosPayViewModel.kt (60%) create mode 100644 mifospay-shared/src/commonMain/kotlin/org/mifospay/shared/di/KoinModules.kt rename {mifospay/src/main/java/org/mifospay => mifospay-shared/src/commonMain/kotlin/org/mifospay/shared}/navigation/LoginNavGraph.kt (58%) rename {mifospay/src/main/java/org/mifospay => mifospay-shared/src/commonMain/kotlin/org/mifospay/shared}/navigation/MifosNavGraph.kt (93%) create mode 100644 mifospay-shared/src/commonMain/kotlin/org/mifospay/shared/navigation/MifosNavHost.kt rename {mifospay/src/main/java/org/mifospay => mifospay-shared/src/commonMain/kotlin/org/mifospay/shared}/navigation/PasscodeNavGraph.kt (63%) rename {mifospay/src/main/java/org/mifospay => mifospay-shared/src/commonMain/kotlin/org/mifospay/shared}/navigation/RootNavGraph.kt (76%) rename {mifospay/src/main/java/org/mifospay => mifospay-shared/src/commonMain/kotlin/org/mifospay/shared}/ui/MifosApp.kt (62%) rename {mifospay/src/main/java/org/mifospay => mifospay-shared/src/commonMain/kotlin/org/mifospay/shared}/ui/MifosAppState.kt (66%) rename {mifospay/src/main/java/org/mifospay/navigation => mifospay-shared/src/commonMain/kotlin/org/mifospay/shared/utils}/TopLevelDestination.kt (57%) create mode 100644 mifospay-web/.gitignore create mode 100644 mifospay-web/README.md create mode 100644 mifospay-web/build.gradle.kts create mode 100644 mifospay-web/src/jsMain/kotlin/Application.kt create mode 100644 mifospay-web/src/jsMain/resources/index.html create mode 100644 mifospay-web/src/jsMain/resources/styles.css create mode 100644 mifospay-web/src/wasmJsMain/kotlin/Main.kt create mode 100644 mifospay-web/src/wasmJsMain/resources/index.html delete mode 100644 mifospay/dependencies/prodReleaseRuntimeClasspath.tree.txt delete mode 100644 mifospay/dependencies/prodReleaseRuntimeClasspath.txt delete mode 100644 mifospay/src/main/java/org/mifospay/MainActivity.kt delete mode 100644 mifospay/src/main/java/org/mifospay/MifosPayApp.kt delete mode 100644 mifospay/src/main/java/org/mifospay/data/firebase/api/services/MifosPayMessagingService.kt delete mode 100644 mifospay/src/main/java/org/mifospay/di/JankStatsModule.kt delete mode 100644 mifospay/src/main/java/org/mifospay/di/KoinModules.kt delete mode 100644 mifospay/src/main/java/org/mifospay/navigation/MifosNavHost.kt delete mode 100644 mifospay/src/main/java/org/mifospay/utils/NotificationUtils.kt delete mode 100644 mifospay/src/test/java/org/mifospay/KoinModulesCheck.kt delete mode 100644 shared/build.gradle.kts delete mode 100644 shared/src/androidMain/kotlin/org/mifospay/shared/MainActivity.kt delete mode 100644 shared/src/androidMain/kotlin/org/mifospay/shared/Platform.android.kt delete mode 100644 shared/src/androidMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.android.kt delete mode 100644 shared/src/commonMain/kotlin/org/mifospay/shared/App.kt delete mode 100644 shared/src/commonMain/kotlin/org/mifospay/shared/Platform.kt delete mode 100644 shared/src/commonMain/kotlin/org/mifospay/shared/di/KoinModule.kt delete mode 100644 shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/Client.kt delete mode 100644 shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/Role.kt delete mode 100644 shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/UserData.kt delete mode 100644 shared/src/commonMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.kt delete mode 100644 shared/src/commonMain/kotlin/org/mifospay/shared/preferences/UserPreferenceRepository.kt delete mode 100644 shared/src/commonMain/kotlin/org/mifospay/shared/preferences/UserPreferenceSerializer.kt delete mode 100644 shared/src/commonMain/proto/user_preferences.proto delete mode 100644 shared/src/desktopMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.desktop.kt delete mode 100644 shared/src/iosMain/kotlin/org/mifospay/shared/MainViewController.kt delete mode 100644 shared/src/iosMain/kotlin/org/mifospay/shared/Platform.ios.kt delete mode 100644 shared/src/iosMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.ios.kt diff --git a/.github/workflows/feature_branch_ci.yml b/.github/workflows/feature_branch_ci.yml deleted file mode 100644 index 64dffd00a..000000000 --- a/.github/workflows/feature_branch_ci.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Mobile-Wallet CI[Feature] - -on: - push: - branches: - - '*' - - '!dev' - - '!master' -jobs: - build: - name: Build APK - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - # Set up JDK - - name: Set Up JDK 17 - uses: actions/setup-java@v1 - with: - java-version: 17 - - # Install NDK - - name: Install NDK - run: echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;20.0.5594570" --sdk_root=${ANDROID_SDK_ROOT} - - # Update Gradle Permission - - name: Change gradlew Permission - run: chmod +x gradlew - - # Build App - - name: Build with Gradle - run: ./gradlew assemble diff --git a/.github/workflows/master_dev_ci.yml b/.github/workflows/master_dev_ci.yml index 88fe178ef..ba41c9883 100644 --- a/.github/workflows/master_dev_ci.yml +++ b/.github/workflows/master_dev_ci.yml @@ -75,7 +75,7 @@ jobs: - name: Check Dependency Guard id: dependencyguard_verify continue-on-error: true - run: ./gradlew dependencyGuard + run: ./gradlew :mifospay-android:dependencyGuard - name: Prevent updating Dependency Guard baselines if this is a fork id: checkfork_dependencyguard @@ -88,7 +88,7 @@ jobs: id: dependencyguard_baseline if: steps.dependencyguard_verify.outcome == 'failure' && github.event_name == 'pull_request' run: | - ./gradlew dependencyGuardBaseline + ./gradlew :mifospay-android:dependencyGuardBaseline - name: Push new Dependency Guard baselines if available uses: stefanzweifel/git-auto-commit-action@v5 @@ -109,7 +109,8 @@ jobs: java-version: 17 - name: Run tests run: | - ./gradlew testDemoDebug :lint:test :mifospay:lintProdRelease :lint:lint + ./gradlew :mifospay-android:testDemoDebug +# ./gradlew testDemoDebug :lint:test :mifospay-android:lintProdRelease :lint:lint - name: Upload reports if: always() uses: actions/upload-artifact@v4 @@ -130,12 +131,12 @@ jobs: java-version: 17 - name: Build APKs - run: ./gradlew :mifospay:assembleDemoDebug + run: ./gradlew :mifospay-android:assembleDemoDebug - name: Check badging # This step is allowed to fail, as it's not critical for the build continue-on-error: true - run: ./gradlew :mifospay:checkProdReleaseBadging + run: ./gradlew :mifospay-android:checkProdReleaseBadging - name: Upload APKs uses: actions/upload-artifact@v4 diff --git a/.run/mifospay-android.run.xml b/.run/mifospay-android.run.xml new file mode 100644 index 000000000..2b81165ce --- /dev/null +++ b/.run/mifospay-android.run.xml @@ -0,0 +1,70 @@ + + + + + \ No newline at end of file diff --git a/.run/mifospay-desktop.run.xml b/.run/mifospay-desktop.run.xml new file mode 100644 index 000000000..6044007fa --- /dev/null +++ b/.run/mifospay-desktop.run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/mifospay-web-js.run.xml b/.run/mifospay-web-js.run.xml new file mode 100644 index 000000000..d6b902502 --- /dev/null +++ b/.run/mifospay-web-js.run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/mifospay-web-wasm.run.xml b/.run/mifospay-web-wasm.run.xml new file mode 100644 index 000000000..6bdae484b --- /dev/null +++ b/.run/mifospay-web-wasm.run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/README.md b/README.md index 953bdb92b..4755e4e1c 100644 --- a/README.md +++ b/README.md @@ -6,24 +6,103 @@ Mobile Wallet is an Android-based framework for mobile wallets based on top of < clean architecture and contains a core library module that can be used as a dependency in any other wallet based project. It is developed at MIFOS together with a global community. +# Run the project +![Screenshot 2024-10-19 005524](https://github.com/user-attachments/assets/8023c529-1215-4c4b-b212-630f0233223f) +- To run the android-app select the `mifospay-android` run configuration and click run. +- To run the desktop-app select the `mifospay-desktop` run configuration and click run. +- To run the web-app-js select the `mifospay-web-js` run configuration and click run. + +## KMP Status for modules + +| Module | Progress | Desktop supported | Android supported | iOS supported | Web supported(JS) | Web supported(WASM-JS) | +|-------------------------------|----------|-------------------|-------------------|---------------|-------------------|-------------------------| +| mifospay-android | Done | āœ… | āœ… | ā” | āœ… | ā” | +| mifospay-desktop | Done | āœ… | āœ… | ā” | āœ… | ā” | +| mifospay-web | Done | āœ… | āœ… | ā” | āœ… | ā” | +| mifospay-ios | NO OP | āŒ | āŒ | āŒ | āŒ | āŒ | +| :core:analytics | Done | āŒ | āœ”ļø | ā” | āŒ | ā” | +| :core:common | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :core:data | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :core:datastore | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :core:datastore-proto | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :core:designsystem | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :core:domain | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :core:model | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :core:network | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :core:ui | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:auth | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:editpassword | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:faq | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:history | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:home | Done | āœ… | āœ… | ā” | āœ… | āŒ | +| :feature:profile | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:settings | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:payments | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:finance | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:account | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:invoices | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:kyc | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:make-transfer | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:merchants | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:notification | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:qr | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:receipt | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:request-money | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:saved-cards | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:send-money | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:standing-instruction | Done | āœ… | āœ… | ā” | āœ… | āœ… | +| :feature:upi-setup | Done | āœ… | āœ… | ā” | āœ… | āœ… | + +āœ…: Functioning properly +ā”: Not yet tested, but expected to work +āœ”ļø: Successfully compiled +āŒ: Not functioning, requires further attention + ## Notice :warning: We are fully committed to implement [Jetpack Compose](https://developer.android.com/jetpack/compose) and moving ourself to support -`kotlin multi-platform`. **If you are sending any PR regarding `XML changes` we will `not` consider at this moment but converting XML to jetpack compose are most welcome.** If you sending any PR regarding logical changes in Activity/Fragment you are most welcome. - +`kotlin multi-platform`. **If you are sending any PR regarding `XML changes` we will `not` consider at this moment but converting XML to jetpack compose are most welcome.** If you sending any PR regarding logical changes in Activity/Fragment you are most welcome. -Development | Chat | -|-----------------|-----------------| -![Mobile-Wallet CI[Master/Dev]](https://github.com/openMF/mobile-wallet/workflows/Mobile-Wallet%20CI%5BMaster/Dev%5D/badge.svg?branch=dev) | [![Join the chat at https://mifos.slack.com/](https://img.shields.io/badge/Join%20Our%20Community-Slack-blue)](https://mifos.slack.com/) | +| Development | Chat | +|--------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------| +| ![Mobile-Wallet CI[Master/Dev]](https://github.com/openMF/mobile-wallet/workflows/Mobile-Wallet%20CI%5BMaster/Dev%5D/badge.svg?branch=dev) | [![Join the chat at https://mifos.slack.com/](https://img.shields.io/badge/Join%20Our%20Community-Slack-blue)](https://mifos.slack.com/) | ## Join Us on Slack Mifos boasts an active and vibrant contributor community, Please join us on [slack](https://join.slack.com/t/mifos/shared_invite/zt-2f4nr6tk3-ZJlHMi1lc0R19FFEHxdvng). Once you've joined the mifos slack community, please join the `#mobile-wallet` channel to engage with mobile-wallet development. If you encounter any difficulties joining our Slack channel, please don't hesitate to open an issue. This will allow us to assist you promptly or send you an invitation. -### [How to Contribute](https://github.com/openMF/mobile-wallet/wiki/How-to-Contribute) -### [Branch Policy](https://github.com/openMF/mobile-wallet/wiki/Branch-Policy) + +## How to Contribute + +Thank you for your interest in contributing to the Mobile Wallet project by Mifos! We welcome all contributions and encourage you to follow these guidelines to ensure a smooth and efficient collaboration process. + +The issues should be raised via the GitHub issue tracker. For Issue tracker guidelines please click here. All fixes should be proposed via pull requests. For pull request guidelines please click here. For commit style guidelines please click here. + +### Branch Policy + +We have the following branches : + + * **dev** + All the contributions should be pushed to this branch. If you're making a contribution, + you are supposed to make a pull request to _dev_. + Please make sure it passes a build check on Travis. + + It is advisable to clone only the development branch using the following command: + + ``` + git clone -b + ``` + + With Git 1.7.10 and later, add --single-branch to prevent fetching of all branches. Example, with development branch: + + ``` + git clone -b dev --single-branch https://github.com/username/mobile-wallet.git` + ``` + + * **master** + The master branch contains all the stable and bug-free working code. The development branch once complete will be merged with this branch. ### Demo credentials Fineract Instance: demo.mifos.io diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index 0dd037feb..2f8cf70e2 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -23,11 +23,8 @@ dependencies { compileOnly(libs.android.gradlePlugin) compileOnly(libs.android.tools.common) compileOnly(libs.compose.gradlePlugin) - compileOnly(libs.firebase.crashlytics.gradlePlugin) - compileOnly(libs.firebase.performance.gradlePlugin) compileOnly(libs.kotlin.gradlePlugin) compileOnly(libs.ksp.gradlePlugin) - compileOnly(libs.room.gradlePlugin) compileOnly(libs.detekt.gradlePlugin) compileOnly(libs.ktlint.gradlePlugin) compileOnly(libs.spotless.gradle) @@ -43,6 +40,7 @@ tasks { gradlePlugin { plugins { + // Android Plugins register("androidApplicationCompose") { id = "mifospay.android.application.compose" implementationClass = "AndroidApplicationComposeConventionPlugin" @@ -51,46 +49,28 @@ gradlePlugin { id = "mifospay.android.application" implementationClass = "AndroidApplicationConventionPlugin" } - register("androidLibraryCompose") { - id = "mifospay.android.library.compose" - implementationClass = "AndroidLibraryComposeConventionPlugin" - } - register("androidLibrary") { - id = "mifospay.android.library" - implementationClass = "AndroidLibraryConventionPlugin" - } - register("androidFeature") { - id = "mifospay.android.feature" - implementationClass = "AndroidFeatureConventionPlugin" - } - register("androidTest") { - id = "mifospay.android.test" - implementationClass = "AndroidTestConventionPlugin" - } - register("androidRoom") { - id = "mifospay.android.room" - implementationClass = "AndroidRoomConventionPlugin" - } - register("androidFirebase") { - id = "mifospay.android.application.firebase" - implementationClass = "AndroidApplicationFirebaseConventionPlugin" - } - register("androidLint") { - id = "mifospay.android.lint" - implementationClass = "AndroidLintConventionPlugin" - } - register("jvmLibrary") { - id = "mifospay.jvm.library" - implementationClass = "JvmLibraryConventionPlugin" - } + register("androidFlavors") { id = "mifospay.android.application.flavors" implementationClass = "AndroidApplicationFlavorsConventionPlugin" } - register("androidKoin") { - id = "mifospay.android.koin" - implementationClass = "AndroidKoinConventionPlugin" + + // KMP & CMP Plugins + register("cmpFeature") { + id = "mifospay.cmp.feature" + implementationClass = "CMPFeatureConventionPlugin" } + + register("kmpKoin") { + id = "mifospay.kmp.koin" + implementationClass = "KMPKoinConventionPlugin" + } + register("kmpLibrary") { + id = "mifospay.kmp.library" + implementationClass = "KMPLibraryConventionPlugin" + } + + // Static Analysis & Formatting Plugins register("detekt") { id = "mifos.detekt.plugin" implementationClass = "MifosDetektConventionPlugin" diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt index b4f907e05..92787bc3a 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -15,11 +15,9 @@ class AndroidApplicationConventionPlugin : Plugin { with(pluginManager) { apply("com.android.application") apply("org.jetbrains.kotlin.android") - apply("mifospay.android.lint") apply("com.dropbox.dependency-guard") apply("mifos.detekt.plugin") apply("mifos.spotless.plugin") - apply("mifos.ktlint.plugin") apply("mifos.git.hooks") } diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationFirebaseConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationFirebaseConventionPlugin.kt deleted file mode 100644 index 83a97395c..000000000 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationFirebaseConventionPlugin.kt +++ /dev/null @@ -1,39 +0,0 @@ -import com.android.build.api.dsl.ApplicationExtension -import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.dependencies -import org.mifospay.libs - -class AndroidApplicationFirebaseConventionPlugin : Plugin { - override fun apply(target: Project) { - with(target) { - with(pluginManager) { - apply("com.google.gms.google-services") - apply("com.google.firebase.firebase-perf") - apply("com.google.firebase.crashlytics") - } - - dependencies { - val bom = libs.findLibrary("firebase-bom").get() - add("implementation", platform(bom)) - "implementation"(libs.findLibrary("firebase.analytics").get()) - "implementation"(libs.findLibrary("firebase.performance").get()) - "implementation"(libs.findLibrary("firebase.crashlytics").get()) - "implementation"(libs.findLibrary("firebase.cloud.messaging").get()) - } - - extensions.configure { - buildTypes.configureEach { - // Disable the Crashlytics mapping file upload. This feature should only be - // enabled if a Firebase backend is available and configured in - // google-services.json. - configure { - mappingFileUploadEnabled = false - } - } - } - } - } -} diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt deleted file mode 100644 index 52e08e684..000000000 --- a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt +++ /dev/null @@ -1,66 +0,0 @@ - -import com.android.build.gradle.LibraryExtension -import com.google.devtools.ksp.gradle.KspExtension -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.dependencies -import org.gradle.kotlin.dsl.kotlin -import org.mifospay.libs - -class AndroidFeatureConventionPlugin : Plugin { - override fun apply(target: Project) { - with(target) { - pluginManager.apply { - apply("mifospay.android.library") - apply("mifospay.android.koin") - } - - extensions.configure { - defaultConfig { - // set custom test runner - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } - testOptions.animationsDisabled = true - } - - extensions.configure { - arg("KOIN_USE_COMPOSE_VIEWMODEL","true") - } - - dependencies { - add("implementation", project(":core:ui")) - add("implementation", project(":core:designsystem")) - add("implementation", project(":core:data")) - - add("implementation", project(":libs:material3-navigation")) - - add("implementation", libs.findLibrary("androidx.navigation.compose").get()) - add("implementation", libs.findLibrary("kotlinx.collections.immutable").get()) - add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get()) - add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get()) - add("implementation", libs.findLibrary("androidx.tracing.ktx").get()) - - add("implementation", platform(libs.findLibrary("koin-bom").get())) - add("implementation", libs.findLibrary("koin-android").get()) - add("implementation", libs.findLibrary("koin.androidx.compose").get()) - - add("implementation", libs.findLibrary("koin.android").get()) - add("implementation", libs.findLibrary("koin.androidx.navigation").get()) - add("implementation", libs.findLibrary("koin.androidx.compose").get()) - add("implementation", libs.findLibrary("koin.core.viewmodel").get()) - - add("androidTestImplementation", libs.findLibrary("androidx.lifecycle.runtimeTesting").get()) - - add("testImplementation", kotlin("test")) - - add("testImplementation", libs.findLibrary("koin.test").get()) - add("testImplementation", libs.findLibrary("koin.test.junit4").get()) - - add("debugImplementation", libs.findLibrary("androidx.compose.ui.test.manifest").get()) - add("androidTestImplementation", libs.findLibrary("androidx.navigation.testing").get()) - add("androidTestImplementation", libs.findLibrary("androidx.compose.ui.test").get()) - } - } - } -} diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt deleted file mode 100644 index fb80756ee..000000000 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt +++ /dev/null @@ -1,19 +0,0 @@ -import com.android.build.gradle.LibraryExtension -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.kotlin.dsl.apply -import org.gradle.kotlin.dsl.getByType -import org.mifospay.configureAndroidCompose - -class AndroidLibraryComposeConventionPlugin : Plugin { - override fun apply(target: Project) { - with(target) { - pluginManager.apply("com.android.library") - apply(plugin = "org.jetbrains.kotlin.plugin.compose") - - val extension = extensions.getByType() - configureAndroidCompose(extension) - } - } - -} diff --git a/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt deleted file mode 100644 index 4614a16ab..000000000 --- a/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt +++ /dev/null @@ -1,37 +0,0 @@ -import com.android.build.api.dsl.ApplicationExtension -import com.android.build.api.dsl.LibraryExtension -import com.android.build.api.dsl.Lint -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.kotlin.dsl.configure -import java.io.File - -class AndroidLintConventionPlugin : Plugin { - override fun apply(target: Project) { - with(target) { - when { - pluginManager.hasPlugin("com.android.application") -> - configure { lint(Lint::configure) } - - pluginManager.hasPlugin("com.android.library") -> - configure { lint(Lint::configure) } - - else -> { - pluginManager.apply("com.android.lint") - configure(Lint::configure) - } - } - } - } -} - -private fun Lint.configure() { - xmlReport = true - checkDependencies = true - abortOnError = false - // Disable this rule until we ship the libraries to some maven. - disable += "ResourceName" - baseline = File("lint-baseline.xml") - explainIssues = true - htmlReport = true -} diff --git a/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt deleted file mode 100644 index b26d22035..000000000 --- a/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt +++ /dev/null @@ -1,29 +0,0 @@ -import androidx.room.gradle.RoomExtension -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.dependencies -import org.mifospay.libs - -class AndroidRoomConventionPlugin : Plugin { - - override fun apply(target: Project) { - with(target) { - pluginManager.apply("androidx.room") - pluginManager.apply("com.google.devtools.ksp") - - extensions.configure { - // The schemas directory contains a schema file for each version of the Room database. - // This is required to enable Room auto migrations. - // See https://developer.android.com/reference/kotlin/androidx/room/AutoMigration. - schemaDirectory("$projectDir/schemas") - } - - dependencies { - add("implementation", libs.findLibrary("room.runtime").get()) - add("implementation", libs.findLibrary("room.ktx").get()) - add("ksp", libs.findLibrary("room.compiler").get()) - } - } - } -} diff --git a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt deleted file mode 100644 index f726b8b8c..000000000 --- a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt +++ /dev/null @@ -1,21 +0,0 @@ -import com.android.build.gradle.TestExtension -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.kotlin.dsl.configure -import org.mifospay.configureKotlinAndroid - -class AndroidTestConventionPlugin : Plugin { - override fun apply(target: Project) { - with(target) { - with(pluginManager) { - apply("com.android.test") - apply("org.jetbrains.kotlin.android") - } - - extensions.configure { - configureKotlinAndroid(this) - defaultConfig.targetSdk = 34 - } - } - } -} diff --git a/build-logic/convention/src/main/kotlin/CMPFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/CMPFeatureConventionPlugin.kt new file mode 100644 index 000000000..44559cacd --- /dev/null +++ b/build-logic/convention/src/main/kotlin/CMPFeatureConventionPlugin.kt @@ -0,0 +1,55 @@ + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.dependencies +import org.mifospay.libs + +class CMPFeatureConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply { + apply("mifospay.kmp.library") + apply("mifospay.kmp.koin") + apply("org.jetbrains.kotlin.plugin.compose") + apply("org.jetbrains.compose") + } + + dependencies { + add("commonMainImplementation", project(":core:ui")) + add("commonMainImplementation", project(":core:designsystem")) + add("commonMainImplementation", project(":core:data")) + + add("commonMainImplementation", libs.findLibrary("koin.compose").get()) + add("commonMainImplementation", libs.findLibrary("koin.compose.viewmodel").get()) + + add("commonMainImplementation", libs.findLibrary("jb.composeRuntime").get()) + add("commonMainImplementation", libs.findLibrary("jb.composeViewmodel").get()) + add("commonMainImplementation", libs.findLibrary("jb.lifecycleViewmodel").get()) + add("commonMainImplementation", libs.findLibrary("jb.lifecycleViewmodelSavedState").get()) + add("commonMainImplementation", libs.findLibrary("jb.savedstate").get()) + add("commonMainImplementation", libs.findLibrary("jb.bundle").get()) + add("commonMainImplementation", libs.findLibrary("jb.composeNavigation").get()) + add("commonMainImplementation", libs.findLibrary("kotlinx.collections.immutable").get()) + + add("androidMainImplementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get()) + add("androidMainImplementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get()) + add("androidMainImplementation", libs.findLibrary("androidx.tracing.ktx").get()) + + add("androidMainImplementation", platform(libs.findLibrary("koin-bom").get())) + add("androidMainImplementation", libs.findLibrary("koin-android").get()) + add("androidMainImplementation", libs.findLibrary("koin.androidx.compose").get()) + + add("androidMainImplementation", libs.findLibrary("koin.android").get()) + add("androidMainImplementation", libs.findLibrary("koin.androidx.navigation").get()) + add("androidMainImplementation", libs.findLibrary("koin.androidx.compose").get()) + add("androidMainImplementation", libs.findLibrary("koin.core.viewmodel").get()) + + add("androidTestImplementation", libs.findLibrary("koin.test.junit4").get()) + + add("androidInstrumentedTestImplementation", libs.findLibrary("androidx.navigation.testing").get()) + add("androidInstrumentedTestImplementation", libs.findLibrary("androidx.compose.ui.test").get()) + add("androidInstrumentedTestImplementation", libs.findLibrary("androidx.lifecycle.runtimeTesting").get()) + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt deleted file mode 100644 index 8fcc18712..000000000 --- a/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt +++ /dev/null @@ -1,15 +0,0 @@ -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.mifospay.configureKotlinJvm - -class JvmLibraryConventionPlugin : Plugin { - override fun apply(target: Project) { - with(target) { - with(pluginManager) { - apply("org.jetbrains.kotlin.jvm") - apply("mifospay.android.lint") - } - configureKotlinJvm() - } - } -} diff --git a/build-logic/convention/src/main/kotlin/AndroidKoinConventionPlugin.kt b/build-logic/convention/src/main/kotlin/KMPKoinConventionPlugin.kt similarity index 50% rename from build-logic/convention/src/main/kotlin/AndroidKoinConventionPlugin.kt rename to build-logic/convention/src/main/kotlin/KMPKoinConventionPlugin.kt index 7f5142d57..1480f61b7 100644 --- a/build-logic/convention/src/main/kotlin/AndroidKoinConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/KMPKoinConventionPlugin.kt @@ -6,7 +6,7 @@ import org.gradle.kotlin.dsl.dependencies import org.mifospay.libs -class AndroidKoinConventionPlugin : Plugin { +class KMPKoinConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { with(pluginManager) { @@ -15,21 +15,17 @@ class AndroidKoinConventionPlugin : Plugin { dependencies { val bom = libs.findLibrary("koin-bom").get() - add("implementation", platform(bom)) - add("implementation", libs.findLibrary("koin.core").get()) + add("commonMainImplementation", platform(bom)) + add("commonMainImplementation", libs.findLibrary("koin.core").get()) - add("implementation", libs.findLibrary("koin.annotations").get()) - add("ksp", libs.findLibrary("koin.ksp.compiler").get()) + add("commonMainImplementation", libs.findLibrary("koin.annotations").get()) + add("kspCommonMainMetadata", libs.findLibrary("koin.ksp.compiler").get()) - - add("testImplementation", libs.findLibrary("koin.test").get()) - add("testImplementation", libs.findLibrary("koin.test.junit4").get()) + add("commonTestImplementation", libs.findLibrary("koin.test").get()) } extensions.configure { arg("KOIN_CONFIG_CHECK","true") - arg("USE_COMPOSE_VIEWMODEL", "false") - arg("KOIN_USE_COMPOSE_VIEWMODEL", "true") } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/KMPLibraryConventionPlugin.kt similarity index 50% rename from build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt rename to build-logic/convention/src/main/kotlin/KMPLibraryConventionPlugin.kt index edea58609..23d0a8913 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/KMPLibraryConventionPlugin.kt @@ -1,48 +1,44 @@ -import com.android.build.api.variant.LibraryAndroidComponentsExtension + import com.android.build.gradle.LibraryExtension import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.dependencies -import org.gradle.kotlin.dsl.kotlin import org.mifospay.configureFlavors import org.mifospay.configureKotlinAndroid -import org.mifospay.configurePrintApksTask -import org.mifospay.disableUnnecessaryAndroidTests +import org.mifospay.configureKotlinMultiplatform import org.mifospay.libs -class AndroidLibraryConventionPlugin : Plugin { +class KMPLibraryConventionPlugin: Plugin { override fun apply(target: Project) { with(target) { with(pluginManager) { apply("com.android.library") - apply("org.jetbrains.kotlin.android") - apply("mifospay.android.lint") + apply("org.jetbrains.kotlin.multiplatform") + apply("mifospay.kmp.koin") apply("mifos.detekt.plugin") apply("mifos.spotless.plugin") - apply("mifos.ktlint.plugin") - apply("mifospay.android.koin") } + configureKotlinMultiplatform() + extensions.configure { configureKotlinAndroid(this) defaultConfig.targetSdk = 34 - testOptions.animationsDisabled = true configureFlavors(this) // The resource prefix is derived from the module name, // so resources inside ":core:module1" must be prefixed with "core_module1_" - resourcePrefix = path.split("""\W""".toRegex()).drop(1).distinct().joinToString(separator = "_").lowercase() + "_" - } - - extensions.configure { - configurePrintApksTask(this) - disableUnnecessaryAndroidTests(target) + resourcePrefix = path + .split("""\W""".toRegex()) + .drop(1).distinct() + .joinToString(separator = "_") + .lowercase() + "_" } dependencies { - add("testImplementation", kotlin("test")) - add("implementation", libs.findLibrary("androidx.tracing.ktx").get()) + add("commonTestImplementation", libs.findLibrary("kotlin.test").get()) + add("commonTestImplementation", libs.findLibrary("kotlinx.coroutines.test").get()) } } } -} +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/org/mifospay/Detekt.kt b/build-logic/convention/src/main/kotlin/org/mifospay/Detekt.kt index 134c76d64..1059d2da3 100644 --- a/build-logic/convention/src/main/kotlin/org/mifospay/Detekt.kt +++ b/build-logic/convention/src/main/kotlin/org/mifospay/Detekt.kt @@ -5,11 +5,9 @@ import io.gitlab.arturbosch.detekt.extensions.DetektExtension import org.gradle.api.Project import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.named -import org.jetbrains.kotlin.gradle.dsl.JvmTarget internal fun Project.configureDetekt(extension: DetektExtension) = extension.apply { tasks.named("detekt") { - jvmTarget = "17" reports { xml.required.set(true) html.required.set(true) diff --git a/build-logic/convention/src/main/kotlin/org/mifospay/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/org/mifospay/KotlinAndroid.kt index bd39d9387..d05ebad92 100644 --- a/build-logic/convention/src/main/kotlin/org/mifospay/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/org/mifospay/KotlinAndroid.kt @@ -10,9 +10,6 @@ import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.provideDelegate import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension import org.jetbrains.kotlin.gradle.tasks.KotlinCompile /** @@ -37,7 +34,7 @@ internal fun Project.configureKotlinAndroid( } } - configureKotlin() + configureKotlin() dependencies { add("coreLibraryDesugaring", libs.findLibrary("android.desugarJdkLibs").get()) @@ -55,29 +52,26 @@ internal fun Project.configureKotlinJvm() { targetCompatibility = JavaVersion.VERSION_17 } - configureKotlin() + configureKotlin() } /** * Configure base Kotlin options */ -private inline fun Project.configureKotlin() = configure { - // Treat all Kotlin warnings as errors (disabled by default) - // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties - val warningsAsErrors: String? by project - when (this) { - is KotlinAndroidProjectExtension -> compilerOptions - is KotlinJvmProjectExtension -> compilerOptions - else -> TODO("Unsupported project extension $this ${T::class}") - }.apply { - jvmTarget = JvmTarget.JVM_17 - allWarningsAsErrors = warningsAsErrors.toBoolean() - freeCompilerArgs.add( - // Enable experimental coroutines APIs, including Flow - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - ) - freeCompilerArgs.add( - "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api" - ) +private fun Project.configureKotlin() { + // Use withType to workaround https://youtrack.jetbrains.com/issue/KT-55947 + tasks.withType().configureEach { + compilerOptions { + // Set JVM target to 17 + jvmTarget = JvmTarget.JVM_17 + // Treat all Kotlin warnings as errors (disabled by default) + // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties + val warningsAsErrors: String? by project + allWarningsAsErrors = warningsAsErrors.toBoolean() + freeCompilerArgs.add( + // Enable experimental coroutines APIs, including Flow + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + ) + } } -} +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/org/mifospay/KotlinMultiplatform.kt b/build-logic/convention/src/main/kotlin/org/mifospay/KotlinMultiplatform.kt new file mode 100644 index 000000000..755cc0009 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/org/mifospay/KotlinMultiplatform.kt @@ -0,0 +1,40 @@ +package org.mifospay + +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +@OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class) +internal fun Project.configureKotlinMultiplatform() { + extensions.configure { + applyDefaultHierarchyTemplate() + + jvm("desktop") + androidTarget() + iosSimulatorArm64() + iosX64() + iosArm64() + js(IR) { + this.nodejs() + binaries.executable() + } + wasmJs() { + browser() + nodejs() + } + // Suppress 'expect'/'actual' classes are in Beta. + targets.configureEach { + compilations.configureEach { + compilerOptions.configure { + freeCompilerArgs.addAll("-Xexpect-actual-classes") + } + } + } + + // Fixes Cannot locate tasks that match ':core:model:testClasses' as task 'testClasses' + // not found in project ':core:model'. Some candidates are: 'jsTestClasses', 'jvmTestClasses'. + project.tasks.create("testClasses") { + dependsOn("allTests") + } + } +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index b9fa219e3..84a0026c2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,7 +21,6 @@ plugins { alias(libs.plugins.ksp) apply false alias(libs.plugins.roborazzi) apply false alias(libs.plugins.secrets) apply false - alias(libs.plugins.room) apply false alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.module.graph) apply true alias(libs.plugins.detekt) apply false @@ -33,6 +32,7 @@ plugins { alias(libs.plugins.compose.compiler) apply false alias(libs.plugins.kotlinMultiplatform) apply false alias(libs.plugins.wire) apply false + alias(libs.plugins.ktrofit) apply false } object DynamicVersion { diff --git a/ci-prepush.bat b/ci-prepush.bat index 60ffba915..49298e3e7 100644 --- a/ci-prepush.bat +++ b/ci-prepush.bat @@ -12,11 +12,9 @@ echo Starting all checks and tests... call :run_gradle_task "check -p build-logic" call :run_gradle_task "spotlessApply --no-configuration-cache" call :run_gradle_task "dependencyGuardBaseline" -call :run_gradle_task "formatVersionCatalog" call :run_gradle_task "detekt" -call :run_gradle_task "testDemoDebug :lint:test :mifospay:lintProdRelease :lint:lint" -call :run_gradle_task "build" -call :run_gradle_task "updateProdReleaseBadging" +call :run_gradle_task ":mifospay-android:build" +call :run_gradle_task ":mifospay-android:updateProdReleaseBadging" echo All checks and tests completed successfully. exit /b 0 diff --git a/ci-prepush.sh b/ci-prepush.sh index 95cc04913..6689fd494 100644 --- a/ci-prepush.sh +++ b/ci-prepush.sh @@ -28,10 +28,8 @@ tasks=( "spotlessApply --no-configuration-cache" "dependencyGuardBaseline" "detekt" - "formatVersionCatalog" - "testDemoDebug :lint:test :lint:lint :mifospay:lintProdRelease" - "build" - "updateProdReleaseBadging" + ":mifospay-android:build" + ":mifospay-android:updateProdReleaseBadging" ) for task in "${tasks[@]}"; do diff --git a/core/analytics/build.gradle.kts b/core/analytics/build.gradle.kts index 6df4ddd5f..0059b3e4d 100644 --- a/core/analytics/build.gradle.kts +++ b/core/analytics/build.gradle.kts @@ -8,17 +8,23 @@ * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ plugins { - alias(libs.plugins.mifospay.android.library) - alias(libs.plugins.mifospay.android.library.compose) + alias(libs.plugins.mifospay.kmp.library) + alias(libs.plugins.jetbrainsCompose) + alias(libs.plugins.compose.compiler) } android { namespace = "org.mifospay.core.analytics" } -dependencies { - implementation(libs.androidx.compose.runtime) - - implementation(platform(libs.firebase.bom)) - implementation(libs.firebase.analytics) -} +kotlin { + sourceSets { + commonMain.dependencies { + implementation(compose.runtime) + } + androidMain.dependencies { + implementation(project.dependencies.platform(libs.firebase.bom)) + implementation(libs.firebase.analytics) + } + } +} \ No newline at end of file diff --git a/core/analytics/proguard-rules.pro b/core/analytics/proguard-rules.pro deleted file mode 100644 index 481bb4348..000000000 --- a/core/analytics/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/analytics/src/main/AndroidManifest.xml b/core/analytics/src/androidMain/kotlin/AndroidManifest.xml similarity index 100% rename from core/analytics/src/main/AndroidManifest.xml rename to core/analytics/src/androidMain/kotlin/AndroidManifest.xml diff --git a/core/analytics/src/main/kotlin/org/mifospay/core/analytics/AnalyticsEvent.kt b/core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/AnalyticsEvent.kt similarity index 100% rename from core/analytics/src/main/kotlin/org/mifospay/core/analytics/AnalyticsEvent.kt rename to core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/AnalyticsEvent.kt diff --git a/core/analytics/src/main/kotlin/org/mifospay/core/analytics/AnalyticsHelper.kt b/core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/AnalyticsHelper.kt similarity index 100% rename from core/analytics/src/main/kotlin/org/mifospay/core/analytics/AnalyticsHelper.kt rename to core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/AnalyticsHelper.kt diff --git a/core/analytics/src/main/kotlin/org/mifospay/core/analytics/NoOpAnalyticsHelper.kt b/core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/NoOpAnalyticsHelper.kt similarity index 100% rename from core/analytics/src/main/kotlin/org/mifospay/core/analytics/NoOpAnalyticsHelper.kt rename to core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/NoOpAnalyticsHelper.kt diff --git a/core/analytics/src/main/kotlin/org/mifospay/core/analytics/StubAnalyticsHelper.kt b/core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/StubAnalyticsHelper.kt similarity index 100% rename from core/analytics/src/main/kotlin/org/mifospay/core/analytics/StubAnalyticsHelper.kt rename to core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/StubAnalyticsHelper.kt diff --git a/core/analytics/src/main/kotlin/org/mifospay/core/analytics/UiHelpers.kt b/core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/UiHelpers.kt similarity index 100% rename from core/analytics/src/main/kotlin/org/mifospay/core/analytics/UiHelpers.kt rename to core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/UiHelpers.kt diff --git a/core/analytics/src/main/kotlin/org/mifospay/core/analytics/di/AnalyticsModule.kt b/core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/di/AnalyticsModule.kt similarity index 100% rename from core/analytics/src/main/kotlin/org/mifospay/core/analytics/di/AnalyticsModule.kt rename to core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/di/AnalyticsModule.kt diff --git a/core/analytics/src/main/kotlin/org/mifospay/core/analytics/di/FirebaseAnalyticsHelper.kt b/core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/di/FirebaseAnalyticsHelper.kt similarity index 100% rename from core/analytics/src/main/kotlin/org/mifospay/core/analytics/di/FirebaseAnalyticsHelper.kt rename to core/analytics/src/androidMain/kotlin/org/mifospay/core/analytics/di/FirebaseAnalyticsHelper.kt diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 27f8f6fac..35745924c 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -8,14 +8,56 @@ * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ plugins { - alias(libs.plugins.mifospay.android.library) + alias(libs.plugins.mifospay.kmp.library) + alias(libs.plugins.kotlin.parcelize) } android { namespace = "org.mifospay.common" } -dependencies { - implementation(libs.kotlinx.coroutines.core) - implementation(libs.kotlinx.coroutines.android) -} +kotlin { + + listOf( + iosX64(), + iosArm64(), + iosSimulatorArm64(), + ).forEach { + it.binaries.framework { + isStatic = false + export(libs.kermit.simple) + } + } + + sourceSets { + commonMain.dependencies { + implementation(libs.kotlinx.coroutines.core) + api(libs.coil.kt) + api(libs.coil.core) + api(libs.coil.svg) + api(libs.coil.network.ktor) + api(libs.kermit.logging) + api(libs.squareup.okio) + api(libs.jb.kotlin.stdlib) + api(libs.kotlinx.datetime) + } + + androidMain.dependencies { + implementation(libs.kotlinx.coroutines.android) + } + commonTest.dependencies { + implementation(libs.kotlinx.coroutines.test) + } + iosMain.dependencies { + api(libs.kermit.simple) + } + desktopMain.dependencies { + implementation(libs.kotlinx.coroutines.swing) + implementation(libs.kotlin.reflect) + } + jsMain.dependencies { + api(libs.jb.kotlin.stdlib.js) + api(libs.jb.kotlin.dom) + } + } +} \ No newline at end of file diff --git a/core/common/proguard-rules.pro b/core/common/proguard-rules.pro deleted file mode 100644 index 481bb4348..000000000 --- a/core/common/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/common/src/main/AndroidManifest.xml b/core/common/src/androidMain/AndroidManifest.xml similarity index 100% rename from core/common/src/main/AndroidManifest.xml rename to core/common/src/androidMain/AndroidManifest.xml diff --git a/core/common/src/androidMain/kotlin/org/mifospay/core/common/CurrencyFormatter.android.kt b/core/common/src/androidMain/kotlin/org/mifospay/core/common/CurrencyFormatter.android.kt new file mode 100644 index 000000000..4fee020b7 --- /dev/null +++ b/core/common/src/androidMain/kotlin/org/mifospay/core/common/CurrencyFormatter.android.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +import java.text.NumberFormat +import java.util.Currency + +actual object CurrencyFormatter { + actual fun format( + balance: Double?, + currencyCode: String?, + maximumFractionDigits: Int?, + ): String { + val balanceFormatter = NumberFormat.getCurrencyInstance() + balanceFormatter.maximumFractionDigits = maximumFractionDigits ?: 0 + balanceFormatter.currency = Currency.getInstance(currencyCode) + return balanceFormatter.format(balance) + } +} diff --git a/core/model/src/main/java/com/mifospay/core/model/domain/client/UpdateClientEntityMobile.kt b/core/common/src/androidMain/kotlin/org/mifospay/core/common/FileUtils.android.kt similarity index 70% rename from core/model/src/main/java/com/mifospay/core/model/domain/client/UpdateClientEntityMobile.kt rename to core/common/src/androidMain/kotlin/org/mifospay/core/common/FileUtils.android.kt index 9ca0bc770..83a3f6ff1 100644 --- a/core/model/src/main/java/com/mifospay/core/model/domain/client/UpdateClientEntityMobile.kt +++ b/core/common/src/androidMain/kotlin/org/mifospay/core/common/FileUtils.android.kt @@ -7,6 +7,7 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.domain.client +package org.mifospay.core.common -data class UpdateClientEntityMobile(val mobileNo: String) +// JVM and Android implementation +actual fun createPlatformFileUtils(): FileUtils = CommonFileUtils() diff --git a/core/common/src/androidMain/kotlin/org/mifospay/core/common/Parcelize.kt b/core/common/src/androidMain/kotlin/org/mifospay/core/common/Parcelize.kt new file mode 100644 index 000000000..d76561bc8 --- /dev/null +++ b/core/common/src/androidMain/kotlin/org/mifospay/core/common/Parcelize.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +import android.os.Parcel +import android.os.Parcelable +import kotlinx.parcelize.IgnoredOnParcel +import kotlinx.parcelize.Parceler +import kotlinx.parcelize.Parcelize +import kotlinx.parcelize.TypeParceler + +actual typealias Parcelize = Parcelize + +actual typealias Parcelable = Parcelable + +actual typealias IgnoredOnParcel = IgnoredOnParcel + +actual typealias Parceler

= Parceler

+ +actual typealias TypeParceler = TypeParceler + +actual typealias Parcel = Parcel diff --git a/core/common/src/main/kotlin/org/mifospay/core/network/di/DispatchersModule.kt b/core/common/src/androidMain/kotlin/org/mifospay/core/common/di/DispatchersModule.android.kt similarity index 61% rename from core/common/src/main/kotlin/org/mifospay/core/network/di/DispatchersModule.kt rename to core/common/src/androidMain/kotlin/org/mifospay/core/common/di/DispatchersModule.android.kt index 9ad058f96..f7f54ce0c 100644 --- a/core/common/src/main/kotlin/org/mifospay/core/network/di/DispatchersModule.kt +++ b/core/common/src/androidMain/kotlin/org/mifospay/core/common/di/DispatchersModule.android.kt @@ -7,15 +7,16 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.core.network.di +package org.mifospay.core.common.di import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers +import org.koin.core.module.Module import org.koin.core.qualifier.named import org.koin.dsl.module -import org.mifospay.core.network.MifosDispatchers +import org.mifospay.core.common.MifosDispatchers -val DispatchersModule = module { - single(named(MifosDispatchers.IO.name)) { Dispatchers.IO } - single(named(MifosDispatchers.Default.name)) { Dispatchers.Default } -} +actual val ioDispatcherModule: Module + get() = module { + single(named(MifosDispatchers.IO.name)) { Dispatchers.IO } + } diff --git a/core/common/src/main/kotlin/org/mifospay/common/Constants.kt b/core/common/src/commonMain/kotlin/org/mifospay/core/common/Constants.kt similarity index 99% rename from core/common/src/main/kotlin/org/mifospay/common/Constants.kt rename to core/common/src/commonMain/kotlin/org/mifospay/core/common/Constants.kt index 83371ea82..8dbd49a63 100644 --- a/core/common/src/main/kotlin/org/mifospay/common/Constants.kt +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/Constants.kt @@ -7,7 +7,7 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.common +package org.mifospay.core.common /** * Created by naman on 17/6/17. diff --git a/feature/search/build.gradle.kts b/core/common/src/commonMain/kotlin/org/mifospay/core/common/CurrencyFormatter.kt similarity index 58% rename from feature/search/build.gradle.kts rename to core/common/src/commonMain/kotlin/org/mifospay/core/common/CurrencyFormatter.kt index 2576ecd05..9ef39ab76 100644 --- a/feature/search/build.gradle.kts +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/CurrencyFormatter.kt @@ -7,13 +7,12 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -plugins { - alias(libs.plugins.mifospay.android.feature) - alias(libs.plugins.mifospay.android.library.compose) -} +package org.mifospay.core.common -android { - namespace = "org.mifospay.feature.search" +expect object CurrencyFormatter { + fun format(balance: Double?, currencyCode: String?, maximumFractionDigits: Int?): String } -dependencies { } +fun List.toArrayList(): ArrayList { + return ArrayList(this) +} diff --git a/core/common/src/commonMain/kotlin/org/mifospay/core/common/DataState.kt b/core/common/src/commonMain/kotlin/org/mifospay/core/common/DataState.kt new file mode 100644 index 000000000..fca285e34 --- /dev/null +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/DataState.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onStart + +sealed class DataState { + abstract val data: T? + + data object Loading : DataState() { + override val data: Nothing? get() = null + } + + data class Success( + override val data: T, + ) : DataState() + + data class Error( + val exception: Throwable, + override val data: T? = null, + ) : DataState() { + val message = exception.message.toString() + } +} + +fun Flow.asDataStateFlow(): Flow> = + map> { DataState.Success(it) } + .onStart { emit(DataState.Loading) } + .catch { emit(DataState.Error(it, null)) } diff --git a/core/common/src/commonMain/kotlin/org/mifospay/core/common/DataStateExtensions.kt b/core/common/src/commonMain/kotlin/org/mifospay/core/common/DataStateExtensions.kt new file mode 100644 index 000000000..9e7baea60 --- /dev/null +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/DataStateExtensions.kt @@ -0,0 +1,105 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transformWhile + +inline fun DataState.map( + transform: (T) -> R, +): DataState = when (this) { + is DataState.Success -> DataState.Success(transform(data)) + is DataState.Loading -> DataState.Loading + is DataState.Error -> DataState.Error(exception, data?.let(transform)) +} + +inline fun DataState.mapNullable( + transform: (T?) -> R, +): DataState = when (this) { + is DataState.Success -> DataState.Success(data = transform(data)) + is DataState.Loading -> DataState.Loading + is DataState.Error -> DataState.Error(exception = exception, data = transform(data)) +} + +fun Flow>.takeUntilResultSuccess(): Flow> = transformWhile { + emit(it) + it !is DataState.Success +} + +fun combineResults( + dataState1: DataState, + dataState2: DataState, + transform: (t1: T1, t2: T2) -> R, +): DataState { + val nullableTransform: (T1?, T2?) -> R? = { t1, t2 -> + if (t1 != null && t2 != null) transform(t1, t2) else null + } + + return when { + // Error states have highest priority, fail fast. + dataState1 is DataState.Error -> { + DataState.Error( + exception = dataState1.exception, + data = nullableTransform(dataState1.data, dataState2.data), + ) + } + + dataState2 is DataState.Error -> { + DataState.Error( + exception = dataState2.exception, + data = nullableTransform(dataState1.data, dataState2.data), + ) + } + + // Something is still loading, we will wait for all the data. + dataState1 is DataState.Loading || dataState2 is DataState.Loading -> DataState.Loading + + // Pending state for everything while any one piece of data is updating. + // Both states are _root_ide_package_.org.mifospay.core.common.Result.Success and have data + else -> { + @Suppress("UNCHECKED_CAST") + DataState.Success(transform(dataState1.data as T1, dataState2.data as T2)) + } + } +} + +fun combineResults( + dataState1: DataState, + dataState2: DataState, + dataState3: DataState, + transform: (t1: T1, t2: T2, t3: T3) -> R, +): DataState = + dataState1 + .combineResultsWith(dataState2) { t1, t2 -> t1 to t2 } + .combineResultsWith(dataState3) { t1t2Pair, t3 -> + transform(t1t2Pair.first, t1t2Pair.second, t3) + } + +fun combineResults( + dataState1: DataState, + dataState2: DataState, + dataState3: DataState, + dataState4: DataState, + transform: (t1: T1, t2: T2, t3: T3, t4: T4) -> R, +): DataState = + dataState1 + .combineResultsWith(dataState2) { t1, t2 -> t1 to t2 } + .combineResultsWith(dataState3) { t1t2Pair, t3 -> + Triple(t1t2Pair.first, t1t2Pair.second, t3) + } + .combineResultsWith(dataState4) { t1t2t3Triple, t3 -> + transform(t1t2t3Triple.first, t1t2t3Triple.second, t1t2t3Triple.third, t3) + } + +fun DataState.combineResultsWith( + dataState2: DataState, + transform: (t1: T1, t2: T2) -> R, +): DataState = + combineResults(this, dataState2, transform) diff --git a/core/common/src/commonMain/kotlin/org/mifospay/core/common/DateHelper.kt b/core/common/src/commonMain/kotlin/org/mifospay/core/common/DateHelper.kt new file mode 100644 index 000000000..8e7579c6d --- /dev/null +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/DateHelper.kt @@ -0,0 +1,353 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +import kotlinx.datetime.Clock +import kotlinx.datetime.Instant +import kotlinx.datetime.LocalDate +import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.Month +import kotlinx.datetime.TimeZone +import kotlinx.datetime.format +import kotlinx.datetime.format.FormatStringsInDatetimeFormats +import kotlinx.datetime.format.byUnicodePattern +import kotlinx.datetime.toLocalDateTime + +@OptIn(FormatStringsInDatetimeFormats::class) +object DateHelper { + /* + * This is the full month format for the date picker. + * "dd MM yyyy" is the format of the date picker. + */ + const val FULL_MONTH = "dd MM yyyy" + + /* + * This is the short month format for the date picker. + * "dd-MM-yyyy" is the format of the date picker. + */ + const val SHORT_MONTH = "dd-MM-yyyy" + + const val MONTH_FORMAT = "dd MMMM" + + private val fullMonthFormat = LocalDateTime.Format { + byUnicodePattern(FULL_MONTH) + } + + private val shortMonthFormat = LocalDateTime.Format { + byUnicodePattern(SHORT_MONTH) + } + + /** + * the result string uses the list given in a reverse order ([x, y, z] results in "z y x") + * + * @param integersOfDate [year-month-day] (ex [2016, 4, 14]) + * @return date in the format day month year (ex 14 Apr 2016) + */ + fun getDateAsString(integersOfDate: List): String { + val stringBuilder = StringBuilder() + stringBuilder.append(integersOfDate[2]) + .append(' ') + .append(getMonthName(integersOfDate[1])) + .append(' ') + .append(integersOfDate[0]) + return stringBuilder.toString() + } + + fun getDateAsString(integersOfDate: List, pattern: String): String { + return getFormatConverter( + currentFormat = FULL_MONTH, + requiredFormat = pattern, + dateString = getDateAsString(integersOfDate.map { it.toInt() }), + ) + } + + /** + * This Method converting the dd-MM-yyyy format type date string into dd MMMM yyyy + * + * @param format Final Format of date string + * @param dateString date string + * @return dd MMMM yyyy format date string. + */ + fun getSpecificFormat(format: String, dateString: String): String { + val pickerFormat = shortMonthFormat + val finalFormat = LocalDateTime.Format { byUnicodePattern(format) } + + return finalFormat.format(pickerFormat.parse(dateString)) + } + + private fun getFormatConverter( + currentFormat: String, + requiredFormat: String, + dateString: String, + ): String { + val pickerFormat = LocalDateTime.Format { byUnicodePattern(currentFormat) } + val finalFormat = LocalDateTime.Format { byUnicodePattern(requiredFormat) } + + return pickerFormat.parse(dateString).format(finalFormat) + } + + /** + * Gets the date string in the format "dd-MM-yyyy" from an array of integers representing the year, month, and day. + * + * @param dateComponents An array of three integers representing the year, month, and day, e.g. [2024, 11, 10] + * @return The date string in the format "dd-MM-yyyy", e.g. "10-11-2024" + */ + fun formatTransferDate(dateComponents: List, pattern: String = SHORT_MONTH): String { + require(dateComponents.size == 3) { "dateComponents must have exactly 3 elements" } + val (year, month, day) = dateComponents + + val localDate = LocalDate(year, Month(month), day) + return localDate.format(pattern) + } + + // Extension function to format LocalDate + fun LocalDate.format(pattern: String): String { + val year = this.year.toString().padStart(4, '0') + val month = this.monthNumber.toString().padStart(2, '0') + val day = this.dayOfMonth.toString().padStart(2, '0') + + return pattern + .replace("yyyy", year) + .replace("MM", month) + .replace("dd", day) + } + + /** + * @param month an integer from 1 to 12 + * @return string representation of the month like Jan or Feb..etc + */ + private fun getMonthName(month: Int): String { + return when (month) { + 1 -> "Jan" + 2 -> "Feb" + 3 -> "Mar" + 4 -> "Apr" + 5 -> "May" + 6 -> "Jun" + 7 -> "Jul" + 8 -> "Aug" + 9 -> "Sep" + 10 -> "Oct" + 11 -> "Nov" + 12 -> "Dec" + else -> throw IllegalArgumentException("Month should be between 1 and 12") + } + } + + /** + * Input timestamp string in milliseconds + * Example timestamp "1698278400000" + * Output examples: "dd-MM-yyyy" - "14-04-2016" + */ + fun getDateAsStringFromLong(timeInMillis: Long): String { + val instant = Instant.fromEpochMilliseconds(timeInMillis) + .toLocalDateTime(TimeZone.currentSystemDefault()) + + return instant.format(shortMonthFormat) + } + + /** + * Input timestamp string in milliseconds + * Example timestamp "1698278400000" + * Output examples: "14 April" + */ + fun getMonthAsStringFromLong(timeInMillis: Long): String { + val instant = Instant.fromEpochMilliseconds(timeInMillis) + .toLocalDateTime(TimeZone.currentSystemDefault()) + + val monthName = instant.month.name.lowercase().capitalize() + + return "${instant.dayOfMonth} $monthName" + } + + /** + * Gets the date string in the format "day month year" from an array of integers representing the day and month. + * + * @param integersOfDate An array of two integers representing the day and month, e.g. [11, 10] + * @return The date string in the format "day month year", e.g. "11 October" + */ + fun getDateMonthString(integersOfDate: List): String { + require(integersOfDate.size == 2) { "integersOfDate must have exactly 2 elements" } + val (day, month) = integersOfDate + + val monthName = when (month) { + 1 -> "January" + 2 -> "February" + 3 -> "March" + 4 -> "April" + 5 -> "May" + 6 -> "June" + 7 -> "July" + 8 -> "August" + 9 -> "September" + 10 -> "October" + 11 -> "November" + 12 -> "December" + else -> throw IllegalArgumentException("Invalid month value: $month") + } + + return "$day $monthName" + } + + /** + * Handles the specific format "yyyy-MM-dd HH:mm:ss.SSSSSS" + * For example "2024-09-19 05:41:18.558995" + * Possible outputs depending on current date: + * "Today at 05:41" + * "Tomorrow at 05:41" + */ + fun String.toFormattedDateTime(): String { + // Parse the datetime string + val dateTime = try { + // Split into date and time parts + val (datePart, timePart) = this.split(" ") + // Remove microseconds from time part + val simplifiedTime = timePart.split(".")[0] + // Combine date and simplified time + val isoString = "${datePart}T$simplifiedTime" + // Parse to LocalDateTime + LocalDateTime.parse(isoString) + } catch (e: Exception) { + return this // Return original string if parsing fails + } + + val timeZone = TimeZone.currentSystemDefault() + val now = Clock.System.now() + val nowDateTime = now.toLocalDateTime(timeZone) + + return when { + // Same year + nowDateTime.year == dateTime.year -> { + when { + // Same month + nowDateTime.monthNumber == dateTime.monthNumber -> { + when { + // Tomorrow + dateTime.dayOfMonth - nowDateTime.dayOfMonth == 1 -> { + "Tomorrow at ${dateTime.format()}" + } + // Today + dateTime.dayOfMonth == nowDateTime.dayOfMonth -> { + "Today at ${dateTime.format()}" + } + // Yesterday + nowDateTime.dayOfMonth - dateTime.dayOfMonth == 1 -> { + "Yesterday at ${dateTime.format()}" + } + // Same month but different day + else -> { + "${ + dateTime.month.name.lowercase().capitalize() + } ${dateTime.dayOfMonth}, ${dateTime.format()}" + } + } + } + // Different month, same year + else -> { + "${ + dateTime.month.name.lowercase().capitalize() + } ${dateTime.dayOfMonth}, ${dateTime.format()}" + } + } + } + // Different year + else -> { + "${ + dateTime.month.name.lowercase().capitalize() + } ${dateTime.dayOfMonth} ${dateTime.year}, ${dateTime.format()}" + } + } + } + + /** + * Input timestamp string in milliseconds + * Example timestamp "1698278400000" + * Output examples: + * "Today at 12:00" + * "Tomorrow at 15:30" + */ + fun String.toPrettyDate(): String { + val timestamp = this.toLong() + val instant = Instant.fromEpochMilliseconds(timestamp) + val timeZone = TimeZone.currentSystemDefault() + val nowDateTime = Clock.System.now().toLocalDateTime(timeZone) + val neededDateTime = instant.toLocalDateTime(timeZone) + + return when { + // Same year + nowDateTime.year == neededDateTime.year -> { + when { + // Same month + nowDateTime.monthNumber == neededDateTime.monthNumber -> { + when { + // Tomorrow + neededDateTime.dayOfMonth - nowDateTime.dayOfMonth == 1 -> { + val time = neededDateTime.format() + "Tomorrow at $time" + } + // Today + neededDateTime.dayOfMonth == nowDateTime.dayOfMonth -> { + val time = neededDateTime.format() + "Today at $time" + } + // Yesterday + nowDateTime.dayOfMonth - neededDateTime.dayOfMonth == 1 -> { + val time = neededDateTime.format() + "Yesterday at $time" + } + // Same month but different day + else -> { + "${ + neededDateTime.month.name.lowercase().capitalize() + } ${neededDateTime.dayOfMonth}, ${neededDateTime.format()}" + } + } + } + // Different month, same year + else -> { + "${ + neededDateTime.month.name.lowercase().capitalize() + } ${neededDateTime.dayOfMonth}, ${neededDateTime.format()}" + } + } + } + // Different year + else -> { + "${ + neededDateTime.month.name.lowercase().capitalize() + } ${neededDateTime.dayOfMonth} ${neededDateTime.year}, ${neededDateTime.format()}" + } + } + } + + // Helper function to format time + private fun LocalDateTime.format(): String { + return "${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}" + } + + // Extension to capitalize first letter + private fun String.capitalize() = replaceFirstChar { + if (it.isLowerCase()) it.titlecase() else it.toString() + } + + val currentDate = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) + + /** + * This is the full date format for the date picker. + * "dd MM yyyy" is the format of the date picker. + */ + val formattedFullDate = currentDate.format(fullMonthFormat) + + /** + * This is the short date format for the date picker. + * "dd-MM-yyyy" is the format of the date picker. + */ + val formattedShortDate = currentDate.format(shortMonthFormat) +} diff --git a/shared/src/androidMain/kotlin/org/mifospay/shared/di/AndroidPlatformContextProvider.kt b/core/common/src/commonMain/kotlin/org/mifospay/core/common/DebugUtil.kt similarity index 52% rename from shared/src/androidMain/kotlin/org/mifospay/shared/di/AndroidPlatformContextProvider.kt rename to core/common/src/commonMain/kotlin/org/mifospay/core/common/DebugUtil.kt index 9c6908224..2611aab15 100644 --- a/shared/src/androidMain/kotlin/org/mifospay/shared/di/AndroidPlatformContextProvider.kt +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/DebugUtil.kt @@ -7,17 +7,17 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.shared.di +package org.mifospay.core.common -import android.content.Context +import co.touchlab.kermit.Logger -object AndroidPlatformContextProvider { - private var appContext: Context? = null +object DebugUtil { - val context: Context? - get() = appContext + private val logger = Logger.withTag("QXZ") - fun setContext(context: Context) { - appContext = context + fun log(vararg objects: Any): Array { + val stringToPrint = objects.joinToString(", ") + logger.d { stringToPrint } + return objects } } diff --git a/core/common/src/commonMain/kotlin/org/mifospay/core/common/FileUtils.kt b/core/common/src/commonMain/kotlin/org/mifospay/core/common/FileUtils.kt new file mode 100644 index 000000000..3bb4cdfe1 --- /dev/null +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/FileUtils.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +import co.touchlab.kermit.Logger +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +interface FileUtils { + suspend fun writeInputStreamDataToFile(inputStream: ByteArray, filePath: String): Boolean + + companion object { + val logger = Logger.withTag("FileUtils") + } +} + +expect fun createPlatformFileUtils(): FileUtils + +class CommonFileUtils : FileUtils { + override suspend fun writeInputStreamDataToFile( + inputStream: ByteArray, + filePath: String, + ): Boolean = + withContext(Dispatchers.Default) { + try { + true + } catch (e: Exception) { + FileUtils.logger.e { "Error writing file: ${e.message}" } + false + } + } +} diff --git a/core/common/src/main/kotlin/org/mifospay/core/network/MifosDispatchers.kt b/core/common/src/commonMain/kotlin/org/mifospay/core/common/MifosDispatchers.kt similarity index 92% rename from core/common/src/main/kotlin/org/mifospay/core/network/MifosDispatchers.kt rename to core/common/src/commonMain/kotlin/org/mifospay/core/common/MifosDispatchers.kt index 3122bf45b..7f3002ba5 100644 --- a/core/common/src/main/kotlin/org/mifospay/core/network/MifosDispatchers.kt +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/MifosDispatchers.kt @@ -7,7 +7,7 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.core.network +package org.mifospay.core.common import org.koin.core.annotation.Qualifier @@ -18,6 +18,7 @@ annotation class Dispatcher(val mifosDispatcher: MifosDispatchers) enum class MifosDispatchers { Default, IO, + Unconfined, } @Qualifier diff --git a/core/common/src/main/kotlin/org/mifospay/common/NavArgsConstants.kt b/core/common/src/commonMain/kotlin/org/mifospay/core/common/NavArgsConstants.kt similarity index 92% rename from core/common/src/main/kotlin/org/mifospay/common/NavArgsConstants.kt rename to core/common/src/commonMain/kotlin/org/mifospay/core/common/NavArgsConstants.kt index 0dcb73540..f243d5cee 100644 --- a/core/common/src/main/kotlin/org/mifospay/common/NavArgsConstants.kt +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/NavArgsConstants.kt @@ -7,7 +7,7 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.common +package org.mifospay.core.common const val PAYEE_EXTERNAL_ID_ARG = "payeeExternalId" const val TRANSFER_AMOUNT_ARG = "transferAmount" diff --git a/core/common/src/commonMain/kotlin/org/mifospay/core/common/Parcelize.kt b/core/common/src/commonMain/kotlin/org/mifospay/core/common/Parcelize.kt new file mode 100644 index 000000000..576822cb7 --- /dev/null +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/Parcelize.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +expect annotation class Parcelize() + +expect interface Parcelable + +expect annotation class IgnoredOnParcel() + +expect interface Parceler

{ + fun create(parcel: Parcel): P + + fun P.write(parcel: Parcel, flags: Int) +} + +expect annotation class TypeParceler>() + +expect class Parcel { + fun readByte(): Byte + fun readInt(): Int + + fun readFloat(): Float + fun readDouble(): Double + fun readString(): String? + + fun writeByte(value: Byte) + fun writeInt(value: Int) + + fun writeFloat(value: Float) + + fun writeDouble(value: Double) + fun writeString(value: String?) +} diff --git a/core/common/src/main/kotlin/org/mifospay/core/network/di/CoroutineScopesModule.kt b/core/common/src/commonMain/kotlin/org/mifospay/core/common/di/DispatchersModule.kt similarity index 57% rename from core/common/src/main/kotlin/org/mifospay/core/network/di/CoroutineScopesModule.kt rename to core/common/src/commonMain/kotlin/org/mifospay/core/common/di/DispatchersModule.kt index 501cf3b80..4bf17cc0c 100644 --- a/core/common/src/main/kotlin/org/mifospay/core/network/di/CoroutineScopesModule.kt +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/di/DispatchersModule.kt @@ -7,17 +7,24 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.core.network.di +package org.mifospay.core.common.di +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob +import org.koin.core.module.Module import org.koin.core.qualifier.named import org.koin.dsl.module +import org.mifospay.core.common.MifosDispatchers -val CoroutineScopesModule = module { - +val DispatchersModule = module { + includes(ioDispatcherModule) + single(named(MifosDispatchers.Default.name)) { Dispatchers.Default } + single(named(MifosDispatchers.Unconfined.name)) { Dispatchers.Unconfined } single(named("ApplicationScope")) { CoroutineScope(SupervisorJob() + Dispatchers.Default) } } + +expect val ioDispatcherModule: Module diff --git a/core/common/src/commonMain/kotlin/org/mifospay/core/common/utils/StringExtensions.kt b/core/common/src/commonMain/kotlin/org/mifospay/core/common/utils/StringExtensions.kt new file mode 100644 index 000000000..4145e954d --- /dev/null +++ b/core/common/src/commonMain/kotlin/org/mifospay/core/common/utils/StringExtensions.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common.utils + +/** + * Whether or not string is a valid email address. + * + * This just checks if the string contains the "@" symbol. + */ +fun String.isValidEmail(): Boolean = contains("@") + +fun maskString(input: String, maskChar: Char = '*'): String { + if (input.length <= 3) return input + + val visibleCount = 3 + val maskLength = input.length - visibleCount + + return buildString { + append(maskChar.toString().repeat(maskLength)) + append(input.takeLast(visibleCount)) + } +} + +fun String.capitalizeWords(): String = split(" ").joinToString(" ") { it -> + it.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() } +} diff --git a/core/common/src/desktopMain/kotlin/org/mifospay/core/common/CurrencyFormatter.jvm.kt b/core/common/src/desktopMain/kotlin/org/mifospay/core/common/CurrencyFormatter.jvm.kt new file mode 100644 index 000000000..ce7c14600 --- /dev/null +++ b/core/common/src/desktopMain/kotlin/org/mifospay/core/common/CurrencyFormatter.jvm.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +import java.text.NumberFormat +import java.util.Currency + +actual object CurrencyFormatter { + actual fun format( + balance: Double?, + currencyCode: String?, + maximumFractionDigits: Int?, + ): String { + val numberFormat = NumberFormat.getCurrencyInstance() + numberFormat.maximumFractionDigits = maximumFractionDigits ?: 0 + numberFormat.currency = Currency.getInstance(currencyCode) + return numberFormat.format(balance) + } +} diff --git a/core/common/src/desktopMain/kotlin/org/mifospay/core/common/FileUtils.jvm.kt b/core/common/src/desktopMain/kotlin/org/mifospay/core/common/FileUtils.jvm.kt new file mode 100644 index 000000000..83a3f6ff1 --- /dev/null +++ b/core/common/src/desktopMain/kotlin/org/mifospay/core/common/FileUtils.jvm.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +// JVM and Android implementation +actual fun createPlatformFileUtils(): FileUtils = CommonFileUtils() diff --git a/core/common/src/desktopMain/kotlin/org/mifospay/core/common/Parcelize.kt b/core/common/src/desktopMain/kotlin/org/mifospay/core/common/Parcelize.kt new file mode 100644 index 000000000..addff633c --- /dev/null +++ b/core/common/src/desktopMain/kotlin/org/mifospay/core/common/Parcelize.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +actual interface Parcelable +actual annotation class IgnoredOnParcel +actual annotation class Parcelize +actual interface Parceler

{ + actual fun create(parcel: Parcel): P + actual fun P.write(parcel: Parcel, flags: Int) +} + +actual annotation class TypeParceler> + +actual class Parcel { + actual fun readString(): String? = null + actual fun readByte(): Byte = 1 + + actual fun readInt(): Int = 1 + + actual fun readFloat(): Float = 1f + + actual fun readDouble(): Double = 1.0 + + actual fun writeByte(value: Byte) { + } + + actual fun writeInt(value: Int) { + } + + actual fun writeFloat(value: Float) { + } + + actual fun writeDouble(value: Double) { + } + + actual fun writeString(value: String?) { + } +} diff --git a/core/common/src/desktopMain/kotlin/org/mifospay/core/common/di/DispatchersModule.desktop.kt b/core/common/src/desktopMain/kotlin/org/mifospay/core/common/di/DispatchersModule.desktop.kt new file mode 100644 index 000000000..52d18ff45 --- /dev/null +++ b/core/common/src/desktopMain/kotlin/org/mifospay/core/common/di/DispatchersModule.desktop.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common.di + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import org.koin.core.module.Module +import org.koin.core.qualifier.named +import org.koin.dsl.module +import org.mifospay.core.common.MifosDispatchers + +actual val ioDispatcherModule: Module + get() = module { + single(named(MifosDispatchers.IO.name)) { Dispatchers.Default } + } diff --git a/core/common/src/jsMain/kotlin/org/mifospay/core/common/CurrencyFormatter.js.kt b/core/common/src/jsMain/kotlin/org/mifospay/core/common/CurrencyFormatter.js.kt new file mode 100644 index 000000000..54fbc2601 --- /dev/null +++ b/core/common/src/jsMain/kotlin/org/mifospay/core/common/CurrencyFormatter.js.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +actual object CurrencyFormatter { + actual fun format( + balance: Double?, + currencyCode: String?, + maximumFractionDigits: Int?, + ): String { + if (balance == null || currencyCode == null) { + return "" + } + + val options = js("{}").unsafeCast() + options.style = "currency" + options.currency = currencyCode + if (maximumFractionDigits != null) { + options.maximumFractionDigits = maximumFractionDigits + } + + return try { + js("new Intl.NumberFormat('en-US', options).format(balance)").toString() + } catch (e: Exception) { + console.error("Error formatting currency: ${e.message}") + balance.toString() + } + } +} diff --git a/shared/src/androidMain/kotlin/org/mifospay/shared/di/Modules.android.kt b/core/common/src/jsMain/kotlin/org/mifospay/core/common/FileUtils.js.kt similarity index 76% rename from shared/src/androidMain/kotlin/org/mifospay/shared/di/Modules.android.kt rename to core/common/src/jsMain/kotlin/org/mifospay/core/common/FileUtils.js.kt index 8d463b4df..018f0cd7d 100644 --- a/shared/src/androidMain/kotlin/org/mifospay/shared/di/Modules.android.kt +++ b/core/common/src/jsMain/kotlin/org/mifospay/core/common/FileUtils.js.kt @@ -7,9 +7,6 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.shared.di +package org.mifospay.core.common -import org.koin.dsl.module - -actual val platformModule = module { -} +actual fun createPlatformFileUtils(): FileUtils = CommonFileUtils() diff --git a/core/common/src/jsMain/kotlin/org/mifospay/core/common/Parcelize.kt b/core/common/src/jsMain/kotlin/org/mifospay/core/common/Parcelize.kt new file mode 100644 index 000000000..addff633c --- /dev/null +++ b/core/common/src/jsMain/kotlin/org/mifospay/core/common/Parcelize.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +actual interface Parcelable +actual annotation class IgnoredOnParcel +actual annotation class Parcelize +actual interface Parceler

{ + actual fun create(parcel: Parcel): P + actual fun P.write(parcel: Parcel, flags: Int) +} + +actual annotation class TypeParceler> + +actual class Parcel { + actual fun readString(): String? = null + actual fun readByte(): Byte = 1 + + actual fun readInt(): Int = 1 + + actual fun readFloat(): Float = 1f + + actual fun readDouble(): Double = 1.0 + + actual fun writeByte(value: Byte) { + } + + actual fun writeInt(value: Int) { + } + + actual fun writeFloat(value: Float) { + } + + actual fun writeDouble(value: Double) { + } + + actual fun writeString(value: String?) { + } +} diff --git a/core/common/src/jsMain/kotlin/org/mifospay/core/common/di/DispatchersModule.js.kt b/core/common/src/jsMain/kotlin/org/mifospay/core/common/di/DispatchersModule.js.kt new file mode 100644 index 000000000..52d18ff45 --- /dev/null +++ b/core/common/src/jsMain/kotlin/org/mifospay/core/common/di/DispatchersModule.js.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common.di + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import org.koin.core.module.Module +import org.koin.core.qualifier.named +import org.koin.dsl.module +import org.mifospay.core.common.MifosDispatchers + +actual val ioDispatcherModule: Module + get() = module { + single(named(MifosDispatchers.IO.name)) { Dispatchers.Default } + } diff --git a/core/common/src/main/kotlin/org/mifospay/common/CreditCardUtils.kt b/core/common/src/main/kotlin/org/mifospay/common/CreditCardUtils.kt deleted file mode 100644 index 9f114eb32..000000000 --- a/core/common/src/main/kotlin/org/mifospay/common/CreditCardUtils.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.common - -object CreditCardUtils { - fun validateCreditCardNumber(str: String): Boolean { - if (str.isEmpty()) { - return false - } - val ints = IntArray(str.length) - for (i in str.indices) { - ints[i] = str.substring(i, i + 1).toInt() - } - run { - var i = ints.size - 2 - while (i >= 0) { - var j = ints[i] - j *= 2 - if (j > 9) { - j = j % 10 + 1 - } - ints[i] = j - i -= 2 - } - } - var sum = 0 - for (i in ints.indices) { - sum += ints[i] - } - return sum % 10 == 0 - } -} diff --git a/core/common/src/main/kotlin/org/mifospay/common/DebugUtil.kt b/core/common/src/main/kotlin/org/mifospay/common/DebugUtil.kt deleted file mode 100644 index 685662541..000000000 --- a/core/common/src/main/kotlin/org/mifospay/common/DebugUtil.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.common - -import android.util.Log - -// TODO Move into separate module -object DebugUtil { - - fun log(vararg objects: Any): Array { - var stringToPrint = "" - for (`object` in objects) { - stringToPrint += "$`object`, " - } - stringToPrint = stringToPrint.substring(0, stringToPrint.lastIndexOf(',')) - Log.d("QXZ:: ", stringToPrint) - return objects as Array - } -} diff --git a/core/common/src/main/kotlin/org/mifospay/common/FileUtils.kt b/core/common/src/main/kotlin/org/mifospay/common/FileUtils.kt deleted file mode 100644 index d3725d562..000000000 --- a/core/common/src/main/kotlin/org/mifospay/common/FileUtils.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.common - -import android.util.Log -import java.io.File -import java.io.FileOutputStream -import java.io.InputStream -import java.io.OutputStream - -object FileUtils { - - fun writeInputStreamDataToFile(inputStream: InputStream, file: File?): Boolean { - return try { - val out: OutputStream = FileOutputStream(file) - val buf = ByteArray(1024) - var len: Int - while (inputStream.read(buf).also { len = it } > 0) { - out.write(buf, 0, len) - } - out.close() - inputStream.close() - true - } catch (e: Exception) { - Log.e("Message", e.message.toString()) - false - } - } -} diff --git a/core/common/src/main/kotlin/org/mifospay/common/Utils.kt b/core/common/src/main/kotlin/org/mifospay/common/Utils.kt deleted file mode 100644 index c4acdc226..000000000 --- a/core/common/src/main/kotlin/org/mifospay/common/Utils.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.common - -import java.text.NumberFormat -import java.util.Currency - -object Utils { - - @JvmStatic - fun getFormattedAccountBalance( - balance: Double?, - currencyCode: String?, - maximumFractionDigits: Int? = 0, - ): String { - val accountBalanceFormatter = NumberFormat.getCurrencyInstance() - accountBalanceFormatter.maximumFractionDigits = maximumFractionDigits ?: 0 - accountBalanceFormatter.currency = Currency.getInstance(currencyCode) - return accountBalanceFormatter.format(balance) - } - - // returns in "$ 10,000.00" format - fun getNewCurrencyFormatter( - balance: Double, - currencySymbol: String, - minimumFractionDigit: Int = 0, - ): String { - val accountBalanceFormatter = NumberFormat.getNumberInstance().apply { - maximumFractionDigits = 2 - minimumFractionDigits = minimumFractionDigit - } - return currencySymbol + " " + accountBalanceFormatter.format(balance) - } - - fun List.toArrayList(): ArrayList { - val array: ArrayList = ArrayList() - for (index in this) array.add(index) - return array - } -} diff --git a/core/common/src/nativeMain/kotlin/org/mifospay/core/common/CurrencyFormatter.native.kt b/core/common/src/nativeMain/kotlin/org/mifospay/core/common/CurrencyFormatter.native.kt new file mode 100644 index 000000000..f70c063e4 --- /dev/null +++ b/core/common/src/nativeMain/kotlin/org/mifospay/core/common/CurrencyFormatter.native.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +import platform.Foundation.NSNumber +import platform.Foundation.NSNumberFormatter +import platform.Foundation.NSNumberFormatterCurrencyStyle + +actual object CurrencyFormatter { + actual fun format( + balance: Double?, + currencyCode: String?, + maximumFractionDigits: Int?, + ): String { + val numberFormatter = NSNumberFormatter() + numberFormatter.numberStyle = NSNumberFormatterCurrencyStyle + numberFormatter.currencyCode = currencyCode ?: "$" + numberFormatter.maximumFractionDigits = (maximumFractionDigits ?: 0).toULong() + return numberFormatter.stringFromNumber(NSNumber(balance ?: 0.0)) ?: "" + } +} diff --git a/core/common/src/nativeMain/kotlin/org/mifospay/core/common/FileUtils.native.kt b/core/common/src/nativeMain/kotlin/org/mifospay/core/common/FileUtils.native.kt new file mode 100644 index 000000000..e93691e22 --- /dev/null +++ b/core/common/src/nativeMain/kotlin/org/mifospay/core/common/FileUtils.native.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +import kotlinx.cinterop.BetaInteropApi +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.allocArrayOf +import kotlinx.cinterop.memScoped +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import platform.Foundation.NSData +import platform.Foundation.create +import platform.Foundation.writeToFile + +// iOS implementation +@BetaInteropApi +@OptIn(ExperimentalForeignApi::class) +actual fun createPlatformFileUtils(): FileUtils = object : FileUtils { + override suspend fun writeInputStreamDataToFile( + inputStream: ByteArray, + filePath: String, + ): Boolean = + withContext(Dispatchers.Default) { + try { + val nsData = inputStream.toNSData() + nsData.writeToFile(filePath, true) + true + } catch (e: Exception) { + FileUtils.logger.e { "Error writing file: ${e.message}" } + false + } + } + + @BetaInteropApi + fun ByteArray.toNSData(): NSData = memScoped { + NSData.create(bytes = allocArrayOf(this@toNSData), length = this@toNSData.size.toULong()) + } +} diff --git a/core/common/src/nativeMain/kotlin/org/mifospay/core/common/Parcelize.kt b/core/common/src/nativeMain/kotlin/org/mifospay/core/common/Parcelize.kt new file mode 100644 index 000000000..addff633c --- /dev/null +++ b/core/common/src/nativeMain/kotlin/org/mifospay/core/common/Parcelize.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +actual interface Parcelable +actual annotation class IgnoredOnParcel +actual annotation class Parcelize +actual interface Parceler

{ + actual fun create(parcel: Parcel): P + actual fun P.write(parcel: Parcel, flags: Int) +} + +actual annotation class TypeParceler> + +actual class Parcel { + actual fun readString(): String? = null + actual fun readByte(): Byte = 1 + + actual fun readInt(): Int = 1 + + actual fun readFloat(): Float = 1f + + actual fun readDouble(): Double = 1.0 + + actual fun writeByte(value: Byte) { + } + + actual fun writeInt(value: Int) { + } + + actual fun writeFloat(value: Float) { + } + + actual fun writeDouble(value: Double) { + } + + actual fun writeString(value: String?) { + } +} diff --git a/core/common/src/nativeMain/kotlin/org/mifospay/core/common/di/DispatchersModule.native.kt b/core/common/src/nativeMain/kotlin/org/mifospay/core/common/di/DispatchersModule.native.kt new file mode 100644 index 000000000..52d18ff45 --- /dev/null +++ b/core/common/src/nativeMain/kotlin/org/mifospay/core/common/di/DispatchersModule.native.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common.di + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import org.koin.core.module.Module +import org.koin.core.qualifier.named +import org.koin.dsl.module +import org.mifospay.core.common.MifosDispatchers + +actual val ioDispatcherModule: Module + get() = module { + single(named(MifosDispatchers.IO.name)) { Dispatchers.Default } + } diff --git a/core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/CurrencyFormatter.js.kt b/core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/CurrencyFormatter.js.kt new file mode 100644 index 000000000..21d949d99 --- /dev/null +++ b/core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/CurrencyFormatter.js.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +actual object CurrencyFormatter { + actual fun format( + balance: Double?, + currencyCode: String?, + maximumFractionDigits: Int?, + ): String { + return "$currencyCode ${ + balance?.let { + val formattedBalance = balance.toString() + val fractionDigits = formattedBalance.substringAfterLast(".") + val fractionDigitsLength = fractionDigits.length + val fractionDigitsToDisplay = if (fractionDigitsLength > maximumFractionDigits!!) { + fractionDigits.substring(0, maximumFractionDigits) + } else { + fractionDigits + } + val integerDigits = formattedBalance.substringBeforeLast(".") + val integerDigitsWithCommas = + integerDigits.reversed().chunked(3).joinToString(",").reversed() + "$integerDigitsWithCommas.$fractionDigitsToDisplay" + } ?: "0.00" + }" + } +} diff --git a/core/network/src/main/kotlin/org/mifospay/core/network/services/SavingsAccountsService.kt b/core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/FileUtils.js.kt similarity index 76% rename from core/network/src/main/kotlin/org/mifospay/core/network/services/SavingsAccountsService.kt rename to core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/FileUtils.js.kt index 690658bce..018f0cd7d 100644 --- a/core/network/src/main/kotlin/org/mifospay/core/network/services/SavingsAccountsService.kt +++ b/core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/FileUtils.js.kt @@ -7,6 +7,6 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.core.network.services +package org.mifospay.core.common -interface SavingsAccountsService +actual fun createPlatformFileUtils(): FileUtils = CommonFileUtils() diff --git a/core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/Parcelize.kt b/core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/Parcelize.kt new file mode 100644 index 000000000..addff633c --- /dev/null +++ b/core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/Parcelize.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common + +actual interface Parcelable +actual annotation class IgnoredOnParcel +actual annotation class Parcelize +actual interface Parceler

{ + actual fun create(parcel: Parcel): P + actual fun P.write(parcel: Parcel, flags: Int) +} + +actual annotation class TypeParceler> + +actual class Parcel { + actual fun readString(): String? = null + actual fun readByte(): Byte = 1 + + actual fun readInt(): Int = 1 + + actual fun readFloat(): Float = 1f + + actual fun readDouble(): Double = 1.0 + + actual fun writeByte(value: Byte) { + } + + actual fun writeInt(value: Int) { + } + + actual fun writeFloat(value: Float) { + } + + actual fun writeDouble(value: Double) { + } + + actual fun writeString(value: String?) { + } +} diff --git a/core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/di/DispatchersModule.js.kt b/core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/di/DispatchersModule.js.kt new file mode 100644 index 000000000..52d18ff45 --- /dev/null +++ b/core/common/src/wasmJsMain/kotlin/org/mifospay/core/common/di/DispatchersModule.js.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.common.di + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import org.koin.core.module.Module +import org.koin.core.qualifier.named +import org.koin.dsl.module +import org.mifospay.core.common.MifosDispatchers + +actual val ioDispatcherModule: Module + get() = module { + single(named(MifosDispatchers.IO.name)) { Dispatchers.Default } + } diff --git a/core/data/build.gradle.kts b/core/data/build.gradle.kts index 0531b1e9f..23a406caa 100644 --- a/core/data/build.gradle.kts +++ b/core/data/build.gradle.kts @@ -8,7 +8,7 @@ * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ plugins { - alias(libs.plugins.mifospay.android.library) + alias(libs.plugins.mifospay.kmp.library) alias(libs.plugins.kotlin.parcelize) id("kotlinx-serialization") } @@ -23,26 +23,26 @@ android { } } -dependencies { - api(projects.core.common) - api(projects.core.model) - api(projects.core.network) - - implementation(libs.squareup.retrofit2) { - // exclude Retrofitā€™s OkHttp peer-dependency module and define your own module import - exclude(module = "okhttp") - } - implementation(libs.squareup.retrofit.adapter.rxjava) - implementation(libs.squareup.retrofit.converter.gson) - implementation(libs.squareup.okhttp) - implementation(libs.squareup.logging.interceptor) - - implementation(libs.reactivex.rxjava.android) - implementation(libs.reactivex.rxjava) +kotlin { + sourceSets { + commonMain.dependencies { + api(projects.core.common) + api(projects.core.datastore) + api(projects.core.model) + implementation(projects.core.network) + implementation(projects.core.analytics) + implementation(libs.kotlinx.serialization.json) + } - testImplementation(libs.junit) - androidTestImplementation(libs.espresso.core) + commonTest.dependencies { + implementation(libs.multiplatform.settings) + implementation(libs.multiplatform.settings.test) + } - implementation(libs.kotlinx.serialization.json) - implementation(libs.koin.android) -} + androidMain.dependencies { + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.tracing.ktx) + implementation(libs.koin.android) + } + } +} \ No newline at end of file diff --git a/core/data/src/main/AndroidManifest.xml b/core/data/src/androidMain/AndroidManifest.xml similarity index 100% rename from core/data/src/main/AndroidManifest.xml rename to core/data/src/androidMain/AndroidManifest.xml diff --git a/core/data/src/androidMain/kotlin/org/mifospay/core/data/di/AndroidPlatformDependentDataModule.kt b/core/data/src/androidMain/kotlin/org/mifospay/core/data/di/AndroidPlatformDependentDataModule.kt new file mode 100644 index 000000000..3aeddba79 --- /dev/null +++ b/core/data/src/androidMain/kotlin/org/mifospay/core/data/di/AndroidPlatformDependentDataModule.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.di + +import android.content.Context +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import org.mifospay.core.data.util.ConnectivityManagerNetworkMonitor +import org.mifospay.core.data.util.NetworkMonitor +import org.mifospay.core.data.util.TimeZoneBroadcastMonitor +import org.mifospay.core.data.util.TimeZoneMonitor + +class AndroidPlatformDependentDataModule( + private val context: Context, + private val dispatcher: CoroutineDispatcher, + private val scope: CoroutineScope, +) : PlatformDependentDataModule { + override val networkMonitor: NetworkMonitor by lazy { + ConnectivityManagerNetworkMonitor(context, dispatcher) + } + + override val timeZoneMonitor: TimeZoneMonitor by lazy { + TimeZoneBroadcastMonitor(context, scope, dispatcher) + } +} diff --git a/core/data/src/androidMain/kotlin/org/mifospay/core/data/di/AndroidPlatformModule.kt b/core/data/src/androidMain/kotlin/org/mifospay/core/data/di/AndroidPlatformModule.kt new file mode 100644 index 000000000..1a45dea18 --- /dev/null +++ b/core/data/src/androidMain/kotlin/org/mifospay/core/data/di/AndroidPlatformModule.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.di + +import org.koin.android.ext.koin.androidContext +import org.koin.core.module.Module +import org.koin.core.qualifier.named +import org.koin.dsl.module +import org.mifospay.core.common.MifosDispatchers +import org.mifospay.core.data.util.ConnectivityManagerNetworkMonitor +import org.mifospay.core.data.util.NetworkMonitor +import org.mifospay.core.data.util.TimeZoneBroadcastMonitor +import org.mifospay.core.data.util.TimeZoneMonitor + +val AndroidDataModule = module { + single { + ConnectivityManagerNetworkMonitor(androidContext(), get(named(MifosDispatchers.IO.name))) + } + + single { + TimeZoneBroadcastMonitor( + context = androidContext(), + appScope = get(named("ApplicationScope")), + ioDispatcher = get(named(MifosDispatchers.IO.name)), + ) + } + + single { + AndroidPlatformDependentDataModule( + context = androidContext(), + dispatcher = get(named(MifosDispatchers.IO.name)), + scope = get(named("ApplicationScope")), + ) + } +} + +actual val platformModule: Module = AndroidDataModule + +actual val getPlatformDataModule: PlatformDependentDataModule + get() = org.koin.core.context.GlobalContext.get().get() diff --git a/core/data/src/main/java/org/mifospay/core/data/util/ConnectivityManagerNetworkMonitor.kt b/core/data/src/androidMain/kotlin/org/mifospay/core/data/util/ConnectivityManagerNetworkMonitor.kt similarity index 84% rename from core/data/src/main/java/org/mifospay/core/data/util/ConnectivityManagerNetworkMonitor.kt rename to core/data/src/androidMain/kotlin/org/mifospay/core/data/util/ConnectivityManagerNetworkMonitor.kt index 8e0986c79..5d1e606e9 100644 --- a/core/data/src/main/java/org/mifospay/core/data/util/ConnectivityManagerNetworkMonitor.kt +++ b/core/data/src/androidMain/kotlin/org/mifospay/core/data/util/ConnectivityManagerNetworkMonitor.kt @@ -16,16 +16,17 @@ import android.net.Network import android.net.NetworkCapabilities import android.net.NetworkRequest import android.net.NetworkRequest.Builder -import android.os.Build.VERSION -import android.os.Build.VERSION_CODES import androidx.core.content.getSystemService +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.conflate +import kotlinx.coroutines.flow.flowOn internal class ConnectivityManagerNetworkMonitor( private val context: Context, + ioDispatcher: CoroutineDispatcher, ) : NetworkMonitor { override val isOnline: Flow = callbackFlow { val connectivityManager = context.getSystemService() @@ -53,12 +54,10 @@ internal class ConnectivityManagerNetworkMonitor( channel.trySend(networks.isNotEmpty()) } } - val request = Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build() connectivityManager.registerNetworkCallback(request, callback) - /** * Sends the latest connectivity status to the underlying channel. */ @@ -68,15 +67,10 @@ internal class ConnectivityManagerNetworkMonitor( connectivityManager.unregisterNetworkCallback(callback) } } + .flowOn(ioDispatcher) .conflate() - @Suppress("DEPRECATION") - private fun ConnectivityManager.isCurrentlyConnected() = when { - VERSION.SDK_INT >= VERSION_CODES.M -> - activeNetwork - ?.let(::getNetworkCapabilities) - ?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) - - else -> activeNetworkInfo?.isConnected - } ?: false + private fun ConnectivityManager.isCurrentlyConnected() = activeNetwork + ?.let(::getNetworkCapabilities) + ?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) ?: false } diff --git a/core/data/src/main/java/org/mifospay/core/data/util/TimeZoneMonitor.kt b/core/data/src/androidMain/kotlin/org/mifospay/core/data/util/TimeZoneBroadcastMonitor.kt similarity index 91% rename from core/data/src/main/java/org/mifospay/core/data/util/TimeZoneMonitor.kt rename to core/data/src/androidMain/kotlin/org/mifospay/core/data/util/TimeZoneBroadcastMonitor.kt index bd92230cd..012bd5376 100644 --- a/core/data/src/main/java/org/mifospay/core/data/util/TimeZoneMonitor.kt +++ b/core/data/src/androidMain/kotlin/org/mifospay/core/data/util/TimeZoneBroadcastMonitor.kt @@ -19,7 +19,6 @@ import androidx.tracing.trace import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.callbackFlow @@ -31,19 +30,10 @@ import kotlinx.datetime.TimeZone import kotlinx.datetime.toKotlinTimeZone import java.time.ZoneId -/** - * Utility for reporting current timezone the device has set. - * It always emits at least once with default setting and then for each TZ change. - */ - -interface TimeZoneMonitor { - val currentTimeZone: Flow -} - internal class TimeZoneBroadcastMonitor( private val context: Context, appScope: CoroutineScope, - private val ioDispatcher: CoroutineDispatcher, + ioDispatcher: CoroutineDispatcher, ) : TimeZoneMonitor { override val currentTimeZone: SharedFlow = diff --git a/core/data/src/main/res/values/strings.xml b/core/data/src/androidMain/res/values/strings.xml similarity index 100% rename from core/data/src/main/res/values/strings.xml rename to core/data/src/androidMain/res/values/strings.xml diff --git a/core/data/src/main/assets/banks.json b/core/data/src/commonMain/assets/banks.json similarity index 100% rename from core/data/src/main/assets/banks.json rename to core/data/src/commonMain/assets/banks.json diff --git a/core/data/src/main/assets/cities.json b/core/data/src/commonMain/assets/cities.json similarity index 100% rename from core/data/src/main/assets/cities.json rename to core/data/src/commonMain/assets/cities.json diff --git a/core/data/src/main/assets/countriesToCities.json b/core/data/src/commonMain/assets/countriesToCities.json similarity index 100% rename from core/data/src/main/assets/countriesToCities.json rename to core/data/src/commonMain/assets/countriesToCities.json diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.kt new file mode 100644 index 000000000..7b2a0a087 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.di + +import org.koin.core.module.Module +import org.mifospay.core.data.util.NetworkMonitor +import org.mifospay.core.data.util.TimeZoneMonitor + +interface PlatformDependentDataModule { + val networkMonitor: NetworkMonitor + + val timeZoneMonitor: TimeZoneMonitor +} + +expect val platformModule: Module + +expect val getPlatformDataModule: PlatformDependentDataModule diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/di/RepositoryModule.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/di/RepositoryModule.kt new file mode 100644 index 000000000..442a19387 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/di/RepositoryModule.kt @@ -0,0 +1,105 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.di + +import kotlinx.serialization.json.Json +import org.koin.core.qualifier.named +import org.koin.dsl.module +import org.mifospay.core.common.MifosDispatchers +import org.mifospay.core.data.repository.AccountRepository +import org.mifospay.core.data.repository.AuthenticationRepository +import org.mifospay.core.data.repository.BeneficiaryRepository +import org.mifospay.core.data.repository.ClientRepository +import org.mifospay.core.data.repository.DocumentRepository +import org.mifospay.core.data.repository.InvoiceRepository +import org.mifospay.core.data.repository.KycLevelRepository +import org.mifospay.core.data.repository.LocalAssetRepository +import org.mifospay.core.data.repository.NotificationRepository +import org.mifospay.core.data.repository.RegistrationRepository +import org.mifospay.core.data.repository.RunReportRepository +import org.mifospay.core.data.repository.SavedCardRepository +import org.mifospay.core.data.repository.SavingsAccountRepository +import org.mifospay.core.data.repository.SearchRepository +import org.mifospay.core.data.repository.SelfServiceRepository +import org.mifospay.core.data.repository.StandingInstructionRepository +import org.mifospay.core.data.repository.ThirdPartyTransferRepository +import org.mifospay.core.data.repository.TwoFactorAuthRepository +import org.mifospay.core.data.repository.UserRepository +import org.mifospay.core.data.repositoryImp.AccountRepositoryImpl +import org.mifospay.core.data.repositoryImp.AuthenticationRepositoryImpl +import org.mifospay.core.data.repositoryImp.BeneficiaryRepositoryImpl +import org.mifospay.core.data.repositoryImp.ClientRepositoryImpl +import org.mifospay.core.data.repositoryImp.DocumentRepositoryImpl +import org.mifospay.core.data.repositoryImp.InvoiceRepositoryImpl +import org.mifospay.core.data.repositoryImp.KycLevelRepositoryImpl +import org.mifospay.core.data.repositoryImp.LocalAssetRepositoryImpl +import org.mifospay.core.data.repositoryImp.NotificationRepositoryImpl +import org.mifospay.core.data.repositoryImp.RegistrationRepositoryImpl +import org.mifospay.core.data.repositoryImp.RunReportRepositoryImpl +import org.mifospay.core.data.repositoryImp.SavedCardRepositoryImpl +import org.mifospay.core.data.repositoryImp.SavingsAccountRepositoryImpl +import org.mifospay.core.data.repositoryImp.SearchRepositoryImpl +import org.mifospay.core.data.repositoryImp.SelfServiceRepositoryImpl +import org.mifospay.core.data.repositoryImp.StandingInstructionRepositoryImpl +import org.mifospay.core.data.repositoryImp.ThirdPartyTransferRepositoryImpl +import org.mifospay.core.data.repositoryImp.TwoFactorAuthRepositoryImpl +import org.mifospay.core.data.repositoryImp.UserRepositoryImpl +import org.mifospay.core.data.util.NetworkMonitor +import org.mifospay.core.data.util.TimeZoneMonitor + +private val ioDispatcher = named(MifosDispatchers.IO.name) +private val unconfined = named(MifosDispatchers.Unconfined.name) + +val RepositoryModule = module { + single { Json { ignoreUnknownKeys = true } } + + single { AccountRepositoryImpl(get(), get(ioDispatcher)) } + single { + AuthenticationRepositoryImpl(get(), get(ioDispatcher)) + } + single { BeneficiaryRepositoryImpl(get(), get(ioDispatcher)) } + single { + ClientRepositoryImpl( + apiManager = get(), + fineractApiManager = get(), + ioDispatcher = get(ioDispatcher), + ) + } + single { DocumentRepositoryImpl(get(), get(ioDispatcher)) } + single { InvoiceRepositoryImpl(get(), get(ioDispatcher)) } + single { KycLevelRepositoryImpl(get(), get(ioDispatcher)) } + single { NotificationRepositoryImpl(get(), get(ioDispatcher)) } + single { RegistrationRepositoryImpl(get(), get(ioDispatcher)) } + single { RunReportRepositoryImpl(get(), get(ioDispatcher)) } + single { SavedCardRepositoryImpl(get(), get(ioDispatcher)) } + single { SavingsAccountRepositoryImpl(get(), get(ioDispatcher)) } + single { SearchRepositoryImpl(get(), get(ioDispatcher)) } + single { SelfServiceRepositoryImpl(get(), get(ioDispatcher)) } + single { + StandingInstructionRepositoryImpl(get(), get(ioDispatcher)) + } + single { + ThirdPartyTransferRepositoryImpl(get(), get(ioDispatcher)) + } + single { TwoFactorAuthRepositoryImpl(get(), get(ioDispatcher)) } + single { UserRepositoryImpl(get(), get(ioDispatcher)) } + + includes(platformModule) + single { getPlatformDataModule } + single { getPlatformDataModule.networkMonitor } + single { getPlatformDataModule.timeZoneMonitor } + single { + LocalAssetRepositoryImpl( + ioDispatcher = get(qualifier = ioDispatcher), + unconfinedDispatcher = get(unconfined), + networkJson = get(), + ) + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/AccountMapper.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/AccountMapper.kt new file mode 100644 index 000000000..708fe7d4f --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/AccountMapper.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.mapper + +import org.mifospay.core.model.account.Account +import org.mifospay.core.model.savingsaccount.SavingAccountEntity +import org.mifospay.core.network.model.entity.client.ClientAccountsEntity + +fun ClientAccountsEntity.toAccount(): List { + return this.savingsAccounts.toAccount() +} + +fun List.toAccount(): List { + return map { + Account( + name = it.productName, + number = it.accountNo, + id = it.id, + balance = it.accountBalance, + currency = it.currency, + productId = it.productId, + status = it.status, + ) + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/ClientDetailsMapper.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/ClientDetailsMapper.kt new file mode 100644 index 000000000..cffeca119 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/ClientDetailsMapper.kt @@ -0,0 +1,106 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.mapper + +import org.mifospay.core.model.client.Client +import org.mifospay.core.model.client.ClientAddress +import org.mifospay.core.model.client.ClientStatus +import org.mifospay.core.model.client.ClientTimeline +import org.mifospay.core.model.client.NewClient +import org.mifospay.core.model.client.UpdatedClient +import org.mifospay.core.network.model.entity.Page +import org.mifospay.core.network.model.entity.client.Address +import org.mifospay.core.network.model.entity.client.ClientEntity +import org.mifospay.core.network.model.entity.client.ClientTimelineEntity +import org.mifospay.core.network.model.entity.client.NewClientEntity +import org.mifospay.core.network.model.entity.client.Status +import org.mifospay.core.network.model.entity.client.UpdateClientEntity + +fun ClientEntity.toModel(): Client { + return Client( + id = id ?: 0, + accountNo = accountNo ?: "", + externalId = externalId ?: "", + active = active, + activationDate = activationDate, + firstname = firstname ?: "", + lastname = lastname ?: "", + displayName = displayName ?: "", + mobileNo = mobileNo ?: "", + emailAddress = emailAddress ?: "", + dateOfBirth = dateOfBirth, + isStaff = isStaff ?: false, + officeId = officeId ?: 0, + officeName = officeName ?: "", + savingsProductName = savingsProductName ?: "", + status = status?.toModel() ?: ClientStatus(), + timeline = timeline?.toModel() ?: ClientTimeline(), + legalForm = legalForm?.toModel() ?: ClientStatus(), + ) +} + +fun List.toModel(): List = map { it.toModel() } + +fun Page.toModel(): Page { + return Page( + totalFilteredRecords = this.totalFilteredRecords, + pageItems = this.pageItems.map { it.toModel() }.toMutableList(), + ) +} + +fun NewClient.toEntity(): NewClientEntity { + return NewClientEntity( + firstname = firstname, + lastname = lastname, + externalId = externalId, + mobileNo = mobileNo, + address = address.toEntity(), + savingsProductId = savingsProductId, + ) +} + +fun ClientAddress.toEntity(): Address { + return Address( + addressLine1 = addressLine1, + addressLine2 = addressLine2, + postalCode = postalCode, + stateProvinceId = stateProvinceId, + countryId = countryId, + addressTypeId = addressTypeId, + ) +} + +fun Status.toModel(): ClientStatus { + return ClientStatus( + id = id ?: 0, + code = code ?: "", + value = value ?: "", + ) +} + +fun ClientTimelineEntity.toModel(): ClientTimeline { + return ClientTimeline( + submittedOnDate = submittedOnDate, + activatedOnDate = activatedOnDate, + activatedByUsername = activatedByUsername, + activatedByFirstname = activatedByFirstname, + activatedByLastname = activatedByLastname, + ) +} + +fun UpdatedClient.toEntity(): UpdateClientEntity { + return UpdateClientEntity( + firstname = firstname, + lastname = lastname, + externalId = externalId, + mobileNo = mobileNo, + emailAddress = emailAddress, + ) +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/SavingAccountMapper.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/SavingAccountMapper.kt new file mode 100644 index 000000000..c45a00dc9 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/SavingAccountMapper.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.mapper + +import org.mifospay.core.model.savingsaccount.SavingAccount +import org.mifospay.core.model.savingsaccount.SavingAccountDetail +import org.mifospay.core.model.savingsaccount.SavingAccountEntity +import org.mifospay.core.model.savingsaccount.SavingsWithAssociationsEntity + +fun SavingAccountEntity.toModel(): SavingAccount { + return SavingAccount( + id = id, + accountNo = accountNo, + productId = productId, + productName = productName, + shortProductName = shortProductName, + status = status, + currency = currency, + accountBalance = accountBalance, + accountType = accountType, + timeline = timeline, + subStatus = subStatus, + lastActiveTransactionDate = lastActiveTransactionDate, + depositType = depositType, + externalId = externalId, + ) +} + +fun SavingsWithAssociationsEntity.toSavingDetail(): SavingAccountDetail { + return SavingAccountDetail( + id = id, + accountNo = accountNo, + depositType = depositType, + clientId = clientId, + clientName = clientName, + savingsProductId = savingsProductId, + savingsProductName = savingsProductName, + fieldOfficerId = fieldOfficerId, + status = status, + timeline = timeline, + currency = currency, + nominalAnnualInterestRate = nominalAnnualInterestRate, + withdrawalFeeForTransfers = withdrawalFeeForTransfers, + allowOverdraft = allowOverdraft, + enforceMinRequiredBalance = enforceMinRequiredBalance, + lienAllowed = lienAllowed, + withHoldTax = withHoldTax, + lastActiveTransactionDate = lastActiveTransactionDate, + isDormancyTrackingActive = isDormancyTrackingActive, + summary = summary, + transactions = transactions.map { it.toModel() }, + ) +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/SearchedEntitiesMapper.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/SearchedEntitiesMapper.kt new file mode 100644 index 000000000..7ee5d1ec9 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/SearchedEntitiesMapper.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.mapper + +import org.mifospay.core.model.search.SearchResult +import org.mifospay.core.network.model.entity.SearchedEntity + +fun SearchedEntity.toModel(): SearchResult { + return SearchResult( + entityId = entityId, + entityAccountNo = entityAccountNo, + entityName = entityName, + entityType = entityType, + parentId = parentId, + parentName = parentName, + ) +} + +fun List.toSearchResult(): List = map { it.toModel() } diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/TransactionMapper.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/TransactionMapper.kt new file mode 100644 index 000000000..c932b9d15 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/TransactionMapper.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.mapper + +import org.mifospay.core.common.DateHelper +import org.mifospay.core.model.savingsaccount.SavingsWithAssociationsEntity +import org.mifospay.core.model.savingsaccount.Transaction +import org.mifospay.core.model.savingsaccount.TransactionType +import org.mifospay.core.model.savingsaccount.TransactionsEntity + +fun SavingsWithAssociationsEntity.toTransactionList(): List { + return this.transactions.map { it.toModel() } +} + +fun TransactionsEntity.toModel(): Transaction { + return Transaction( + transactionId = this.id, + amount = this.amount, + date = DateHelper.getDateAsString(this.submittedOnDate), + currency = this.currency, + transactionType = when { + this.transactionType.deposit -> TransactionType.CREDIT + this.transactionType.withdrawal -> TransactionType.DEBIT + else -> TransactionType.OTHER + }, + transferId = this.transfer?.id, + accountId = this.accountId, + accountNo = this.accountNo, + originalTransactionId = this.originalTransactionId, + paymentDetailId = this.paymentDetailData?.id, + ) +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/UserMapper.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/UserMapper.kt new file mode 100644 index 000000000..bedfc89d6 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/mapper/UserMapper.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.mapper + +import org.mifospay.core.model.user.NewUser +import org.mifospay.core.model.user.RoleInfo +import org.mifospay.core.model.user.UserInfo +import org.mifospay.core.network.model.entity.Role +import org.mifospay.core.network.model.entity.user.NewUserEntity +import org.mifospay.core.network.model.entity.user.User + +private const val OFFICE_ID = 1 +private const val MOBILE_WALLET_ROLE_ID = 2 +private const val SUPER_USER_ROLE_ID = 1 + +val NEW_USER_ROLE_IDS: ArrayList = arrayListOf(MOBILE_WALLET_ROLE_ID, SUPER_USER_ROLE_ID) + +fun NewUser.toEntity(): NewUserEntity { + return NewUserEntity( + username = username, + firstname = firstname, + lastname = lastname, + email = email, + password = password, + officeId = OFFICE_ID, + roles = NEW_USER_ROLE_IDS, + sendPasswordToEmail = false, + isSelfServiceUser = true, + repeatPassword = password, + ) +} + +fun User.toUserInfo() = UserInfo( + username = username, + userId = userId, + base64EncodedAuthenticationKey = base64EncodedAuthenticationKey, + authenticated = authenticated, + officeId = officeId, + officeName = officeName, + roles = roles.map { it.toRoleInfo() }, + permissions = permissions, + clients = clients, + shouldRenewPassword = shouldRenewPassword, + isTwoFactorAuthenticationRequired = isTwoFactorAuthenticationRequired, +) + +fun Role.toRoleInfo() = RoleInfo( + id = id ?: "", + name = name ?: "", + description = description ?: "", + disabled = disabled, +) diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/AccountRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/AccountRepository.kt new file mode 100644 index 000000000..a747be1fc --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/AccountRepository.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.account.Account +import org.mifospay.core.model.account.AccountTransferPayload +import org.mifospay.core.model.savingsaccount.Transaction +import org.mifospay.core.model.savingsaccount.TransferDetail +import org.mifospay.core.model.search.AccountResult + +interface AccountRepository { + fun getTransaction(accountId: Long, transactionId: Long): Flow> + + fun getAccountTransfer(transferId: Long): Flow> + + fun searchAccounts(query: String): Flow>> + + fun getSelfAccounts(clientId: Long): Flow>> + + suspend fun makeTransfer(payload: AccountTransferPayload): DataState +} diff --git a/feature/auth/src/main/kotlin/org/mifospay/feature/auth/utils/ValidateUtil.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/AuthenticationRepository.kt similarity index 56% rename from feature/auth/src/main/kotlin/org/mifospay/feature/auth/utils/ValidateUtil.kt rename to core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/AuthenticationRepository.kt index 543bead45..e4d65eb89 100644 --- a/feature/auth/src/main/kotlin/org/mifospay/feature/auth/utils/ValidateUtil.kt +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/AuthenticationRepository.kt @@ -7,10 +7,11 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.feature.auth.utils +package org.mifospay.core.data.repository -import android.util.Patterns +import org.mifospay.core.common.DataState +import org.mifospay.core.model.user.UserInfo -object ValidateUtil { - fun String.isValidEmail() = this.isNotEmpty() && Patterns.EMAIL_ADDRESS.matcher(this).matches() +interface AuthenticationRepository { + suspend fun authenticate(username: String, password: String): DataState } diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/BeneficiaryRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/BeneficiaryRepository.kt new file mode 100644 index 000000000..31d421686 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/BeneficiaryRepository.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.beneficiary.Beneficiary +import org.mifospay.core.model.beneficiary.BeneficiaryPayload +import org.mifospay.core.model.beneficiary.BeneficiaryUpdatePayload +import org.mifospay.core.network.model.entity.templates.beneficiary.BeneficiaryTemplate + +interface BeneficiaryRepository { + suspend fun getBeneficiaryList(): Flow>> + + suspend fun getBeneficiaryTemplate(): Flow> + + suspend fun createBeneficiary(beneficiaryPayload: BeneficiaryPayload): DataState + + suspend fun updateBeneficiary( + beneficiaryId: Long, + payload: BeneficiaryUpdatePayload, + ): DataState + + suspend fun deleteBeneficiary(beneficiaryId: Long): DataState +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/ClientRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/ClientRepository.kt new file mode 100644 index 000000000..656ece770 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/ClientRepository.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.account.Account +import org.mifospay.core.model.client.Client +import org.mifospay.core.model.client.NewClient +import org.mifospay.core.model.client.UpdatedClient +import org.mifospay.core.network.model.entity.Page +import org.mifospay.core.network.model.entity.client.ClientAccountsEntity + +interface ClientRepository { + + fun getClientInfo(clientId: Long): Flow> + + suspend fun getClients(): Flow>> + + suspend fun getClient(clientId: Long): DataState + + suspend fun updateClient(clientId: Long, client: UpdatedClient): DataState + + fun getClientImage(clientId: Long): Flow> + + suspend fun updateClientImage(clientId: Long, image: String): DataState + + suspend fun getClientAccounts(clientId: Long): Flow> + + suspend fun getAccounts(clientId: Long, accountType: String): Flow>> + + suspend fun createClient(newClient: NewClient): DataState + + suspend fun deleteClient(clientId: Int): DataState +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/DocumentRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/DocumentRepository.kt new file mode 100644 index 000000000..5c8b52f4e --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/DocumentRepository.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import io.ktor.http.content.PartData +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.network.model.entity.noncore.Document + +interface DocumentRepository { + suspend fun getDocuments(entityType: String, entityId: Int): Flow>> + + suspend fun createDocument( + entityType: String, + entityId: Int, + name: String, + description: String, + fileName: PartData.FileItem, + ): Flow> + + suspend fun createDocument( + entityType: String, + entityId: Long, + name: String, + description: String, + file: ByteArray, + ): DataState + + suspend fun downloadDocument(entityType: String, entityId: Int, documentId: Int): Flow> + + suspend fun deleteDocument(entityType: String, entityId: Int, documentId: Int): Flow> + + suspend fun updateDocument( + entityType: String, + entityId: Int, + documentId: Int, + name: String, + description: String, + fileName: PartData.FileItem, + ): Flow> +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/InvoiceRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/InvoiceRepository.kt new file mode 100644 index 000000000..97833ce9c --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/InvoiceRepository.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.datatables.invoice.Invoice +import org.mifospay.core.model.datatables.invoice.InvoiceEntity + +interface InvoiceRepository { + fun getInvoice(clientId: Long, invoiceId: Long): Flow> + + fun getInvoices(clientId: Long): Flow>> + + suspend fun createInvoice(clientId: Long, invoice: InvoiceEntity): DataState + + suspend fun updateInvoice( + clientId: Long, + invoiceId: Long, + invoice: InvoiceEntity, + ): DataState + + suspend fun deleteInvoice(clientId: Long, invoiceId: Long): DataState +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/KycLevelRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/KycLevelRepository.kt new file mode 100644 index 000000000..510e14371 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/KycLevelRepository.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.kyc.KYCLevel1Details + +interface KycLevelRepository { + fun fetchKYCLevel1Details(clientId: Long): Flow> + + suspend fun addKYCLevel1Details( + clientId: Long, + kycLevel1Details: KYCLevel1Details, + ): DataState + + suspend fun updateKYCLevel1Details( + clientId: Long, + kycLevel1Details: KYCLevel1Details, + ): DataState +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/LocalAssetRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/LocalAssetRepository.kt new file mode 100644 index 000000000..353370e45 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/LocalAssetRepository.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.StateFlow +import org.mifospay.core.model.utils.CurrencyCode +import org.mifospay.core.model.utils.Locale + +interface LocalAssetRepository { + val localeList: StateFlow> + + val currencyList: StateFlow> +} diff --git a/core/data/src/main/java/org/mifospay/core/data/repository/auth/UserDataRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/NotificationRepository.kt similarity index 59% rename from core/data/src/main/java/org/mifospay/core/data/repository/auth/UserDataRepository.kt rename to core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/NotificationRepository.kt index 5241ba9ab..a0c4eb906 100644 --- a/core/data/src/main/java/org/mifospay/core/data/repository/auth/UserDataRepository.kt +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/NotificationRepository.kt @@ -7,16 +7,12 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.core.data.repository.auth +package org.mifospay.core.data.repository -import com.mifospay.core.model.UserData import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.notification.Notification -interface UserDataRepository { - /** - * Stream of [UserData] - */ - val userData: Flow - - fun logOut(): Unit +interface NotificationRepository { + fun fetchNotifications(): Flow>> } diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/RegistrationRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/RegistrationRepository.kt new file mode 100644 index 000000000..c0f715f6b --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/RegistrationRepository.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import org.mifospay.core.common.DataState +import org.mifospay.core.network.model.entity.register.RegisterPayload +import org.mifospay.core.network.model.entity.register.UserVerify + +interface RegistrationRepository { + suspend fun registerUser(registerPayload: RegisterPayload): DataState + + suspend fun verifyUser(userVerify: UserVerify): DataState +} diff --git a/core/data/src/main/java/org/mifospay/core/data/repository/local/LocalAssetRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/RunReportRepository.kt similarity index 50% rename from core/data/src/main/java/org/mifospay/core/data/repository/local/LocalAssetRepository.kt rename to core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/RunReportRepository.kt index 4ed5c49d0..2e8dc8c6c 100644 --- a/core/data/src/main/java/org/mifospay/core/data/repository/local/LocalAssetRepository.kt +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/RunReportRepository.kt @@ -7,20 +7,15 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.core.data.repository.local +package org.mifospay.core.data.repository -import com.mifospay.core.model.City -import com.mifospay.core.model.Country -import com.mifospay.core.model.State import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.savingsaccount.Transaction -interface LocalAssetRepository { - - fun getCountries(): Flow> - - fun getStateList(): Flow> - - fun getBanks(): Flow> - - fun getCities(): Flow> +interface RunReportRepository { + suspend fun getTransactionReceipt( + outputType: String, + transactionId: String, + ): Flow> } diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SavedCardRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SavedCardRepository.kt new file mode 100644 index 000000000..8fd45d708 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SavedCardRepository.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.savedcards.CardPayload +import org.mifospay.core.model.savedcards.SavedCard + +interface SavedCardRepository { + fun getSavedCards(clientId: Long): Flow>> + + fun getSavedCard(clientId: Long, cardId: Long): Flow> + + suspend fun addSavedCard(clientId: Long, card: CardPayload): DataState + + suspend fun deleteCard(clientId: Long, cardId: Long): DataState + + suspend fun updateCard(clientId: Long, cardId: Long, card: CardPayload): DataState +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SavingsAccountRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SavingsAccountRepository.kt new file mode 100644 index 000000000..3e97f2fd4 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SavingsAccountRepository.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.savingsaccount.CreateNewSavingEntity +import org.mifospay.core.model.savingsaccount.SavingAccountDetail +import org.mifospay.core.model.savingsaccount.SavingAccountTemplate +import org.mifospay.core.model.savingsaccount.SavingsWithAssociationsEntity +import org.mifospay.core.model.savingsaccount.Transaction +import org.mifospay.core.model.savingsaccount.UpdateSavingAccountEntity +import org.mifospay.core.network.model.entity.Page + +interface SavingsAccountRepository { + suspend fun getSavingsAccounts(limit: Int): Flow>> + + suspend fun getSavingsWithAssociations( + accountId: Long, + associationType: String, + ): Flow> + + fun getAccountDetail(accountId: Long): Flow> + + suspend fun createSavingsAccount(savingAccount: CreateNewSavingEntity): DataState + + suspend fun updateSavingsAccount( + accountId: Long, + savingAccount: UpdateSavingAccountEntity, + ): DataState + + suspend fun unblockAccount( + accountId: Long, + ): DataState + + suspend fun blockAccount( + accountId: Long, + ): DataState + + suspend fun getSavingAccountTransaction( + accountId: Long, + transactionId: Long, + ): Flow> + + suspend fun payViaMobile(accountId: Long): Flow> + + fun getSavingAccountTemplate(clientId: Long): Flow> +} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/history/HistoryContract.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SearchRepository.kt similarity index 50% rename from core/data/src/main/java/org/mifospay/core/data/domain/usecase/history/HistoryContract.kt rename to core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SearchRepository.kt index 7d59304ab..6c0d78f8e 100644 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/history/HistoryContract.kt +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SearchRepository.kt @@ -7,12 +7,15 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.core.data.domain.usecase.history +package org.mifospay.core.data.repository -import com.mifospay.core.model.domain.Transaction +import org.mifospay.core.common.DataState +import org.mifospay.core.model.search.SearchResult -interface HistoryContract { - interface TransactionsHistoryAsync { - fun onTransactionsFetchCompleted(transactions: List?) - } +interface SearchRepository { + suspend fun searchResources( + query: String, + resources: String, + exactMatch: Boolean, + ): DataState> } diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SelfServiceRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SelfServiceRepository.kt new file mode 100644 index 000000000..f4c4cb695 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/SelfServiceRepository.kt @@ -0,0 +1,65 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.account.Account +import org.mifospay.core.model.account.AccountContent +import org.mifospay.core.model.account.AccountsWithTransactions +import org.mifospay.core.model.beneficiary.Beneficiary +import org.mifospay.core.model.beneficiary.BeneficiaryPayload +import org.mifospay.core.model.beneficiary.BeneficiaryUpdatePayload +import org.mifospay.core.model.client.Client +import org.mifospay.core.model.savingsaccount.Transaction +import org.mifospay.core.network.model.entity.Page +import org.mifospay.core.network.model.entity.authentication.AuthenticationPayload +import org.mifospay.core.network.model.entity.user.User + +interface SelfServiceRepository { + suspend fun loginSelf(payload: AuthenticationPayload): DataState + + fun getSelfClientDetails(clientId: Long): Flow> + + suspend fun getSelfClientDetails(): Flow>> + + fun getSelfAccountTransactions( + accountId: Long, + ): Flow> + + suspend fun getSelfAccountTransactionFromId( + accountId: Long, + transactionId: Long, + ): DataState> + + fun getSelfAccounts(clientId: Long): Flow>> + + fun getBeneficiaryList(): Flow>> + + fun getActiveAccountsWithTransactions( + clientId: Long, + limit: Int, + ): Flow> + + fun getAccountsTransactions(clientId: Long): Flow>> + + fun getTransactions(accountId: List, limit: Int?): Flow> + + fun getAccountAndBeneficiaryList(clientId: Long): Flow> + + suspend fun createBeneficiary(beneficiaryPayload: BeneficiaryPayload): DataState + + suspend fun updateBeneficiary( + beneficiaryId: Long, + payload: BeneficiaryUpdatePayload, + ): DataState + + suspend fun deleteBeneficiary(beneficiaryId: Long): DataState +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/StandingInstructionRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/StandingInstructionRepository.kt new file mode 100644 index 000000000..b9e10d7a0 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/StandingInstructionRepository.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.standinginstruction.SITemplate +import org.mifospay.core.model.standinginstruction.SIUpdatePayload +import org.mifospay.core.model.standinginstruction.StandingInstruction +import org.mifospay.core.model.standinginstruction.StandingInstructionPayload + +interface StandingInstructionRepository { + fun getStandingInstructionTemplate( + fromOfficeId: Long, + fromClientId: Long, + fromAccountType: Long, + ): Flow> + + fun getAllStandingInstructions( + clientId: Long, + ): Flow>> + + fun getStandingInstruction(instructionId: Long): Flow> + + suspend fun createStandingInstruction( + payload: StandingInstructionPayload, + ): DataState + + suspend fun updateStandingInstruction( + instructionId: Long, + payload: SIUpdatePayload, + ): DataState + + suspend fun deleteStandingInstruction(instructionId: Long): DataState +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/ThirdPartyTransferRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/ThirdPartyTransferRepository.kt new file mode 100644 index 000000000..80598f2e3 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/ThirdPartyTransferRepository.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.network.model.entity.TPTResponse +import org.mifospay.core.network.model.entity.payload.TransferPayload +import org.mifospay.core.network.model.entity.templates.account.AccountOptionsTemplate + +interface ThirdPartyTransferRepository { + suspend fun getTransferTemplate(): Flow> + + suspend fun makeTransfer(payload: TransferPayload): Flow> +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/TwoFactorAuthRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/TwoFactorAuthRepository.kt new file mode 100644 index 000000000..890b6751a --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/TwoFactorAuthRepository.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.network.model.twofactor.AccessToken +import org.mifospay.core.network.model.twofactor.DeliveryMethod + +interface TwoFactorAuthRepository { + suspend fun deliveryMethods(): Flow>> + + suspend fun requestOTP(deliveryMethod: String): Flow> + + suspend fun validateToken(token: String): Flow> +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/UserRepository.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/UserRepository.kt new file mode 100644 index 000000000..5d9be9d9f --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repository/UserRepository.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repository + +import kotlinx.coroutines.flow.Flow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.user.NewUser +import org.mifospay.core.network.model.CommonResponse +import org.mifospay.core.network.model.GenericResponse +import org.mifospay.core.network.model.entity.UserWithRole + +interface UserRepository { + suspend fun getUsers(): Flow>> + + suspend fun getUser(): Flow> + + suspend fun createUser(newUser: NewUser): DataState + + suspend fun updateUser(userId: Int, updatedUser: NewUser): Flow> + + suspend fun updateUserPassword(userId: Long, password: String): DataState + + suspend fun deleteUser(userId: Int): DataState + + suspend fun assignClientToUser(userId: Int, clientId: Int): DataState +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/AccountRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/AccountRepositoryImpl.kt new file mode 100644 index 000000000..188107a27 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/AccountRepositoryImpl.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.mapper.toAccount +import org.mifospay.core.data.mapper.toModel +import org.mifospay.core.data.repository.AccountRepository +import org.mifospay.core.data.util.Constants +import org.mifospay.core.model.account.Account +import org.mifospay.core.model.account.AccountTransferPayload +import org.mifospay.core.model.savingsaccount.Transaction +import org.mifospay.core.model.savingsaccount.TransferDetail +import org.mifospay.core.model.search.AccountResult +import org.mifospay.core.network.FineractApiManager + +class AccountRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : AccountRepository { + + override fun getTransaction( + accountId: Long, + transactionId: Long, + ): Flow> { + return apiManager.accountTransfersApi + .getTransaction(accountId, transactionId) + .map { it.toModel() } + .asDataStateFlow().flowOn(ioDispatcher) + } + + override fun getAccountTransfer(transferId: Long): Flow> { + return apiManager.accountTransfersApi + .getAccountTransfer(transferId.toInt()) + .asDataStateFlow().flowOn(ioDispatcher) + } + + override fun searchAccounts(query: String): Flow>> { + return apiManager.accountTransfersApi + .searchAccounts(query, "savings") + .catch { DataState.Error(it, null) } + .asDataStateFlow().flowOn(ioDispatcher) + } + + override fun getSelfAccounts(clientId: Long): Flow>> { + return apiManager.clientsApi + .getAccounts(clientId, Constants.SAVINGS) + .map { it.toAccount() } + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun makeTransfer(payload: AccountTransferPayload): DataState { + return try { + withContext(ioDispatcher) { + apiManager.accountTransfersApi.makeTransfer(payload) + } + + DataState.Success("Transaction Successful") + } catch (e: Exception) { + DataState.Error(e, null) + } + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/AuthenticationRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/AuthenticationRepositoryImpl.kt new file mode 100644 index 000000000..397e540f8 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/AuthenticationRepositoryImpl.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.data.mapper.toUserInfo +import org.mifospay.core.data.repository.AuthenticationRepository +import org.mifospay.core.model.user.UserInfo +import org.mifospay.core.network.SelfServiceApiManager +import org.mifospay.core.network.model.entity.authentication.AuthenticationPayload + +class AuthenticationRepositoryImpl( + private val apiManager: SelfServiceApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : AuthenticationRepository { + override suspend fun authenticate(username: String, password: String): DataState { + return try { + val payload = AuthenticationPayload(username, password) + + val result = withContext(ioDispatcher) { + apiManager.authenticationApi.authenticate(payload) + } + + DataState.Success(result.toUserInfo()) + } catch (e: Exception) { + DataState.Error(e) + } + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/BeneficiaryRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/BeneficiaryRepositoryImpl.kt new file mode 100644 index 000000000..466f4884a --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/BeneficiaryRepositoryImpl.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.repository.BeneficiaryRepository +import org.mifospay.core.model.beneficiary.Beneficiary +import org.mifospay.core.model.beneficiary.BeneficiaryPayload +import org.mifospay.core.model.beneficiary.BeneficiaryUpdatePayload +import org.mifospay.core.network.SelfServiceApiManager +import org.mifospay.core.network.model.entity.templates.beneficiary.BeneficiaryTemplate + +class BeneficiaryRepositoryImpl( + private val apiManager: SelfServiceApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : BeneficiaryRepository { + override suspend fun getBeneficiaryList(): Flow>> { + return apiManager.beneficiaryApi.beneficiaryList().asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun getBeneficiaryTemplate(): Flow> { + return apiManager.beneficiaryApi.beneficiaryTemplate().asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun createBeneficiary( + beneficiaryPayload: BeneficiaryPayload, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.beneficiaryApi.createBeneficiary(beneficiaryPayload) + } + + DataState.Success("Beneficiary created successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun updateBeneficiary( + beneficiaryId: Long, + payload: BeneficiaryUpdatePayload, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.beneficiaryApi.updateBeneficiary(beneficiaryId, payload) + } + + DataState.Success("Beneficiary updated successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun deleteBeneficiary(beneficiaryId: Long): DataState { + return try { + withContext(ioDispatcher) { + apiManager.beneficiaryApi.deleteBeneficiary(beneficiaryId) + } + + DataState.Success("Beneficiary deleted successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/ClientRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/ClientRepositoryImpl.kt new file mode 100644 index 000000000..8a62a4de0 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/ClientRepositoryImpl.kt @@ -0,0 +1,132 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.mapper.toAccount +import org.mifospay.core.data.mapper.toEntity +import org.mifospay.core.data.mapper.toModel +import org.mifospay.core.data.repository.ClientRepository +import org.mifospay.core.model.account.Account +import org.mifospay.core.model.client.Client +import org.mifospay.core.model.client.NewClient +import org.mifospay.core.model.client.UpdatedClient +import org.mifospay.core.network.FineractApiManager +import org.mifospay.core.network.SelfServiceApiManager +import org.mifospay.core.network.model.entity.Page +import org.mifospay.core.network.model.entity.client.ClientAccountsEntity + +class ClientRepositoryImpl( + private val apiManager: SelfServiceApiManager, + private val fineractApiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : ClientRepository { + override suspend fun getClients(): Flow>> { + return apiManager.clientsApi.clients().map { it.toModel() }.asDataStateFlow().flowOn(ioDispatcher) + } + + override fun getClientInfo(clientId: Long): Flow> { + return fineractApiManager.clientsApi + .getClient(clientId) + .catch { DataState.Error(it, null) } + .map { DataState.Success(it.toModel()) } + .flowOn(ioDispatcher) + } + + override suspend fun getClient(clientId: Long): DataState { + return try { + val result = fineractApiManager.clientsApi.getClientForId(clientId) + DataState.Success(result.toModel()) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun updateClient(clientId: Long, client: UpdatedClient): DataState { + return try { + withContext(ioDispatcher) { + fineractApiManager.clientsApi.updateClient(clientId, client.toEntity()) + } + + DataState.Success("Client updated successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override fun getClientImage(clientId: Long): Flow> { + return fineractApiManager.clientsApi + .getClientImage(clientId) + .catch { DataState.Error(it, null) } + .map { DataState.Success(it) } + } + + override suspend fun updateClientImage(clientId: Long, image: String): DataState { + return try { + withContext(ioDispatcher) { + fineractApiManager.clientsApi.updateClientImage( + clientId = clientId, + typedFile = "data:image/png;base64,$image", + ) + } + + DataState.Success("Client image updated successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun getClientAccounts(clientId: Long): Flow> { + return apiManager.clientsApi + .getClientAccounts(clientId) + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun getAccounts( + clientId: Long, + accountType: String, + ): Flow>> { + return fineractApiManager.clientsApi + .getAccounts(clientId, accountType) + .map { it.toAccount() } + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun createClient(newClient: NewClient): DataState { + return try { + val result = withContext(ioDispatcher) { + fineractApiManager.clientsApi.createClient(newClient.toEntity()) + } + + DataState.Success(result.clientId) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun deleteClient(clientId: Int): DataState { + return try { + val result = withContext(ioDispatcher) { + fineractApiManager.clientsApi.deleteClient(clientId) + } + + DataState.Success(result.clientId) + } catch (e: Exception) { + DataState.Error(e) + } + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/DocumentRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/DocumentRepositoryImpl.kt new file mode 100644 index 000000000..adda6c6e7 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/DocumentRepositoryImpl.kt @@ -0,0 +1,125 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import io.ktor.client.request.forms.MultiPartFormDataContent +import io.ktor.client.request.forms.formData +import io.ktor.http.Headers +import io.ktor.http.HttpHeaders +import io.ktor.http.content.PartData +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.repository.DocumentRepository +import org.mifospay.core.network.FineractApiManager +import org.mifospay.core.network.model.entity.noncore.Document + +class DocumentRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : DocumentRepository { + override suspend fun getDocuments( + entityType: String, + entityId: Int, + ): Flow>> { + return apiManager.documentApi + .getDocuments(entityType, entityId) + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun createDocument( + entityType: String, + entityId: Int, + name: String, + description: String, + fileName: PartData.FileItem, + ): Flow> { + return apiManager.documentApi + .createDocument(entityType, entityId, name, description, fileName) + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun createDocument( + entityType: String, + entityId: Long, + name: String, + description: String, + file: ByteArray, + ): DataState { + return try { + val formData = MultiPartFormDataContent( + formData { + // File part + append( + "file", + file, + Headers.build { + append(HttpHeaders.ContentType, "multipart/form-data") + append(HttpHeaders.ContentDisposition, "filename=\"$name\"") + }, + ) + + // Name and description fields + append("name", name) + append("description", description) + }, + ) + + withContext(ioDispatcher) { + apiManager.documentApi.createDocumentFile( + entityType = entityType, + entityId = entityId, + file = formData, + ) + } + + DataState.Success("Document Uploaded Successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun downloadDocument( + entityType: String, + entityId: Int, + documentId: Int, + ): Flow> { + return apiManager.documentApi + .downloadDocument(entityType, entityId, documentId) + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun deleteDocument( + entityType: String, + entityId: Int, + documentId: Int, + ): Flow> { + return apiManager.documentApi + .removeDocument(entityType, entityId, documentId) + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun updateDocument( + entityType: String, + entityId: Int, + documentId: Int, + name: String, + description: String, + fileName: PartData.FileItem, + ): Flow> { + return apiManager.documentApi + .updateDocument(entityType, entityId, documentId, name, description, fileName) + .asDataStateFlow() + .flowOn(ioDispatcher) + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/InvoiceRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/InvoiceRepositoryImpl.kt new file mode 100644 index 000000000..f0b1098b8 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/InvoiceRepositoryImpl.kt @@ -0,0 +1,88 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.repository.InvoiceRepository +import org.mifospay.core.model.datatables.invoice.Invoice +import org.mifospay.core.model.datatables.invoice.InvoiceEntity +import org.mifospay.core.network.FineractApiManager + +class InvoiceRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : InvoiceRepository { + override fun getInvoice(clientId: Long, invoiceId: Long): Flow> { + return apiManager.invoiceApi + .getInvoice(clientId, invoiceId) + .onStart { DataState.Loading } + .catch { DataState.Error(it, null) } + .map { it.first() } + .asDataStateFlow() + .flowOn(ioDispatcher) + } + + override fun getInvoices(clientId: Long): Flow>> { + return apiManager.invoiceApi + .getInvoices(clientId) + .onStart { DataState.Loading } + .catch { DataState.Error(it, null) } + .asDataStateFlow() + .flowOn(ioDispatcher) + } + + override suspend fun createInvoice(clientId: Long, invoice: InvoiceEntity): DataState { + return try { + withContext(ioDispatcher) { + apiManager.invoiceApi.addInvoice(clientId, invoice) + } + + DataState.Success("Invoice created successfully") + } catch (e: Exception) { + DataState.Error(e, null) + } + } + + override suspend fun updateInvoice( + clientId: Long, + invoiceId: Long, + invoice: InvoiceEntity, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.invoiceApi.updateInvoice(clientId, invoiceId, invoice) + } + + DataState.Success("Invoice updated successfully") + } catch (e: Exception) { + DataState.Error(e, null) + } + } + + override suspend fun deleteInvoice(clientId: Long, invoiceId: Long): DataState { + return try { + withContext(ioDispatcher) { + apiManager.invoiceApi.deleteInvoice(clientId, invoiceId) + } + + DataState.Success("Invoice deleted successfully") + } catch (e: Exception) { + DataState.Error(e, null) + } + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/KycLevelRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/KycLevelRepositoryImpl.kt new file mode 100644 index 000000000..020d572a2 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/KycLevelRepositoryImpl.kt @@ -0,0 +1,67 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.repository.KycLevelRepository +import org.mifospay.core.model.kyc.KYCLevel1Details +import org.mifospay.core.network.FineractApiManager + +class KycLevelRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : KycLevelRepository { + override fun fetchKYCLevel1Details( + clientId: Long, + ): Flow> { + return apiManager.kycLevel1Api + .fetchKYCLevel1Details(clientId) + .catch { DataState.Error(it, null) } + .map { it.firstOrNull() } + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun addKYCLevel1Details( + clientId: Long, + kycLevel1Details: KYCLevel1Details, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.kycLevel1Api.addKYCLevel1Details(clientId, kycLevel1Details) + } + + DataState.Success("KYC Level One details added successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun updateKYCLevel1Details( + clientId: Long, + kycLevel1Details: KYCLevel1Details, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.kycLevel1Api.updateKYCLevel1Details(clientId, kycLevel1Details) + } + + DataState.Success("KYC Level One details added successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/LocalAssetRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/LocalAssetRepositoryImpl.kt new file mode 100644 index 000000000..fc4a19b72 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/LocalAssetRepositoryImpl.kt @@ -0,0 +1,64 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import co.touchlab.kermit.Logger +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.withContext +import kotlinx.serialization.json.Json +import org.mifospay.core.data.repository.LocalAssetRepository +import org.mifospay.core.data.util.SAMPLE_CURRENCY +import org.mifospay.core.data.util.SAMPLE_LOCALE +import org.mifospay.core.model.utils.CurrencyCode +import org.mifospay.core.model.utils.Locale + +class LocalAssetRepositoryImpl( + private val ioDispatcher: CoroutineDispatcher, + unconfinedDispatcher: CoroutineDispatcher, + private val networkJson: Json, +) : LocalAssetRepository { + private val coroutineScope = CoroutineScope(unconfinedDispatcher) + + override val localeList: StateFlow> + get() = flow { + val data = withContext(ioDispatcher) { + networkJson.decodeFromString>(SAMPLE_LOCALE) + } + + emit(data) + }.catch { + Logger.e(it) { "Error while fetching locale list" } + }.stateIn( + scope = coroutineScope, + initialValue = emptyList(), + started = SharingStarted.Eagerly, + ) + + override val currencyList: StateFlow> + get() = flow { + val data = withContext(ioDispatcher) { + networkJson.decodeFromString>(SAMPLE_CURRENCY) + } + + emit(data) + }.catch { + Logger.e(it) { "Error while fetching currency list" } + }.stateIn( + scope = coroutineScope, + initialValue = emptyList(), + started = SharingStarted.Eagerly, + ) +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/NotificationRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/NotificationRepositoryImpl.kt new file mode 100644 index 000000000..f5c8288e0 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/NotificationRepositoryImpl.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.repository.NotificationRepository +import org.mifospay.core.model.notification.Notification +import org.mifospay.core.network.FineractApiManager + +class NotificationRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : NotificationRepository { + override fun fetchNotifications(): Flow>> { + return apiManager.notificationApi + .fetchNotifications(true) + .map { it.pageItems } + .asDataStateFlow().flowOn(ioDispatcher) + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/RegistrationRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/RegistrationRepositoryImpl.kt new file mode 100644 index 000000000..e40c98fc1 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/RegistrationRepositoryImpl.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.data.repository.RegistrationRepository +import org.mifospay.core.network.FineractApiManager +import org.mifospay.core.network.model.entity.register.RegisterPayload +import org.mifospay.core.network.model.entity.register.UserVerify + +class RegistrationRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : RegistrationRepository { + override suspend fun registerUser(registerPayload: RegisterPayload): DataState { + return try { + val result = withContext(ioDispatcher) { + apiManager.registrationAPi.registerUser(registerPayload) + } + DataState.Success(result) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun verifyUser(userVerify: UserVerify): DataState { + return try { + val result = withContext(ioDispatcher) { + apiManager.registrationAPi.verifyUser(userVerify) + } + DataState.Success(result) + } catch (e: Exception) { + DataState.Error(e) + } + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/RunReportRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/RunReportRepositoryImpl.kt new file mode 100644 index 000000000..708859703 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/RunReportRepositoryImpl.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.mapper.toModel +import org.mifospay.core.data.repository.RunReportRepository +import org.mifospay.core.model.savingsaccount.Transaction +import org.mifospay.core.network.FineractApiManager + +class RunReportRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : RunReportRepository { + override suspend fun getTransactionReceipt( + outputType: String, + transactionId: String, + ): Flow> { + return apiManager.runReportApi + .getTransactionReceipt(outputType, transactionId) + .map { it.toModel() } + .asDataStateFlow() + .flowOn(ioDispatcher) + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SavedCardRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SavedCardRepositoryImpl.kt new file mode 100644 index 000000000..54f7fabbd --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SavedCardRepositoryImpl.kt @@ -0,0 +1,86 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.repository.SavedCardRepository +import org.mifospay.core.model.savedcards.CardPayload +import org.mifospay.core.model.savedcards.SavedCard +import org.mifospay.core.network.FineractApiManager + +class SavedCardRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : SavedCardRepository { + override fun getSavedCards(clientId: Long): Flow>> { + return apiManager.savedCardApi + .getSavedCards(clientId) + .catch { DataState.Error(it, null) } + .onStart { DataState.Loading } + .asDataStateFlow().flowOn(ioDispatcher) + } + + override fun getSavedCard(clientId: Long, cardId: Long): Flow> { + return apiManager.savedCardApi + .getSavedCard(clientId, cardId) + .catch { DataState.Error(it, null) } + .onStart { DataState.Loading } + .map { it.first() } + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun addSavedCard(clientId: Long, card: CardPayload): DataState { + return try { + withContext(ioDispatcher) { + apiManager.savedCardApi.addSavedCard(clientId, card) + } + + DataState.Success("Card added successfully") + } catch (e: Exception) { + DataState.Error(e, null) + } + } + + override suspend fun deleteCard(clientId: Long, cardId: Long): DataState { + return try { + withContext(ioDispatcher) { + apiManager.savedCardApi.deleteCard(clientId, cardId) + } + + DataState.Success("Card deleted successfully") + } catch (e: Exception) { + DataState.Error(e, null) + } + } + + override suspend fun updateCard( + clientId: Long, + cardId: Long, + card: CardPayload, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.savedCardApi.updateCard(clientId, cardId, card) + } + + DataState.Success("Card updated successfully") + } catch (e: Exception) { + DataState.Error(e, null) + } + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SavingsAccountRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SavingsAccountRepositoryImpl.kt new file mode 100644 index 000000000..505b2aff4 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SavingsAccountRepositoryImpl.kt @@ -0,0 +1,146 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.withContext +import org.mifospay.core.common.Constants +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.mapper.toModel +import org.mifospay.core.data.mapper.toSavingDetail +import org.mifospay.core.data.repository.SavingsAccountRepository +import org.mifospay.core.model.savingsaccount.CreateNewSavingEntity +import org.mifospay.core.model.savingsaccount.SavingAccountDetail +import org.mifospay.core.model.savingsaccount.SavingAccountTemplate +import org.mifospay.core.model.savingsaccount.SavingsWithAssociationsEntity +import org.mifospay.core.model.savingsaccount.Transaction +import org.mifospay.core.model.savingsaccount.TransactionsEntity +import org.mifospay.core.model.savingsaccount.UpdateSavingAccountEntity +import org.mifospay.core.network.FineractApiManager +import org.mifospay.core.network.model.entity.Page + +class SavingsAccountRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : SavingsAccountRepository { + override suspend fun getSavingsAccounts( + limit: Int, + ): Flow>> { + return apiManager.savingsAccountsApi + .getSavingsAccounts(limit) + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun getSavingsWithAssociations( + accountId: Long, + associationType: String, + ): Flow> { + return apiManager.savingsAccountsApi + .getSavingsWithAssociations(accountId, associationType) + .catch { DataState.Error(it, null) } + .asDataStateFlow() + .flowOn(ioDispatcher) + } + + override fun getAccountDetail(accountId: Long): Flow> { + return apiManager.savingsAccountsApi + .getSavingsWithAssociations(accountId, Constants.TRANSACTIONS) + .catch { DataState.Error(it, null) } + .map(SavingsWithAssociationsEntity::toSavingDetail) + .asDataStateFlow() + .flowOn(ioDispatcher) + } + + override suspend fun createSavingsAccount( + savingAccount: CreateNewSavingEntity, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.savingsAccountsApi.createSavingsAccount(savingAccount) + } + + DataState.Success("Savings Account Created Successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun updateSavingsAccount( + accountId: Long, + savingAccount: UpdateSavingAccountEntity, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.savingsAccountsApi.updateSavingsAccount(accountId, savingAccount) + } + + DataState.Success("Savings Account Updated Successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun unblockAccount( + accountId: Long, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.savingsAccountsApi.blockUnblockAccount(accountId, "unblock") + } + + DataState.Success("Account unblocked successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun blockAccount(accountId: Long): DataState { + return try { + withContext(ioDispatcher) { + apiManager.savingsAccountsApi.blockUnblockAccount(accountId, "block") + } + + DataState.Success("Account blocked successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun getSavingAccountTransaction( + accountId: Long, + transactionId: Long, + ): Flow> { + return apiManager.savingsAccountsApi + .getSavingAccountTransaction(accountId, transactionId) + .map(TransactionsEntity::toModel) + .asDataStateFlow() + .flowOn(ioDispatcher) + } + + override suspend fun payViaMobile(accountId: Long): Flow> { + return apiManager.savingsAccountsApi + .payViaMobile(accountId) + .map(TransactionsEntity::toModel) + .asDataStateFlow().flowOn(ioDispatcher) + } + + override fun getSavingAccountTemplate(clientId: Long): Flow> { + return apiManager.savingsAccountsApi + .getSavingAccountTemplate(clientId) + .catch { DataState.Error(it, null) } + .asDataStateFlow() + .flowOn(ioDispatcher) + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SearchRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SearchRepositoryImpl.kt new file mode 100644 index 000000000..c4bda89ed --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SearchRepositoryImpl.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.data.mapper.toSearchResult +import org.mifospay.core.data.repository.SearchRepository +import org.mifospay.core.model.search.SearchResult +import org.mifospay.core.network.FineractApiManager + +class SearchRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : SearchRepository { + override suspend fun searchResources( + query: String, + resources: String, + exactMatch: Boolean, + ): DataState> { + return try { + val result = withContext(ioDispatcher) { + apiManager.searchApi.searchResources(query, resources, exactMatch) + } + + DataState.Success(result.toSearchResult()) + } catch (e: Exception) { + DataState.Error(e) + } + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SelfServiceRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SelfServiceRepositoryImpl.kt new file mode 100644 index 000000000..4227cf727 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/SelfServiceRepositoryImpl.kt @@ -0,0 +1,227 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flatMapMerge +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.flow.scan +import kotlinx.coroutines.flow.zip +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.common.combineResultsWith +import org.mifospay.core.data.mapper.toAccount +import org.mifospay.core.data.mapper.toModel +import org.mifospay.core.data.mapper.toTransactionList +import org.mifospay.core.data.repository.SelfServiceRepository +import org.mifospay.core.data.util.Constants +import org.mifospay.core.model.account.Account +import org.mifospay.core.model.account.AccountContent +import org.mifospay.core.model.account.AccountsWithTransactions +import org.mifospay.core.model.beneficiary.Beneficiary +import org.mifospay.core.model.beneficiary.BeneficiaryPayload +import org.mifospay.core.model.beneficiary.BeneficiaryUpdatePayload +import org.mifospay.core.model.client.Client +import org.mifospay.core.model.savingsaccount.Transaction +import org.mifospay.core.network.SelfServiceApiManager +import org.mifospay.core.network.model.entity.Page +import org.mifospay.core.network.model.entity.authentication.AuthenticationPayload +import org.mifospay.core.network.model.entity.user.User + +@OptIn(ExperimentalCoroutinesApi::class) +class SelfServiceRepositoryImpl( + private val apiManager: SelfServiceApiManager, + private val dispatcher: CoroutineDispatcher, +) : SelfServiceRepository { + override suspend fun loginSelf(payload: AuthenticationPayload): DataState { + return try { + val result = apiManager.authenticationApi.authenticate(payload) + + DataState.Success(result) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override fun getSelfClientDetails(clientId: Long): Flow> { + return apiManager.clientsApi + .getClient(clientId) + .onStart { DataState.Loading } + .catch { DataState.Error(it, null) } + .map { it.toModel() } + .asDataStateFlow().flowOn(dispatcher) + } + + override suspend fun getSelfClientDetails(): Flow>> { + return apiManager.clientsApi.clients().map { it.toModel() }.asDataStateFlow() + .flowOn(dispatcher) + } + + override fun getSelfAccountTransactions( + accountId: Long, + ): Flow> { + return apiManager.savingAccountsListApi + .getSavingsWithAssociations(accountId, Constants.TRANSACTIONS) + .map { it.toTransactionList() } + .flowOn(dispatcher) + } + + override suspend fun getSelfAccountTransactionFromId( + accountId: Long, + transactionId: Long, + ): DataState> { + return try { + val result = withContext(dispatcher) { + apiManager.savingAccountsListApi.getSavingAccountTransaction( + accountId, + transactionId, + ) + } + + DataState.Success(result.map { it.toModel() }) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override fun getSelfAccounts(clientId: Long): Flow>> { + return apiManager.clientsApi + .getAccounts(clientId, Constants.SAVINGS) + .map { it.toAccount() } + .asDataStateFlow().flowOn(dispatcher) + } + + override fun getAccountAndBeneficiaryList(clientId: Long): Flow> { + val accountList = apiManager.clientsApi + .getAccounts(clientId, Constants.SAVINGS) + .onStart { DataState.Loading } + .catch { DataState.Error(it, null) } + .map { DataState.Success(it.toAccount()) } + .flowOn(dispatcher) + + val beneficiaryList = apiManager.beneficiaryApi + .beneficiaryList() + .onStart { DataState.Loading } + .catch { DataState.Error(it, null) } + .map { DataState.Success(it) } + .flowOn(dispatcher) + + return accountList.zip(beneficiaryList) { accounts, beneficiaries -> + accounts.combineResultsWith(beneficiaries) { accData, bccData -> + AccountContent(accData, bccData) + } + }.flowOn(dispatcher) + } + + // TODO:: Optimize below functions + @OptIn(ExperimentalCoroutinesApi::class) + override fun getActiveAccountsWithTransactions( + clientId: Long, + limit: Int, + ): Flow> { + val accounts = apiManager.clientsApi + .getAccounts(clientId, Constants.SAVINGS) + .map { entity -> entity.savingsAccounts.filter { it.status.active } } + .map { it.toAccount() } + .flowOn(dispatcher) + + val transactions = accounts + .map { list -> list.map { it.id } } + .flatMapLatest { + getTransactions(it, limit) + } + + return accounts.combine(transactions) { accountList, transaction -> + AccountsWithTransactions(accountList, transaction) + }.map { DataState.Success(it) }.flowOn(dispatcher) + } + + override fun getTransactions(accountId: List, limit: Int?): Flow> { + return accountId.asFlow().flatMapMerge { clientId -> + getSelfAccountTransactions(clientId) + }.scan(emptyList()) { acc, transactions -> + acc + transactions.sortedByDescending { it.date }.let { sortedList -> + limit?.let { sortedList.take(it) } ?: sortedList + } + } + } + + override fun getAccountsTransactions( + clientId: Long, + ): Flow>> { + return apiManager.clientsApi + .getAccounts(clientId, Constants.SAVINGS) + .onStart { DataState.Loading } + .catch { DataState.Error(it, null) } + .map { it.toAccount() } + .map { list -> list.filter { it.status.active } } + .map { list -> list.map { it.id } } + .flatMapLatest { + getTransactions(accountId = it, null) + }.map { + DataState.Success(it) + } + .flowOn(dispatcher) + } + + override fun getBeneficiaryList(): Flow>> { + return apiManager.beneficiaryApi.beneficiaryList().asDataStateFlow().flowOn(dispatcher) + } + + override suspend fun createBeneficiary( + beneficiaryPayload: BeneficiaryPayload, + ): DataState { + return try { + withContext(dispatcher) { + apiManager.beneficiaryApi.createBeneficiary(beneficiaryPayload) + } + + DataState.Success("Beneficiary created successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun updateBeneficiary( + beneficiaryId: Long, + payload: BeneficiaryUpdatePayload, + ): DataState { + return try { + withContext(dispatcher) { + apiManager.beneficiaryApi.updateBeneficiary(beneficiaryId, payload) + } + + DataState.Success("Beneficiary updated successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun deleteBeneficiary(beneficiaryId: Long): DataState { + return try { + withContext(dispatcher) { + apiManager.beneficiaryApi.deleteBeneficiary(beneficiaryId) + } + + DataState.Success("Beneficiary deleted successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/StandingInstructionRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/StandingInstructionRepositoryImpl.kt new file mode 100644 index 000000000..ff74375db --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/StandingInstructionRepositoryImpl.kt @@ -0,0 +1,109 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.repository.StandingInstructionRepository +import org.mifospay.core.model.standinginstruction.SITemplate +import org.mifospay.core.model.standinginstruction.SIUpdatePayload +import org.mifospay.core.model.standinginstruction.StandingInstruction +import org.mifospay.core.model.standinginstruction.StandingInstructionPayload +import org.mifospay.core.network.FineractApiManager + +class StandingInstructionRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : StandingInstructionRepository { + override fun getStandingInstructionTemplate( + fromOfficeId: Long, + fromClientId: Long, + fromAccountType: Long, + ): Flow> { + return apiManager.standingInstructionApi + .getStandingInstructionTemplate(fromOfficeId, fromClientId, fromAccountType) + .catch { DataState.Error(it, null) } + .asDataStateFlow().flowOn(ioDispatcher) + } + + override fun getAllStandingInstructions( + clientId: Long, + ): Flow>> { + return apiManager.standingInstructionApi + .getAllStandingInstructions(clientId) + .catch { DataState.Error(it, null) } + .map { it.pageItems } + .asDataStateFlow().flowOn(ioDispatcher) + } + + override fun getStandingInstruction( + instructionId: Long, + ): Flow> { + return apiManager.standingInstructionApi + .getStandingInstruction(instructionId) + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun createStandingInstruction( + payload: StandingInstructionPayload, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.standingInstructionApi.createStandingInstruction(payload) + } + + DataState.Success("Standing Instruction created successfully") + } catch (e: Exception) { + DataState.Error(e, null) + } + } + + override suspend fun updateStandingInstruction( + instructionId: Long, + payload: SIUpdatePayload, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.standingInstructionApi.updateStandingInstruction( + instructionId = instructionId, + payload = payload, + command = "update", + ) + } + + DataState.Success("Standing Instruction updated successfully") + } catch (e: Exception) { + DataState.Error(e, null) + } + } + + override suspend fun deleteStandingInstruction( + instructionId: Long, + ): DataState { + return try { + withContext(ioDispatcher) { + apiManager.standingInstructionApi.deleteStandingInstruction( + instructionId = instructionId, + command = "delete", + ) + } + + DataState.Success("Standing Instruction deleted successfully") + } catch (e: Exception) { + DataState.Error(e, null) + } + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/ThirdPartyTransferRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/ThirdPartyTransferRepositoryImpl.kt new file mode 100644 index 000000000..0db69798d --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/ThirdPartyTransferRepositoryImpl.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.repository.ThirdPartyTransferRepository +import org.mifospay.core.network.FineractApiManager +import org.mifospay.core.network.model.entity.TPTResponse +import org.mifospay.core.network.model.entity.payload.TransferPayload +import org.mifospay.core.network.model.entity.templates.account.AccountOptionsTemplate + +class ThirdPartyTransferRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : ThirdPartyTransferRepository { + override suspend fun getTransferTemplate(): Flow> { + return apiManager.thirdPartyTransferApi + .accountTransferTemplate() + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun makeTransfer(payload: TransferPayload): Flow> { + return apiManager.thirdPartyTransferApi + .makeTransfer(payload) + .asDataStateFlow().flowOn(ioDispatcher) + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/TwoFactorAuthRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/TwoFactorAuthRepositoryImpl.kt new file mode 100644 index 000000000..c4390b86a --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/TwoFactorAuthRepositoryImpl.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.repository.TwoFactorAuthRepository +import org.mifospay.core.network.FineractApiManager +import org.mifospay.core.network.model.twofactor.AccessToken +import org.mifospay.core.network.model.twofactor.DeliveryMethod + +class TwoFactorAuthRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : TwoFactorAuthRepository { + override suspend fun deliveryMethods(): Flow>> { + return apiManager.twoFactorAuthApi.deliveryMethods().asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun requestOTP(deliveryMethod: String): Flow> { + return apiManager.twoFactorAuthApi + .requestOTP(deliveryMethod) + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun validateToken(token: String): Flow> { + return apiManager.twoFactorAuthApi.validateToken(token).asDataStateFlow().flowOn(ioDispatcher) + } +} diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/UserRepositoryImpl.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/UserRepositoryImpl.kt new file mode 100644 index 000000000..4911802c4 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/repositoryImp/UserRepositoryImpl.kt @@ -0,0 +1,96 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.repositoryImp + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.common.asDataStateFlow +import org.mifospay.core.data.mapper.toEntity +import org.mifospay.core.data.repository.UserRepository +import org.mifospay.core.model.user.NewUser +import org.mifospay.core.network.FineractApiManager +import org.mifospay.core.network.model.CommonResponse +import org.mifospay.core.network.model.GenericResponse +import org.mifospay.core.network.model.entity.UserWithRole +import org.mifospay.core.network.model.entity.user.UpdateUserEntityPassword + +class UserRepositoryImpl( + private val apiManager: FineractApiManager, + private val ioDispatcher: CoroutineDispatcher, +) : UserRepository { + override suspend fun getUsers(): Flow>> { + return apiManager.userApi.users().asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun getUser(): Flow> { + return apiManager.userApi.getUser().asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun createUser(newUser: NewUser): DataState { + return try { + val result = withContext(ioDispatcher) { + apiManager.userApi.createUser(newUser.toEntity()) + } + + DataState.Success(result.resourceId) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun updateUser( + userId: Int, + updatedUser: NewUser, + ): Flow> { + return apiManager.userApi + .updateUser(userId, updatedUser.toEntity()) + .asDataStateFlow().flowOn(ioDispatcher) + } + + override suspend fun updateUserPassword(userId: Long, password: String): DataState { + return try { + apiManager.userApi.updateUserPassword( + userId = userId, + updateUserEntity = UpdateUserEntityPassword(password, password), + ) + + DataState.Success("Password updated successfully") + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun deleteUser(userId: Int): DataState { + return try { + val result = withContext(ioDispatcher) { + apiManager.userApi.deleteUser(userId) + } + + DataState.Success(result) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun assignClientToUser(userId: Int, clientId: Int): DataState { + return try { + val result = withContext(ioDispatcher) { + apiManager.userApi.assignClientToUser(userId, mapOf("clients" to listOf(clientId))) + } + + DataState.Success(Unit) + } catch (e: Exception) { + DataState.Error(e) + } + } +} diff --git a/core/data/src/main/java/org/mifospay/core/data/util/Constants.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/Constants.kt similarity index 90% rename from core/data/src/main/java/org/mifospay/core/data/util/Constants.kt rename to core/data/src/commonMain/kotlin/org/mifospay/core/data/util/Constants.kt index 758c1fb23..4c5e6d58b 100644 --- a/core/data/src/main/java/org/mifospay/core/data/util/Constants.kt +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/Constants.kt @@ -9,9 +9,6 @@ */ package org.mifospay.core.data.util -import java.util.Arrays -import java.util.Collections - object Constants { const val BASIC = "Basic " const val SAVINGS = "savingsAccounts" @@ -19,13 +16,10 @@ object Constants { const val WALLET_ACCOUNT_SAVINGS_PRODUCT_ID = 1 const val MIFOS_MERCHANT_SAVINGS_PRODUCT_ID = 165 // 372 const val MIFOS_CONSUMER_SAVINGS_PRODUCT_ID = 165 // 373 - private const val MOBILE_WALLET_ROLE_ID = 471 + private const val MOBILE_WALLET_ROLE_ID = 2 private const val SUPER_USER_ROLE_ID = 1 - @JvmField - val NEW_USER_ROLE_IDS: Collection = Collections.unmodifiableList( - Arrays.asList(MOBILE_WALLET_ROLE_ID, SUPER_USER_ROLE_ID), - ) + val NEW_USER_ROLE_IDS: List = listOf(MOBILE_WALLET_ROLE_ID, SUPER_USER_ROLE_ID) const val ENTITY_TYPE_CLIENTS = "clients" const val FETCH_ACCOUNT_TRANSFER_USECASE = "FetchAccountTransfer" const val NO_SAVED_CARDS = "No saved cards." diff --git a/core/data/src/main/java/org/mifospay/core/data/util/NetworkMonitor.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/NetworkMonitor.kt similarity index 100% rename from core/data/src/main/java/org/mifospay/core/data/util/NetworkMonitor.kt rename to core/data/src/commonMain/kotlin/org/mifospay/core/data/util/NetworkMonitor.kt diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/SampleCurrency.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/SampleCurrency.kt new file mode 100644 index 000000000..f6b5d168a --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/SampleCurrency.kt @@ -0,0 +1,160 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.util + +internal val SAMPLE_CURRENCY = """ + [ + { + "countryName": "United States", + "currencyCode": "USD", + "currencySymbol": "${'$'}" + }, + { + "countryName": "European Union", + "currencyCode": "EUR", + "currencySymbol": "ā‚¬" + }, + { + "countryName": "Japan", + "currencyCode": "JPY", + "currencySymbol": "Ā„" + }, + { + "countryName": "United Kingdom", + "currencyCode": "GBP", + "currencySymbol": "Ā£" + }, + { + "countryName": "China", + "currencyCode": "CNY", + "currencySymbol": "Ā„" + }, + { + "countryName": "Switzerland", + "currencyCode": "CHF", + "currencySymbol": "CHF" + }, + { + "countryName": "Canada", + "currencyCode": "CAD", + "currencySymbol": "${'$'}" + }, + { + "countryName": "Australia", + "currencyCode": "AUD", + "currencySymbol": "${'$'}" + }, + { + "countryName": "India", + "currencyCode": "INR", + "currencySymbol": "ā‚¹" + }, + { + "countryName": "Brazil", + "currencyCode": "BRL", + "currencySymbol": "R${'$'}" + }, + { + "countryName": "South Korea", + "currencyCode": "KRW", + "currencySymbol": "ā‚©" + }, + { + "countryName": "Russia", + "currencyCode": "RUB", + "currencySymbol": "ā‚½" + }, + { + "countryName": "Mexico", + "currencyCode": "MXN", + "currencySymbol": "${'$'}" + }, + { + "countryName": "Singapore", + "currencyCode": "SGD", + "currencySymbol": "${'$'}" + }, + { + "countryName": "Sweden", + "currencyCode": "SEK", + "currencySymbol": "kr" + }, + { + "countryName": "Norway", + "currencyCode": "NOK", + "currencySymbol": "kr" + }, + { + "countryName": "Denmark", + "currencyCode": "DKK", + "currencySymbol": "kr" + }, + { + "countryName": "Saudi Arabia", + "currencyCode": "SAR", + "currencySymbol": "ļ·¼" + }, + { + "countryName": "United Arab Emirates", + "currencyCode": "AED", + "currencySymbol": "ŲÆ.Ų„" + }, + { + "countryName": "Turkey", + "currencyCode": "TRY", + "currencySymbol": "ā‚ŗ" + }, + { + "countryName": "South Africa", + "currencyCode": "ZAR", + "currencySymbol": "R" + }, + { + "countryName": "Israel", + "currencyCode": "ILS", + "currencySymbol": "ā‚Ŗ" + }, + { + "countryName": "Poland", + "currencyCode": "PLN", + "currencySymbol": "zł" + }, + { + "countryName": "Hungary", + "currencyCode": "HUF", + "currencySymbol": "Ft" + }, + { + "countryName": "Czech Republic", + "currencyCode": "CZK", + "currencySymbol": "Kč" + }, + { + "countryName": "Thailand", + "currencyCode": "THB", + "currencySymbol": "ąøæ" + }, + { + "countryName": "Malaysia", + "currencyCode": "MYR", + "currencySymbol": "RM" + }, + { + "countryName": "Indonesia", + "currencyCode": "IDR", + "currencySymbol": "Rp" + }, + { + "countryName": "Argentina", + "currencyCode": "ARS", + "currencySymbol": "${'$'}" + } + ] +""".trimIndent() diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/SampleLocale.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/SampleLocale.kt new file mode 100644 index 000000000..6956465fb --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/SampleLocale.kt @@ -0,0 +1,700 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.util + +internal val SAMPLE_LOCALE = """ + [ + { + "countryName": "Afrikaans (South Africa)", + "localName": "af_ZA", + "dominantName": "af_ZA" + }, + { + "countryName": "Albanian (Albania)", + "localName": "sq_AL", + "dominantName": "sq_AL" + }, + { + "countryName": "Arabic (Algeria)", + "localName": "ar_DZ", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Bahrain)", + "localName": "ar_BH", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Egypt)", + "localName": "ar_EG", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Iraq)", + "localName": "ar_IQ", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Jordan)", + "localName": "ar_JO", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Kuwait)", + "localName": "ar_KW", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Lebanon)", + "localName": "ar_LB", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Libya)", + "localName": "ar_LY", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Morocco)", + "localName": "ar_MA", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Oman)", + "localName": "ar_OM", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Qatar)", + "localName": "ar_QA", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Saudi Arabia)", + "localName": "ar_SA", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Syria)", + "localName": "ar_SY", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Tunisia)", + "localName": "ar_TN", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (United Arab Emirates)", + "localName": "ar_AE", + "dominantName": "ar_SA" + }, + { + "countryName": "Arabic (Yemen)", + "localName": "ar_YE", + "dominantName": "ar_SA" + }, + { + "countryName": "Armenian (Armenia)", + "localName": "hy_AM", + "dominantName": "hy_AM" + }, + { + "countryName": "Azerbaijani (Azerbaijan)", + "localName": "az_AZ", + "dominantName": "az_AZ" + }, + { + "countryName": "Basque (Spain)", + "localName": "eu_ES", + "dominantName": "eu_ES" + }, + { + "countryName": "Belarusian (Belarus)", + "localName": "be_BY", + "dominantName": "be_BY" + }, + { + "countryName": "Bengali (India)", + "localName": "bn_IN", + "dominantName": "bn_IN" + }, + { + "countryName": "Bosnian (Bosnia and Herzegovina)", + "localName": "bs_BA", + "dominantName": "bs_BA" + }, + { + "countryName": "Bulgarian (Bulgaria)", + "localName": "bg_BG", + "dominantName": "bg_BG" + }, + { + "countryName": "Catalan (Spain)", + "localName": "ca_ES", + "dominantName": "ca_ES" + }, + { + "countryName": "Chinese (China)", + "localName": "zh_CN", + "dominantName": "zh_CN" + }, + { + "countryName": "Chinese (Hong Kong SAR China)", + "localName": "zh_HK", + "dominantName": "zh_TW" + }, + { + "countryName": "Chinese (Macao SAR China)", + "localName": "zh_MO", + "dominantName": "zh_TW" + }, + { + "countryName": "Chinese (Singapore)", + "localName": "zh_SG", + "dominantName": "zh_CN" + }, + { + "countryName": "Chinese (Taiwan)", + "localName": "zh_TW", + "dominantName": "zh_TW" + }, + { + "countryName": "Croatian (Croatia)", + "localName": "hr_HR", + "dominantName": "hr_HR" + }, + { + "countryName": "Czech (Czech Republic)", + "localName": "cs_CZ", + "dominantName": "cs_CZ" + }, + { + "countryName": "Danish (Denmark)", + "localName": "da_DK", + "dominantName": "da_DK" + }, + { + "countryName": "Dutch (Belgium)", + "localName": "nl_BE", + "dominantName": "nl_NL" + }, + { + "countryName": "Dutch (Netherlands)", + "localName": "nl_NL", + "dominantName": "nl_NL" + }, + { + "countryName": "English (Australia)", + "localName": "en_AU", + "dominantName": "en_US" + }, + { + "countryName": "English (Belize)", + "localName": "en_BZ", + "dominantName": "en_US" + }, + { + "countryName": "English (Canada)", + "localName": "en_CA", + "dominantName": "en_US" + }, + { + "countryName": "English (Ireland)", + "localName": "en_IE", + "dominantName": "en_US" + }, + { + "countryName": "English (Jamaica)", + "localName": "en_JM", + "dominantName": "en_US" + }, + { + "countryName": "English (New Zealand)", + "localName": "en_NZ", + "dominantName": "en_US" + }, + { + "countryName": "English (Philippines)", + "localName": "en_PH", + "dominantName": "en_US" + }, + { + "countryName": "English (South Africa)", + "localName": "en_ZA", + "dominantName": "en_US" + }, + { + "countryName": "English (Trinidad and Tobago)", + "localName": "en_TT", + "dominantName": "en_US" + }, + { + "countryName": "English (U.S. Virgin Islands)", + "localName": "en_VI", + "dominantName": "en_US" + }, + { + "countryName": "English (India)", + "localName": "en_IN", + "dominantName": "en_IN" + }, + { + "countryName": "English (United Kingdom)", + "localName": "en_GB", + "dominantName": "en_US" + }, + { + "countryName": "English (United States)", + "localName": "en_US", + "dominantName": "en_US" + }, + { + "countryName": "English (Zimbabwe)", + "localName": "en_ZW", + "dominantName": "en_US" + }, + { + "countryName": "Estonian (Estonia)", + "localName": "et_EE", + "dominantName": "et_EE" + }, + { + "countryName": "Faroese (Faroe Islands)", + "localName": "fo_FO", + "dominantName": "fo_FO" + }, + { + "countryName": "Finnish (Finland)", + "localName": "fi_FI", + "dominantName": "fi_FI" + }, + { + "countryName": "French (Belgium)", + "localName": "fr_BE", + "dominantName": "fr_FR" + }, + { + "countryName": "French (Canada)", + "localName": "fr_CA", + "dominantName": "fr_FR" + }, + { + "countryName": "French (France)", + "localName": "fr_FR", + "dominantName": "fr_FR" + }, + { + "countryName": "French (Luxembourg)", + "localName": "fr_LU", + "dominantName": "fr_FR" + }, + { + "countryName": "French (Monaco)", + "localName": "fr_MC", + "dominantName": "fr_FR" + }, + { + "countryName": "French (Switzerland)", + "localName": "fr_CH", + "dominantName": "fr_FR" + }, + { + "countryName": "Galician (Spain)", + "localName": "gl_ES", + "dominantName": "gl_ES" + }, + { + "countryName": "Georgian (Georgia)", + "localName": "ka_GE", + "dominantName": "ka_GE" + }, + { + "countryName": "German (Austria)", + "localName": "de_AT", + "dominantName": "de_DE" + }, + { + "countryName": "German (Germany)", + "localName": "de_DE", + "dominantName": "de_DE" + }, + { + "countryName": "German (Liechtenstein)", + "localName": "de_LI", + "dominantName": "de_DE" + }, + { + "countryName": "German (Luxembourg)", + "localName": "de_LU", + "dominantName": "de_DE" + }, + { + "countryName": "German (Switzerland)", + "localName": "de_CH", + "dominantName": "de_DE" + }, + { + "countryName": "Greek (Greece)", + "localName": "el_GR", + "dominantName": "el_GR" + }, + { + "countryName": "Gujarati (India)", + "localName": "gu_IN", + "dominantName": "gu_IN" + }, + { + "countryName": "Hebrew (Israel)", + "localName": "he_IL", + "dominantName": "he_IL" + }, + { + "countryName": "Hindi (India)", + "localName": "hi_IN", + "dominantName": "hi_IN" + }, + { + "countryName": "Hungarian (Hungary)", + "localName": "hu_HU", + "dominantName": "hu_HU" + }, + { + "countryName": "Icelandic (Iceland)", + "localName": "is_IS", + "dominantName": "is_IS" + }, + { + "countryName": "Indonesian (Indonesia)", + "localName": "id_ID", + "dominantName": "id_ID" + }, + { + "countryName": "Italian (Italy)", + "localName": "it_IT", + "dominantName": "it_IT" + }, + { + "countryName": "Italian (Switzerland)", + "localName": "it_CH", + "dominantName": "it_IT" + }, + { + "countryName": "Japanese (Japan)", + "localName": "ja_JP", + "dominantName": "ja_JP" + }, + { + "countryName": "Kannada (India)", + "localName": "kn_IN", + "dominantName": "kn_IN" + }, + { + "countryName": "Kazakh (Kazakhstan)", + "localName": "kk_KZ", + "dominantName": "kk_KZ" + }, + { + "countryName": "Konkani (India)", + "localName": "kok_IN", + "dominantName": "kok_IN" + }, + { + "countryName": "Korean (South Korea)", + "localName": "ko_KR", + "dominantName": "ko_KR" + }, + { + "countryName": "Latvian (Latvia)", + "localName": "lv_LV", + "dominantName": "lv_LV" + }, + { + "countryName": "Lithuanian (Lithuania)", + "localName": "lt_LT", + "dominantName": "lt_LT" + }, + { + "countryName": "Macedonian (Macedonia)", + "localName": "mk_MK", + "dominantName": "mk_MK" + }, + { + "countryName": "Malay (Brunei)", + "localName": "ms_BN", + "dominantName": "ms_MY" + }, + { + "countryName": "Malay (Malaysia)", + "localName": "ms_MY", + "dominantName": "ms_MY" + }, + { + "countryName": "Malayalam (India)", + "localName": "ml_IN", + "dominantName": "ml_IN" + }, + { + "countryName": "Maltese (Malta)", + "localName": "mt_MT", + "dominantName": "mt_MT" + }, + { + "countryName": "Marathi (India)", + "localName": "mr_IN", + "dominantName": "mr_IN" + }, + { + "countryName": "Mongolian (Mongolia)", + "localName": "mn_MN", + "dominantName": "mn_MN" + }, + { + "countryName": "Northern Sami (Norway)", + "localName": "se_NO", + "dominantName": "se_NO" + }, + { + "countryName": "Norwegian BokmĆ„l (Norway)", + "localName": "nb_NO", + "dominantName": "nb_NO" + }, + { + "countryName": "Norwegian Nynorsk (Norway)", + "localName": "nn_NO", + "dominantName": "nn_NO" + }, + { + "countryName": "Persian (Iran)", + "localName": "fa_IR", + "dominantName": "fa_IR" + }, + { + "countryName": "Polish (Poland)", + "localName": "pl_PL", + "dominantName": "pl_PL" + }, + { + "countryName": "Portuguese (Brazil)", + "localName": "pt_BR", + "dominantName": "pt_BR" + }, + { + "countryName": "Portuguese (Portugal)", + "localName": "pt_PT", + "dominantName": "pt_BR" + }, + { + "countryName": "Punjabi (India)", + "localName": "pa_IN", + "dominantName": "pa_IN" + }, + { + "countryName": "Romanian (Romania)", + "localName": "ro_RO", + "dominantName": "ro_RO" + }, + { + "countryName": "Russian (Russia)", + "localName": "ru_RU", + "dominantName": "ru_RU" + }, + { + "countryName": "Serbian (Bosnia and Herzegovina)", + "localName": "sr_BA", + "dominantName": "sr_BA" + }, + { + "countryName": "Serbian (Serbia And Montenegro)", + "localName": "sr_CS", + "dominantName": "sr_BA" + }, + { + "countryName": "Slovak (Slovakia)", + "localName": "sk_SK", + "dominantName": "sk_SK" + }, + { + "countryName": "Slovenian (Slovenia)", + "localName": "sl_SI", + "dominantName": "sk_SK" + }, + { + "countryName": "Spanish (Argentina)", + "localName": "es_AR", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Bolivia)", + "localName": "es_BO", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Chile)", + "localName": "es_CL", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Colombia)", + "localName": "es_CO", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Costa Rica)", + "localName": "es_CR", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Dominican Republic)", + "localName": "es_DO", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Ecuador)", + "localName": "es_EC", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (El Salvador)", + "localName": "es_SV", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Guatemala)", + "localName": "es_GT", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Honduras)", + "localName": "es_HN", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Mexico)", + "localName": "es_MX", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Nicaragua)", + "localName": "es_NI", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Panama)", + "localName": "es_PA", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Paraguay)", + "localName": "es_PY", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Peru)", + "localName": "es_PE", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Puerto Rico)", + "localName": "es_PR", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Spain)", + "localName": "es_ES", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Uruguay)", + "localName": "es_UY", + "dominantName": "es_ES" + }, + { + "countryName": "Spanish (Venezuela)", + "localName": "es_VE", + "dominantName": "es_ES" + }, + { + "countryName": "Swahili (Kenya)", + "localName": "sw_KE", + "dominantName": "sw_KE" + }, + { + "countryName": "Swedish (Finland)", + "localName": "sv_FI", + "dominantName": "sv_SE" + }, + { + "countryName": "Swedish (Sweden)", + "localName": "sv_SE", + "dominantName": "sv_SE" + }, + { + "countryName": "Syriac (Syria)", + "localName": "syr_SY", + "dominantName": "syr_SY" + }, + { + "countryName": "Tamil (India)", + "localName": "ta_IN", + "dominantName": "ta_IN" + }, + { + "countryName": "Telugu (India)", + "localName": "te_IN", + "dominantName": "te_IN" + }, + { + "countryName": "Thai (Thailand)", + "localName": "th_TH", + "dominantName": "th_TH" + }, + { + "countryName": "Tswana (South Africa)", + "localName": "tn_ZA", + "dominantName": "tn_ZA" + }, + { + "countryName": "Turkish (Turkey)", + "localName": "tr_TR", + "dominantName": "tr_TR" + }, + { + "countryName": "Ukrainian (Ukraine)", + "localName": "uk_UA", + "dominantName": "uk_UA" + }, + { + "countryName": "Uzbek (Uzbekistan)", + "localName": "uz_UZ", + "dominantName": "uz_UZ" + }, + { + "countryName": "Vietnamese (Vietnam)", + "localName": "vi_VN", + "dominantName": "vi_VN" + }, + { + "countryName": "Welsh (United Kingdom)", + "localName": "cy_GB", + "dominantName": "cy_GB" + }, + { + "countryName": "Xhosa (South Africa)", + "localName": "xh_ZA", + "dominantName": "xh_ZA" + }, + { + "countryName": "Zulu (South Africa)", + "localName": "zu_ZA", + "dominantName": "zu_ZA" + } + ] +""".trimIndent() diff --git a/lint/src/main/kotlin/org/mifos/mifospay/lint/util/LintOption.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/TimeZoneMonitor.kt similarity index 51% rename from lint/src/main/kotlin/org/mifos/mifospay/lint/util/LintOption.kt rename to core/data/src/commonMain/kotlin/org/mifospay/core/data/util/TimeZoneMonitor.kt index 6d14aaf0e..bea88a147 100644 --- a/lint/src/main/kotlin/org/mifos/mifospay/lint/util/LintOption.kt +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/TimeZoneMonitor.kt @@ -7,14 +7,16 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifos.mifospay.lint.util +package org.mifospay.core.data.util -import com.android.tools.lint.client.api.Configuration +import kotlinx.coroutines.flow.Flow +import kotlinx.datetime.TimeZone /** - * A layer of indirection for implementations of option loaders without needing to extend from - * Detector. This goes along with [OptionLoadingDetector]. + * Utility for reporting current timezone the device has set. + * It always emits at least once with default setting and then for each TZ change. */ -interface LintOption { - fun load(configuration: Configuration) + +interface TimeZoneMonitor { + val currentTimeZone: Flow } diff --git a/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/UpiQrCodeProcessor.kt b/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/UpiQrCodeProcessor.kt new file mode 100644 index 000000000..46a02d123 --- /dev/null +++ b/core/data/src/commonMain/kotlin/org/mifospay/core/data/util/UpiQrCodeProcessor.kt @@ -0,0 +1,148 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.util + +import io.ktor.util.decodeBase64String +import io.ktor.util.encodeBase64 +import org.mifospay.core.model.utils.PaymentQrData +import kotlin.io.encoding.ExperimentalEncodingApi + +/** + * UPI QR Code Encoder and Decoder with validation + */ +@OptIn(ExperimentalEncodingApi::class) +object UpiQrCodeProcessor { + // Regex patterns for validation + private val VPA_PATTERN = Regex("^[a-zA-Z0-9.-]+@[a-zA-Z0-9]+$") + private val CURRENCY_PATTERN = Regex("^[A-Z]{3}$") + + // Maximum allowed amount + private const val MAX_AMOUNT = 100000.0 + + /** + * Encodes UPI payment details into a Base64 encoded string + * @param paymentQrData UPI payment request details + * @return Base64 encoded UPI payment string + * @throws IllegalArgumentException for invalid input + */ + fun encodeUpiString(paymentQrData: PaymentQrData): String { + // Validate input data + validate(paymentQrData) + + // Build UPI string + val requestPaymentString = buildString { + append("upi://pay") + append("?ci=${paymentQrData.clientId}") + append("&am=${paymentQrData.amount}") + append("&cn=${paymentQrData.clientName}") + append("&an=${paymentQrData.accountNo}") + append("&ai=${paymentQrData.accountId}") + append("&cu=${paymentQrData.currency}") + append("&oi=${paymentQrData.officeId}") + append("&pi=${paymentQrData.accountTypeId}") + append("&mode=02") + append("&s=000000") + } + + return requestPaymentString.encodeBase64() + } + + /** + * Decodes a Base64 encoded UPI payment string + * @param encodedString Base64 encoded UPI payment string + * @return Decoded PaymentQrData object + * @throws IllegalArgumentException for invalid encoded string + */ + fun decodeUpiString(encodedString: String): PaymentQrData { + // Decode the Base64 string + val decodedString = encodedString.decodeBase64String() + + // Extract parameters + val params = parseUpiString(decodedString) + + // Create PaymentQrData + val requestQrData = PaymentQrData( + clientId = params["ci"]?.toLongOrNull() + ?: throw IllegalArgumentException("Missing client ID"), + clientName = params["cn"] + ?: throw IllegalArgumentException("Missing client name"), + accountNo = params["an"] + ?: throw IllegalArgumentException("Missing account number"), + amount = params["am"] ?: "", + accountId = params["ai"]?.toLongOrNull() + ?: throw IllegalArgumentException("Missing account ID"), + currency = params["cu"] + ?: PaymentQrData.DEFAULT_CURRENCY, + officeId = params["oi"]?.toLongOrNull() + ?: PaymentQrData.OFFICE_ID, + accountTypeId = params["pi"]?.toLongOrNull() + ?: PaymentQrData.ACCOUNT_TYPE_ID, + ) + + // Validate the created object + validate(requestQrData) + + return requestQrData + } + + /** + * Validates the PaymentQrData + * @param data UPI payment request details to validate + * @throws IllegalArgumentException for any validation failures + */ + private fun validate(data: PaymentQrData) { + // Name validation + require(data.clientName.isNotBlank()) { + "Client name cannot be empty" + } + + require(data.clientName.length <= 50) { + "Client name too long (max 50 characters)" + } + + // Account number validation + require(data.accountNo.isNotBlank()) { + "Account number cannot be empty" + } + + // Optional amount validation (if not empty) + if (data.amount.isNotEmpty()) { + val amountValue = data.amount.toDoubleOrNull() + ?: throw IllegalArgumentException("Invalid amount format") + + require(amountValue > 0) { + "Amount must be positive" + } + require(amountValue <= MAX_AMOUNT) { + "Amount exceeds maximum limit of ā‚¹$MAX_AMOUNT" + } + } + + // Currency validation + require(CURRENCY_PATTERN.matches(data.currency)) { + "Invalid currency code. Must be 3 uppercase letters" + } + } + + /** + * Parses the UPI payment string into a map of parameters + * @param upiString Decoded UPI payment string + * @return Map of parameter keys and values + */ + private fun parseUpiString(upiString: String): Map { + return upiString + .substringAfter("upi://pay?") + .split("&") + .associate { + val (key, value) = it.split("=") + key to value + } + } +} diff --git a/core/data/src/desktopMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt b/core/data/src/desktopMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt new file mode 100644 index 000000000..fe646afb5 --- /dev/null +++ b/core/data/src/desktopMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf +import kotlinx.datetime.TimeZone +import org.mifospay.core.data.di.PlatformDependentDataModule +import org.mifospay.core.data.util.NetworkMonitor +import org.mifospay.core.data.util.TimeZoneMonitor + +class JsPlatformDependentDataModule : PlatformDependentDataModule { + override val networkMonitor: NetworkMonitor by lazy { + object : NetworkMonitor { + override val isOnline: Flow = flowOf(true) + } + } + + override val timeZoneMonitor: TimeZoneMonitor by lazy { + object : TimeZoneMonitor { + override val currentTimeZone: Flow = flowOf(TimeZone.currentSystemDefault()) + } + } +} diff --git a/shared/src/iosMain/kotlin/org/mifospay/shared/di/Modules.ios.kt b/core/data/src/desktopMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt similarity index 54% rename from shared/src/iosMain/kotlin/org/mifospay/shared/di/Modules.ios.kt rename to core/data/src/desktopMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt index e7cbc9318..9dbf3539a 100644 --- a/shared/src/iosMain/kotlin/org/mifospay/shared/di/Modules.ios.kt +++ b/core/data/src/desktopMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt @@ -7,9 +7,16 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package org.mifospay.shared.di +package org.mifospay.core.data.di import org.koin.core.module.Module +import org.koin.dsl.module +import org.mifospay.core.data.JsPlatformDependentDataModule + +actual val getPlatformDataModule: PlatformDependentDataModule + get() = JsPlatformDependentDataModule() actual val platformModule: Module - get() = TODO("Not yet implemented") + get() = module { + single { getPlatformDataModule } + } diff --git a/core/data/src/jsMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt b/core/data/src/jsMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt new file mode 100644 index 000000000..fe646afb5 --- /dev/null +++ b/core/data/src/jsMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf +import kotlinx.datetime.TimeZone +import org.mifospay.core.data.di.PlatformDependentDataModule +import org.mifospay.core.data.util.NetworkMonitor +import org.mifospay.core.data.util.TimeZoneMonitor + +class JsPlatformDependentDataModule : PlatformDependentDataModule { + override val networkMonitor: NetworkMonitor by lazy { + object : NetworkMonitor { + override val isOnline: Flow = flowOf(true) + } + } + + override val timeZoneMonitor: TimeZoneMonitor by lazy { + object : TimeZoneMonitor { + override val currentTimeZone: Flow = flowOf(TimeZone.currentSystemDefault()) + } + } +} diff --git a/core/data/src/jsMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt b/core/data/src/jsMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt new file mode 100644 index 000000000..9dbf3539a --- /dev/null +++ b/core/data/src/jsMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.di + +import org.koin.core.module.Module +import org.koin.dsl.module +import org.mifospay.core.data.JsPlatformDependentDataModule + +actual val getPlatformDataModule: PlatformDependentDataModule + get() = JsPlatformDependentDataModule() + +actual val platformModule: Module + get() = module { + single { getPlatformDataModule } + } diff --git a/core/data/src/main/java/org/mifospay/core/data/base/TaskLooper.kt b/core/data/src/main/java/org/mifospay/core/data/base/TaskLooper.kt deleted file mode 100644 index 6fa7abbf7..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/base/TaskLooper.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.base - -import org.mifospay.core.data.base.UseCase.UseCaseCallback - -class TaskLooper( - private val mUseCaseHandler: UseCaseHandler, -) { - var isFailed = false - private var tasksPending: Long = 0 - private var listener: Listener? = null - - fun addTask( - useCase: UseCase, - values: T, - taskData: TaskData, - ) { - tasksPending++ - mUseCaseHandler.execute( - useCase, - values, - object : UseCaseCallback { - override fun onSuccess(response: R) { - if (isFailed) return - listener!!.onTaskSuccess(taskData, response) - tasksPending-- - if (isCompleted) { - listener!!.onComplete() - } - } - - override fun onError(message: String) { - isFailed = true - listener!!.onFailure(message) - } - }, - ) - } - - private val isCompleted: Boolean - get() = tasksPending == 0L - - fun listen(listener: Listener?) { - this.listener = listener - } - - interface Listener { - fun onTaskSuccess(taskData: TaskData, response: R) - fun onComplete() - fun onFailure(message: String?) - } - - class TaskData(var taskName: String, var taskId: Int) -} diff --git a/core/data/src/main/java/org/mifospay/core/data/base/ThreadPoolQueue.kt b/core/data/src/main/java/org/mifospay/core/data/base/ThreadPoolQueue.kt deleted file mode 100644 index 083de6576..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/base/ThreadPoolQueue.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.base - -import java.util.concurrent.ArrayBlockingQueue - -class ThreadPoolQueue(capacity: Int) : ArrayBlockingQueue(capacity) { - - override fun offer(e: Runnable?): Boolean { - try { - put(e) - } catch (e1: InterruptedException) { - return false - } - return true - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/base/UseCase.kt b/core/data/src/main/java/org/mifospay/core/data/base/UseCase.kt deleted file mode 100644 index 2784fd0a8..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/base/UseCase.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.base - -/** - * Use cases are the entry points to the domain layer. - * - * @param the request type - * @param

the response type -

*/ -abstract class UseCase { - lateinit var walletRequestValues: Q - lateinit var useCaseCallback: UseCaseCallback

- - fun setRequestValues(requestValues: Q) { - this.walletRequestValues = requestValues - } - - fun run() { - executeUseCase(walletRequestValues) - } - - protected abstract fun executeUseCase(requestValues: Q) - - /** - * Data passed to a request. - */ - interface RequestValues - - /** - * Data received from a request. - */ - interface ResponseValue - interface UseCaseCallback { - fun onSuccess(response: R) - fun onError(message: String) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/base/UseCaseFactory.kt b/core/data/src/main/java/org/mifospay/core/data/base/UseCaseFactory.kt deleted file mode 100644 index d7f6b510b..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/base/UseCaseFactory.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.base - -import org.mifospay.core.data.domain.usecase.account.FetchAccountTransfer -import org.mifospay.core.data.domain.usecase.client.FetchClientDetails -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants - -class UseCaseFactory( - private val mFineractRepository: FineractRepository, -) { - fun getUseCase(useCase: String): UseCase<*, *>? { - return when (useCase) { - Constants.FETCH_ACCOUNT_TRANSFER_USECASE -> { - FetchAccountTransfer(mFineractRepository) - } - - Constants.FETCH_CLIENT_DETAILS_USE_CASE -> { - FetchClientDetails(mFineractRepository) - } - - else -> null - } - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/base/UseCaseHandler.kt b/core/data/src/main/java/org/mifospay/core/data/base/UseCaseHandler.kt deleted file mode 100644 index 9fe654b62..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/base/UseCaseHandler.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.base - -import org.mifospay.core.data.base.UseCase.UseCaseCallback - -/** - * Runs [UseCase]s using a [UseCaseScheduler]. - */ -class UseCaseHandler(private val mUseCaseScheduler: UseCaseScheduler) { - fun execute( - useCase: UseCase, - values: T?, - callback: UseCaseCallback, - ) { - values?.let { useCase.walletRequestValues = values } - useCase.useCaseCallback = UiCallbackWrapper(callback, this) - mUseCaseScheduler.execute { useCase.run() } - } - - fun notifyResponse( - response: V, - useCaseCallback: UseCaseCallback?, - ) { - mUseCaseScheduler.notifyResponse(response, useCaseCallback) - } - - private fun notifyError( - message: String?, - useCaseCallback: UseCaseCallback?, - ) { - mUseCaseScheduler.onError(message, useCaseCallback) - } - - private class UiCallbackWrapper( - private val mCallback: UseCaseCallback?, - private val mUseCaseHandler: UseCaseHandler, - ) : UseCaseCallback { - override fun onSuccess(response: V) { - mUseCaseHandler.notifyResponse(response, mCallback) - } - - override fun onError(message: String) { - mUseCaseHandler.notifyError(message, mCallback) - } - } - - companion object { - var instance: UseCaseHandler? = null - get() { - if (field == null) { - field = UseCaseHandler(UseCaseThreadPoolScheduler()) - } - return field - } - private set - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/base/UseCaseScheduler.kt b/core/data/src/main/java/org/mifospay/core/data/base/UseCaseScheduler.kt deleted file mode 100644 index bff30b7e4..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/base/UseCaseScheduler.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.base - -import org.mifospay.core.data.base.UseCase.UseCaseCallback - -/** - * Interface for schedulers, see [UseCaseThreadPoolScheduler]. - */ -interface UseCaseScheduler { - fun execute(runnable: Runnable?) - fun notifyResponse( - response: V, - useCaseCallback: UseCaseCallback?, - ) - - fun onError( - message: String?, - useCaseCallback: UseCaseCallback?, - ) -} diff --git a/core/data/src/main/java/org/mifospay/core/data/base/UseCaseThreadPoolScheduler.kt b/core/data/src/main/java/org/mifospay/core/data/base/UseCaseThreadPoolScheduler.kt deleted file mode 100644 index 2066f1faa..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/base/UseCaseThreadPoolScheduler.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.base - -import android.os.Handler -import android.os.Looper -import org.mifospay.core.data.base.UseCase.UseCaseCallback -import java.util.concurrent.ThreadPoolExecutor -import java.util.concurrent.TimeUnit - -/** - * Executes asynchronous tasks using a [ThreadPoolExecutor]. - * - * - * See also [ThreadPoolExecutor] for a list of factory methods to create common - * [java.util.concurrent.ExecutorService]s for different scenarios. - */ -class UseCaseThreadPoolScheduler : UseCaseScheduler { - - private val mHandler = Handler(Looper.getMainLooper()) - private var mThreadPoolExecutor: ThreadPoolExecutor = ThreadPoolExecutor( - POOL_SIZE, - MAX_POOL_SIZE, - TIMEOUT.toLong(), - TimeUnit.SECONDS, - ThreadPoolQueue(MAX_POOL_SIZE), - ) - - override fun execute(runnable: Runnable?) { - mThreadPoolExecutor.execute(runnable) - } - - override fun notifyResponse( - response: V, - useCaseCallback: UseCaseCallback?, - ) { - mHandler.post { useCaseCallback!!.onSuccess(response) } - } - - override fun onError( - message: String?, - useCaseCallback: UseCaseCallback?, - ) { - mHandler.post { useCaseCallback!!.onError(message!!) } - } - - companion object { - const val POOL_SIZE = 2 - const val MAX_POOL_SIZE = 40 - const val TIMEOUT = 60 - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/di/DataModule.kt b/core/data/src/main/java/org/mifospay/core/data/di/DataModule.kt deleted file mode 100644 index 48a560509..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/di/DataModule.kt +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.di - -import org.koin.android.ext.koin.androidContext -import org.koin.core.qualifier.named -import org.koin.dsl.module -import org.mifospay.core.data.base.TaskLooper -import org.mifospay.core.data.base.UseCaseFactory -import org.mifospay.core.data.base.UseCaseHandler -import org.mifospay.core.data.base.UseCaseScheduler -import org.mifospay.core.data.base.UseCaseThreadPoolScheduler -import org.mifospay.core.data.domain.usecase.account.BlockUnblockCommand -import org.mifospay.core.data.domain.usecase.account.DownloadTransactionReceipt -import org.mifospay.core.data.domain.usecase.account.FetchAccount -import org.mifospay.core.data.domain.usecase.account.FetchAccountTransaction -import org.mifospay.core.data.domain.usecase.account.FetchAccountTransactions -import org.mifospay.core.data.domain.usecase.account.FetchAccountTransfer -import org.mifospay.core.data.domain.usecase.account.FetchAccounts -import org.mifospay.core.data.domain.usecase.account.FetchMerchants -import org.mifospay.core.data.domain.usecase.account.TransferFunds -import org.mifospay.core.data.domain.usecase.client.CreateClient -import org.mifospay.core.data.domain.usecase.client.FetchClientData -import org.mifospay.core.data.domain.usecase.client.FetchClientDetails -import org.mifospay.core.data.domain.usecase.client.FetchClientImage -import org.mifospay.core.data.domain.usecase.client.SearchClient -import org.mifospay.core.data.domain.usecase.client.UpdateClient -import org.mifospay.core.data.domain.usecase.history.TransactionsHistory -import org.mifospay.core.data.domain.usecase.invoice.FetchInvoice -import org.mifospay.core.data.domain.usecase.invoice.FetchInvoices -import org.mifospay.core.data.domain.usecase.kyc.FetchKYCLevel1Details -import org.mifospay.core.data.domain.usecase.kyc.UpdateKYCLevel1Details -import org.mifospay.core.data.domain.usecase.kyc.UploadKYCDocs -import org.mifospay.core.data.domain.usecase.kyc.UploadKYCLevel1Details -import org.mifospay.core.data.domain.usecase.notification.FetchNotifications -import org.mifospay.core.data.domain.usecase.savedcards.AddCard -import org.mifospay.core.data.domain.usecase.savedcards.DeleteCard -import org.mifospay.core.data.domain.usecase.savedcards.EditCard -import org.mifospay.core.data.domain.usecase.savedcards.FetchSavedCards -import org.mifospay.core.data.domain.usecase.standinginstruction.CreateStandingTransaction -import org.mifospay.core.data.domain.usecase.standinginstruction.DeleteStandingInstruction -import org.mifospay.core.data.domain.usecase.standinginstruction.FetchStandingInstruction -import org.mifospay.core.data.domain.usecase.standinginstruction.GetAllStandingInstructions -import org.mifospay.core.data.domain.usecase.standinginstruction.UpdateStandingInstruction -import org.mifospay.core.data.domain.usecase.twofactor.FetchDeliveryMethods -import org.mifospay.core.data.domain.usecase.twofactor.RequestOTP -import org.mifospay.core.data.domain.usecase.twofactor.ValidateOTP -import org.mifospay.core.data.domain.usecase.user.AuthenticateUser -import org.mifospay.core.data.domain.usecase.user.CreateUser -import org.mifospay.core.data.domain.usecase.user.DeleteUser -import org.mifospay.core.data.domain.usecase.user.FetchUserDetails -import org.mifospay.core.data.domain.usecase.user.FetchUsers -import org.mifospay.core.data.domain.usecase.user.RegisterUser -import org.mifospay.core.data.domain.usecase.user.UpdateUser -import org.mifospay.core.data.domain.usecase.user.VerifyUser -import org.mifospay.core.data.fineract.entity.mapper.AccountMapper -import org.mifospay.core.data.fineract.entity.mapper.ClientDetailsMapper -import org.mifospay.core.data.fineract.entity.mapper.CurrencyMapper -import org.mifospay.core.data.fineract.entity.mapper.SearchedEntitiesMapper -import org.mifospay.core.data.fineract.entity.mapper.TransactionMapper -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.repository.auth.AuthenticationUserRepository -import org.mifospay.core.data.repository.auth.UserDataRepository -import org.mifospay.core.data.repository.local.LocalAssetRepository -import org.mifospay.core.data.repository.local.LocalRepository -import org.mifospay.core.data.repository.local.MifosLocalAssetRepository -import org.mifospay.core.data.util.ConnectivityManagerNetworkMonitor -import org.mifospay.core.data.util.NetworkMonitor -import org.mifospay.core.data.util.TimeZoneBroadcastMonitor -import org.mifospay.core.data.util.TimeZoneMonitor -import org.mifospay.core.datastore.PreferencesHelper -import org.mifospay.core.network.MifosDispatchers -import org.mifospay.core.network.di.LocalModule -import org.mifospay.core.network.localAssets.LocalAssetDataSource -import org.mifospay.core.network.localAssets.MifosLocalAssetDataSource - -val DataModule = module { - includes(LocalModule) - - single { UseCaseThreadPoolScheduler() } - single { UseCaseHandler(get()) } - single { TaskLooper(get()) } - single { UseCaseFactory(get()) } - single { FetchClientData(get(), get()) } - single { ClientDetailsMapper() } - single { SearchClient(get(), get()) } - single { UpdateClient(get()) } - single { CreateClient(get()) } - single { FetchClientDetails(get()) } - single { FetchClientImage(get()) } - single { BlockUnblockCommand(get()) } - single { DownloadTransactionReceipt(get()) } - single { AccountMapper(get()) } - single { FetchAccount(get(), get()) } - single { FetchAccounts(get(), get()) } - single { FetchAccountTransaction(get(), get()) } - single { FetchAccountTransactions(get(), get()) } - single { FetchAccountTransfer(get()) } - single { FetchMerchants(get()) } - single { TransferFunds(get()) } - single { - TransactionsHistory( - mUseCaseHandler = get(), - fetchAccountTransactionsUseCase = get(), - ) - } - - // Invoice UseCase - single { FetchInvoice(get()) } - single { FetchInvoices(get()) } - - // KYC UseCase - single { FetchKYCLevel1Details(get()) } - single { UpdateKYCLevel1Details(get()) } - single { UploadKYCDocs(get()) } - single { UploadKYCLevel1Details(get()) } - - // Notifications - single { FetchNotifications(get()) } - - // Saved Cards - single { AddCard(get()) } - single { DeleteCard(get()) } - single { EditCard(get()) } - single { FetchSavedCards(get()) } - - // Standing Instructions - single { CreateStandingTransaction(get()) } - single { DeleteStandingInstruction(get()) } - single { FetchStandingInstruction(get()) } - single { GetAllStandingInstructions(get()) } - single { UpdateStandingInstruction(get()) } - - // Two-Factor - single { FetchDeliveryMethods(get()) } - single { RequestOTP(get()) } - single { ValidateOTP(get()) } - - // User - single { AuthenticateUser(get()) } - single { CreateUser(get()) } - single { DeleteUser(get()) } - single { FetchUserDetails(get()) } - single { FetchUsers(get()) } - single { RegisterUser(get()) } - single { UpdateUser(get()) } - single { VerifyUser(get()) } - - // Fineract Entity Mappers - single { CurrencyMapper() } - single { SearchedEntitiesMapper() } - single { TransactionMapper(get()) } - single { AccountMapper(get()) } - single { ClientDetailsMapper() } - - // Fineract Repository - - single { - FineractRepository( - fineractApiManager = get(), - selfApiManager = get(), - ktorAuthenticationService = get(), - ) - } - - // Fineract Repository Auth - - single { AuthenticationUserRepository(get()) } - - // Fineract Repository Local - - single { - val preferencesHelper: PreferencesHelper = get() - LocalRepository(preferencesHelper) - } - - factory { - MifosLocalAssetDataSource( - ioDispatcher = get( - named(MifosDispatchers.IO.name), - ), - networkJson = get(), - assets = get(), - ) - } - - factory { - MifosLocalAssetRepository( - ioDispatcher = get( - named(MifosDispatchers.IO.name), - ), - datasource = get(), - ) - } - - // Util - - single { ConnectivityManagerNetworkMonitor(context = androidContext()) } - - single { - TimeZoneBroadcastMonitor( - context = androidContext(), - appScope = get(named("ApplicationScope")), - ioDispatcher = get(named(MifosDispatchers.IO.name)), - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/BlockUnblockCommand.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/BlockUnblockCommand.kt deleted file mode 100644 index 45075fd22..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/BlockUnblockCommand.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.account - -import android.util.Log -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository - -class BlockUnblockCommand( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - CoroutineScope(Dispatchers.IO).launch { - try { - val res = mFineractRepository.blockUnblockAccount( - requestValues.accountId, - requestValues.command, - ) - withContext(Dispatchers.Main) { - Log.d("BlockUnblockCommand@@@@", "$res") - useCaseCallback.onSuccess(ResponseValue) - } - } catch (e: Exception) { - Log.d("BlockUnblockCommand@@@@", "${e.message}") - useCaseCallback.onError( - "Error " + requestValues.command + "ing account", - ) - } - } - } - - data class RequestValues(val accountId: Long, val command: String) : UseCase.RequestValues - data object ResponseValue : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/DownloadTransactionReceipt.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/DownloadTransactionReceipt.kt deleted file mode 100644 index 36d955040..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/DownloadTransactionReceipt.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.account - -import okhttp3.ResponseBody -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class DownloadTransactionReceipt( - private val mFineractRepository: FineractRepository, -) : UseCase() { - override fun executeUseCase(requestValues: RequestValues) { - requestValues.transactionId?.let { - mFineractRepository.getTransactionReceipt(Constants.PDF, it) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(t: ResponseBody) { - useCaseCallback.onSuccess(ResponseValue(t)) - } - }, - ) - } - } - - data class RequestValues(val transactionId: String?) : UseCase.RequestValues - data class ResponseValue(val responseBody: ResponseBody) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccount.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccount.kt deleted file mode 100644 index 4bc88a5e1..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccount.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.account - -import com.mifospay.core.model.domain.Account -import com.mifospay.core.model.entity.client.ClientAccounts -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.entity.mapper.AccountMapper -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchAccount( - private val fineractRepository: FineractRepository, - private val accountMapper: AccountMapper, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - fineractRepository.getSelfAccounts(requestValues.clientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_ACCOUNTS) - } - - override fun onNext(clientAccounts: ClientAccounts) { - val accounts = accountMapper.transform(clientAccounts) - - if (accounts.isNotEmpty()) { - var walletAccount: Account? = null - for (account in accounts) { - if (account.productId.toInt() == Constants.WALLET_ACCOUNT_SAVINGS_PRODUCT_ID) { - walletAccount = account - break - } - } - if (walletAccount != null) { - useCaseCallback.onSuccess(ResponseValue(walletAccount)) - } else { - useCaseCallback.onError(Constants.NO_ACCOUNT_FOUND) - } - } else { - useCaseCallback.onError(Constants.NO_ACCOUNTS_FOUND) - } - } - }, - ) - } - - data class RequestValues(val clientId: Long) : UseCase.RequestValues - - data class ResponseValue(val account: Account) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransaction.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransaction.kt deleted file mode 100644 index 6ad743a05..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransaction.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.account - -import android.util.Log -import com.mifospay.core.model.domain.Transaction -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.entity.mapper.TransactionMapper -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants - -class FetchAccountTransaction( - private val fineractRepository: FineractRepository, - private val transactionMapper: TransactionMapper, -) : - UseCase() { - override fun executeUseCase(requestValues: RequestValues) { - CoroutineScope(Dispatchers.IO).launch { - try { - val res = fineractRepository.getSelfAccountTransactionFromId( - requestValues.accountId, - requestValues.transactionId, - ) - withContext(Dispatchers.Main) { - Log.d("FetchTransactions@@@@", "$res") - useCaseCallback.onSuccess( - ResponseValue(transactionMapper.transformInvoice(res)), - ) - } - } catch (e: Exception) { - Log.d("FetchTransactions@@@@", "${e.message}") - withContext(Dispatchers.Main) { - if (e.message == "HTTP 401 Unauthorized") { - useCaseCallback.onError(Constants.UNAUTHORIZED_ERROR) - } else { - useCaseCallback.onError( - Constants.ERROR_FETCHING_REMOTE_ACCOUNT_TRANSACTIONS, - ) - } - } - } - } - } - - data class RequestValues( - val accountId: Long, - val transactionId: Long, - ) : UseCase.RequestValues - - data class ResponseValue(val transaction: Transaction) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransactions.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransactions.kt deleted file mode 100644 index 7ab0830d4..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransactions.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.account - -import android.util.Log -import com.mifospay.core.model.domain.Transaction -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.entity.mapper.TransactionMapper -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants - -class FetchAccountTransactions( - private val fineractRepository: FineractRepository, - private val transactionMapper: TransactionMapper, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - CoroutineScope(Dispatchers.IO).launch { - try { - val api = fineractRepository.getSelfAccountTransactions(requestValues.accountId) - withContext(Dispatchers.Main) { - Log.d("FetchTransactions@@@@", "$api") - useCaseCallback.onSuccess( - ResponseValue( - transactionMapper.transformTransactionList(api), - ), - ) - } - } catch (e: Exception) { - withContext(Dispatchers.Main) { - Log.d("FetchTransactions@@@@", "${e.message}") - useCaseCallback.onError( - Constants.ERROR_FETCHING_REMOTE_ACCOUNT_TRANSACTIONS, - ) - } - } - } - } - - data class RequestValues(var accountId: Long) : UseCase.RequestValues - data class ResponseValue(val transactions: List) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransfer.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransfer.kt deleted file mode 100644 index 78cc231a7..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccountTransfer.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.account - -import com.mifospay.core.model.entity.accounts.savings.TransferDetail -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchAccountTransfer( - private val mFineractRepository: FineractRepository, -) : UseCase() { - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.getAccountTransfer(requestValues.transferId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe(object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(transferDetail: TransferDetail) { - useCaseCallback.onSuccess(ResponseValue(transferDetail)) - } - }) - } - - data class RequestValues(var transferId: Long) : UseCase.RequestValues - data class ResponseValue(val transferDetail: TransferDetail) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccounts.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccounts.kt deleted file mode 100644 index 9b3b4732f..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchAccounts.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.account - -import com.mifospay.core.model.domain.Account -import com.mifospay.core.model.entity.client.ClientAccounts -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.entity.mapper.AccountMapper -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchAccounts( - private val fineractRepository: FineractRepository, - private val accountMapper: AccountMapper, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - fineractRepository.getAccounts(requestValues.clientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_ACCOUNTS) - } - - override fun onNext(t: ClientAccounts?) { - if (t != null) { - useCaseCallback.onSuccess( - ResponseValue( - accountMapper.transform(t), - ), - ) - } else { - useCaseCallback.onError(Constants.NO_ACCOUNTS_FOUND) - } - } - }, - ) - } - - data class RequestValues(val clientId: Long) : UseCase.RequestValues - data class ResponseValue(val accountList: List) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchMerchants.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchMerchants.kt deleted file mode 100644 index 57bdbba0a..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/FetchMerchants.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.account - -import android.util.Log -import com.mifospay.core.model.entity.accounts.savings.SavingsWithAssociations -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants - -class FetchMerchants( - private val mFineractRepository: FineractRepository, -) : UseCase() { - override fun executeUseCase(requestValues: RequestValues) { - CoroutineScope(Dispatchers.IO).launch { - try { - val res = mFineractRepository.savingsAccounts() - withContext(Dispatchers.Main) { - Log.d("FetchMerchants@@@@", "$res") - val savingsWithAssociationsList = res.pageItems - val merchantsList: MutableList = ArrayList() - for (i in savingsWithAssociationsList.indices) { - if (savingsWithAssociationsList[i].savingsProductId == - Constants.MIFOS_MERCHANT_SAVINGS_PRODUCT_ID - ) { - merchantsList.add(savingsWithAssociationsList[i]) - } - } - useCaseCallback.onSuccess(ResponseValue(merchantsList)) - } - } catch (e: Exception) { - Log.d("FetchTransactions@@@@", "${e.message}") - e.message?.let { useCaseCallback.onError(it) } - } - } - } - - class RequestValues : UseCase.RequestValues - data class ResponseValue( - val savingsWithAssociationsList: List, - ) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/TransferFunds.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/TransferFunds.kt deleted file mode 100644 index ec3efb669..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/account/TransferFunds.kt +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.account - -import com.mifospay.core.model.entity.TPTResponse -import com.mifospay.core.model.entity.accounts.savings.SavingAccount -import com.mifospay.core.model.entity.beneficary.Beneficiary -import com.mifospay.core.model.entity.beneficary.BeneficiaryPayload -import com.mifospay.core.model.entity.beneficary.BeneficiaryUpdatePayload -import com.mifospay.core.model.entity.client.Client -import com.mifospay.core.model.entity.client.ClientAccounts -import com.mifospay.core.model.entity.payload.TransferPayload -import com.mifospay.core.model.utils.DateHelper -import okhttp3.ResponseBody -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -@Suppress("UnusedPrivateMember") -class TransferFunds( - private val apiRepository: FineractRepository, -) : UseCase() { - - // override var requestValues: RequestValues - private lateinit var fromClient: Client - private lateinit var toClient: Client - private lateinit var fromAccount: SavingAccount - private lateinit var toAccount: SavingAccount - - override fun executeUseCase(requestValues: RequestValues) { - this.walletRequestValues = requestValues - apiRepository.getSelfClientDetails(requestValues.fromClientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_CLIENT_DATA) - } - - override fun onNext(client: Client) { - fromClient = client - fetchToClientDetails() - } - }, - ) - } - - private fun fetchToClientDetails() { - apiRepository.getClientDetails(walletRequestValues.toClientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_CLIENT_DATA) - } - - override fun onNext(client: Client) { - toClient = client - fetchFromAccountDetails() - } - }, - ) - } - - private fun fetchFromAccountDetails() { - apiRepository.getSelfAccounts(walletRequestValues.fromClientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_FROM_ACCOUNT) - } - - override fun onNext(clientAccounts: ClientAccounts) { - val accounts = clientAccounts.savingsAccounts - if (accounts.isNotEmpty()) { - var walletAccount: SavingAccount? = null - for (account in accounts) { - if (account.productId == Constants.WALLET_ACCOUNT_SAVINGS_PRODUCT_ID) { - walletAccount = account - break - } - } - if (walletAccount != null) { - fromAccount = walletAccount - fetchToAccountDetails() - } else { - useCaseCallback.onError(Constants.NO_WALLET_FOUND) - } - } else { - useCaseCallback.onError(Constants.ERROR_FETCHING_FROM_ACCOUNT) - } - } - }, - ) - } - - private fun fetchToAccountDetails() { - apiRepository.getAccounts(walletRequestValues.toClientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_TO_ACCOUNT) - } - - override fun onNext(clientAccounts: ClientAccounts) { - val accounts = clientAccounts.savingsAccounts - if (accounts.isNotEmpty()) { - var walletAccount: SavingAccount? = null - for (account in accounts) { - if (account.productId == Constants.WALLET_ACCOUNT_SAVINGS_PRODUCT_ID) { - walletAccount = account - break - } - } - if (walletAccount != null) { - toAccount = walletAccount - makeTransfer() - } else { - useCaseCallback.onError(Constants.NO_WALLET_FOUND) - } - } else { - useCaseCallback.onError(Constants.ERROR_FETCHING_TO_ACCOUNT) - } - } - }, - ) - } - - private fun checkBeneficiary() { - apiRepository.beneficiaryList - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber>() { - override fun onCompleted() {} - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_BENEFICIARIES) - } - - override fun onNext(beneficiaries: List) { - var exists = false - beneficiaries.forEach { beneficiary -> - if (beneficiary.accountNumber == toAccount.accountNo) { - exists = true - if (beneficiary.transferLimit >= walletRequestValues.amount) { - makeTransfer() - } else { - updateTransferLimit(beneficiary.id?.toLong()!!) - } - return@forEach - } - } - if (!exists) { - addBeneficiary() - } - } - }, - ) - } - - private fun addBeneficiary() { - val payload = BeneficiaryPayload().apply { - accountNumber = toAccount.accountNo - name = toClient.displayName - officeName = toClient.officeName - transferLimit = walletRequestValues.amount.toInt() - accountType = 2 - } - - apiRepository.createBeneficiary(payload) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_ADDING_BENEFICIARY) - } - - override fun onNext(responseBody: ResponseBody) { - makeTransfer() - } - }, - ) - } - - private fun updateTransferLimit(beneficiaryId: Long) { - val updatePayload = BeneficiaryUpdatePayload().apply { - transferLimit = walletRequestValues.amount.toInt() - } - apiRepository.updateBeneficiary(beneficiaryId, updatePayload) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_ADDING_BENEFICIARY) - } - - override fun onNext(responseBody: ResponseBody) { - makeTransfer() - } - }, - ) - } - - private fun makeTransfer() { - val transferPayload = TransferPayload().apply { - fromAccountId = fromAccount.id.toInt() - fromClientId = fromClient.id.toLong() - fromAccountType = 2 - fromOfficeId = fromClient.officeId - toOfficeId = toClient.officeId - toAccountId = toAccount.id.toInt() - toClientId = toClient.id.toLong() - toAccountType = 2 - transferDate = DateHelper.getDateAsStringFromLong(System.currentTimeMillis()) - transferAmount = walletRequestValues.amount - transferDescription = Constants.WALLET_TRANSFER - } - - apiRepository.makeThirdPartyTransfer(transferPayload) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_MAKING_TRANSFER) - } - - override fun onNext(responseBody: TPTResponse) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } - - data class RequestValues( - val fromClientId: Long, - val toClientId: Long, - val amount: Double, - ) : UseCase.RequestValues - - class ResponseValue : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/CreateClient.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/CreateClient.kt deleted file mode 100644 index fd84e1477..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/CreateClient.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.client - -import com.mifospay.core.model.domain.client.NewClient -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.ErrorJsonMessageHelper.getUserMessage -import retrofit2.HttpException -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class CreateClient( - private val apiRepository: FineractRepository, -) : UseCase() { - - data class RequestValues(val client: NewClient) : UseCase.RequestValues - - data class ResponseValue(val clientId: Int) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - apiRepository.createClient(requestValues.client) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - var message: String - try { - message = - (e as HttpException).response()?.errorBody()?.string().toString() - message = getUserMessage(message) - } catch (e1: Exception) { - message = e1.message.toString() - } - useCaseCallback.onError(message) - } - - override fun onNext(genericResponse: ResponseValue) { - useCaseCallback.onSuccess(genericResponse) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientData.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientData.kt deleted file mode 100644 index ad588cd33..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientData.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.client - -import com.mifospay.core.model.entity.Page -import com.mifospay.core.model.entity.client.Client -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.entity.mapper.ClientDetailsMapper -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchClientData( - private val fineractRepository: FineractRepository, - private val clientDetailsMapper: ClientDetailsMapper, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - requestValues.clientId?.let { clientId -> - fineractRepository.getSelfClientDetails(clientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_CLIENT_DATA) - } - - override fun onNext(client: Client) { - useCaseCallback.onSuccess( - ResponseValue(clientDetailsMapper.transform(client)), - ) - } - }, - ) - } ?: run { - fineractRepository.selfClientDetails - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber>() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_CLIENT_DATA) - } - - override fun onNext(client: Page) { - if (client.pageItems.size != 0) { - useCaseCallback.onSuccess( - ResponseValue(clientDetailsMapper.transform(client.pageItems[0])), - ) - } else { - useCaseCallback.onError(Constants.NO_CLIENT_FOUND) - } - } - }, - ) - } - } - - data class RequestValues(val clientId: Long?) : UseCase.RequestValues - data class ResponseValue( - val clientDetails: com.mifospay.core.model.domain.client.Client, - ) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientDetails.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientDetails.kt deleted file mode 100644 index 3ab9b074f..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientDetails.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.client - -import com.mifospay.core.model.entity.client.Client -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchClientDetails( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - data class RequestValues(val clientId: Long) : UseCase.RequestValues - data class ResponseValue(val client: Client) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.getClientDetails(requestValues.clientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_CLIENT_DATA) - } - - override fun onNext(client: Client) { - useCaseCallback.onSuccess(ResponseValue(client)) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientImage.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientImage.kt deleted file mode 100644 index 90bd05665..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/FetchClientImage.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.client - -import okhttp3.ResponseBody -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.ErrorJsonMessageHelper.getUserMessage -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchClientImage( - private val mFineractRepository: FineractRepository, -) : - UseCase() { - - data class RequestValues(val clientId: Long) : UseCase.RequestValues - data class ResponseValue(val responseBody: ResponseBody) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.getClientImage(requestValues.clientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - getUserMessage(e)?.let { useCaseCallback.onError(it) } - } - - override fun onNext(responseBody: ResponseBody) { - useCaseCallback.onSuccess(ResponseValue(responseBody)) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/SearchClient.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/SearchClient.kt deleted file mode 100644 index 05b882da0..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/SearchClient.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.client - -import com.mifospay.core.model.domain.SearchResult -import com.mifospay.core.model.entity.SearchedEntity -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.entity.mapper.SearchedEntitiesMapper -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class SearchClient( - private val apiRepository: FineractRepository, - private val searchedEntitiesMapper: SearchedEntitiesMapper, -) : UseCase() { - - data class RequestValues(val externalId: String) : UseCase.RequestValues - data class ResponseValue(val results: List) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - apiRepository.searchResources(requestValues.externalId, Constants.CLIENTS, false) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber>() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_SEARCHING_CLIENTS) - } - - override fun onNext(results: List) { - if (results.isNotEmpty()) { - useCaseCallback.onSuccess( - ResponseValue( - searchedEntitiesMapper.transformList(results), - ), - ) - } else { - useCaseCallback.onError(Constants.NO_CLIENTS_FOUND) - } - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/UpdateClient.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/UpdateClient.kt deleted file mode 100644 index 6badef3e6..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/client/UpdateClient.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.client - -import okhttp3.ResponseBody -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.ErrorJsonMessageHelper.getUserMessage -import retrofit2.HttpException -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class UpdateClient( - private val fineractRepository: FineractRepository, -) : UseCase() { - - data class RequestValues(val updateClientEntity: Any, val clientId: Long) : - UseCase.RequestValues - - data class ResponseValue(val responseBody: ResponseBody) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - fineractRepository.updateClient(requestValues.clientId, requestValues.updateClientEntity) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - var message: String - try { - message = - (e as HttpException).response()?.errorBody()?.string().toString() - message = getUserMessage(message) - } catch (e1: Exception) { - message = e1.message.toString() - } - useCaseCallback.onError(message) - } - - override fun onNext(responseBody: ResponseBody) { - useCaseCallback.onSuccess(ResponseValue(responseBody)) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/history/TransactionsHistory.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/history/TransactionsHistory.kt deleted file mode 100644 index 10e105b76..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/history/TransactionsHistory.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.history - -import com.mifospay.core.model.domain.Transaction -import org.mifospay.core.data.base.UseCase.UseCaseCallback -import org.mifospay.core.data.base.UseCaseHandler -import org.mifospay.core.data.domain.usecase.account.FetchAccountTransactions - -class TransactionsHistory( - private val mUseCaseHandler: UseCaseHandler, - private val fetchAccountTransactionsUseCase: FetchAccountTransactions, -) { - var delegate: HistoryContract.TransactionsHistoryAsync? = null - private var transactions: List? - - init { - transactions = ArrayList() - } - - fun fetchTransactionsHistory(accountId: Long) { - mUseCaseHandler.execute( - fetchAccountTransactionsUseCase, - FetchAccountTransactions.RequestValues(accountId), - object : UseCaseCallback { - override fun onSuccess(response: FetchAccountTransactions.ResponseValue?) { - transactions = response?.transactions - delegate!!.onTransactionsFetchCompleted(transactions) - } - - override fun onError(message: String) { - transactions = null - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/invoice/FetchInvoice.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/invoice/FetchInvoice.kt deleted file mode 100644 index 162f9a97d..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/invoice/FetchInvoice.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.invoice - -import android.net.Uri -import android.util.Log -import com.mifospay.core.model.entity.invoice.Invoice -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchInvoice( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - class RequestValues(val uniquePaymentLink: Uri?) : UseCase.RequestValues - class ResponseValue( - val invoices: List, - ) : UseCase.ResponseValue - override fun executeUseCase(requestValues: RequestValues) { - val paymentLink = requestValues.uniquePaymentLink - try { - val params = paymentLink?.pathSegments - val clientId = params?.get(0)?.toLong() // "clientId" - val invoiceId = params?.get(1)?.toLong() // "invoiceId - if (clientId != null && invoiceId != null) { - mFineractRepository.fetchInvoice(clientId, invoiceId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber?>() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.INVALID_UPL) - } - - override fun onNext(invoices: List?) { - if (invoices?.isNotEmpty() == true) { - useCaseCallback.onSuccess(ResponseValue(invoices)) - } else { - useCaseCallback.onError(Constants.INVOICE_DOES_NOT_EXIST) - } - } - }, - ) - } - } catch (e: IndexOutOfBoundsException) { - Log.e("Error", e.message.toString()) - useCaseCallback.onError("Invalid link used to open the App") - } - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/invoice/FetchInvoices.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/invoice/FetchInvoices.kt deleted file mode 100644 index 262a05383..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/invoice/FetchInvoices.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.invoice - -import android.util.Log -import com.mifospay.core.model.entity.invoice.Invoice -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchInvoices( - private val mFineractRepository: FineractRepository, -) : - UseCase() { - - class RequestValues(val clientId: String) : UseCase.RequestValues - class ResponseValue( - val invoiceList: List, - ) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.fetchInvoices(requestValues.clientId.toLong()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber>() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - Log.e("Invoices", e.message.toString()) - useCaseCallback.onError(e.toString()) - } - - override fun onNext(invoices: List) { - Log.d("invoice@@@", invoices.toString()) - useCaseCallback.onSuccess(ResponseValue(invoices)) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/FetchKYCLevel1Details.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/FetchKYCLevel1Details.kt deleted file mode 100644 index 42e9d19c9..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/FetchKYCLevel1Details.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.kyc - -import com.mifospay.core.model.entity.kyc.KYCLevel1Details -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchKYCLevel1Details( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - class RequestValues(val clientId: Int) : UseCase.RequestValues - class ResponseValue( - val kycLevel1DetailsList: List, - ) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.fetchKYCLevel1Details(requestValues.clientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber>() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(kycLevel1Details: List) { - useCaseCallback.onSuccess( - ResponseValue(kycLevel1Details), - ) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UpdateKYCLevel1Details.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UpdateKYCLevel1Details.kt deleted file mode 100644 index 6f232ca29..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UpdateKYCLevel1Details.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.kyc - -import com.mifospay.core.model.entity.kyc.KYCLevel1Details -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.network.GenericResponse -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class UpdateKYCLevel1Details( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - class RequestValues( - val clientId: Int, - val kycLevel1Details: KYCLevel1Details, - ) : UseCase.RequestValues - - class ResponseValue : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.updateKYCLevel1Details( - requestValues.clientId, - requestValues.kycLevel1Details, - ) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(t: GenericResponse) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UploadKYCDocs.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UploadKYCDocs.kt deleted file mode 100644 index 6eb539c1f..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UploadKYCDocs.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.kyc - -import okhttp3.MultipartBody -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.network.GenericResponse -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class UploadKYCDocs( - private val apiRepository: FineractRepository, -) : UseCase() { - - class RequestValues( - val entityType: String, - val clientId: Long, - val docname: String, - val identityType: String, - val file: MultipartBody.Part, - ) : UseCase.RequestValues - - class ResponseValue : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - apiRepository.uploadKYCDocs( - requestValues.entityType, - requestValues.clientId, - requestValues.docname, - requestValues.identityType, - requestValues.file, - ) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(t: GenericResponse) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UploadKYCLevel1Details.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UploadKYCLevel1Details.kt deleted file mode 100644 index 74ace32cb..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/kyc/UploadKYCLevel1Details.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.kyc - -import com.mifospay.core.model.entity.kyc.KYCLevel1Details -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.network.GenericResponse -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class UploadKYCLevel1Details( - var mFineractRepository: FineractRepository, -) : UseCase() { - class RequestValues( - val clientId: Int, - val mKYCLevel1Details: KYCLevel1Details, - ) : UseCase.RequestValues - - class ResponseValue : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.uploadKYCLevel1Details( - requestValues.clientId, - requestValues.mKYCLevel1Details, - ) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(t: GenericResponse) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/notification/FetchNotifications.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/notification/FetchNotifications.kt deleted file mode 100644 index 4237dc12a..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/notification/FetchNotifications.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.notification - -import com.mifospay.core.model.domain.NotificationPayload -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchNotifications( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - class RequestValues(val clientId: Long) : UseCase.RequestValues - class ResponseValue( - val notificationPayloadList: List?, - ) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.fetchNotifications(requestValues.clientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber>() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_NOTIFICATIONS) - } - - override fun onNext(notificationPayloads: List) { - useCaseCallback.onSuccess(ResponseValue(notificationPayloads)) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/AddCard.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/AddCard.kt deleted file mode 100644 index 73bb2bbcc..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/AddCard.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.savedcards - -import com.mifospay.core.model.entity.savedcards.Card -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.network.GenericResponse -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class AddCard( - private val mFineractRepository: FineractRepository, -) : UseCase() { - class RequestValues(val clientId: Long, val card: Card) : UseCase.RequestValues - class ResponseValue : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.addSavedCards(requestValues.clientId, requestValues.card) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(t: GenericResponse?) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/DeleteCard.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/DeleteCard.kt deleted file mode 100644 index c11cb90f0..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/DeleteCard.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.savedcards - -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.network.GenericResponse -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class DeleteCard( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - class RequestValues(val clientId: Int, val cardId: Int) : UseCase.RequestValues - class ResponseValue : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.deleteSavedCard(requestValues.clientId, requestValues.cardId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(t: GenericResponse?) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/EditCard.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/EditCard.kt deleted file mode 100644 index 7f0440b18..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/EditCard.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.savedcards - -import com.mifospay.core.model.entity.savedcards.Card -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.network.GenericResponse -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class EditCard( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - class RequestValues(val clientId: Int, val card: Card) : UseCase.RequestValues - class ResponseValue : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.editSavedCard(requestValues.clientId, requestValues.card) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(t: GenericResponse?) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/FetchSavedCards.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/FetchSavedCards.kt deleted file mode 100644 index 8750008de..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/savedcards/FetchSavedCards.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.savedcards - -import com.mifospay.core.model.entity.savedcards.Card -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchSavedCards( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - class RequestValues(val clientId: Long) : UseCase.RequestValues - class ResponseValue(val cardList: List) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.fetchSavedCards(requestValues.clientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber>() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(cards: List) { - if (cards.isNotEmpty()) { - useCaseCallback.onSuccess(ResponseValue(cards)) - } else { - useCaseCallback.onError(Constants.NO_SAVED_CARDS) - } - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/CreateStandingTransaction.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/CreateStandingTransaction.kt deleted file mode 100644 index 5e4dfd300..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/CreateStandingTransaction.kt +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.standinginstruction - -import com.mifospay.core.model.entity.accounts.savings.SavingAccount -import com.mifospay.core.model.entity.client.Client -import com.mifospay.core.model.entity.client.ClientAccounts -import com.mifospay.core.model.entity.payload.StandingInstructionPayload -import com.mifospay.core.model.entity.standinginstruction.SDIResponse -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class CreateStandingTransaction( - private val apiRepository: FineractRepository, -) : UseCase() { - - lateinit var fromClient: Client - lateinit var toClient: Client - lateinit var fromAccount: SavingAccount - lateinit var toAccount: SavingAccount - - override fun executeUseCase(requestValues: RequestValues) { - apiRepository.getSelfClientDetails(requestValues.fromClientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - - override fun onCompleted() { - } - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_CLIENT_DATA) - } - - override fun onNext(client: Client) { - fromClient = client - fetchToClientData() - } - }, - ) - } - - private fun fetchToClientData() { - apiRepository.getClientDetails(walletRequestValues.toClientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - - override fun onCompleted() { - } - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_CLIENT_DATA) - } - - override fun onNext(client: Client) { - toClient = client - fetchFromAccountDetails() - } - }, - ) - } - - private fun fetchFromAccountDetails() { - apiRepository.getSelfAccounts(walletRequestValues.fromClientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() { - } - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_FROM_ACCOUNT) - } - - override fun onNext(clientAccounts: ClientAccounts) { - val accounts = clientAccounts.savingsAccounts - if (accounts.isNotEmpty()) { - var walletAccount: SavingAccount? = null - for (account in accounts) { - if (account.productId == - Constants.WALLET_ACCOUNT_SAVINGS_PRODUCT_ID - ) { - walletAccount = account - break - } - } - walletAccount?.let { - fromAccount = walletAccount - fetchToAccountDetails() - } ?: useCaseCallback.onError(Constants.NO_WALLET_FOUND) - } else { - useCaseCallback.onError(Constants.ERROR_FETCHING_FROM_ACCOUNT) - } - } - }, - ) - } - - private fun fetchToAccountDetails() { - apiRepository.getAccounts(walletRequestValues.toClientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_TO_ACCOUNT) - } - - override fun onNext(clientAccounts: ClientAccounts) { - val accounts = clientAccounts.savingsAccounts - if (accounts.isNotEmpty()) { - var walletAccount: SavingAccount? = null - for (account in accounts) { - if (account.productId == - Constants.WALLET_ACCOUNT_SAVINGS_PRODUCT_ID - ) { - walletAccount = account - break - } - } - walletAccount?.let { - toAccount = walletAccount - createNewStandingInstruction() - } ?: useCaseCallback.onError(Constants.NO_WALLET_FOUND) - } else { - useCaseCallback.onError(Constants.ERROR_FETCHING_TO_ACCOUNT) - } - } - }, - ) - } - - private fun createNewStandingInstruction() { - val standingInstructionPayload = StandingInstructionPayload( - fromClient.officeId, - fromClient.id, - 2, - "wallet standing transaction", - 1, - 2, - 1, - fromAccount.id, - toClient.officeId, - toClient.id, - 2, - toAccount.id, - 1, - walletRequestValues.amount, - walletRequestValues.validFrom, - 1, - walletRequestValues.recurrenceInterval, - 2, - "en", - "dd MM yyyy", - walletRequestValues.validTill, - walletRequestValues.recurrenceOnDayMonth, - "dd MM", - ) - apiRepository.createStandingInstruction(standingInstructionPayload) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - - override fun onCompleted() { - } - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_MAKING_TRANSFER) - } - - override fun onNext(sdiResponse: SDIResponse) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } - - class RequestValues( - val validTill: String, - val validFrom: String, - val recurrenceInterval: Int, - val recurrenceOnDayMonth: String, - val fromClientId: Long, - val toClientId: Long, - val amount: Double, - ) : UseCase.RequestValues - - class ResponseValue : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/DeleteStandingInstruction.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/DeleteStandingInstruction.kt deleted file mode 100644 index 569a9149b..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/DeleteStandingInstruction.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.standinginstruction - -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.network.GenericResponse -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class DeleteStandingInstruction( - private val apiRepository: FineractRepository, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - apiRepository.deleteStandingInstruction(requestValues.standingInstructionId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - - override fun onCompleted() { - } - - override fun onError(e: Throwable) { - e.message?.let { useCaseCallback.onError(it) } - } - - override fun onNext(genericResponse: GenericResponse) = - useCaseCallback.onSuccess(ResponseValue()) - }, - ) - } - - class RequestValues(val standingInstructionId: Long) : - UseCase.RequestValues - - class ResponseValue : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/FetchStandingInstruction.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/FetchStandingInstruction.kt deleted file mode 100644 index 8e165f333..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/FetchStandingInstruction.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.standinginstruction - -import com.mifospay.core.model.entity.standinginstruction.StandingInstruction -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchStandingInstruction( - private val apiRepository: FineractRepository, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - apiRepository.getStandingInstruction(requestValues.standingInstructionId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - - override fun onCompleted() { - } - - override fun onError(e: Throwable) { - e.message?.let { useCaseCallback.onError(it) } - } - - override fun onNext(standingInstruction: StandingInstruction) = - useCaseCallback.onSuccess(ResponseValue(standingInstruction)) - }, - ) - } - - class RequestValues(val standingInstructionId: Long) : UseCase.RequestValues - - class ResponseValue(val standingInstruction: StandingInstruction) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/GetAllStandingInstructions.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/GetAllStandingInstructions.kt deleted file mode 100644 index 1e4338704..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/GetAllStandingInstructions.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.standinginstruction - -import com.mifospay.core.model.entity.Page -import com.mifospay.core.model.entity.standinginstruction.StandingInstruction -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class GetAllStandingInstructions( - private val apiRepository: FineractRepository, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - apiRepository.getAllStandingInstructions(requestValues.clientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber>() { - - override fun onCompleted() { - } - - override fun onError(e: Throwable) { - e.message?.let { useCaseCallback.onError(it) } - } - - override fun onNext(standingInstructionPage: Page) { - return useCaseCallback.onSuccess( - ResponseValue(standingInstructionPage.pageItems), - ) - } - }, - ) - } - - class RequestValues(val clientId: Long) : UseCase.RequestValues - - class ResponseValue(val standingInstructionsList: List) : - UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/UpdateStandingInstruction.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/UpdateStandingInstruction.kt deleted file mode 100644 index 8eef580b2..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/standinginstruction/UpdateStandingInstruction.kt +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.standinginstruction - -import com.mifospay.core.model.entity.payload.StandingInstructionPayload -import com.mifospay.core.model.entity.standinginstruction.StandingInstruction -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.network.GenericResponse -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class UpdateStandingInstruction( - private val apiRepository: FineractRepository, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - val validTillString = "${requestValues.standingInstruction.validTill?.get(2)} " + - "${requestValues.standingInstruction.validTill?.get(1)} " + - "${requestValues.standingInstruction.validTill?.get(0)}" - val validFromString = "${requestValues.standingInstruction.validFrom[2]} " + - "${requestValues.standingInstruction.validFrom[1]} " + - "${requestValues.standingInstruction.validFrom[0]}" - val recurrenceOnMonthDayString = "${requestValues.standingInstruction.validFrom[2]} " + - "${requestValues.standingInstruction.validFrom[1]}" - - val standingInstructionPayload = StandingInstructionPayload( - requestValues.standingInstruction.fromClient.officeId, - requestValues.standingInstruction.fromClient.id, - 2, - "wallet standing transaction", - 1, - 2, - 1, - requestValues.standingInstruction.fromAccount.id, - requestValues.standingInstruction.toClient.officeId, - requestValues.standingInstruction.toClient.id, - 2, - requestValues.standingInstruction.toAccount.id, - 1, - requestValues.standingInstruction.amount, - validFromString, - 1, - 1, - 2, - "en", - "dd MM yyyy", - validTillString, - recurrenceOnMonthDayString, - "dd MM", - ) - - apiRepository.updateStandingInstruction( - requestValues.standingInstructionId, - standingInstructionPayload, - ) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - - override fun onCompleted() { - } - - override fun onError(e: Throwable) { - e.message?.let { useCaseCallback.onError(it) } - } - - override fun onNext(genericResponse: GenericResponse) = - useCaseCallback.onSuccess(ResponseValue()) - }, - ) - } - - class RequestValues( - val standingInstructionId: Long, - val standingInstruction: StandingInstruction, - ) : UseCase.RequestValues - - class ResponseValue : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/FetchDeliveryMethods.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/FetchDeliveryMethods.kt deleted file mode 100644 index 29cf2bb7c..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/FetchDeliveryMethods.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.twofactor - -import com.mifospay.core.model.domain.twofactor.DeliveryMethod -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchDeliveryMethods( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - class RequestValues : UseCase.RequestValues - class ResponseValue( - val deliveryMethodList: List, - ) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.deliveryMethods - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber>() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(deliveryMethods: List) { - useCaseCallback.onSuccess(ResponseValue(deliveryMethods)) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/RequestOTP.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/RequestOTP.kt deleted file mode 100644 index 004806f96..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/RequestOTP.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.twofactor - -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class RequestOTP( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - class RequestValues(val deliveryMethod: String) : UseCase.RequestValues - class ResponseValue(val response: String) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.requestOTP(requestValues.deliveryMethod) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(response: String) { - useCaseCallback.onSuccess(ResponseValue(response)) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/ValidateOTP.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/ValidateOTP.kt deleted file mode 100644 index 1249e58be..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/twofactor/ValidateOTP.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.twofactor - -import com.mifospay.core.model.domain.twofactor.AccessToken -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class ValidateOTP( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - class RequestValues(val token: String) : UseCase.RequestValues - class ResponseValue(val accessToken: AccessToken) : UseCase.ResponseValue - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.validateToken(requestValues.token) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(accessToken: AccessToken) { - useCaseCallback.onSuccess(ResponseValue(accessToken)) - } - }, - ) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/AuthenticateUser.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/AuthenticateUser.kt deleted file mode 100644 index c849b1261..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/AuthenticateUser.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.user - -import com.mifospay.core.model.domain.user.User -import com.mifospay.core.model.entity.authentication.AuthenticationPayload -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants - -class AuthenticateUser( - private val apiRepository: FineractRepository, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - CoroutineScope(Dispatchers.IO).launch { - try { - val user = apiRepository.loginSelf( - AuthenticationPayload(requestValues.username, requestValues.password), - ) - withContext(Dispatchers.Main) { - useCaseCallback.onSuccess(ResponseValue(user)) - } - } catch (e: Exception) { - withContext(Dispatchers.Main) { - useCaseCallback.onError(Constants.ERROR_LOGGING_IN) - } - } - } - } - - data class RequestValues(val username: String, val password: String) : UseCase.RequestValues - data class ResponseValue(val user: User) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/CreateUser.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/CreateUser.kt deleted file mode 100644 index 79f056b70..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/CreateUser.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.user - -import com.mifospay.core.model.domain.user.NewUser -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.ErrorJsonMessageHelper.getUserMessage -import retrofit2.HttpException -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class CreateUser(private val apiRepository: FineractRepository) : - UseCase() { - override fun executeUseCase(requestValues: RequestValues) { - apiRepository.createUser(requestValues.user) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - getUserMessage(e) - var message: String - try { - message = (e as HttpException).response()!!.errorBody()!!.string() - message = getUserMessage(message) - } catch (e1: Exception) { - message = e1.message.toString() - } - useCaseCallback.onError(message) - } - - override fun onNext(genericResponse: ResponseValue) { - useCaseCallback.onSuccess(genericResponse) - } - }, - ) - } - - class RequestValues(val user: NewUser) : UseCase.RequestValues - class ResponseValue(val userId: Int) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/DeleteUser.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/DeleteUser.kt deleted file mode 100644 index 2a537345f..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/DeleteUser.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.user - -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.network.GenericResponse -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class DeleteUser( - private val mFineractRepository: FineractRepository, -) : UseCase() { - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.deleteUser(requestValues.userId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - e.message?.let { useCaseCallback.onError(it) } - } - - override fun onNext(genericResponse: GenericResponse) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } - - class RequestValues(val userId: Int) : UseCase.RequestValues - class ResponseValue : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/FetchUserDetails.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/FetchUserDetails.kt deleted file mode 100644 index 153e46ee0..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/FetchUserDetails.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.user - -import com.mifospay.core.model.entity.UserWithRole -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchUserDetails( - private val mFineractRepository: FineractRepository, -) : UseCase() { - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.getUser() - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - e.message?.let { useCaseCallback.onError(it) } - } - - override fun onNext(userWithRole: UserWithRole) { - useCaseCallback.onSuccess(ResponseValue(userWithRole)) - } - }, - ) - } - - class RequestValues(val userId: Long) : UseCase.RequestValues - class ResponseValue(val userWithRole: UserWithRole) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/FetchUsers.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/FetchUsers.kt deleted file mode 100644 index 61340673a..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/FetchUsers.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.user - -import com.mifospay.core.model.entity.UserWithRole -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchUsers( - private val mFineractRepository: FineractRepository, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.users - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe(object : Subscriber>() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(e.toString()) - } - - override fun onNext(userWithRoles: List) { - val tbp: MutableList = ArrayList() - for (userWithRole in userWithRoles) { - for ((_, name) in userWithRole.selectedRoles!!) { - if (name == Constants.MERCHANT) { - tbp.add(userWithRole) - break - } - } - } - useCaseCallback.onSuccess(ResponseValue(tbp)) - } - }) - } - - class RequestValues : UseCase.RequestValues - data class ResponseValue(val userWithRoleList: List) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/RegisterUser.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/RegisterUser.kt deleted file mode 100644 index f37d1df98..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/RegisterUser.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.user - -import com.mifospay.core.model.entity.register.RegisterPayload -import okhttp3.ResponseBody -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class RegisterUser( - private val apiRepository: FineractRepository, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - apiRepository.registerUser(requestValues.registerPayload) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_REGISTERING_USER) - } - - override fun onNext(t: ResponseBody?) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } - - data class RequestValues(val registerPayload: RegisterPayload) : UseCase.RequestValues - class ResponseValue : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/UpdateUser.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/UpdateUser.kt deleted file mode 100644 index 9fac23150..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/UpdateUser.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.user - -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.ErrorJsonMessageHelper.getUserMessage -import org.mifospay.core.network.GenericResponse -import retrofit2.HttpException -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class UpdateUser( - private val mFineractRepository: FineractRepository, -) : UseCase() { - override fun executeUseCase(requestValues: RequestValues) { - mFineractRepository.updateUser(requestValues.updateUserEntity, requestValues.userId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - var message: String - try { - message = (e as HttpException).response()!!.errorBody()!!.string() - message = getUserMessage(message) - } catch (e1: Exception) { - message = e1.message.toString() - } - useCaseCallback.onError(message) - } - - override fun onNext(genericResponse: GenericResponse?) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } - - class RequestValues(val updateUserEntity: Any, val userId: Int) : UseCase.RequestValues - - class ResponseValue : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/VerifyUser.kt b/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/VerifyUser.kt deleted file mode 100644 index d946eff90..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/domain/usecase/user/VerifyUser.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.domain.usecase.user - -import com.mifospay.core.model.entity.register.UserVerify -import okhttp3.ResponseBody -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class VerifyUser( - private val apiRepository: FineractRepository, -) : UseCase() { - override fun executeUseCase(requestValues: RequestValues) { - apiRepository.verifyUser(requestValues.userVerify) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe( - object : Subscriber() { - override fun onCompleted() {} - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_VERIFYING_USER) - } - - override fun onNext(t: ResponseBody?) { - useCaseCallback.onSuccess(ResponseValue()) - } - }, - ) - } - - class RequestValues(val userVerify: UserVerify) : UseCase.RequestValues - class ResponseValue : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/AccountMapper.kt b/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/AccountMapper.kt deleted file mode 100644 index 672f1a393..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/AccountMapper.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.fineract.entity.mapper - -import com.mifospay.core.model.domain.Account -import com.mifospay.core.model.entity.client.ClientAccounts - -class AccountMapper( - private val currencyMapper: CurrencyMapper, -) { - - fun transform(clientAccounts: ClientAccounts?): List { - val accountList = mutableListOf() - - clientAccounts?.savingsAccounts?.forEach { savingAccount -> - val account = Account( - name = savingAccount.productName, - number = savingAccount.accountNo, - id = savingAccount.id, - balance = savingAccount.accountBalance, - currency = currencyMapper.transform(savingAccount.currency), - productId = savingAccount.productId.toLong(), - ) - accountList.add(account) - } - return accountList - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/ClientDetailsMapper.kt b/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/ClientDetailsMapper.kt deleted file mode 100644 index eccd4a613..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/ClientDetailsMapper.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.fineract.entity.mapper - -import com.mifospay.core.model.entity.client.Client -import com.mifospay.core.model.domain.client.Client as DomainClient - -class ClientDetailsMapper { - fun transformList(clients: List?): List { - val clientList: MutableList = ArrayList() - clients?.forEach { client -> - clientList.add(transform(client)) - } - return clientList - } - - fun transform(client: Client?): DomainClient { - val clientDetails = DomainClient() - if (client != null) { - clientDetails.name = client.displayName - clientDetails.clientId = client.id.toLong() - clientDetails.externalId = client.externalId - clientDetails.mobileNo = client.mobileNo - } - return clientDetails - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/CurrencyMapper.kt b/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/CurrencyMapper.kt deleted file mode 100644 index 21270ee2d..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/CurrencyMapper.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.fineract.entity.mapper - -import com.mifospay.core.model.entity.accounts.savings.Currency -import com.mifospay.core.model.domain.Currency as DomainCurrency - -class CurrencyMapper { - fun transform(savingsCurrency: Currency): DomainCurrency { - val currency = DomainCurrency() - currency.code = savingsCurrency.code - currency.displayLabel = savingsCurrency.displayLabel - currency.displaySymbol = savingsCurrency.displaySymbol - return currency - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/FetchAccount.kt b/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/FetchAccount.kt deleted file mode 100644 index d21aa0b8e..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/FetchAccount.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.fineract.entity.mapper - -import com.mifospay.core.model.domain.Account -import com.mifospay.core.model.entity.client.ClientAccounts -import org.mifospay.core.data.base.UseCase -import org.mifospay.core.data.fineract.repository.FineractRepository -import org.mifospay.core.data.util.Constants -import rx.Subscriber -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers - -class FetchAccount( - private val fineractRepository: FineractRepository, - private val accountMapper: AccountMapper, -) : UseCase() { - - override fun executeUseCase(requestValues: RequestValues) { - fineractRepository.getSelfAccounts(requestValues.clientId) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeOn(Schedulers.io()) - .subscribe(object : Subscriber() { - override fun onCompleted() {} - - override fun onError(e: Throwable) { - useCaseCallback.onError(Constants.ERROR_FETCHING_ACCOUNTS) - } - - override fun onNext(clientAccounts: ClientAccounts) { - val accounts: List = accountMapper.transform(clientAccounts) - if (accounts.isNotEmpty()) { - var walletAccount: Account? = null - for (account in accounts) { - if (account.productId.toInt() == Constants.WALLET_ACCOUNT_SAVINGS_PRODUCT_ID) { - walletAccount = account - break - } - } - if (walletAccount != null) { - useCaseCallback.onSuccess(ResponseValue(walletAccount)) - } else { - useCaseCallback.onError(Constants.NO_ACCOUNT_FOUND) - } - } else { - useCaseCallback.onError(Constants.NO_ACCOUNTS_FOUND) - } - } - }) - } - - data class RequestValues(val clientId: Long) : UseCase.RequestValues - - data class ResponseValue(val account: Account) : UseCase.ResponseValue -} diff --git a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/SearchedEntitiesMapper.kt b/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/SearchedEntitiesMapper.kt deleted file mode 100644 index affc21632..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/SearchedEntitiesMapper.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.fineract.entity.mapper - -import com.mifospay.core.model.domain.SearchResult -import com.mifospay.core.model.entity.SearchedEntity - -class SearchedEntitiesMapper { - fun transformList(searchedEntities: List?): List { - val searchResults: MutableList = ArrayList() - - searchedEntities?.forEach { entity -> - searchResults.add(transform(entity)) - } - - return searchResults - } - - fun transform(searchedEntity: SearchedEntity): SearchResult { - val searchResult = SearchResult() - searchResult.resultId = searchedEntity.entityId - searchResult.resultName = searchedEntity.entityName - searchResult.resultType = searchedEntity.entityType - return searchResult - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/TransactionMapper.kt b/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/TransactionMapper.kt deleted file mode 100644 index 340298508..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/fineract/entity/mapper/TransactionMapper.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.fineract.entity.mapper - -import com.mifospay.core.model.domain.Transaction -import com.mifospay.core.model.domain.TransactionType -import com.mifospay.core.model.entity.accounts.savings.SavingsWithAssociations -import com.mifospay.core.model.entity.accounts.savings.Transactions -import com.mifospay.core.model.utils.DateHelper - -class TransactionMapper( - private val currencyMapper: CurrencyMapper, -) { - - fun transformTransactionList(savingsWithAssociations: SavingsWithAssociations?): List { - val transactionList = ArrayList() - - savingsWithAssociations?.transactions?.forEach { transaction -> - transactionList.add(transformInvoice(transaction)) - } - return transactionList - } - - fun transformInvoice(transactions: Transactions?): Transaction { - val transaction = Transaction() - - if (transactions != null) { - transaction.transactionId = transactions.id.toString() - transactions.paymentDetailData?.let { - transaction.receiptId = it.receiptNumber - } - transaction.amount = transactions.amount - transactions.submittedOnDate.let { - transaction.date = DateHelper.getDateAsString(it) - } - transaction.currency = currencyMapper.transform(transactions.currency) - transaction.transactionType = TransactionType.OTHER - - if (transactions.transactionType.deposit) { - transaction.transactionType = TransactionType.CREDIT - } - - if (transactions.transactionType.withdrawal) { - transaction.transactionType = TransactionType.DEBIT - } - - transactions.transfer.let { - transaction.transferId = it.id - } - } - return transaction - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/fineract/repository/FineractRepository.kt b/core/data/src/main/java/org/mifospay/core/data/fineract/repository/FineractRepository.kt deleted file mode 100644 index 89e7e7a53..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/fineract/repository/FineractRepository.kt +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.fineract.repository - -import com.mifospay.core.model.domain.NewAccount -import com.mifospay.core.model.domain.NotificationPayload -import com.mifospay.core.model.domain.client.NewClient -import com.mifospay.core.model.domain.twofactor.AccessToken -import com.mifospay.core.model.domain.twofactor.DeliveryMethod -import com.mifospay.core.model.domain.user.NewUser -import com.mifospay.core.model.domain.user.User -import com.mifospay.core.model.entity.Page -import com.mifospay.core.model.entity.SearchedEntity -import com.mifospay.core.model.entity.TPTResponse -import com.mifospay.core.model.entity.UserWithRole -import com.mifospay.core.model.entity.accounts.savings.SavingsWithAssociations -import com.mifospay.core.model.entity.accounts.savings.Transactions -import com.mifospay.core.model.entity.accounts.savings.TransferDetail -import com.mifospay.core.model.entity.authentication.AuthenticationPayload -import com.mifospay.core.model.entity.beneficary.Beneficiary -import com.mifospay.core.model.entity.beneficary.BeneficiaryPayload -import com.mifospay.core.model.entity.beneficary.BeneficiaryUpdatePayload -import com.mifospay.core.model.entity.client.Client -import com.mifospay.core.model.entity.client.ClientAccounts -import com.mifospay.core.model.entity.invoice.Invoice -import com.mifospay.core.model.entity.invoice.InvoiceEntity -import com.mifospay.core.model.entity.kyc.KYCLevel1Details -import com.mifospay.core.model.entity.payload.StandingInstructionPayload -import com.mifospay.core.model.entity.payload.TransferPayload -import com.mifospay.core.model.entity.register.RegisterPayload -import com.mifospay.core.model.entity.register.UserVerify -import com.mifospay.core.model.entity.savedcards.Card -import com.mifospay.core.model.entity.standinginstruction.SDIResponse -import com.mifospay.core.model.entity.standinginstruction.StandingInstruction -import okhttp3.MultipartBody -import okhttp3.ResponseBody -import org.mifospay.core.data.domain.usecase.client.CreateClient -import org.mifospay.core.data.domain.usecase.user.CreateUser -import org.mifospay.core.data.util.Constants -import org.mifospay.core.network.FineractApiManager -import org.mifospay.core.network.GenericResponse -import org.mifospay.core.network.SelfServiceApiManager -import org.mifospay.core.network.services.KtorAuthenticationService -import rx.Observable - -@Suppress("TooManyFunctions") -class FineractRepository( - private val fineractApiManager: FineractApiManager, - private val selfApiManager: SelfServiceApiManager, - private val ktorAuthenticationService: KtorAuthenticationService, -) { - fun createClient(newClient: NewClient): Observable { - return fineractApiManager.clientsApi.createClient(newClient) - } - - fun createUser(user: NewUser): Observable { - return fineractApiManager.userApi.createUser(user) - } - - fun updateUser(updateUserEntity: Any, userId: Int): Observable { - return fineractApiManager.userApi.updateUser(userId, updateUserEntity) - } - - fun registerUser(registerPayload: RegisterPayload): Observable { - return fineractApiManager.registrationAPi.registerUser(registerPayload) - } - - fun deleteUser(userId: Int): Observable { - return fineractApiManager.userApi.deleteUser(userId) - } - - fun verifyUser(userVerify: UserVerify): Observable { - return fineractApiManager.registrationAPi.verifyUser(userVerify) - } - - fun searchResources( - query: String, - resources: String, - exactMatch: Boolean, - ): Observable> { - return fineractApiManager.searchApi.searchResources(query, resources, exactMatch) - } - - fun updateClient(clientId: Long, payload: Any): Observable { - return fineractApiManager.clientsApi.updateClient(clientId, payload) - .map { responseBody -> responseBody } - } - - fun createSavingsAccount(newAccount: NewAccount?): Observable { - return fineractApiManager.clientsApi.createAccount(newAccount) - } - - fun getAccounts(clientId: Long): Observable { - return fineractApiManager.clientsApi.getAccounts(clientId, Constants.SAVINGS) - } - - suspend fun savingsAccounts(): Page = - fineractApiManager.ktorSavingsAccountApi.getSavingsAccounts(-1) - - suspend fun blockUnblockAccount(accountId: Long, command: String?): GenericResponse { - return fineractApiManager.ktorSavingsAccountApi.blockUnblockAccount( - accountId, - command, - ) - } - - fun getClientDetails(clientId: Long): Observable { - return fineractApiManager.clientsApi.getClientForId(clientId) - } - - fun getClientImage(clientId: Long): Observable { - return fineractApiManager.clientsApi.getClientImage(clientId) - } - - fun addSavedCards( - clientId: Long, - card: Card, - ): Observable { - return fineractApiManager.savedCardApi.addSavedCard(clientId.toInt(), card) - } - - fun fetchSavedCards(clientId: Long): Observable> { - return fineractApiManager.savedCardApi.getSavedCards(clientId.toInt()) - } - - fun editSavedCard(clientId: Int, card: Card): Observable { - return fineractApiManager.savedCardApi.updateCard(clientId, card.id, card) - } - - fun deleteSavedCard(clientId: Int, cardId: Int): Observable { - return fineractApiManager.savedCardApi.deleteCard(clientId, cardId) - } - - fun uploadKYCDocs( - entityType: String, - entityId: Long, - name: String, - desc: String, - file: MultipartBody.Part, - ): Observable { - return fineractApiManager.documentApi.createDocument( - entityType, - entityId, - name, - desc, - file, - ) - } - - fun getAccountTransfer(transferId: Long): Observable { - return fineractApiManager.accountTransfersApi.getAccountTransfer(transferId) - } - - fun uploadKYCLevel1Details( - clientId: Int, - kycLevel1Details: KYCLevel1Details, - ): Observable { - return fineractApiManager.kycLevel1Api.addKYCLevel1Details( - clientId, - kycLevel1Details, - ) - } - - fun fetchKYCLevel1Details(clientId: Int): Observable> { - return fineractApiManager.kycLevel1Api.fetchKYCLevel1Details(clientId) - } - - fun updateKYCLevel1Details( - clientId: Int, - kycLevel1Details: KYCLevel1Details, - ): Observable { - return fineractApiManager.kycLevel1Api.updateKYCLevel1Details( - clientId, - kycLevel1Details, - ) - } - - fun fetchNotifications(clientId: Long): Observable> { - return fineractApiManager.notificationApi.fetchNotifications(clientId) - } - - val deliveryMethods: Observable> - get() = fineractApiManager.twoFactorAuthApi.deliveryMethods - - fun requestOTP(deliveryMethod: String): Observable { - return fineractApiManager.twoFactorAuthApi.requestOTP(deliveryMethod) - } - - fun validateToken(token: String): Observable { - return fineractApiManager.twoFactorAuthApi.validateToken(token) - } - - fun getTransactionReceipt( - outputType: String, - transactionId: String, - ): Observable { - return fineractApiManager.runReportApi.getTransactionReceipt( - outputType, - transactionId, - ) - } - - fun addInvoice(clientId: Long, invoice: InvoiceEntity?): Observable { - return Observable.fromCallable { - fineractApiManager.invoiceApi.addInvoice(clientId, invoice) - } - } - - fun fetchInvoices(clientId: Long): Observable> { - return fineractApiManager.invoiceApi.getInvoices(clientId) - } - - fun fetchInvoice(clientId: Long, invoiceId: Long): Observable> { - return fineractApiManager.invoiceApi.getInvoice(clientId, invoiceId) - } - - fun editInvoice(clientId: Long, invoice: Invoice): Observable { - return Observable.fromCallable { - fineractApiManager.invoiceApi.updateInvoice(clientId, invoice.id, invoice) - } - } - - fun deleteInvoice(clientId: Long, invoiceId: Long): Observable { - return Observable.fromCallable { - fineractApiManager.invoiceApi.deleteInvoice(clientId, invoiceId) - } - } - - val users: Observable> - get() = fineractApiManager.userApi.users - - fun getUser(): Observable { - return fineractApiManager.userApi.getUser() - } - - fun makeThirdPartyTransfer(transferPayload: TransferPayload): Observable { - return fineractApiManager.thirdPartyTransferApi.makeTransfer(transferPayload) - } - - fun createStandingInstruction( - standingInstructionPayload: StandingInstructionPayload, - ): Observable { - return fineractApiManager.standingInstructionApi - .createStandingInstruction(standingInstructionPayload) - } - - fun getAllStandingInstructions(clientId: Long): Observable> { - return fineractApiManager.standingInstructionApi.getAllStandingInstructions(clientId) - } - - fun getStandingInstruction(standingInstructionId: Long): Observable { - return fineractApiManager.standingInstructionApi - .getStandingInstruction(standingInstructionId) - } - - fun updateStandingInstruction( - standingInstructionId: Long, - data: StandingInstructionPayload, - ): Observable { - return fineractApiManager.standingInstructionApi.updateStandingInstruction( - standingInstructionId, - data, - "update", - ) - } - - fun deleteStandingInstruction(standingInstruction: Long): Observable { - return fineractApiManager.standingInstructionApi.deleteStandingInstruction( - standingInstruction, - "delete", - ) - } - - // self user apis - suspend fun loginSelf(payload: AuthenticationPayload): User { - return ktorAuthenticationService.authenticate(payload) - } - - fun getSelfClientDetails(clientId: Long): Observable { - return selfApiManager.clientsApi.getClientForId(clientId) - } - - val selfClientDetails: Observable> - get() = selfApiManager.clientsApi.clients - - suspend fun getSelfAccountTransactions(accountId: Long): SavingsWithAssociations { - return selfApiManager.ktorSavingsAccountApi.getSavingsWithAssociations( - accountId, - Constants.TRANSACTIONS, - ) - } - - suspend fun getSelfAccountTransactionFromId( - accountId: Long, - transactionId: Long, - ): Transactions { - return selfApiManager.ktorSavingsAccountApi.getSavingAccountTransaction( - accountId, - transactionId, - ) - } - - fun getSelfAccounts(clientId: Long): Observable { - return selfApiManager.clientsApi.getAccounts(clientId, Constants.SAVINGS) - } - - val beneficiaryList: Observable> - get() = selfApiManager.beneficiaryApi.beneficiaryList - - fun createBeneficiary(beneficiaryPayload: BeneficiaryPayload): Observable { - return selfApiManager.beneficiaryApi.createBeneficiary(beneficiaryPayload) - } - - fun updateBeneficiary( - beneficiaryId: Long, - payload: BeneficiaryUpdatePayload, - ): Observable { - return selfApiManager.beneficiaryApi.updateBeneficiary(beneficiaryId, payload) - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/repository/auth/AuthenticationUserRepository.kt b/core/data/src/main/java/org/mifospay/core/data/repository/auth/AuthenticationUserRepository.kt deleted file mode 100644 index 70cc1a2c3..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/repository/auth/AuthenticationUserRepository.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.repository.auth - -import com.mifospay.core.model.UserData -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import org.mifospay.core.datastore.PreferencesHelper - -class AuthenticationUserRepository( - private val preferencesHelper: PreferencesHelper, -) : UserDataRepository { - - override val userData: Flow = flow { - emit( - UserData( - isAuthenticated = !preferencesHelper.token.isNullOrEmpty(), - userName = preferencesHelper.username, - // user = preferencesHelper.user, - clientId = preferencesHelper.clientId, - ), - ) - } - - override fun logOut() { - preferencesHelper.clear() - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/repository/local/LocalRepository.kt b/core/data/src/main/java/org/mifospay/core/data/repository/local/LocalRepository.kt deleted file mode 100644 index de55915ed..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/repository/local/LocalRepository.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.repository.local - -import com.mifospay.core.model.domain.client.Client -import org.mifospay.core.datastore.PreferencesHelper - -class LocalRepository( - val preferencesHelper: PreferencesHelper, -) { - - val clientDetails: Client - get() { - val details = Client() - details.name = preferencesHelper.fullName - details.clientId = preferencesHelper.clientId - details.externalId = preferencesHelper.clientVpa - return details - } - - fun saveClientData(client: Client) { - preferencesHelper.saveFullName(client.name) - preferencesHelper.clientId = client.clientId - preferencesHelper.clientVpa = client.externalId - } -} diff --git a/core/data/src/main/java/org/mifospay/core/data/repository/local/MifosLocalAssetRepository.kt b/core/data/src/main/java/org/mifospay/core/data/repository/local/MifosLocalAssetRepository.kt deleted file mode 100644 index 4456a8363..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/repository/local/MifosLocalAssetRepository.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.repository.local - -import com.mifospay.core.model.City -import com.mifospay.core.model.Country -import com.mifospay.core.model.State -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.flowOn -import org.mifospay.core.network.localAssets.LocalAssetDataSource - -/** - * Local implementation of the [LocalAssetRepository] that retrieves the countries, banks, cities - * and state list from a JSON String. - * - */ - -class MifosLocalAssetRepository( - private val ioDispatcher: CoroutineDispatcher, - private val datasource: LocalAssetDataSource, -) : LocalAssetRepository { - - override fun getCountries(): Flow> = flow { - emit(datasource.getCountries()) - }.flowOn(ioDispatcher) - - override fun getStateList(): Flow> = flow { - emit(datasource.getStateList()) - }.flowOn(ioDispatcher) - - override fun getBanks(): Flow> = flow { - emit(datasource.getBanks()) - }.flowOn(ioDispatcher) - - override fun getCities(): Flow> = flow { - emit(datasource.getCities()) - }.flowOn(ioDispatcher) -} diff --git a/core/data/src/main/java/org/mifospay/core/data/util/ErrorJsonMessageHelper.kt b/core/data/src/main/java/org/mifospay/core/data/util/ErrorJsonMessageHelper.kt deleted file mode 100644 index db17053e7..000000000 --- a/core/data/src/main/java/org/mifospay/core/data/util/ErrorJsonMessageHelper.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.data.util - -import org.json.JSONException -import org.json.JSONObject -import retrofit2.HttpException - -object ErrorJsonMessageHelper { - @JvmStatic - @Throws(JSONException::class) - fun getUserMessage(message: String?): String { - val jsonObject = JSONObject(message) - return jsonObject.getJSONArray("errors") - .getJSONObject(0).getString("defaultUserMessage") - } - - @JvmStatic - fun getUserMessage(e: Throwable): String? { - var message: String? - try { - message = (e as HttpException).response()?.errorBody()?.string().toString() - message = getUserMessage(message) - } catch (e1: Exception) { - message = e1.message.toString() - } - return message - } -} diff --git a/core/data/src/nativeMain/kotlin/org/mifospay/core/data/NativePlatformDependentDataModule.kt b/core/data/src/nativeMain/kotlin/org/mifospay/core/data/NativePlatformDependentDataModule.kt new file mode 100644 index 000000000..0bc0489c2 --- /dev/null +++ b/core/data/src/nativeMain/kotlin/org/mifospay/core/data/NativePlatformDependentDataModule.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf +import kotlinx.datetime.TimeZone +import org.mifospay.core.data.di.PlatformDependentDataModule +import org.mifospay.core.data.util.NetworkMonitor +import org.mifospay.core.data.util.TimeZoneMonitor + +class NativePlatformDependentDataModule : PlatformDependentDataModule { + override val networkMonitor: NetworkMonitor by lazy { + object : NetworkMonitor { + override val isOnline: Flow = flowOf(true) + } + } + + override val timeZoneMonitor: TimeZoneMonitor by lazy { + object : TimeZoneMonitor { + override val currentTimeZone: Flow = flowOf(TimeZone.currentSystemDefault()) + } + } +} diff --git a/core/data/src/nativeMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.native.kt b/core/data/src/nativeMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.native.kt new file mode 100644 index 000000000..0b6e1b1f8 --- /dev/null +++ b/core/data/src/nativeMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.native.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.di + +import org.koin.core.module.Module +import org.koin.dsl.module +import org.mifospay.core.data.NativePlatformDependentDataModule + +actual val getPlatformDataModule: PlatformDependentDataModule + get() = NativePlatformDependentDataModule() + +actual val platformModule: Module + get() = module { + single { getPlatformDataModule } + } diff --git a/core/data/src/test/java/org/mifospay/mobilewallet/core/ExampleUnitTest.kt b/core/data/src/test/java/org/mifospay/mobilewallet/core/ExampleUnitTest.kt deleted file mode 100644 index abad7a3e6..000000000 --- a/core/data/src/test/java/org/mifospay/mobilewallet/core/ExampleUnitTest.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.mobilewallet.core - -import org.junit.Assert -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see [Testing documentation](http://d.android.com/tools/testing) - */ -class ExampleUnitTest { - @Test - @Throws(Exception::class) - fun additionIsCorrect() { - Assert.assertEquals(4, (2 + 2).toLong()) - } -} diff --git a/core/data/src/wasmJsMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt b/core/data/src/wasmJsMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt new file mode 100644 index 000000000..fe646afb5 --- /dev/null +++ b/core/data/src/wasmJsMain/kotlin/org/mifospay/core/data/JsPlatformDependentDataModule.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf +import kotlinx.datetime.TimeZone +import org.mifospay.core.data.di.PlatformDependentDataModule +import org.mifospay.core.data.util.NetworkMonitor +import org.mifospay.core.data.util.TimeZoneMonitor + +class JsPlatformDependentDataModule : PlatformDependentDataModule { + override val networkMonitor: NetworkMonitor by lazy { + object : NetworkMonitor { + override val isOnline: Flow = flowOf(true) + } + } + + override val timeZoneMonitor: TimeZoneMonitor by lazy { + object : TimeZoneMonitor { + override val currentTimeZone: Flow = flowOf(TimeZone.currentSystemDefault()) + } + } +} diff --git a/core/data/src/wasmJsMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt b/core/data/src/wasmJsMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt new file mode 100644 index 000000000..9dbf3539a --- /dev/null +++ b/core/data/src/wasmJsMain/kotlin/org/mifospay/core/data/di/PlatformDependentDataModule.jvm.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.data.di + +import org.koin.core.module.Module +import org.koin.dsl.module +import org.mifospay.core.data.JsPlatformDependentDataModule + +actual val getPlatformDataModule: PlatformDependentDataModule + get() = JsPlatformDependentDataModule() + +actual val platformModule: Module + get() = module { + single { getPlatformDataModule } + } diff --git a/core/datastore-proto/build.gradle.kts b/core/datastore-proto/build.gradle.kts index b579ecfba..51683868e 100644 --- a/core/datastore-proto/build.gradle.kts +++ b/core/datastore-proto/build.gradle.kts @@ -8,8 +8,9 @@ * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ plugins { - alias(libs.plugins.mifospay.android.library) + alias(libs.plugins.mifospay.kmp.library) alias(libs.plugins.protobuf) + id("kotlinx-serialization") } android { @@ -24,9 +25,6 @@ protobuf { generateProtoTasks { all().forEach { task -> task.builtins { - register("java") { - option("lite") - } register("kotlin") { option("lite") } @@ -35,14 +33,11 @@ protobuf { } } -/*androidComponents.beforeVariants { - android.sourceSets.register(it.name) { - val buildDir = layout.buildDirectory.get().asFile - java.srcDir(buildDir.resolve("generated/source/proto/${it.name}/java")) - kotlin.srcDir(buildDir.resolve("generated/source/proto/${it.name}/kotlin")) +kotlin { + sourceSets { + commonMain.dependencies { + api(libs.protobuf.kotlin.lite) + implementation(libs.kotlinx.serialization.core) + } } -}*/ - -dependencies { - api(libs.protobuf.kotlin.lite) -} +} \ No newline at end of file diff --git a/core/datastore-proto/consumer-rules.pro b/core/datastore-proto/consumer-rules.pro deleted file mode 100644 index e69de29bb..000000000 diff --git a/core/datastore-proto/proguard-rules.pro b/core/datastore-proto/proguard-rules.pro deleted file mode 100644 index 481bb4348..000000000 --- a/core/datastore-proto/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/ClientPreferences.kt b/core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/ClientPreferences.kt new file mode 100644 index 000000000..1bc5477f4 --- /dev/null +++ b/core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/ClientPreferences.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.datastore.proto + +import kotlinx.serialization.Serializable + +@Serializable +data class ClientPreferences( + val id: Long, + val accountNo: String, + val externalId: String, + val active: Boolean, + val activationDate: List, + val firstname: String, + val lastname: String, + val displayName: String, + val mobileNo: String, + val emailAddress: String, + val dateOfBirth: List, + val isStaff: Boolean, + val officeId: Long, + val officeName: String, + val savingsProductName: String, +) { + companion object { + val DEFAULT = ClientPreferences( + id = 0L, + accountNo = "", + externalId = "", + active = false, + activationDate = emptyList(), + firstname = "", + lastname = "", + displayName = "", + mobileNo = "", + emailAddress = "", + dateOfBirth = emptyList(), + isStaff = false, + officeId = 0, + officeName = "", + savingsProductName = "", + ) + } +} diff --git a/core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/RolePreferences.kt b/core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/RolePreferences.kt new file mode 100644 index 000000000..17269b376 --- /dev/null +++ b/core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/RolePreferences.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.datastore.proto + +import kotlinx.serialization.Serializable + +@Serializable +data class RolePreferences( + val id: String, + val name: String, + val description: String, + val disabled: Boolean, +) { + companion object { + val DEFAULT = RolePreferences( + id = "", + name = "", + description = "", + disabled = false, + ) + } +} diff --git a/core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/UserInfoPreferences.kt b/core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/UserInfoPreferences.kt new file mode 100644 index 000000000..32ab5c4a4 --- /dev/null +++ b/core/datastore-proto/src/commonMain/kotlin/org/mifospay/core/datastore/proto/UserInfoPreferences.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.datastore.proto + +import kotlinx.serialization.Serializable + +@Serializable +data class UserInfoPreferences( + val username: String, + val userId: Long, + val base64EncodedAuthenticationKey: String, + val authenticated: Boolean, + val officeId: Int, + val officeName: String, + val roles: List, + val permissions: List, + val clients: List, + val shouldRenewPassword: Boolean, + val isTwoFactorAuthenticationRequired: Boolean, +) { + companion object { + val DEFAULT = UserInfoPreferences( + username = "", + userId = 0, + base64EncodedAuthenticationKey = "", + authenticated = false, + officeId = 0, + officeName = "", + roles = emptyList(), + permissions = emptyList(), + clients = emptyList(), + shouldRenewPassword = false, + isTwoFactorAuthenticationRequired = false, + ) + } +} diff --git a/core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/client_info.proto b/core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/client_info.proto new file mode 100644 index 000000000..f845e980c --- /dev/null +++ b/core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/client_info.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +option java_package = "org.mifospay.core.datastore.proto"; +option java_multiple_files = true; + +message Client { + string name = 1; + string image = 2; + string external_id = 3; + int64 client_id = 4; + string display_name = 5; + string mobile_no = 6; +} \ No newline at end of file diff --git a/core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/role_info.proto b/core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/role_info.proto new file mode 100644 index 000000000..b9756aa52 --- /dev/null +++ b/core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/role_info.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +option java_package = "org.mifospay.core.datastore.proto"; +option java_multiple_files = true; + +message Role { + string id = 1; + string name = 2; + string description = 3; + bool disabled = 4; +} \ No newline at end of file diff --git a/core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/user_info.proto b/core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/user_info.proto new file mode 100644 index 000000000..9d38f3d91 --- /dev/null +++ b/core/datastore-proto/src/commonMain/kotlin/proto/org/mifospay/core/datastore/proto/user_info.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +import "proto/org/mifospay/core/datastore/proto/role_info.proto"; + +option java_package = "org.mifospay.core.datastore.proto"; +option java_multiple_files = true; + +message User { + string username = 1; + int64 userId = 2; + string base64EncodedAuthenticationKey = 3; + bool authenticated = 4; + int32 officeId = 5; + string officeName = 6; + repeated Role roles = 7; + repeated string permissions = 8; + repeated int64 clients = 9; + bool shouldRenewPassword = 10; + bool isTwoFactorAuthenticationRequired = 11; +} \ No newline at end of file diff --git a/core/datastore-proto/src/main/proto/org.mifospay.core.data/user_preferences.proto b/core/datastore-proto/src/main/proto/org.mifospay.core.data/user_preferences.proto deleted file mode 100644 index 03791d71b..000000000 --- a/core/datastore-proto/src/main/proto/org.mifospay.core.data/user_preferences.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -option java_package = "org.mifospay.core.datastore.proto"; -option java_multiple_files = true; - -message UserPreferences { - string auth_token = 1; - string user = 2; - string user_email = 3; - string client = 4; - - // NEXT AVAILABLE ID: 5 -} diff --git a/core/datastore/build.gradle.kts b/core/datastore/build.gradle.kts index 1deb96ab2..154a4d55b 100644 --- a/core/datastore/build.gradle.kts +++ b/core/datastore/build.gradle.kts @@ -8,10 +8,9 @@ * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ plugins { - alias(libs.plugins.mifospay.android.library) + alias(libs.plugins.mifospay.kmp.library) } - android { namespace = "org.mifospay.core.datastore" defaultConfig { @@ -24,13 +23,25 @@ android { } } -dependencies { - api(libs.kotlinx.datetime) - api(libs.androidx.dataStore.core) - api(projects.core.datastoreProto) - api(projects.core.common) - api(projects.core.model) +kotlin { + sourceSets { + commonMain.dependencies { + implementation(libs.multiplatform.settings) + implementation(libs.multiplatform.settings.serialization) + implementation(libs.multiplatform.settings.coroutines) + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.serialization.core) + implementation(projects.core.model) + implementation(projects.core.common) + implementation(projects.core.datastoreProto) + } + + commonTest.dependencies { + implementation(libs.multiplatform.settings.test) + } - implementation(libs.squareup.retrofit.converter.gson) - implementation(libs.koin.android) + desktopMain.dependencies { + implementation(libs.kotlinx.coroutines.swing) + } + } } \ No newline at end of file diff --git a/core/datastore/proguard-rules.pro b/core/datastore/proguard-rules.pro deleted file mode 100644 index 481bb4348..000000000 --- a/core/datastore/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/datastore-proto/src/main/AndroidManifest.xml b/core/datastore/src/androidMain/AndroidManifest.xml similarity index 100% rename from core/datastore-proto/src/main/AndroidManifest.xml rename to core/datastore/src/androidMain/AndroidManifest.xml diff --git a/core/datastore/src/main/java/org/mifospay/core/datastore/PreferencesHelper.kt b/core/datastore/src/androidMain/java/org/mifospay/core/datastore/PreferencesHelper.kt similarity index 100% rename from core/datastore/src/main/java/org/mifospay/core/datastore/PreferencesHelper.kt rename to core/datastore/src/androidMain/java/org/mifospay/core/datastore/PreferencesHelper.kt diff --git a/core/datastore/src/main/java/org/mifospay/core/datastore/di/CoreDataStoreModule.kt b/core/datastore/src/androidMain/java/org/mifospay/core/datastore/di/CoreDataStoreModule.kt similarity index 100% rename from core/datastore/src/main/java/org/mifospay/core/datastore/di/CoreDataStoreModule.kt rename to core/datastore/src/androidMain/java/org/mifospay/core/datastore/di/CoreDataStoreModule.kt diff --git a/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/PreferencesMapper.kt b/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/PreferencesMapper.kt new file mode 100644 index 000000000..4825e32fc --- /dev/null +++ b/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/PreferencesMapper.kt @@ -0,0 +1,107 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.datastore + +import org.mifospay.core.datastore.proto.ClientPreferences +import org.mifospay.core.datastore.proto.RolePreferences +import org.mifospay.core.datastore.proto.UserInfoPreferences +import org.mifospay.core.model.client.Client +import org.mifospay.core.model.user.RoleInfo +import org.mifospay.core.model.user.UserInfo + +fun ClientPreferences.toClientInfo(): Client { + return Client( + id = id, + accountNo = accountNo, + externalId = externalId, + active = active, + activationDate = activationDate, + firstname = firstname, + lastname = lastname, + displayName = displayName, + mobileNo = mobileNo, + emailAddress = emailAddress, + dateOfBirth = dateOfBirth, + isStaff = isStaff, + officeId = officeId, + officeName = officeName, + savingsProductName = savingsProductName, + ) +} + +fun Client.toClientPreferences(): ClientPreferences { + return ClientPreferences( + id = id, + accountNo = accountNo, + externalId = externalId, + active = active, + activationDate = activationDate, + firstname = firstname, + lastname = lastname, + displayName = displayName, + mobileNo = mobileNo, + emailAddress = emailAddress, + dateOfBirth = dateOfBirth, + isStaff = isStaff, + officeId = officeId, + officeName = officeName, + savingsProductName = savingsProductName, + ) +} + +fun RolePreferences.toRoleInfo(): RoleInfo { + return RoleInfo( + id = id, + name = name, + description = description, + disabled = disabled, + ) +} + +fun RoleInfo.toRolePreferences(): RolePreferences { + return RolePreferences( + id = id, + name = name, + description = description, + disabled = disabled, + ) +} + +fun UserInfoPreferences.toUserInfo(): UserInfo { + return UserInfo( + username = username, + userId = userId, + base64EncodedAuthenticationKey = base64EncodedAuthenticationKey, + authenticated = authenticated, + officeId = officeId, + officeName = officeName, + roles = roles.map { it.toRoleInfo() }, + permissions = permissions, + clients = clients, + shouldRenewPassword = shouldRenewPassword, + isTwoFactorAuthenticationRequired = isTwoFactorAuthenticationRequired, + ) +} + +fun UserInfo.toUserInfoPreferences(): UserInfoPreferences { + return UserInfoPreferences( + username = username, + userId = userId, + base64EncodedAuthenticationKey = base64EncodedAuthenticationKey, + authenticated = authenticated, + officeId = officeId, + officeName = officeName, + roles = roles.map { it.toRolePreferences() }, + permissions = permissions, + clients = clients, + shouldRenewPassword = shouldRenewPassword, + isTwoFactorAuthenticationRequired = isTwoFactorAuthenticationRequired, + ) +} diff --git a/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesDataSource.kt b/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesDataSource.kt new file mode 100644 index 000000000..2c8b7a2ad --- /dev/null +++ b/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesDataSource.kt @@ -0,0 +1,175 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +@file:OptIn(ExperimentalSerializationApi::class, ExperimentalSettingsApi::class) + +package org.mifospay.core.datastore + +import com.russhwolf.settings.ExperimentalSettingsApi +import com.russhwolf.settings.Settings +import com.russhwolf.settings.serialization.decodeValue +import com.russhwolf.settings.serialization.decodeValueOrNull +import com.russhwolf.settings.serialization.encodeValue +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.withContext +import kotlinx.serialization.ExperimentalSerializationApi +import org.mifospay.core.datastore.UserPreferencesDataSource.Companion.DEFAULT_ACCOUNT +import org.mifospay.core.datastore.proto.ClientPreferences +import org.mifospay.core.datastore.proto.UserInfoPreferences +import org.mifospay.core.model.account.DefaultAccount +import org.mifospay.core.model.client.Client +import org.mifospay.core.model.client.UpdatedClient +import org.mifospay.core.model.user.UserInfo + +private const val USER_INFO_KEY = "userInfo" +private const val CLIENT_INFO_KEY = "clientInfo" + +@OptIn(ExperimentalSerializationApi::class) +class UserPreferencesDataSource( + private val settings: Settings, + private val dispatcher: CoroutineDispatcher, +) { + private val _userInfo = MutableStateFlow( + settings.decodeValue( + key = USER_INFO_KEY, + serializer = UserInfoPreferences.serializer(), + defaultValue = settings.decodeValueOrNull( + key = USER_INFO_KEY, + serializer = UserInfoPreferences.serializer(), + ) ?: UserInfoPreferences.DEFAULT, + ), + ) + + private val _clientInfo = MutableStateFlow( + settings.decodeValue( + key = CLIENT_INFO_KEY, + serializer = ClientPreferences.serializer(), + defaultValue = settings.decodeValueOrNull( + key = CLIENT_INFO_KEY, + serializer = ClientPreferences.serializer(), + ) ?: ClientPreferences.DEFAULT, + ), + ) + + private val _defaultAccount = MutableStateFlow( + settings.decodeValue( + key = DEFAULT_ACCOUNT, + serializer = DefaultAccount.serializer(), + defaultValue = settings.decodeValueOrNull( + key = DEFAULT_ACCOUNT, + serializer = DefaultAccount.serializer(), + ) ?: DefaultAccount.DEFAULT, + ), + ) + + val token = _userInfo.map { + it.base64EncodedAuthenticationKey + } + val userInfo = _userInfo.map(UserInfoPreferences::toUserInfo) + + val clientInfo = _clientInfo.map(ClientPreferences::toClientInfo) + + val clientId = _clientInfo.map { it.id } + + val defaultAccount = _defaultAccount.map { it.takeIf { it.accountId != 0L } } + + suspend fun updateClientInfo(client: Client) { + withContext(dispatcher) { + settings.putClientPreference(client.toClientPreferences()) + _clientInfo.value = client.toClientPreferences() + } + } + + suspend fun updateUserInfo(userInfo: UserInfo) { + withContext(dispatcher) { + settings.putUserInfoPreference(userInfo.toUserInfoPreferences()) + _userInfo.value = userInfo.toUserInfoPreferences() + } + } + + suspend fun updateClientProfile(client: UpdatedClient) { + withContext(dispatcher) { + val updatedClient = _clientInfo.value.copy( + firstname = client.firstname, + lastname = client.lastname, + displayName = client.firstname + " " + client.lastname, + emailAddress = client.emailAddress, + mobileNo = client.mobileNo, + externalId = client.externalId, + ) + + settings.putClientPreference(updatedClient) + _clientInfo.value = updatedClient + } + } + + suspend fun updateToken(token: String) { + withContext(dispatcher) { + settings.putUserInfoPreference( + UserInfoPreferences.DEFAULT.copy( + base64EncodedAuthenticationKey = token, + ), + ) + _userInfo.value = UserInfoPreferences.DEFAULT.copy( + base64EncodedAuthenticationKey = token, + ) + } + } + + fun updateDefaultAccount(account: DefaultAccount) { + settings.putDefaultAccount(account) + + _defaultAccount.value = account + } + + fun updateAuthToken(token: String) { + settings.putString(AUTH_TOKEN, token) + } + + fun getAuthToken(): String? { + return settings.getString(AUTH_TOKEN, "").ifEmpty { null } + } + + suspend fun clearInfo() { + withContext(dispatcher) { + settings.clear() + } + } + + companion object { + const val AUTH_TOKEN = "authToken" + const val DEFAULT_ACCOUNT = "default_account" + } +} + +private fun Settings.putClientPreference(preference: ClientPreferences) { + encodeValue( + key = CLIENT_INFO_KEY, + serializer = ClientPreferences.serializer(), + value = preference, + ) +} + +private fun Settings.putUserInfoPreference(preference: UserInfoPreferences) { + encodeValue( + key = USER_INFO_KEY, + serializer = UserInfoPreferences.serializer(), + value = preference, + ) +} + +private fun Settings.putDefaultAccount(account: DefaultAccount) { + encodeValue( + key = DEFAULT_ACCOUNT, + serializer = DefaultAccount.serializer(), + value = account, + ) +} diff --git a/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesRepository.kt b/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesRepository.kt new file mode 100644 index 000000000..ad8075983 --- /dev/null +++ b/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesRepository.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.datastore + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.StateFlow +import org.mifospay.core.common.DataState +import org.mifospay.core.model.account.DefaultAccount +import org.mifospay.core.model.client.Client +import org.mifospay.core.model.client.UpdatedClient +import org.mifospay.core.model.user.UserInfo + +interface UserPreferencesRepository { + val userInfo: Flow + + val token: StateFlow + + val client: StateFlow + + val clientId: StateFlow + + val authToken: String? + + val defaultAccount: StateFlow + + val defaultAccountId: StateFlow + + suspend fun updateToken(token: String): DataState + + suspend fun updateUserInfo(user: UserInfo): DataState + + suspend fun updateClientInfo(client: Client): DataState + + suspend fun updateClientProfile(client: UpdatedClient): DataState + + suspend fun updateDefaultAccount(account: DefaultAccount): DataState + + suspend fun logOut(): Unit +} diff --git a/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesRepositoryImpl.kt b/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesRepositoryImpl.kt new file mode 100644 index 000000000..c0647b171 --- /dev/null +++ b/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/UserPreferencesRepositoryImpl.kt @@ -0,0 +1,127 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.datastore + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn +import org.mifospay.core.common.DataState +import org.mifospay.core.model.account.DefaultAccount +import org.mifospay.core.model.client.Client +import org.mifospay.core.model.client.UpdatedClient +import org.mifospay.core.model.user.UserInfo + +class UserPreferencesRepositoryImpl( + private val preferenceManager: UserPreferencesDataSource, + private val ioDispatcher: CoroutineDispatcher, + unconfinedDispatcher: CoroutineDispatcher, +) : UserPreferencesRepository { + private val unconfinedScope = CoroutineScope(unconfinedDispatcher) + + override val userInfo: Flow + get() = preferenceManager.userInfo.flowOn(ioDispatcher) + + override val token: StateFlow + get() = preferenceManager.token.stateIn( + scope = unconfinedScope, + initialValue = null, + started = SharingStarted.Eagerly, + ) + + override val client: StateFlow + get() = preferenceManager.clientInfo.stateIn( + scope = unconfinedScope, + initialValue = null, + started = SharingStarted.Eagerly, + ) + + override val clientId: StateFlow + get() = preferenceManager.clientId.stateIn( + scope = unconfinedScope, + initialValue = null, + started = SharingStarted.Eagerly, + ) + + override val authToken: String? + get() = preferenceManager.getAuthToken() + + override val defaultAccount: StateFlow + get() = preferenceManager.defaultAccount.stateIn( + scope = unconfinedScope, + initialValue = null, + started = SharingStarted.Eagerly, + ) + + override val defaultAccountId: StateFlow + get() = preferenceManager.defaultAccount + .map { it?.accountId }.stateIn( + scope = unconfinedScope, + initialValue = null, + started = SharingStarted.Eagerly, + ) + + override suspend fun updateDefaultAccount(account: DefaultAccount): DataState { + return try { + val result = preferenceManager.updateDefaultAccount(account) + + DataState.Success(result) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun updateToken(token: String): DataState { + return try { + val result = preferenceManager.updateAuthToken(token) + + DataState.Success(result) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun updateClientInfo(client: Client): DataState { + return try { + val result = preferenceManager.updateClientInfo(client) + + DataState.Success(result) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun updateClientProfile(client: UpdatedClient): DataState { + return try { + val result = preferenceManager.updateClientProfile(client) + DataState.Success(result) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun updateUserInfo(user: UserInfo): DataState { + return try { + val result = preferenceManager.updateUserInfo(user) + + DataState.Success(result) + } catch (e: Exception) { + DataState.Error(e) + } + } + + override suspend fun logOut() { + preferenceManager.clearInfo() + } +} diff --git a/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/di/PreferenceModule.kt b/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/di/PreferenceModule.kt new file mode 100644 index 000000000..e74bee4cf --- /dev/null +++ b/core/datastore/src/commonMain/kotlin/org/mifospay/core/datastore/di/PreferenceModule.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.datastore.di + +import com.russhwolf.settings.Settings +import org.koin.core.qualifier.named +import org.koin.dsl.module +import org.mifospay.core.common.MifosDispatchers +import org.mifospay.core.datastore.UserPreferencesDataSource +import org.mifospay.core.datastore.UserPreferencesRepository +import org.mifospay.core.datastore.UserPreferencesRepositoryImpl + +val PreferencesModule = module { + factory { Settings() } + // Use the IO dispatcher name - MifosDispatchers.IO.name + factory { UserPreferencesDataSource(get(), get(named(MifosDispatchers.IO.name))) } + + single { + UserPreferencesRepositoryImpl( + preferenceManager = get(), + ioDispatcher = get(named(MifosDispatchers.IO.name)), + unconfinedDispatcher = get(named(MifosDispatchers.Unconfined.name)), + ) + } +} diff --git a/core/datastore/src/test/java/org/mifospay/core/datastore/ExampleUnitTest.kt b/core/datastore/src/test/java/org/mifospay/core/datastore/ExampleUnitTest.kt deleted file mode 100644 index e4d40ddc7..000000000 --- a/core/datastore/src/test/java/org/mifospay/core/datastore/ExampleUnitTest.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.datastore - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} diff --git a/core/designsystem/build.gradle.kts b/core/designsystem/build.gradle.kts index f08a5aea8..470795aa2 100644 --- a/core/designsystem/build.gradle.kts +++ b/core/designsystem/build.gradle.kts @@ -1,3 +1,13 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ + /* * Copyright 2024 Mifos Initiative * @@ -8,8 +18,10 @@ * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ plugins { - alias(libs.plugins.mifospay.android.library) - alias(libs.plugins.mifospay.android.library.compose) + alias(libs.plugins.mifospay.kmp.library) + alias(libs.plugins.jetbrainsCompose) + alias(libs.plugins.compose.compiler) + alias(libs.plugins.roborazzi) } android { @@ -19,20 +31,36 @@ android { namespace = "org.mifospay.core.designsystem" } -dependencies { - lintPublish(projects.lint) - - implementation(projects.core.model) - - api(libs.androidx.compose.ui) - api(libs.androidx.compose.foundation) - api(libs.androidx.compose.foundation.layout) - api(libs.androidx.compose.material.iconsExtended) - api(libs.androidx.compose.material3) - api(libs.androidx.compose.runtime) - api(libs.androidx.compose.ui.util) - api(libs.androidx.activity.compose) +kotlin { + sourceSets { + androidMain.dependencies { + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.activity.compose) + implementation(projects.core.model) + } + androidInstrumentedTest.dependencies { + implementation(libs.androidx.compose.ui.test) + } + androidUnitTest.dependencies { + implementation(libs.androidx.compose.ui.test) + } + commonMain.dependencies { + implementation(libs.coil.kt.compose) + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material3) + implementation(compose.materialIconsExtended) + implementation(compose.ui) + implementation(compose.uiUtil) + implementation(compose.components.resources) + implementation(compose.components.uiToolingPreview) + api(libs.back.handler) + api(libs.window.size) + } + } +} - testImplementation(libs.androidx.compose.ui.test) - androidTestImplementation(libs.androidx.compose.ui.test) +compose.resources { + publicResClass = true + generateResClass = always } \ No newline at end of file diff --git a/core/datastore/src/main/AndroidManifest.xml b/core/designsystem/src/androidMain/AndroidManifest.xml similarity index 100% rename from core/datastore/src/main/AndroidManifest.xml rename to core/designsystem/src/androidMain/AndroidManifest.xml diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/PermissionBox.kt b/core/designsystem/src/androidMain/kotlin/org/mifospay/core/designsystem/component/PermissionBox.kt similarity index 96% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/PermissionBox.kt rename to core/designsystem/src/androidMain/kotlin/org/mifospay/core/designsystem/component/PermissionBox.kt index afff02d09..3b758e8da 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/PermissionBox.kt +++ b/core/designsystem/src/androidMain/kotlin/org/mifospay/core/designsystem/component/PermissionBox.kt @@ -24,21 +24,22 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.compose.LocalLifecycleOwner +// TODO:: Support for compose multiplatform @Suppress("LongMethod", "CyclomaticComplexMethod") @Composable fun PermissionBox( + title: String, + confirmButtonText: String, + dismissButtonText: String, requiredPermissions: List, - title: Int, - confirmButtonText: Int, - dismissButtonText: Int, modifier: Modifier = Modifier, - description: Int? = null, + description: String? = null, onGranted: @Composable (() -> Unit)? = null, ) { val context = LocalContext.current diff --git a/core/designsystem/src/main/res/font/outfit_black.ttf b/core/designsystem/src/commonMain/composeResources/font/outfit_black.ttf similarity index 100% rename from core/designsystem/src/main/res/font/outfit_black.ttf rename to core/designsystem/src/commonMain/composeResources/font/outfit_black.ttf diff --git a/core/designsystem/src/main/res/font/outfit_bold.ttf b/core/designsystem/src/commonMain/composeResources/font/outfit_bold.ttf similarity index 100% rename from core/designsystem/src/main/res/font/outfit_bold.ttf rename to core/designsystem/src/commonMain/composeResources/font/outfit_bold.ttf diff --git a/core/designsystem/src/main/res/font/outfit_extra_bold.ttf b/core/designsystem/src/commonMain/composeResources/font/outfit_extra_bold.ttf similarity index 100% rename from core/designsystem/src/main/res/font/outfit_extra_bold.ttf rename to core/designsystem/src/commonMain/composeResources/font/outfit_extra_bold.ttf diff --git a/core/designsystem/src/main/res/font/outfit_extra_light.ttf b/core/designsystem/src/commonMain/composeResources/font/outfit_extra_light.ttf similarity index 100% rename from core/designsystem/src/main/res/font/outfit_extra_light.ttf rename to core/designsystem/src/commonMain/composeResources/font/outfit_extra_light.ttf diff --git a/core/designsystem/src/main/res/font/outfit_light.ttf b/core/designsystem/src/commonMain/composeResources/font/outfit_light.ttf similarity index 100% rename from core/designsystem/src/main/res/font/outfit_light.ttf rename to core/designsystem/src/commonMain/composeResources/font/outfit_light.ttf diff --git a/core/designsystem/src/main/res/font/outfit_medium.ttf b/core/designsystem/src/commonMain/composeResources/font/outfit_medium.ttf similarity index 100% rename from core/designsystem/src/main/res/font/outfit_medium.ttf rename to core/designsystem/src/commonMain/composeResources/font/outfit_medium.ttf diff --git a/core/designsystem/src/main/res/font/outfit_regular.ttf b/core/designsystem/src/commonMain/composeResources/font/outfit_regular.ttf similarity index 100% rename from core/designsystem/src/main/res/font/outfit_regular.ttf rename to core/designsystem/src/commonMain/composeResources/font/outfit_regular.ttf diff --git a/core/designsystem/src/main/res/font/outfit_semi_bold.ttf b/core/designsystem/src/commonMain/composeResources/font/outfit_semi_bold.ttf similarity index 100% rename from core/designsystem/src/main/res/font/outfit_semi_bold.ttf rename to core/designsystem/src/commonMain/composeResources/font/outfit_semi_bold.ttf diff --git a/core/designsystem/src/main/res/font/outfit_thin.ttf b/core/designsystem/src/commonMain/composeResources/font/outfit_thin.ttf similarity index 100% rename from core/designsystem/src/main/res/font/outfit_thin.ttf rename to core/designsystem/src/commonMain/composeResources/font/outfit_thin.ttf diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/AlertDialog.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/AlertDialog.kt similarity index 80% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/AlertDialog.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/AlertDialog.kt index 76268649d..8a0115a0f 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/AlertDialog.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/AlertDialog.kt @@ -16,27 +16,26 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource @Composable fun MifosDialogBox( + title: String, showDialogState: Boolean, - onDismiss: () -> Unit, - title: Int, - confirmButtonText: Int, + confirmButtonText: String, + dismissButtonText: String, onConfirm: () -> Unit, - dismissButtonText: Int, + onDismiss: () -> Unit, modifier: Modifier = Modifier, - message: Int? = null, + message: String? = null, ) { if (showDialogState) { AlertDialog( modifier = modifier, onDismissRequest = onDismiss, - title = { Text(text = stringResource(id = title)) }, + title = { Text(text = title) }, text = { if (message != null) { - Text(text = stringResource(id = message)) + Text(text = message) } }, confirmButton = { @@ -45,12 +44,12 @@ fun MifosDialogBox( onConfirm() }, ) { - Text(stringResource(id = confirmButtonText)) + Text(text = confirmButtonText) } }, dismissButton = { TextButton(onClick = onDismiss) { - Text(stringResource(id = dismissButtonText)) + Text(text = dismissButtonText) } }, ) diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Background.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/Background.kt similarity index 89% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Background.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/Background.kt index aa6848aad..1d534173a 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Background.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/Background.kt @@ -9,7 +9,6 @@ */ package org.mifospay.core.designsystem.component -import android.content.res.Configuration import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.size @@ -23,9 +22,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawWithCache import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import org.jetbrains.compose.ui.tooling.preview.Preview import org.mifospay.core.designsystem.theme.GradientColors import org.mifospay.core.designsystem.theme.LocalBackgroundTheme import org.mifospay.core.designsystem.theme.LocalGradientColors @@ -99,15 +98,7 @@ fun MifosGradientBackground( } } -/** - * Multipreview annotation that represents light and dark themes. Add this annotation to a - * composable to render the both themes. - */ -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO, name = "Light theme") -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, name = "Dark theme") -annotation class ThemePreviews - -@ThemePreviews +@Preview @Composable fun BackgroundDefault() { MifosTheme { @@ -115,7 +106,7 @@ fun BackgroundDefault() { } } -@ThemePreviews +@Preview @Composable fun BackgroundDynamic() { MifosTheme { @@ -123,7 +114,7 @@ fun BackgroundDynamic() { } } -@ThemePreviews +@Preview @Composable fun BackgroundAndroid() { MifosTheme { @@ -131,7 +122,7 @@ fun BackgroundAndroid() { } } -@ThemePreviews +@Preview @Composable fun GradientBackgroundDefault() { MifosTheme { @@ -139,7 +130,7 @@ fun GradientBackgroundDefault() { } } -@ThemePreviews +@Preview @Composable fun GradientBackgroundDynamic() { MifosTheme { @@ -147,7 +138,7 @@ fun GradientBackgroundDynamic() { } } -@ThemePreviews +@Preview @Composable fun GradientBackgroundAndroid() { MifosTheme { diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/BottomSheet.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/BottomSheet.kt similarity index 87% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/BottomSheet.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/BottomSheet.kt index 7270d4b22..0dd9f6b21 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/BottomSheet.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/BottomSheet.kt @@ -9,7 +9,6 @@ */ package org.mifospay.core.designsystem.component -import androidx.activity.compose.BackHandler import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.height @@ -24,16 +23,17 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.arkivanov.essenty.backhandler.BackCallback import kotlinx.coroutines.launch +import org.jetbrains.compose.ui.tooling.preview.Preview @OptIn(ExperimentalMaterial3Api::class) @Composable fun MifosBottomSheet( - content: @Composable () -> Unit, onDismiss: () -> Unit, modifier: Modifier = Modifier, + content: @Composable () -> Unit, ) { val coroutineScope = rememberCoroutineScope() val modalSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) @@ -48,7 +48,7 @@ fun MifosBottomSheet( onDismiss.invoke() } - BackHandler(modalSheetState.isVisible) { + BackCallback(modalSheetState.isVisible) { dismissSheet() } @@ -70,9 +70,12 @@ fun MifosBottomSheet( @Preview @Composable fun MifosBottomSheetPreview() { - MifosBottomSheet({ - Box { - Modifier.height(100.dp) - } - }, {}) + MifosBottomSheet( + content = { + Box { + Modifier.height(100.dp) + } + }, + onDismiss = {}, + ) } diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Button.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/Button.kt similarity index 95% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Button.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/Button.kt index 2c1d566ad..f420463f9 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Button.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/Button.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.sizeIn @@ -31,6 +32,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp +import org.jetbrains.compose.ui.tooling.preview.Preview import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.core.designsystem.theme.MifosTheme @@ -56,7 +58,8 @@ fun MifosButton( ) { Button( onClick = onClick, - modifier = modifier, + modifier = modifier + .height(48.dp), enabled = enabled, colors = ButtonDefaults.buttonColors(containerColor = color), contentPadding = contentPadding, @@ -77,7 +80,7 @@ fun MifosButton( ) { Button( onClick = onClick, - modifier = modifier, + modifier = modifier.height(48.dp), enabled = enabled, colors = colors, shape = shape, @@ -103,7 +106,7 @@ fun MifosButton( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, - color: Color = MaterialTheme.colorScheme.onBackground, + color: Color = MaterialTheme.colorScheme.primary, leadingIcon: @Composable (() -> Unit)? = null, ) { MifosButton( @@ -141,14 +144,15 @@ fun MifosOutlinedButton( modifier: Modifier = Modifier, enabled: Boolean = true, shape: Shape = ButtonDefaults.outlinedShape, - border: BorderStroke? = ButtonDefaults.outlinedButtonBorder, + border: BorderStroke? = ButtonDefaults.outlinedButtonBorder(enabled), colors: ButtonColors = ButtonDefaults.outlinedButtonColors(), contentPadding: PaddingValues = ButtonDefaults.ContentPadding, content: @Composable RowScope.() -> Unit = {}, ) { OutlinedButton( onClick = onClick, - modifier = modifier, + modifier = modifier + .height(48.dp), enabled = enabled, shape = shape, colors = colors, @@ -178,7 +182,7 @@ fun MifosOutlinedButton( ) { MifosOutlinedButton( onClick = onClick, - modifier = modifier, + modifier = modifier.height(48.dp), enabled = enabled, contentPadding = if (leadingIcon != null) { ButtonDefaults.ButtonWithIconContentPadding @@ -283,7 +287,7 @@ private fun MifosButtonContent( } } -@ThemePreviews +@Preview @Composable fun MifosButtonPreview() { MifosTheme { @@ -293,7 +297,7 @@ fun MifosButtonPreview() { } } -@ThemePreviews +@Preview @Composable fun MifosOutlinedButtonPreview() { MifosTheme { @@ -303,7 +307,7 @@ fun MifosOutlinedButtonPreview() { } } -@ThemePreviews +@Preview @Composable fun MifosButtonLeadingIconPreview() { MifosTheme { diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Card.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/Card.kt similarity index 100% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Card.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/Card.kt diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/IconBox.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/IconBox.kt similarity index 78% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/IconBox.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/IconBox.kt index b6d35f999..aa0e4821f 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/IconBox.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/IconBox.kt @@ -17,10 +17,9 @@ import androidx.compose.material3.OutlinedIconButton import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import org.jetbrains.compose.ui.tooling.preview.Preview import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.core.designsystem.theme.MifosTheme @@ -29,7 +28,6 @@ fun IconBox( icon: ImageVector, onClick: () -> Unit, modifier: Modifier = Modifier, - tint: Color? = null, ) { OutlinedIconButton( onClick = onClick, @@ -37,18 +35,10 @@ fun IconBox( shape = RoundedCornerShape(12.dp), border = BorderStroke(2.dp, MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f)), ) { - if (tint != null) { - Icon( - imageVector = icon, - contentDescription = icon.name, - tint = tint, - ) - } else { - Icon( - imageVector = icon, - contentDescription = icon.name, - ) - } + Icon( + imageVector = icon, + contentDescription = icon.name, + ) } } diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/LoadingWheel.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/LoadingWheel.kt similarity index 99% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/LoadingWheel.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/LoadingWheel.kt index db89435de..d3990e66e 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/LoadingWheel.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/LoadingWheel.kt @@ -46,9 +46,9 @@ import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.testTag import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kotlinx.coroutines.launch +import org.jetbrains.compose.ui.tooling.preview.Preview import org.mifospay.core.designsystem.theme.MifosTheme @Composable diff --git a/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosBasicDialog.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosBasicDialog.kt new file mode 100644 index 000000000..72d841a72 --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosBasicDialog.kt @@ -0,0 +1,142 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.component + +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.testTag +import org.jetbrains.compose.ui.tooling.preview.Preview +import org.mifospay.core.designsystem.theme.MifosTheme + +@Composable +fun MifosBasicDialog( + visibilityState: BasicDialogState, + onDismissRequest: () -> Unit, +): Unit = when (visibilityState) { + BasicDialogState.Hidden -> Unit + is BasicDialogState.Shown -> { + AlertDialog( + onDismissRequest = onDismissRequest, + confirmButton = { + MifosTextButton( + content = { + Text(text = "Ok") + }, + onClick = onDismissRequest, + modifier = Modifier.testTag("AcceptAlertButton"), + ) + }, + title = visibilityState.title?.let { + { + Text( + text = it, + style = MaterialTheme.typography.headlineSmall, + modifier = Modifier.testTag("AlertTitleText"), + ) + } + }, + text = { + Text( + text = visibilityState.message, + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.testTag("AlertContentText"), + ) + }, + containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, + modifier = Modifier.semantics { + testTag = "AlertPopup" + }, + ) + } +} + +@Composable +fun MifosBasicDialog( + visibilityState: BasicDialogState, + onConfirm: () -> Unit, + onDismissRequest: () -> Unit, +): Unit = when (visibilityState) { + BasicDialogState.Hidden -> Unit + is BasicDialogState.Shown -> { + AlertDialog( + onDismissRequest = onDismissRequest, + confirmButton = { + MifosTextButton( + content = { + Text(text = "Ok") + }, + onClick = onConfirm, + modifier = Modifier.testTag("AcceptAlertButton"), + ) + }, + dismissButton = { + MifosTextButton( + content = { + Text(text = "Cancel") + }, + onClick = onDismissRequest, + modifier = Modifier.testTag("DismissAlertButton"), + ) + }, + title = visibilityState.title.let { + { + Text( + text = it, + style = MaterialTheme.typography.headlineSmall, + modifier = Modifier.testTag("AlertTitleText"), + ) + } + }, + text = { + Text( + text = visibilityState.message, + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.testTag("AlertContentText"), + ) + }, + containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, + modifier = Modifier.semantics { + testTag = "AlertPopup" + }, + ) + } +} + +@Preview +@Composable +private fun MifosBasicDialog_preview() { + MifosTheme { + MifosBasicDialog( + visibilityState = BasicDialogState.Shown( + title = "An error has occurred.", + message = "Username or password is incorrect. Try again.", + ), + onDismissRequest = {}, + ) + } +} + +/** + * Models display of a [MifosBasicDialog]. + */ +sealed class BasicDialogState { + + data object Hidden : BasicDialogState() + + data class Shown( + val message: String, + val title: String = "An Error Occurred!", + ) : BasicDialogState() +} diff --git a/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosLoadingDialog.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosLoadingDialog.kt new file mode 100644 index 000000000..b9f66c6bd --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosLoadingDialog.kt @@ -0,0 +1,107 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.component + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.testTag +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import org.jetbrains.compose.ui.tooling.preview.Preview +import org.mifospay.core.designsystem.theme.MifosTheme + +@Composable +fun MifosLoadingDialog( + visibilityState: LoadingDialogState, +) { + when (visibilityState) { + is LoadingDialogState.Hidden -> Unit + is LoadingDialogState.Shown -> { + Dialog( + onDismissRequest = {}, + properties = DialogProperties( + dismissOnBackPress = false, + dismissOnClickOutside = false, + ), + ) { + Card( + shape = RoundedCornerShape(28.dp), + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, + ), + modifier = Modifier + .semantics { + testTag = "AlertPopup" + } + .fillMaxWidth() + .wrapContentHeight(), + ) { + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = "Loading..", + modifier = Modifier + .testTag("AlertTitleText") + .padding( + top = 24.dp, + bottom = 8.dp, + ), + ) + CircularProgressIndicator( + modifier = Modifier + .testTag("AlertProgressIndicator") + .padding( + top = 8.dp, + bottom = 24.dp, + ), + ) + } + } + } + } + } +} + +@Preview +@Composable +private fun MifosLoadingDialog_preview() { + MifosTheme { + MifosLoadingDialog( + visibilityState = LoadingDialogState.Shown, + ) + } +} + +/** + * Models display of a [MifosLoadingDialog]. + */ +sealed class LoadingDialogState { + data object Hidden : LoadingDialogState() + + data object Shown : LoadingDialogState() +} diff --git a/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosScaffold.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosScaffold.kt new file mode 100644 index 000000000..1179c047c --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosScaffold.kt @@ -0,0 +1,177 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.component + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FabPosition +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.ScaffoldDefaults +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults +import androidx.compose.material3.pulltorefresh.pullToRefresh +import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MifosScaffold( + backPress: () -> Unit, + modifier: Modifier = Modifier, + topBarTitle: String? = null, + floatingActionButtonContent: FloatingActionButtonContent? = null, + pullToRefreshState: MifosPullToRefreshState = rememberMifosPullToRefreshState(), + snackbarHost: @Composable () -> Unit = {}, + actions: @Composable RowScope.() -> Unit = {}, + content: @Composable (PaddingValues) -> Unit = {}, +) { + Scaffold( + topBar = { + if (topBarTitle != null) { + MifosTopBar( + topBarTitle = topBarTitle, + backPress = backPress, + actions = actions, + ) + } + }, + floatingActionButton = { + floatingActionButtonContent?.let { content -> + FloatingActionButton( + onClick = content.onClick, + contentColor = content.contentColor, + content = content.content, + ) + } + }, + snackbarHost = snackbarHost, + containerColor = Color.Transparent, + content = { paddingValues -> + val internalPullToRefreshState = rememberPullToRefreshState() + Box( + modifier = Modifier.pullToRefresh( + state = internalPullToRefreshState, + isRefreshing = pullToRefreshState.isRefreshing, + onRefresh = pullToRefreshState.onRefresh, + enabled = pullToRefreshState.isEnabled, + ), + ) { + content(paddingValues) + + PullToRefreshDefaults.Indicator( + modifier = Modifier + .padding(paddingValues) + .align(Alignment.TopCenter), + isRefreshing = pullToRefreshState.isRefreshing, + state = internalPullToRefreshState, + ) + } + }, + modifier = modifier + .fillMaxSize() + .navigationBarsPadding() + .imePadding(), + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MifosScaffold( + modifier: Modifier = Modifier, + topBar: @Composable () -> Unit = {}, + bottomBar: @Composable () -> Unit = {}, + floatingActionButton: @Composable () -> Unit = {}, + snackbarHostState: SnackbarHostState = remember { SnackbarHostState() }, + pullToRefreshState: MifosPullToRefreshState = rememberMifosPullToRefreshState(), + floatingActionButtonPosition: FabPosition = FabPosition.End, + containerColor: Color = Color.Transparent, + contentColor: Color = MaterialTheme.colorScheme.onSurface, + contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets, + content: @Composable (PaddingValues) -> Unit, +) { + Scaffold( + modifier = modifier + .fillMaxSize() + .navigationBarsPadding() + .imePadding(), + topBar = topBar, + bottomBar = bottomBar, + snackbarHost = { SnackbarHost(snackbarHostState) }, + floatingActionButton = { + Box(modifier = Modifier.navigationBarsPadding()) { + floatingActionButton() + } + }, + floatingActionButtonPosition = floatingActionButtonPosition, + containerColor = containerColor, + contentColor = contentColor, + contentWindowInsets = contentWindowInsets, + content = { paddingValues -> + val internalPullToRefreshState = rememberPullToRefreshState() + Box( + modifier = Modifier.pullToRefresh( + state = internalPullToRefreshState, + isRefreshing = pullToRefreshState.isRefreshing, + onRefresh = pullToRefreshState.onRefresh, + enabled = pullToRefreshState.isEnabled, + ), + ) { + content(paddingValues) + + PullToRefreshDefaults.Indicator( + modifier = Modifier + .padding(paddingValues) + .align(Alignment.TopCenter), + isRefreshing = pullToRefreshState.isRefreshing, + state = internalPullToRefreshState, + ) + } + }, + ) +} + +data class FloatingActionButtonContent( + val onClick: (() -> Unit), + val contentColor: Color, + val content: (@Composable () -> Unit), +) + +data class MifosPullToRefreshState( + val isEnabled: Boolean, + val isRefreshing: Boolean, + val onRefresh: () -> Unit, +) + +@Composable +fun rememberMifosPullToRefreshState( + isEnabled: Boolean = false, + isRefreshing: Boolean = false, + onRefresh: () -> Unit = { }, +): MifosPullToRefreshState = remember(isEnabled, isRefreshing, onRefresh) { + MifosPullToRefreshState( + isEnabled = isEnabled, + isRefreshing = isRefreshing, + onRefresh = onRefresh, + ) +} diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosTab.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosTab.kt similarity index 66% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosTab.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosTab.kt index 5a06560d4..cdd34932b 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosTab.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosTab.kt @@ -15,6 +15,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Tab import androidx.compose.material3.Text +import androidx.compose.material3.contentColorFor import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -27,27 +28,20 @@ fun MifosTab( selected: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier, - selectedContentColor: Color = MaterialTheme.colorScheme.primary, - unselectedContentColor: Color = MaterialTheme.colorScheme.primaryContainer, + selectedColor: Color = MaterialTheme.colorScheme.primary, + unselectedColor: Color = MaterialTheme.colorScheme.primaryContainer, ) { Tab( text = { - Text( - text = text, - color = if (selected) { - MaterialTheme.colorScheme.onPrimary - } else { - MaterialTheme.colorScheme.onSurface - }, - ) + Text(text = text) }, selected = selected, + onClick = onClick, + selectedContentColor = contentColorFor(selectedColor), + unselectedContentColor = contentColorFor(unselectedColor), modifier = modifier .clip(RoundedCornerShape(25.dp)) - .background(if (selected) selectedContentColor else unselectedContentColor) + .background(if (selected) selectedColor else unselectedColor) .padding(horizontal = 20.dp), - selectedContentColor = selectedContentColor, - unselectedContentColor = unselectedContentColor, - onClick = onClick, ) } diff --git a/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosTopAppBar.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosTopAppBar.kt new file mode 100644 index 000000000..7f71e3573 --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosTopAppBar.kt @@ -0,0 +1,275 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.component + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.RowScope +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LargeTopAppBar +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MediumTopAppBar +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.material3.TopAppBarScrollBehavior +import androidx.compose.material3.rememberTopAppBarState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import org.jetbrains.compose.ui.tooling.preview.Preview +import org.mifospay.core.designsystem.icon.MifosIcons +import org.mifospay.core.designsystem.theme.MifosTheme +import org.mifospay.core.designsystem.utils.mirrorIfRtl + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MifosTopAppBar( + title: String, + scrollBehavior: TopAppBarScrollBehavior, + navigationIcon: ImageVector, + navigationIconContentDescription: String, + onNavigationIconClick: () -> Unit, + modifier: Modifier = Modifier, + actions: @Composable RowScope.() -> Unit = { }, +) { + MifosTopAppBar( + title = title, + scrollBehavior = scrollBehavior, + navigationIcon = NavigationIcon( + navigationIcon = navigationIcon, + navigationIconContentDescription = navigationIconContentDescription, + onNavigationIconClick = onNavigationIconClick, + ), + modifier = modifier, + actions = actions, + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Suppress("LongMethod") +@Composable +fun MifosTopAppBar( + title: String, + scrollBehavior: TopAppBarScrollBehavior, + navigationIcon: NavigationIcon?, + modifier: Modifier = Modifier, + actions: @Composable RowScope.() -> Unit = {}, +) { + var titleTextHasOverflow by remember { + mutableStateOf(false) + } + + val navigationIconContent: @Composable () -> Unit = remember(navigationIcon) { + { + navigationIcon?.let { + IconButton( + onClick = it.onNavigationIconClick, + modifier = Modifier.testTag("CloseButton"), + ) { + Icon( + modifier = Modifier.mirrorIfRtl(), + imageVector = it.navigationIcon, + contentDescription = it.navigationIconContentDescription, + ) + } + } + } + } + + val topAppBarColors = TopAppBarDefaults.largeTopAppBarColors( + containerColor = MaterialTheme.colorScheme.surface, + scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer, + navigationIconContentColor = MaterialTheme.colorScheme.onSurface, + titleContentColor = MaterialTheme.colorScheme.onSurface, + actionIconContentColor = MaterialTheme.colorScheme.onSurfaceVariant, + ) + + if (titleTextHasOverflow) { + MediumTopAppBar( + colors = topAppBarColors, + scrollBehavior = scrollBehavior, + navigationIcon = navigationIconContent, + title = { + // The height of the component is controlled and will only allow for 1 extra row, + // making adding any arguments for softWrap and minLines superfluous. + Text( + text = title, + style = MaterialTheme.typography.titleLarge, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.testTag("PageTitleLabel"), + ) + }, + modifier = modifier.testTag("HeaderBarComponent"), + actions = actions, + ) + } else { + TopAppBar( + colors = topAppBarColors, + scrollBehavior = scrollBehavior, + navigationIcon = navigationIconContent, + title = { + Text( + text = title, + style = MaterialTheme.typography.titleLarge, + maxLines = 1, + softWrap = false, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.testTag("PageTitleLabel"), + onTextLayout = { + titleTextHasOverflow = it.hasVisualOverflow + }, + ) + }, + modifier = modifier.testTag("HeaderBarComponent"), + actions = actions, + ) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Suppress("LongMethod") +@Composable +fun MifosTopAppBar( + title: String, + subtitle: String, + scrollBehavior: TopAppBarScrollBehavior, + navigationIcon: ImageVector, + navigationIconContentDescription: String, + onNavigationIconClick: () -> Unit, + modifier: Modifier = Modifier, + actions: @Composable RowScope.() -> Unit = {}, +) { + val navigationIconContent: @Composable () -> Unit = remember(navigationIcon) { + { + IconButton( + onClick = onNavigationIconClick, + modifier = Modifier.testTag("CloseButton"), + ) { + Icon( + modifier = Modifier.mirrorIfRtl(), + imageVector = navigationIcon, + contentDescription = navigationIconContentDescription, + ) + } + } + } + + val topAppBarColors = TopAppBarDefaults.largeTopAppBarColors( + containerColor = MaterialTheme.colorScheme.surface, + scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer, + navigationIconContentColor = MaterialTheme.colorScheme.onSurface, + titleContentColor = MaterialTheme.colorScheme.onSurface, + actionIconContentColor = MaterialTheme.colorScheme.onSurfaceVariant, + ) + + LargeTopAppBar( + colors = topAppBarColors, + scrollBehavior = scrollBehavior, + navigationIcon = navigationIconContent, + title = { + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + // The height of the component is controlled and will only allow for 1 extra row, + // making adding any arguments for softWrap and minLines superfluous. + Text( + text = title, + style = MaterialTheme.typography.titleLarge, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.testTag("PageTitleLabel"), + ) + + Text( + text = subtitle, + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.testTag("PageTitleSubTitle"), + ) + } + }, + modifier = modifier.testTag("HeaderBarComponent"), + actions = actions, + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Preview +@Composable +private fun MifosTopAppBar_preview() { + MifosTheme { + MifosTopAppBar( + title = "Title", + scrollBehavior = TopAppBarDefaults + .exitUntilCollapsedScrollBehavior( + rememberTopAppBarState(), + ), + navigationIcon = NavigationIcon( + navigationIcon = MifosIcons.Back, + navigationIconContentDescription = "Back", + onNavigationIconClick = { }, + ), + ) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Preview +@Composable +private fun MifosTopAppBarOverflow_preview() { + MifosTheme { + MifosTopAppBar( + title = "Title that is too long for the top line", + scrollBehavior = TopAppBarDefaults + .exitUntilCollapsedScrollBehavior( + rememberTopAppBarState(), + ), + navigationIcon = NavigationIcon( + navigationIcon = MifosIcons.Close, + navigationIconContentDescription = "Close", + onNavigationIconClick = { }, + ), + ) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Preview +@Composable +private fun MifosTopAppBarOverflowCutoff_preview() { + MifosTheme { + MifosTopAppBar( + title = "Title that is too long for the top line and the bottom line", + scrollBehavior = TopAppBarDefaults + .exitUntilCollapsedScrollBehavior( + rememberTopAppBarState(), + ), + navigationIcon = NavigationIcon( + navigationIcon = MifosIcons.Close, + navigationIconContentDescription = "Close", + onNavigationIconClick = { }, + ), + ) + } +} + +data class NavigationIcon( + val navigationIcon: ImageVector, + val navigationIconContentDescription: String, + val onNavigationIconClick: () -> Unit, +) diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosTopBar.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosTopBar.kt similarity index 83% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosTopBar.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosTopBar.kt index d85d0ae47..0a8e004d6 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosTopBar.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/MifosTopBar.kt @@ -18,32 +18,27 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource import org.mifospay.core.designsystem.icon.MifosIcons @OptIn(ExperimentalMaterial3Api::class) @Composable fun MifosTopBar( - topBarTitle: Int, + topBarTitle: String, backPress: () -> Unit, modifier: Modifier = Modifier, actions: @Composable RowScope.() -> Unit = {}, - titleColor: Color? = null, - iconTint: Color? = null, ) { CenterAlignedTopAppBar( title = { Text( - text = stringResource(id = topBarTitle), + text = topBarTitle, style = MaterialTheme.typography.titleMedium, - color = titleColor ?: MaterialTheme.colorScheme.onSurface, ) }, navigationIcon = { IconBox( icon = MifosIcons.ArrowBack2, onClick = backPress, - tint = iconTint, ) }, colors = TopAppBarDefaults.centerAlignedTopAppBarColors( diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Navigation.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/Navigation.kt similarity index 89% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Navigation.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/Navigation.kt index 61b198126..e532dbe3f 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Navigation.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/Navigation.kt @@ -24,6 +24,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp +import org.jetbrains.compose.ui.tooling.preview.Preview import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.core.designsystem.theme.MifosTheme @@ -85,7 +86,7 @@ fun MifosNavigationBar( ) { NavigationBar( modifier = modifier, - containerColor = MaterialTheme.colorScheme.onPrimary, + containerColor = MaterialTheme.colorScheme.background, contentColor = MifosNavigationDefaults.navigationContentColor(), tonalElevation = 0.dp, content = content, @@ -159,22 +160,24 @@ fun MifosNavigationRail( ) } -@ThemePreviews +@Preview @Composable fun MifosNavigationBarPreview() { val items = listOf("Home", "Payments", "Finance", "Profile") - val icons = listOf( - MifosIcons.Home, - MifosIcons.Payment, - MifosIcons.Finance, - MifosIcons.Profile, - ) - val selectedIcons = listOf( - MifosIcons.HomeBoarder, - MifosIcons.Payment, - MifosIcons.Finance, - MifosIcons.ProfileBoarder, - ) + val icons = + listOf( + MifosIcons.Home, + MifosIcons.Payment, + MifosIcons.Finance, + MifosIcons.Profile, + ) + val selectedIcons = + listOf( + MifosIcons.HomeBoarder, + MifosIcons.Payment, + MifosIcons.Finance, + MifosIcons.ProfileBoarder, + ) MifosTheme { MifosNavigationBar { @@ -201,22 +204,24 @@ fun MifosNavigationBarPreview() { } } -@ThemePreviews +@Preview @Composable fun MifosNavigationRailPreview() { val items = listOf("Home", "Payments", "Finance", "Profile") - val icons = listOf( - MifosIcons.Home, - MifosIcons.Payment, - MifosIcons.Finance, - MifosIcons.Profile, - ) - val selectedIcons = listOf( - MifosIcons.HomeBoarder, - MifosIcons.Payment, - MifosIcons.Finance, - MifosIcons.ProfileBoarder, - ) + val icons = + listOf( + MifosIcons.Home, + MifosIcons.Payment, + MifosIcons.Finance, + MifosIcons.Profile, + ) + val selectedIcons = + listOf( + MifosIcons.HomeBoarder, + MifosIcons.Payment, + MifosIcons.Finance, + MifosIcons.ProfileBoarder, + ) MifosTheme { MifosNavigationRail { @@ -251,8 +256,8 @@ object MifosNavigationDefaults { fun navigationContentColor() = MaterialTheme.colorScheme.onSurfaceVariant @Composable - fun navigationSelectedItemColor() = MaterialTheme.colorScheme.onSurface + fun navigationSelectedItemColor() = MaterialTheme.colorScheme.onPrimaryContainer @Composable - fun navigationIndicatorColor() = MaterialTheme.colorScheme.onPrimary + fun navigationIndicatorColor() = MaterialTheme.colorScheme.primaryContainer } diff --git a/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/TextField.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/TextField.kt new file mode 100644 index 000000000..70cbf7790 --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/TextField.kt @@ -0,0 +1,367 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.component + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsFocusedAsState +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.RectangleShape +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import org.mifospay.core.designsystem.icon.MifosIcons +import org.mifospay.core.designsystem.theme.NewUi + +@Composable +fun MifosOutlinedTextField( + value: String, + label: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + isError: Boolean = false, + errorMessage: String = "", + singleLine: Boolean = false, + showClearIcon: Boolean = true, + readOnly: Boolean = false, + clearIcon: ImageVector = MifosIcons.Close, + onClickClearIcon: () -> Unit = { onValueChange("") }, + onKeyboardActions: (() -> Unit)? = null, + leadingIcon: @Composable (() -> Unit)? = null, + trailingIcon: @Composable (() -> Unit)? = null, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + val isFocused by interactionSource.collectIsFocusedAsState() + + MifosCustomTextField( + modifier = modifier.fillMaxWidth(), + value = value, + onValueChange = onValueChange, + label = label, + readOnly = readOnly, + supportingText = { + if (isError) { + Text(text = errorMessage) + } + }, + singleLine = singleLine, + leadingIcon = leadingIcon, + trailingIcon = @Composable { + if (showClearIcon && isFocused) { + ClearIconButton( + showClearIcon = true, + clearIcon = clearIcon, + onClickClearIcon = onClickClearIcon, + ) + } else { + trailingIcon?.invoke() + } + }, + keyboardActions = KeyboardActions { + onKeyboardActions?.invoke() + }, + keyboardOptions = keyboardOptions, + interactionSource = interactionSource, + textStyle = LocalDensity.current.run { + TextStyle(fontSize = 18.sp, color = MaterialTheme.colorScheme.onSurface) + }, + ) +} + +@Composable +fun MifosTextField( + value: String, + onValueChange: (String) -> Unit, + label: String, + modifier: Modifier = Modifier, + enabled: Boolean = true, + showClearIcon: Boolean = true, + readOnly: Boolean = false, + clearIcon: ImageVector = MifosIcons.Close, + isError: Boolean = false, + errorText: String? = null, + onClickClearIcon: () -> Unit = { onValueChange("") }, + textStyle: TextStyle = LocalTextStyle.current, + visualTransformation: VisualTransformation = VisualTransformation.None, + keyboardActions: KeyboardActions = KeyboardActions.Default, + singleLine: Boolean = true, + maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, + minLines: Int = 1, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + keyboardOptions: KeyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), + trailingIcon: @Composable (() -> Unit)? = null, + leadingIcon: @Composable (() -> Unit)? = null, +) { + val isFocused by interactionSource.collectIsFocusedAsState() + + MifosCustomTextField( + value = value, + label = label, + onValueChange = onValueChange, + textStyle = textStyle, + modifier = modifier.fillMaxWidth(), + enabled = enabled, + readOnly = readOnly, + visualTransformation = visualTransformation, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, + interactionSource = interactionSource, + singleLine = singleLine, + maxLines = maxLines, + minLines = minLines, + leadingIcon = leadingIcon, + isError = isError, + trailingIcon = @Composable { + if (showClearIcon && isFocused) { + ClearIconButton( + showClearIcon = true, + clearIcon = clearIcon, + onClickClearIcon = onClickClearIcon, + ) + } else { + trailingIcon?.invoke() + } + }, + supportingText = errorText?.let { + { + Text( + modifier = Modifier.testTag("errorTag"), + text = it, + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.error, + ) + } + }, + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MifosCustomTextField( + value: String, + onValueChange: (String) -> Unit, + label: String, + modifier: Modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp), + enabled: Boolean = true, + readOnly: Boolean = false, + textStyle: TextStyle = LocalTextStyle.current, + visualTransformation: VisualTransformation = VisualTransformation.None, + keyboardActions: KeyboardActions = KeyboardActions.Default, + singleLine: Boolean = true, + maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, + minLines: Int = 1, + isError: Boolean = false, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + keyboardOptions: KeyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), + trailingIcon: @Composable (() -> Unit)? = null, + leadingIcon: @Composable (() -> Unit)? = null, + supportingText: @Composable (() -> Unit)? = null, +) { + val colors = TextFieldDefaults.colors().copy( + cursorColor = MaterialTheme.colorScheme.primary, + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + errorContainerColor = Color.Transparent, + focusedIndicatorColor = MaterialTheme.colorScheme.primary, + unfocusedIndicatorColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.05f), + focusedTrailingIconColor = NewUi.onSurface.copy(0.5f), + unfocusedTrailingIconColor = NewUi.onSurface.copy(0.5f), + ) + BasicTextField( + value = value, + onValueChange = onValueChange, + modifier = modifier, + interactionSource = interactionSource, + enabled = enabled, + singleLine = singleLine, + readOnly = readOnly, + textStyle = textStyle, + visualTransformation = visualTransformation, + keyboardActions = keyboardActions, + maxLines = maxLines, + minLines = minLines, + keyboardOptions = keyboardOptions, + cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), + ) { + TextFieldDefaults.DecorationBox( + value = value, + visualTransformation = VisualTransformation.None, + innerTextField = it, + singleLine = singleLine, + enabled = enabled, + interactionSource = interactionSource, + label = { + Text( + text = label, + color = MaterialTheme.colorScheme.primary, + style = MaterialTheme.typography.labelLarge, + modifier = Modifier.padding(bottom = 10.dp), + ) + }, + trailingIcon = trailingIcon, + leadingIcon = leadingIcon, + supportingText = supportingText, + colors = colors, + isError = isError, + contentPadding = PaddingValues(bottom = 10.dp), + container = { + TextFieldDefaults.Container( + enabled = enabled, + isError = isError, + colors = colors, + interactionSource = interactionSource, + shape = RectangleShape, + focusedIndicatorLineThickness = 1.dp, + unfocusedIndicatorLineThickness = 1.dp, + ) + }, + ) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MifosCustomTextField( + value: TextFieldValue, + onValueChange: (TextFieldValue) -> Unit, + label: String, + modifier: Modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp), + enabled: Boolean = true, + readOnly: Boolean = false, + textStyle: TextStyle = LocalTextStyle.current, + visualTransformation: VisualTransformation = VisualTransformation.None, + keyboardActions: KeyboardActions = KeyboardActions.Default, + singleLine: Boolean = true, + maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, + minLines: Int = 1, + isError: Boolean = false, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + keyboardOptions: KeyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), + trailingIcon: @Composable (() -> Unit)? = null, + leadingIcon: @Composable (() -> Unit)? = null, + supportingText: @Composable (() -> Unit)? = null, +) { + val colors = TextFieldDefaults.colors().copy( + cursorColor = MaterialTheme.colorScheme.primary, + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + errorContainerColor = Color.Transparent, + focusedIndicatorColor = MaterialTheme.colorScheme.primary, + unfocusedIndicatorColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.05f), + focusedTrailingIconColor = NewUi.onSurface.copy(0.15f), + unfocusedTrailingIconColor = NewUi.onSurface.copy(0.15f), + ) + BasicTextField( + value = value, + onValueChange = onValueChange, + modifier = modifier, + interactionSource = interactionSource, + enabled = enabled, + singleLine = singleLine, + readOnly = readOnly, + textStyle = textStyle, + visualTransformation = visualTransformation, + keyboardActions = keyboardActions, + maxLines = maxLines, + minLines = minLines, + keyboardOptions = keyboardOptions, + cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), + ) { + TextFieldDefaults.DecorationBox( + value = value.text, + visualTransformation = VisualTransformation.None, + innerTextField = it, + singleLine = singleLine, + enabled = enabled, + interactionSource = interactionSource, + label = { + Text( + text = label, + color = MaterialTheme.colorScheme.primary, + style = MaterialTheme.typography.labelLarge, + modifier = Modifier.padding(bottom = 10.dp), + ) + }, + trailingIcon = trailingIcon, + leadingIcon = leadingIcon, + supportingText = supportingText, + colors = colors, + isError = isError, + contentPadding = PaddingValues(bottom = 10.dp), + container = { + TextFieldDefaults.Container( + enabled = enabled, + isError = isError, + colors = colors, + interactionSource = interactionSource, + shape = RectangleShape, + focusedIndicatorLineThickness = 1.dp, + unfocusedIndicatorLineThickness = 1.dp, + ) + }, + ) + } +} + +@Composable +private fun ClearIconButton( + showClearIcon: Boolean, + clearIcon: ImageVector, + onClickClearIcon: () -> Unit, + modifier: Modifier = Modifier, +) { + AnimatedVisibility( + visible = showClearIcon, + modifier = modifier, + ) { + IconButton( + onClick = onClickClearIcon, + modifier = Modifier.semantics { + contentDescription = "clearIcon" + }, + ) { + Icon( + imageVector = clearIcon, + contentDescription = "trailingIcon", + ) + } + } +} diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/TextUserImage.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/TextUserImage.kt similarity index 97% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/TextUserImage.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/TextUserImage.kt index 6be7620d3..a607c6b6f 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/TextUserImage.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/TextUserImage.kt @@ -30,8 +30,7 @@ fun MifosTextUserImage( size: Dp = 100.dp, ) { Box( - modifier = - modifier + modifier = modifier .size(size) .clip(CircleShape) .background(color = MaterialTheme.colorScheme.primary), diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/TopAppBar.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/TopAppBar.kt similarity index 75% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/TopAppBar.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/TopAppBar.kt index 5c01fc963..11c641dc1 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/TopAppBar.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/TopAppBar.kt @@ -11,15 +11,12 @@ package org.mifospay.core.designsystem.component -import androidx.annotation.StringRes -import androidx.compose.foundation.layout.RowScope import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarColors import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable @@ -27,15 +24,14 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview +import org.jetbrains.compose.ui.tooling.preview.Preview import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.core.designsystem.theme.MifosTheme @OptIn(ExperimentalMaterial3Api::class) @Composable fun MifosTopAppBar( - @StringRes titleRes: Int, + titleRes: String, modifier: Modifier = Modifier, navigationIcon: ImageVector? = null, navigationIconContentDescription: String? = null, @@ -46,7 +42,7 @@ fun MifosTopAppBar( onActionClick: (() -> Unit)? = null, ) { CenterAlignedTopAppBar( - title = { Text(text = stringResource(id = titleRes)) }, + title = { Text(text = titleRes) }, navigationIcon = { navigationIcon?.let { IconButton(onClick = onNavigationClick!!) { @@ -74,38 +70,15 @@ fun MifosTopAppBar( ) } -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MifosTopAppBar( - @StringRes titleRes: Int, - modifier: Modifier = Modifier, - actions: - @Composable() - (RowScope.() -> Unit) = {}, - colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - ), -) { - TopAppBar( - title = { Text(text = stringResource(id = titleRes)) }, - actions = actions, - colors = colors, - modifier = modifier.testTag("mifosTopAppBar"), - ) -} - @Composable fun MifosNavigationTopAppBar( - @StringRes titleRes: Int, + titleRes: String, onNavigationClick: (() -> Unit)?, ) { MifosTopAppBar( titleRes = titleRes, navigationIcon = MifosIcons.Back, - navigationIconContentDescription = - stringResource( - id = titleRes, - ), + navigationIconContentDescription = titleRes, colors = TopAppBarDefaults.centerAlignedTopAppBarColors( containerColor = Color.Transparent, @@ -115,12 +88,12 @@ fun MifosNavigationTopAppBar( } @OptIn(ExperimentalMaterial3Api::class) -@Preview("Top App Bar") +@Preview @Composable private fun MifosTopAppBarPreview() { MifosTheme { MifosTopAppBar( - titleRes = android.R.string.untitled, + titleRes = "Demo Preview", navigationIcon = MifosIcons.Search, navigationIconContentDescription = "Navigation icon", actionIcon = MifosIcons.MoreVert, diff --git a/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/AppScrollbars.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/AppScrollbars.kt new file mode 100644 index 000000000..292477587 --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/AppScrollbars.kt @@ -0,0 +1,246 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.component.scrollbar + +import androidx.compose.animation.animateColorAsState +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.SpringSpec +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.gestures.Orientation.Horizontal +import androidx.compose.foundation.gestures.Orientation.Vertical +import androidx.compose.foundation.gestures.ScrollableState +import androidx.compose.foundation.interaction.InteractionSource +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsDraggedAsState +import androidx.compose.foundation.interaction.collectIsHoveredAsState +import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.State +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorProducer +import androidx.compose.ui.graphics.Outline +import androidx.compose.ui.graphics.drawOutline +import androidx.compose.ui.graphics.drawscope.ContentDrawScope +import androidx.compose.ui.node.DrawModifierNode +import androidx.compose.ui.node.ModifierNodeElement +import androidx.compose.ui.node.invalidateDraw +import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.delay +import org.mifospay.core.designsystem.component.scrollbar.ThumbState.Active +import org.mifospay.core.designsystem.component.scrollbar.ThumbState.Dormant +import org.mifospay.core.designsystem.component.scrollbar.ThumbState.Inactive + +/** + * The time period for showing the scrollbar thumb after interacting with it, before it fades away + */ +private const val SCROLLBAR_INACTIVE_TO_DORMANT_TIME_IN_MS = 2_000L + +/** + * A [Scrollbar] that allows for fast scrolling of content by dragging its thumb. + * Its thumb disappears when the scrolling container is dormant. + * @param modifier a [Modifier] for the [Scrollbar] + * @param state the driving state for the [Scrollbar] + * @param orientation the orientation of the scrollbar + * @param onThumbMoved the fast scroll implementation + */ +@Composable +fun ScrollableState.DraggableScrollbar( + state: ScrollbarState, + orientation: Orientation, + onThumbMoved: (Float) -> Unit, + modifier: Modifier = Modifier, +) { + val interactionSource = remember { MutableInteractionSource() } + Scrollbar( + modifier = modifier, + orientation = orientation, + interactionSource = interactionSource, + state = state, + thumb = { + DraggableScrollbarThumb( + interactionSource = interactionSource, + orientation = orientation, + ) + }, + onThumbMoved = onThumbMoved, + ) +} + +/** + * A simple [Scrollbar]. + * Its thumb disappears when the scrolling container is dormant. + * @param modifier a [Modifier] for the [Scrollbar] + * @param state the driving state for the [Scrollbar] + * @param orientation the orientation of the scrollbar + */ +@Composable +fun ScrollableState.DecorativeScrollbar( + state: ScrollbarState, + orientation: Orientation, + modifier: Modifier = Modifier, +) { + val interactionSource = remember { MutableInteractionSource() } + Scrollbar( + modifier = modifier, + orientation = orientation, + interactionSource = interactionSource, + state = state, + thumb = { + DecorativeScrollbarThumb( + interactionSource = interactionSource, + orientation = orientation, + ) + }, + ) +} + +/** + * A scrollbar thumb that is intended to also be a touch target for fast scrolling. + */ +@Composable +private fun ScrollableState.DraggableScrollbarThumb( + interactionSource: InteractionSource, + orientation: Orientation, +) { + Box( + modifier = Modifier + .run { + when (orientation) { + Vertical -> width(12.dp).fillMaxHeight() + Horizontal -> height(12.dp).fillMaxWidth() + } + } + .scrollThumb(this, interactionSource), + ) +} + +/** + * A decorative scrollbar thumb used solely for communicating a user's position in a list. + */ +@Composable +private fun ScrollableState.DecorativeScrollbarThumb( + interactionSource: InteractionSource, + orientation: Orientation, +) { + Box( + modifier = Modifier + .run { + when (orientation) { + Vertical -> width(2.dp).fillMaxHeight() + Horizontal -> height(2.dp).fillMaxWidth() + } + } + .scrollThumb(this, interactionSource), + ) +} + +@Composable +private fun Modifier.scrollThumb( + scrollableState: ScrollableState, + interactionSource: InteractionSource, +): Modifier { + val colorState = scrollbarThumbColor(scrollableState, interactionSource) + return this then ScrollThumbElement { colorState.value } +} + +private data class ScrollThumbElement(val colorProducer: ColorProducer) : + ModifierNodeElement() { + override fun create(): ScrollThumbNode = ScrollThumbNode(colorProducer) + override fun update(node: ScrollThumbNode) { + node.colorProducer = colorProducer + node.invalidateDraw() + } +} + +private class ScrollThumbNode(var colorProducer: ColorProducer) : DrawModifierNode, Modifier.Node() { + private val shape = RoundedCornerShape(16.dp) + + // naive cache outline calculation if size is the same + private var lastSize: Size? = null + private var lastLayoutDirection: LayoutDirection? = null + private var lastOutline: Outline? = null + + override fun ContentDrawScope.draw() { + val color = colorProducer() + val outline = + if (size == lastSize && layoutDirection == lastLayoutDirection) { + lastOutline!! + } else { + shape.createOutline(size, layoutDirection, this) + } + if (color != Color.Unspecified) drawOutline(outline, color = color) + + lastOutline = outline + lastSize = size + lastLayoutDirection = layoutDirection + } +} + +/** + * The color of the scrollbar thumb as a function of its interaction state. + * @param interactionSource source of interactions in the scrolling container + */ +@Composable +private fun scrollbarThumbColor( + scrollableState: ScrollableState, + interactionSource: InteractionSource, +): State { + var state by remember { mutableStateOf(Dormant) } + val pressed by interactionSource.collectIsPressedAsState() + val hovered by interactionSource.collectIsHoveredAsState() + val dragged by interactionSource.collectIsDraggedAsState() + val active = (scrollableState.canScrollForward || scrollableState.canScrollBackward) && + (pressed || hovered || dragged || scrollableState.isScrollInProgress) + + val color = animateColorAsState( + targetValue = when (state) { + Active -> MaterialTheme.colorScheme.onSurface.copy(0.5f) + Inactive -> MaterialTheme.colorScheme.onSurface.copy(alpha = 0.2f) + Dormant -> Color.Transparent + }, + animationSpec = SpringSpec( + stiffness = Spring.StiffnessLow, + ), + label = "Scrollbar thumb color", + ) + LaunchedEffect(active) { + when (active) { + true -> state = Active + false -> if (state == Active) { + state = Inactive + delay(SCROLLBAR_INACTIVE_TO_DORMANT_TIME_IN_MS) + state = Dormant + } + } + } + + return color +} + +private enum class ThumbState { + Active, + Inactive, + Dormant, +} diff --git a/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt new file mode 100644 index 000000000..898431341 --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt @@ -0,0 +1,81 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.component.scrollbar + +import androidx.compose.foundation.gestures.ScrollableState +import kotlin.math.abs + +/** + * Linearly interpolates the index for the first item in [visibleItems] for smooth scrollbar + * progression. + * @param visibleItems a list of items currently visible in the layout. + * @param itemSize a lookup function for the size of an item in the layout. + * @param offset a lookup function for the offset of an item relative to the start of the view port. + * @param nextItemOnMainAxis a lookup function for the next item on the main axis in the direction + * of the scroll. + * @param itemIndex a lookup function for index of an item in the layout relative to + * the total amount of items available. + * + * @return a [Float] in the range [firstItemPosition..nextItemPosition) where nextItemPosition + * is the index of the consecutive item along the major axis. + * */ +internal inline fun LazyState.interpolateFirstItemIndex( + visibleItems: List, + crossinline itemSize: LazyState.(LazyStateItem) -> Int, + crossinline offset: LazyState.(LazyStateItem) -> Int, + crossinline nextItemOnMainAxis: LazyState.(LazyStateItem) -> LazyStateItem?, + crossinline itemIndex: (LazyStateItem) -> Int, +): Float { + if (visibleItems.isEmpty()) return 0f + + val firstItem = visibleItems.first() + val firstItemIndex = itemIndex(firstItem) + + if (firstItemIndex < 0) return Float.NaN + + val firstItemSize = itemSize(firstItem) + if (firstItemSize == 0) return Float.NaN + + val itemOffset = offset(firstItem).toFloat() + val offsetPercentage = abs(itemOffset) / firstItemSize + + val nextItem = nextItemOnMainAxis(firstItem) ?: return firstItemIndex + offsetPercentage + + val nextItemIndex = itemIndex(nextItem) + + return firstItemIndex + ((nextItemIndex - firstItemIndex) * offsetPercentage) +} + +/** + * Returns the percentage of an item that is currently visible in the view port. + * @param itemSize the size of the item + * @param itemStartOffset the start offset of the item relative to the view port start + * @param viewportStartOffset the start offset of the view port + * @param viewportEndOffset the end offset of the view port + */ +internal fun itemVisibilityPercentage( + itemSize: Int, + itemStartOffset: Int, + viewportStartOffset: Int, + viewportEndOffset: Int, +): Float { + if (itemSize == 0) return 0f + val itemEnd = itemStartOffset + itemSize + val startOffset = when { + itemStartOffset > viewportStartOffset -> 0 + else -> abs(abs(viewportStartOffset) - abs(itemStartOffset)) + } + val endOffset = when { + itemEnd < viewportEndOffset -> 0 + else -> abs(abs(itemEnd) - abs(viewportEndOffset)) + } + val size = itemSize.toFloat() + return (size - startOffset - endOffset) / size +} diff --git a/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/Scrollbar.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/Scrollbar.kt new file mode 100644 index 000000000..5434926a6 --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/Scrollbar.kt @@ -0,0 +1,412 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.component.scrollbar + +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.gestures.Orientation.Horizontal +import androidx.compose.foundation.gestures.Orientation.Vertical +import androidx.compose.foundation.gestures.detectHorizontalDragGestures +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.foundation.gestures.detectVerticalDragGestures +import androidx.compose.foundation.hoverable +import androidx.compose.foundation.interaction.DragInteraction +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.PressInteraction +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf +import androidx.compose.runtime.mutableLongStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.input.pointer.PointerInputChange +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.layout.Layout +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.layout.positionInRoot +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.IntSize +import androidx.compose.ui.unit.dp +import androidx.compose.ui.util.packFloats +import androidx.compose.ui.util.unpackFloat1 +import androidx.compose.ui.util.unpackFloat2 +import kotlinx.coroutines.TimeoutCancellationException +import kotlinx.coroutines.delay +import kotlinx.coroutines.withTimeout +import kotlin.jvm.JvmInline +import kotlin.math.max +import kotlin.math.min +import kotlin.math.roundToInt + +/** + * The delay between scrolls when a user long presses on the scrollbar track to initiate a scroll + * instead of dragging the scrollbar thumb. + */ +private const val SCROLLBAR_PRESS_DELAY_MS = 10L + +/** + * The percentage displacement of the scrollbar when scrolled by long presses on the scrollbar + * track. + */ +private const val SCROLLBAR_PRESS_DELTA_PCT = 0.02f + +class ScrollbarState { + private var packedValue by mutableLongStateOf(0L) + + internal fun onScroll(stateValue: ScrollbarStateValue) { + packedValue = stateValue.packedValue + } + + /** + * Returns the thumb size of the scrollbar as a percentage of the total track size + */ + val thumbSizePercent + get() = unpackFloat1(packedValue) + + /** + * Returns the distance the thumb has traveled as a percentage of total track size + */ + val thumbMovedPercent + get() = unpackFloat2(packedValue) + + /** + * Returns the max distance the thumb can travel as a percentage of total track size + */ + val thumbTrackSizePercent + get() = 1f - thumbSizePercent +} + +/** + * Returns the size of the scrollbar track in pixels + */ +private val ScrollbarTrack.size + get() = unpackFloat2(packedValue) - unpackFloat1(packedValue) + +/** + * Returns the position of the scrollbar thumb on the track as a percentage + */ +private fun ScrollbarTrack.thumbPosition( + dimension: Float, +): Float = max( + a = min( + a = dimension / size, + b = 1f, + ), + b = 0f, +) + +/** + * Class definition for the core properties of a scroll bar + */ +@Immutable +@JvmInline +value class ScrollbarStateValue internal constructor( + internal val packedValue: Long, +) + +/** + * Class definition for the core properties of a scroll bar track + */ +@Immutable +@JvmInline +private value class ScrollbarTrack( + val packedValue: Long, +) { + constructor( + max: Float, + min: Float, + ) : this(packFloats(max, min)) +} + +/** + * Creates a [ScrollbarStateValue] with the listed properties + * @param thumbSizePercent the thumb size of the scrollbar as a percentage of the total track size. + * Refers to either the thumb width (for horizontal scrollbars) + * or height (for vertical scrollbars). + * @param thumbMovedPercent the distance the thumb has traveled as a percentage of total + * track size. + */ +fun scrollbarStateValue( + thumbSizePercent: Float, + thumbMovedPercent: Float, +) = ScrollbarStateValue( + packFloats( + val1 = thumbSizePercent, + val2 = thumbMovedPercent, + ), +) + +/** + * Returns the value of [offset] along the axis specified by [this] + */ +internal fun Orientation.valueOf(offset: Offset) = when (this) { + Orientation.Horizontal -> offset.x + Orientation.Vertical -> offset.y +} + +/** + * Returns the value of [intSize] along the axis specified by [this] + */ +internal fun Orientation.valueOf(intSize: IntSize) = when (this) { + Orientation.Horizontal -> intSize.width + Orientation.Vertical -> intSize.height +} + +/** + * Returns the value of [intOffset] along the axis specified by [this] + */ +internal fun Orientation.valueOf(intOffset: IntOffset) = when (this) { + Orientation.Horizontal -> intOffset.x + Orientation.Vertical -> intOffset.y +} + +/** + * A Composable for drawing a scrollbar + * @param orientation the scroll direction of the scrollbar + * @param state the state describing the position of the scrollbar + * @param minThumbSize the minimum size of the scrollbar thumb + * @param interactionSource allows for observing the state of the scroll bar + * @param thumb a composable for drawing the scrollbar thumb + * @param onThumbMoved an function for reacting to scroll bar displacements caused by direct + * interactions on the scrollbar thumb by the user, for example implementing a fast scroll + */ +@Composable +fun Scrollbar( + orientation: Orientation, + state: ScrollbarState, + modifier: Modifier = Modifier, + interactionSource: MutableInteractionSource? = null, + minThumbSize: Dp = 40.dp, + onThumbMoved: ((Float) -> Unit)? = null, + thumb: @Composable () -> Unit, +) { + // Using Offset.Unspecified and Float.NaN instead of null + // to prevent unnecessary boxing of primitives + var pressedOffset by remember { mutableStateOf(Offset.Unspecified) } + var draggedOffset by remember { mutableStateOf(Offset.Unspecified) } + + // Used to immediately show drag feedback in the UI while the scrolling implementation + // catches up + var interactionThumbTravelPercent by remember { mutableFloatStateOf(Float.NaN) } + + var track by remember { mutableStateOf(ScrollbarTrack(packedValue = 0)) } + + // scrollbar track container + Box( + modifier = modifier + .run { + val withHover = interactionSource?.let(::hoverable) ?: this + when (orientation) { + Orientation.Vertical -> withHover.fillMaxHeight() + Orientation.Horizontal -> withHover.fillMaxWidth() + } + } + .onGloballyPositioned { coordinates -> + val scrollbarStartCoordinate = orientation.valueOf(coordinates.positionInRoot()) + track = ScrollbarTrack( + max = scrollbarStartCoordinate, + min = scrollbarStartCoordinate + orientation.valueOf(coordinates.size), + ) + } + // Process scrollbar presses + .pointerInput(Unit) { + detectTapGestures( + onPress = { offset -> + try { + // Wait for a long press before scrolling + withTimeout(viewConfiguration.longPressTimeoutMillis) { + tryAwaitRelease() + } + } catch (e: TimeoutCancellationException) { + // Start the press triggered scroll + val initialPress = PressInteraction.Press(offset) + interactionSource?.tryEmit(initialPress) + + pressedOffset = offset + interactionSource?.tryEmit( + when { + tryAwaitRelease() -> PressInteraction.Release(initialPress) + else -> PressInteraction.Cancel(initialPress) + }, + ) + + // End the press + pressedOffset = Offset.Unspecified + } + }, + ) + } + // Process scrollbar drags + .pointerInput(Unit) { + var dragInteraction: DragInteraction.Start? = null + val onDragStart: (Offset) -> Unit = { offset -> + val start = DragInteraction.Start() + dragInteraction = start + interactionSource?.tryEmit(start) + draggedOffset = offset + } + val onDragEnd: () -> Unit = { + dragInteraction?.let { interactionSource?.tryEmit(DragInteraction.Stop(it)) } + draggedOffset = Offset.Unspecified + } + val onDragCancel: () -> Unit = { + dragInteraction?.let { interactionSource?.tryEmit(DragInteraction.Cancel(it)) } + draggedOffset = Offset.Unspecified + } + val onDrag: (change: PointerInputChange, dragAmount: Float) -> Unit = + onDrag@{ _, delta -> + if (draggedOffset == Offset.Unspecified) return@onDrag + draggedOffset = when (orientation) { + Orientation.Vertical -> draggedOffset.copy( + y = draggedOffset.y + delta, + ) + + Orientation.Horizontal -> draggedOffset.copy( + x = draggedOffset.x + delta, + ) + } + } + + when (orientation) { + Orientation.Horizontal -> detectHorizontalDragGestures( + onDragStart = onDragStart, + onDragEnd = onDragEnd, + onDragCancel = onDragCancel, + onHorizontalDrag = onDrag, + ) + + Orientation.Vertical -> detectVerticalDragGestures( + onDragStart = onDragStart, + onDragEnd = onDragEnd, + onDragCancel = onDragCancel, + onVerticalDrag = onDrag, + ) + } + }, + ) { + // scrollbar thumb container + Layout(content = { thumb() }) { measurables, constraints -> + val measurable = measurables.first() + + val thumbSizePx = max( + a = state.thumbSizePercent * track.size, + b = minThumbSize.toPx(), + ) + + val trackSizePx = when (state.thumbTrackSizePercent) { + 0f -> track.size + else -> (track.size - thumbSizePx) / state.thumbTrackSizePercent + } + + val thumbTravelPercent = max( + a = min( + a = when { + interactionThumbTravelPercent.isNaN() -> state.thumbMovedPercent + else -> interactionThumbTravelPercent + }, + b = state.thumbTrackSizePercent, + ), + b = 0f, + ) + + val thumbMovedPx = trackSizePx * thumbTravelPercent + + val y = when (orientation) { + Horizontal -> 0 + Vertical -> thumbMovedPx.roundToInt() + } + val x = when (orientation) { + Horizontal -> thumbMovedPx.roundToInt() + Vertical -> 0 + } + + val updatedConstraints = when (orientation) { + Horizontal -> { + constraints.copy( + minWidth = thumbSizePx.roundToInt(), + maxWidth = thumbSizePx.roundToInt(), + ) + } + Vertical -> { + constraints.copy( + minHeight = thumbSizePx.roundToInt(), + maxHeight = thumbSizePx.roundToInt(), + ) + } + } + + val placeable = measurable.measure(updatedConstraints) + layout(placeable.width, placeable.height) { + placeable.place(x, y) + } + } + } + + if (onThumbMoved == null) return + + // Process presses + LaunchedEffect(Unit) { + snapshotFlow { pressedOffset }.collect { pressedOffset -> + // Press ended, reset interactionThumbTravelPercent + if (pressedOffset == Offset.Unspecified) { + interactionThumbTravelPercent = Float.NaN + return@collect + } + + var currentThumbMovedPercent = state.thumbMovedPercent + val destinationThumbMovedPercent = track.thumbPosition( + dimension = orientation.valueOf(pressedOffset), + ) + val isPositive = currentThumbMovedPercent < destinationThumbMovedPercent + val delta = SCROLLBAR_PRESS_DELTA_PCT * if (isPositive) 1f else -1f + + while (currentThumbMovedPercent != destinationThumbMovedPercent) { + currentThumbMovedPercent = when { + isPositive -> min( + a = currentThumbMovedPercent + delta, + b = destinationThumbMovedPercent, + ) + + else -> max( + a = currentThumbMovedPercent + delta, + b = destinationThumbMovedPercent, + ) + } + onThumbMoved(currentThumbMovedPercent) + interactionThumbTravelPercent = currentThumbMovedPercent + delay(SCROLLBAR_PRESS_DELAY_MS) + } + } + } + + // Process drags + LaunchedEffect(Unit) { + snapshotFlow { draggedOffset }.collect { draggedOffset -> + if (draggedOffset == Offset.Unspecified) { + interactionThumbTravelPercent = Float.NaN + return@collect + } + val currentTravel = track.thumbPosition( + dimension = orientation.valueOf(draggedOffset), + ) + onThumbMoved(currentTravel) + interactionThumbTravelPercent = currentTravel + } + } +} diff --git a/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/ScrollbarExt.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/ScrollbarExt.kt new file mode 100644 index 000000000..f61cecd85 --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/ScrollbarExt.kt @@ -0,0 +1,227 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.component.scrollbar + +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.lazy.LazyListItemInfo +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.grid.LazyGridItemInfo +import androidx.compose.foundation.lazy.grid.LazyGridState +import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridItemInfo +import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember +import androidx.compose.runtime.snapshotFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filterNotNull +import kotlin.math.min + +/** + * Calculates a [ScrollbarState] driven by the changes in a [LazyListState]. + * + * @param itemsAvailable the total amount of items available to scroll in the lazy list. + * @param itemIndex a lookup function for index of an item in the list relative to [itemsAvailable]. + */ +@Composable +fun LazyListState.scrollbarState( + itemsAvailable: Int, + itemIndex: (LazyListItemInfo) -> Int = LazyListItemInfo::index, +): ScrollbarState { + val state = remember { ScrollbarState() } + LaunchedEffect(this, itemsAvailable) { + snapshotFlow { + if (itemsAvailable == 0) return@snapshotFlow null + + val visibleItemsInfo = layoutInfo.visibleItemsInfo + if (visibleItemsInfo.isEmpty()) return@snapshotFlow null + + val firstIndex = min( + a = interpolateFirstItemIndex( + visibleItems = visibleItemsInfo, + itemSize = { it.size }, + offset = { it.offset }, + nextItemOnMainAxis = { first -> visibleItemsInfo.find { it != first } }, + itemIndex = itemIndex, + ), + b = itemsAvailable.toFloat(), + ) + if (firstIndex.isNaN()) return@snapshotFlow null + + val itemsVisible = visibleItemsInfo.floatSumOf { itemInfo -> + itemVisibilityPercentage( + itemSize = itemInfo.size, + itemStartOffset = itemInfo.offset, + viewportStartOffset = layoutInfo.viewportStartOffset, + viewportEndOffset = layoutInfo.viewportEndOffset, + ) + } + + val thumbTravelPercent = min( + a = firstIndex / itemsAvailable, + b = 1f, + ) + val thumbSizePercent = min( + a = itemsVisible / itemsAvailable, + b = 1f, + ) + scrollbarStateValue( + thumbSizePercent = thumbSizePercent, + thumbMovedPercent = when { + layoutInfo.reverseLayout -> 1f - thumbTravelPercent + else -> thumbTravelPercent + }, + ) + } + .filterNotNull() + .distinctUntilChanged() + .collect { state.onScroll(it) } + } + return state +} + +/** + * Calculates a [ScrollbarState] driven by the changes in a [LazyGridState] + * + * @param itemsAvailable the total amount of items available to scroll in the grid. + * @param itemIndex a lookup function for index of an item in the grid relative to [itemsAvailable]. + */ +@Composable +fun LazyGridState.scrollbarState( + itemsAvailable: Int, + itemIndex: (LazyGridItemInfo) -> Int = LazyGridItemInfo::index, +): ScrollbarState { + val state = remember { ScrollbarState() } + LaunchedEffect(this, itemsAvailable) { + snapshotFlow { + if (itemsAvailable == 0) return@snapshotFlow null + + val visibleItemsInfo = layoutInfo.visibleItemsInfo + if (visibleItemsInfo.isEmpty()) return@snapshotFlow null + + val firstIndex = min( + a = interpolateFirstItemIndex( + visibleItems = visibleItemsInfo, + itemSize = { layoutInfo.orientation.valueOf(it.size) }, + offset = { layoutInfo.orientation.valueOf(it.offset) }, + nextItemOnMainAxis = { first -> + when (layoutInfo.orientation) { + Orientation.Vertical -> visibleItemsInfo.find { + it != first && it.row != first.row + } + + Orientation.Horizontal -> visibleItemsInfo.find { + it != first && it.column != first.column + } + } + }, + itemIndex = itemIndex, + ), + b = itemsAvailable.toFloat(), + ) + if (firstIndex.isNaN()) return@snapshotFlow null + + val itemsVisible = visibleItemsInfo.floatSumOf { itemInfo -> + itemVisibilityPercentage( + itemSize = layoutInfo.orientation.valueOf(itemInfo.size), + itemStartOffset = layoutInfo.orientation.valueOf(itemInfo.offset), + viewportStartOffset = layoutInfo.viewportStartOffset, + viewportEndOffset = layoutInfo.viewportEndOffset, + ) + } + + val thumbTravelPercent = min( + a = firstIndex / itemsAvailable, + b = 1f, + ) + val thumbSizePercent = min( + a = itemsVisible / itemsAvailable, + b = 1f, + ) + scrollbarStateValue( + thumbSizePercent = thumbSizePercent, + thumbMovedPercent = when { + layoutInfo.reverseLayout -> 1f - thumbTravelPercent + else -> thumbTravelPercent + }, + ) + } + .filterNotNull() + .distinctUntilChanged() + .collect { state.onScroll(it) } + } + return state +} + +/** + * Remembers a [ScrollbarState] driven by the changes in a [LazyStaggeredGridState] + * + * @param itemsAvailable the total amount of items available to scroll in the staggered grid. + * @param itemIndex a lookup function for index of an item in the staggered grid relative + * to [itemsAvailable]. + */ +@Composable +fun LazyStaggeredGridState.scrollbarState( + itemsAvailable: Int, + itemIndex: (LazyStaggeredGridItemInfo) -> Int = LazyStaggeredGridItemInfo::index, +): ScrollbarState { + val state = remember { ScrollbarState() } + LaunchedEffect(this, itemsAvailable) { + snapshotFlow { + if (itemsAvailable == 0) return@snapshotFlow null + + val visibleItemsInfo = layoutInfo.visibleItemsInfo + if (visibleItemsInfo.isEmpty()) return@snapshotFlow null + + val firstIndex = min( + a = interpolateFirstItemIndex( + visibleItems = visibleItemsInfo, + itemSize = { layoutInfo.orientation.valueOf(it.size) }, + offset = { layoutInfo.orientation.valueOf(it.offset) }, + nextItemOnMainAxis = { first -> + visibleItemsInfo.find { it != first && it.lane == first.lane } + }, + itemIndex = itemIndex, + ), + b = itemsAvailable.toFloat(), + ) + if (firstIndex.isNaN()) return@snapshotFlow null + + val itemsVisible = visibleItemsInfo.floatSumOf { itemInfo -> + itemVisibilityPercentage( + itemSize = layoutInfo.orientation.valueOf(itemInfo.size), + itemStartOffset = layoutInfo.orientation.valueOf(itemInfo.offset), + viewportStartOffset = layoutInfo.viewportStartOffset, + viewportEndOffset = layoutInfo.viewportEndOffset, + ) + } + + val thumbTravelPercent = min( + a = firstIndex / itemsAvailable, + b = 1f, + ) + val thumbSizePercent = min( + a = itemsVisible / itemsAvailable, + b = 1f, + ) + scrollbarStateValue( + thumbSizePercent = thumbSizePercent, + thumbMovedPercent = thumbTravelPercent, + ) + } + .filterNotNull() + .distinctUntilChanged() + .collect { state.onScroll(it) } + } + return state +} + +private inline fun List.floatSumOf(selector: (T) -> Float): Float = + fold(initial = 0f) { accumulator, listItem -> accumulator + selector(listItem) } diff --git a/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/ThumbExt.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/ThumbExt.kt new file mode 100644 index 000000000..4d64e992e --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/component/scrollbar/ThumbExt.kt @@ -0,0 +1,82 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.component.scrollbar + +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.grid.LazyGridState +import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.setValue +import kotlin.math.roundToInt + +/** + * Remembers a function to react to [Scrollbar] thumb position displacements for a [LazyListState] + * @param itemsAvailable the amount of items in the list. + */ +@Composable +fun LazyListState.rememberDraggableScroller( + itemsAvailable: Int, +): (Float) -> Unit = rememberDraggableScroller( + itemsAvailable = itemsAvailable, + scroll = ::scrollToItem, +) + +/** + * Remembers a function to react to [Scrollbar] thumb position displacements for a [LazyGridState] + * @param itemsAvailable the amount of items in the grid. + */ +@Composable +fun LazyGridState.rememberDraggableScroller( + itemsAvailable: Int, +): (Float) -> Unit = rememberDraggableScroller( + itemsAvailable = itemsAvailable, + scroll = ::scrollToItem, +) + +/** + * Remembers a function to react to [Scrollbar] thumb position displacements for a + * [LazyStaggeredGridState] + * @param itemsAvailable the amount of items in the staggered grid. + */ +@Composable +fun LazyStaggeredGridState.rememberDraggableScroller( + itemsAvailable: Int, +): (Float) -> Unit = rememberDraggableScroller( + itemsAvailable = itemsAvailable, + scroll = ::scrollToItem, +) + +/** + * Generic function to react to [Scrollbar] thumb displacements in a lazy layout. + * @param itemsAvailable the total amount of items available to scroll in the layout. + * @param scroll a function to be invoked when an index has been identified to scroll to. + */ +@Composable +private inline fun rememberDraggableScroller( + itemsAvailable: Int, + crossinline scroll: suspend (index: Int) -> Unit, +): (Float) -> Unit { + var percentage by remember { mutableFloatStateOf(Float.NaN) } + val itemCount by rememberUpdatedState(itemsAvailable) + + LaunchedEffect(percentage) { + if (percentage.isNaN()) return@LaunchedEffect + val indexToFind = (itemCount * percentage).roundToInt() + scroll(indexToFind) + } + return remember { + { newPercentage -> percentage = newPercentage } + } +} diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/icon/MifosIcons.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/icon/MifosIcons.kt similarity index 70% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/icon/MifosIcons.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/icon/MifosIcons.kt index 553fe7e3c..5bca46905 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/icon/MifosIcons.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/icon/MifosIcons.kt @@ -14,32 +14,45 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material.icons.filled.ArrowOutward import androidx.compose.material.icons.filled.AttachMoney +import androidx.compose.material.icons.filled.Badge +import androidx.compose.material.icons.filled.CalendarMonth import androidx.compose.material.icons.filled.Camera import androidx.compose.material.icons.filled.Check -import androidx.compose.material.icons.filled.CheckCircleOutline import androidx.compose.material.icons.filled.ChevronLeft import androidx.compose.material.icons.filled.ChevronRight import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.filled.Delete +import androidx.compose.material.icons.filled.Description import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.FlashOff import androidx.compose.material.icons.filled.FlashOn import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.KeyboardArrowDown +import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Photo import androidx.compose.material.icons.filled.PhotoLibrary import androidx.compose.material.icons.filled.QrCode import androidx.compose.material.icons.filled.QrCode2 -import androidx.compose.material.icons.filled.RemoveCircleOutline +import androidx.compose.material.icons.filled.RadioButtonChecked +import androidx.compose.material.icons.filled.RadioButtonUnchecked import androidx.compose.material.icons.filled.Share import androidx.compose.material.icons.filled.Visibility import androidx.compose.material.icons.filled.VisibilityOff import androidx.compose.material.icons.outlined.AccountCircle import androidx.compose.material.icons.outlined.Cancel +import androidx.compose.material.icons.outlined.DeleteOutline +import androidx.compose.material.icons.outlined.DoneAll import androidx.compose.material.icons.outlined.Edit import androidx.compose.material.icons.outlined.Home +import androidx.compose.material.icons.outlined.Info +import androidx.compose.material.icons.outlined.Lock +import androidx.compose.material.icons.outlined.Notifications +import androidx.compose.material.icons.outlined.QrCodeScanner import androidx.compose.material.icons.outlined.Settings +import androidx.compose.material.icons.outlined.Share +import androidx.compose.material.icons.outlined.Visibility +import androidx.compose.material.icons.outlined.VisibilityOff import androidx.compose.material.icons.outlined.Wallet import androidx.compose.material.icons.rounded.AccountBalance import androidx.compose.material.icons.rounded.AccountCircle @@ -59,27 +72,33 @@ import androidx.compose.ui.graphics.vector.ImageVector * Mifos icons. Material icons are [ImageVector]s, custom icons are drawable resource IDs. */ object MifosIcons { + val OutlinedInfo = Icons.Outlined.Info + val OutlinedLock = Icons.Outlined.Lock + val OutlinedNotifications = Icons.Outlined.Notifications val ChevronRight: ImageVector = Icons.Filled.ChevronRight val QrCode: ImageVector = Icons.Filled.QrCode val Close: ImageVector = Icons.Filled.Close val AttachMoney: ImageVector = Icons.Filled.AttachMoney + val OutlinedVisibilityOff: ImageVector = Icons.Outlined.VisibilityOff + val OutlinedVisibility: ImageVector = Icons.Outlined.Visibility val VisibilityOff: ImageVector = Icons.Filled.VisibilityOff val Visibility: ImageVector = Icons.Filled.Visibility val Check: ImageVector = Icons.Default.Check val KeyboardArrowDown: ImageVector = Icons.Default.KeyboardArrowDown - val Home = Icons.Rounded.Home - val HomeBoarder = Icons.Outlined.Home + val Home = Icons.Outlined.Home + val HomeBoarder = Icons.Rounded.Home val Payment = Icons.Rounded.SwapHoriz - val Finance = Icons.Rounded.Wallet - val FinanceBoarder = Icons.Outlined.Wallet - val Profile = Icons.Rounded.AccountCircle - val ProfileBoarder = Icons.Outlined.AccountCircle + val Finance = Icons.Outlined.Wallet + val FinanceBoarder = Icons.Rounded.Wallet + val Profile = Icons.Outlined.AccountCircle + val ProfileBoarder = Icons.Rounded.AccountCircle val MoreVert = Icons.Rounded.MoreVert val Search = Icons.Rounded.Search val Add = Icons.Rounded.Add val Back = Icons.AutoMirrored.Outlined.ArrowBack val Copy = Icons.Filled.ContentCopy val Share = Icons.Filled.Share + val OutlinedShare = Icons.Outlined.Share val ArrowBack = Icons.AutoMirrored.Filled.ArrowBack val ArrowBack2 = Icons.Filled.ChevronLeft val Cancel = Icons.Outlined.Cancel @@ -89,6 +108,7 @@ object MifosIcons { val Camera = Icons.Filled.Camera val PhotoLibrary = Icons.Filled.PhotoLibrary val Delete = Icons.Filled.Delete + val OutlinedDelete = Icons.Outlined.DeleteOutline val RoundedInfo = Icons.Rounded.Info val Contact = Icons.Rounded.Contacts val Settings = Icons.Rounded.Settings @@ -101,6 +121,12 @@ object MifosIcons { val QrCode2 = Icons.Filled.QrCode2 val Edit = Icons.Filled.Edit val Edit2 = Icons.Outlined.Edit - val CheckCircle = Icons.Default.CheckCircleOutline - val CheckCircle2 = Icons.Default.RemoveCircleOutline + val CalenderMonth = Icons.Filled.CalendarMonth + val OutlinedDoneAll = Icons.Outlined.DoneAll + val Person = Icons.Filled.Person + val Badge = Icons.Filled.Badge + val DataInfo = Icons.Filled.Description + val Scan = Icons.Outlined.QrCodeScanner + val RadioButtonUnchecked = Icons.Default.RadioButtonUnchecked + val RadioButtonChecked = Icons.Filled.RadioButtonChecked } diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/BackgroundTheme.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/BackgroundTheme.kt similarity index 100% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/BackgroundTheme.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/BackgroundTheme.kt diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/Color.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/Color.kt similarity index 96% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/Color.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/Color.kt index d609f2815..8ffbff153 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/Color.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/Color.kt @@ -14,7 +14,7 @@ import androidx.compose.ui.graphics.Color val md_theme_light_primary = Color(0xFF0673BA) // primary val md_theme_light_onPrimary = Color(0xFFFFFFFF) // gradientOne val md_theme_light_primaryContainer = Color(0xFFF5F5F5) // container color -val md_theme_light_onPrimaryContainer = Color(0xFFFFFBFF) // 0xFFF0F0F0 +val md_theme_light_onPrimaryContainer = Color(0xFF3E001D) val md_theme_light_secondary = Color(0xFF984061) val md_theme_light_onSecondary = Color(0xFFFFFFFF) val md_theme_light_secondaryContainer = Color(0xFFFFD9E2) @@ -29,7 +29,7 @@ val md_theme_light_onError = Color(0xFFFFFFFF) val md_theme_light_onErrorContainer = Color(0xFF410002) val md_theme_light_background = Color(0xFFFFFBFF) val md_theme_light_onBackground = Color(0xFF330045) -val md_theme_light_surface = Color(0xFFF0F0F0) +val md_theme_light_surface = Color(0xFFFFFBFF) val md_theme_light_onSurface = Color(0xFF333333) // onSurface val md_theme_light_surfaceVariant = Color(0xFFF2DDE1) val md_theme_light_onSurfaceVariant = Color(0xFF514347) @@ -45,7 +45,7 @@ val md_theme_light_scrim = Color(0xFF000000) val md_theme_dark_primary = Color(0xFFFFFFFF) val md_theme_dark_onPrimary = Color(0xFF000000) val md_theme_dark_primaryContainer = Color(0xFF7B2949) -val md_theme_dark_onPrimaryContainer = Color(0xFF1C1C1C) +val md_theme_dark_onPrimaryContainer = Color(0xFFFFD9E2) val md_theme_dark_secondary = Color(0xFFFFB1C8) val md_theme_dark_onSecondary = Color(0xFF5E1133) val md_theme_dark_secondaryContainer = Color(0xFF7B2949) diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/GradientColors.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/GradientColors.kt similarity index 100% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/GradientColors.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/GradientColors.kt diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/MifosTextStyle.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/MifosTextStyle.kt similarity index 100% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/MifosTextStyle.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/MifosTextStyle.kt diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/Theme.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/Theme.kt similarity index 99% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/Theme.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/Theme.kt index 79a9c784a..e31d96dbf 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/Theme.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/Theme.kt @@ -120,7 +120,7 @@ fun MifosTheme( ) { MaterialTheme( colorScheme = colorScheme, - typography = MifosTypography, + typography = mifosTypography(), content = content, ) } diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/TintTheme.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/TintTheme.kt similarity index 100% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/TintTheme.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/TintTheme.kt diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/Type.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/Type.kt similarity index 65% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/Type.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/Type.kt index c5e9e810b..cf918ca06 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/theme/Type.kt +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/theme/Type.kt @@ -10,65 +10,79 @@ package org.mifospay.core.designsystem.theme import androidx.compose.material3.Typography +import androidx.compose.runtime.Composable import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.LineHeightStyle import androidx.compose.ui.unit.sp -import org.mifospay.core.designsystem.R +import mobile_wallet.core.designsystem.generated.resources.Res +import mobile_wallet.core.designsystem.generated.resources.outfit_black +import mobile_wallet.core.designsystem.generated.resources.outfit_bold +import mobile_wallet.core.designsystem.generated.resources.outfit_extra_bold +import mobile_wallet.core.designsystem.generated.resources.outfit_extra_light +import mobile_wallet.core.designsystem.generated.resources.outfit_light +import mobile_wallet.core.designsystem.generated.resources.outfit_medium +import mobile_wallet.core.designsystem.generated.resources.outfit_regular +import mobile_wallet.core.designsystem.generated.resources.outfit_semi_bold +import mobile_wallet.core.designsystem.generated.resources.outfit_thin +import org.jetbrains.compose.resources.Font -private val fontFamily = FontFamily( - Font(R.font.outfit_black, FontWeight.Black), - Font(R.font.outfit_bold, FontWeight.Bold), - Font(R.font.outfit_semi_bold, FontWeight.SemiBold), - Font(R.font.outfit_medium, FontWeight.Medium), - Font(R.font.outfit_regular, FontWeight.Normal), - Font(R.font.outfit_light, FontWeight.Light), - Font(R.font.outfit_thin, FontWeight.Thin), - Font(R.font.outfit_extra_light, FontWeight.ExtraLight), - Font(R.font.outfit_extra_bold, FontWeight.ExtraBold), -) +@Composable +private fun fontFamily(): FontFamily { + return FontFamily( + Font(Res.font.outfit_black, FontWeight.Black), + Font(Res.font.outfit_bold, FontWeight.Bold), + Font(Res.font.outfit_semi_bold, FontWeight.SemiBold), + Font(Res.font.outfit_medium, FontWeight.Medium), + Font(Res.font.outfit_regular, FontWeight.Normal), + Font(Res.font.outfit_light, FontWeight.Light), + Font(Res.font.outfit_thin, FontWeight.Thin), + Font(Res.font.outfit_extra_light, FontWeight.ExtraLight), + Font(Res.font.outfit_extra_bold, FontWeight.ExtraBold), + ) +} // Set of Material typography styles to start with -internal val MifosTypography = Typography( +@Composable +internal fun mifosTypography() = Typography( displayLarge = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Normal, fontSize = 57.sp, lineHeight = 64.sp, letterSpacing = (-0.25).sp, ), displayMedium = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Normal, fontSize = 45.sp, lineHeight = 52.sp, letterSpacing = 0.sp, ), displaySmall = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Normal, fontSize = 36.sp, lineHeight = 44.sp, letterSpacing = 0.sp, ), headlineLarge = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Normal, fontSize = 32.sp, lineHeight = 40.sp, letterSpacing = 0.sp, ), headlineMedium = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Normal, fontSize = 28.sp, lineHeight = 36.sp, letterSpacing = 0.sp, ), headlineSmall = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Normal, fontSize = 24.sp, lineHeight = 32.sp, @@ -79,20 +93,20 @@ internal val MifosTypography = Typography( ), ), titleLarge = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.SemiBold, fontSize = 24.sp, lineHeight = 30.24.sp, ), titleMedium = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.SemiBold, fontSize = 20.sp, lineHeight = 28.sp, letterSpacing = 0.1.sp, ), titleSmall = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Medium, fontSize = 14.sp, lineHeight = 20.sp, @@ -100,7 +114,7 @@ internal val MifosTypography = Typography( ), // Default text style bodyLarge = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Normal, fontSize = 16.sp, lineHeight = 24.sp, @@ -111,14 +125,14 @@ internal val MifosTypography = Typography( ), ), bodyMedium = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Normal, fontSize = 14.sp, lineHeight = 20.sp, letterSpacing = 0.25.sp, ), bodySmall = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Normal, fontSize = 12.sp, lineHeight = 16.sp, @@ -126,7 +140,7 @@ internal val MifosTypography = Typography( ), // Used for Button labelLarge = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Medium, fontSize = 16.sp, lineHeight = 20.sp, @@ -134,7 +148,7 @@ internal val MifosTypography = Typography( ), // Used for Navigation items labelMedium = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Medium, fontSize = 12.sp, lineHeight = 16.sp, @@ -146,7 +160,7 @@ internal val MifosTypography = Typography( ), // Used for Tag labelSmall = TextStyle( - fontFamily = fontFamily, + fontFamily = fontFamily(), fontWeight = FontWeight.Medium, fontSize = 10.sp, lineHeight = 14.sp, diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/utils/ExpirationDateMask.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/utils/ExpirationDateMask.kt similarity index 100% rename from core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/utils/ExpirationDateMask.kt rename to core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/utils/ExpirationDateMask.kt diff --git a/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/utils/ModifierExt.kt b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/utils/ModifierExt.kt new file mode 100644 index 000000000..926798f3d --- /dev/null +++ b/core/designsystem/src/commonMain/kotlin/org/mifospay/core/designsystem/utils/ModifierExt.kt @@ -0,0 +1,85 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.utils + +import androidx.compose.foundation.Indication +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.draw.scale +import androidx.compose.ui.focus.FocusDirection +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.isShiftPressed +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.input.key.type +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.platform.debugInspectorInfo +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.unit.LayoutDirection + +@Stable +@Composable +fun Modifier.mirrorIfRtl(): Modifier = + if (LocalLayoutDirection.current == LayoutDirection.Rtl) { + scale(scaleX = -1f, scaleY = 1f) + } else { + this + } + +@Stable +@Composable +fun Modifier.tabNavigation(): Modifier { + val focusManager = LocalFocusManager.current + return onPreviewKeyEvent { keyEvent -> + if (keyEvent.key == Key.Tab && keyEvent.type == KeyEventType.KeyDown) { + focusManager.moveFocus( + if (keyEvent.isShiftPressed) { + FocusDirection.Previous + } else { + FocusDirection.Next + }, + ) + true + } else { + false + } + } +} + +fun Modifier.onClick( + indication: Indication? = null, + enabled: Boolean = true, + onClickLabel: String? = null, + role: Role? = null, + onClick: () -> Unit, +) = this.composed( + inspectorInfo = debugInspectorInfo { + name = "onClickModifier" + value = enabled + }, +) { + val interactionSource = remember { MutableInteractionSource() } + clickable( + indication = indication, + interactionSource = interactionSource, + enabled = enabled, + onClickLabel = onClickLabel, + role = role, + ) { + onClick.invoke() + } +} diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosScaffold.kt b/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosScaffold.kt deleted file mode 100644 index f1826e291..000000000 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosScaffold.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.designsystem.component - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.RowScope -import androidx.compose.material3.FloatingActionButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color - -@Composable -fun MifosScaffold( - backPress: () -> Unit, - modifier: Modifier = Modifier, - topBarTitle: Int? = null, - titleColor: Color? = MaterialTheme.colorScheme.onSurface, - iconTint: Color? = null, - floatingActionButtonContent: FloatingActionButtonContent? = null, - snackbarHost: @Composable () -> Unit = {}, - scaffoldContent: @Composable (PaddingValues) -> Unit = {}, - actions: @Composable RowScope.() -> Unit = {}, -) { - Scaffold( - topBar = { - if (topBarTitle != null) { - MifosTopBar( - topBarTitle = topBarTitle, - backPress = backPress, - actions = actions, - titleColor = titleColor, - iconTint = iconTint, - ) - } - }, - floatingActionButton = { - floatingActionButtonContent?.let { content -> - FloatingActionButton( - onClick = content.onClick, - contentColor = content.contentColor, - content = content.content, - containerColor = MaterialTheme.colorScheme.primary, - ) - } - }, - snackbarHost = snackbarHost, - content = scaffoldContent, - modifier = modifier, - containerColor = Color.Transparent, - ) -} - -data class FloatingActionButtonContent( - val onClick: (() -> Unit), - val contentColor: Color, - val content: (@Composable () -> Unit), -) diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/OutlineTextField.kt b/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/OutlineTextField.kt deleted file mode 100644 index 360cc1484..000000000 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/OutlineTextField.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.designsystem.component - -import androidx.compose.foundation.Image -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.OutlinedTextFieldDefaults -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.VisualTransformation -import androidx.compose.ui.unit.sp - -@Composable -fun MifosOutlinedTextField( - label: Int, - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier = Modifier, - maxLines: Int = 1, - singleLine: Boolean = true, - icon: Int? = null, - error: Boolean = false, - visualTransformation: VisualTransformation = VisualTransformation.None, - trailingIcon: @Composable (() -> Unit)? = null, - keyboardOptions: KeyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), -) { - OutlinedTextField( - value = value, - onValueChange = onValueChange, - label = { Text(stringResource(id = label)) }, - modifier = modifier, - leadingIcon = - if (icon != null) { - { - Image( - painter = painterResource(id = icon), - contentDescription = null, - colorFilter = - ColorFilter.tint( - MaterialTheme.colorScheme.onSurface, - ), - ) - } - } else { - null - }, - trailingIcon = trailingIcon, - maxLines = maxLines, - singleLine = singleLine, - colors = - OutlinedTextFieldDefaults.colors( - focusedBorderColor = MaterialTheme.colorScheme.onSurface, - focusedLabelColor = MaterialTheme.colorScheme.onSurface, - ), - textStyle = - LocalDensity.current.run { - TextStyle(fontSize = 18.sp, color = MaterialTheme.colorScheme.onSurface) - }, - keyboardOptions = keyboardOptions, - visualTransformation = visualTransformation, - isError = error, - ) -} diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/TextField.kt b/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/TextField.kt deleted file mode 100644 index f1c90fd8d..000000000 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/TextField.kt +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.core.designsystem.component - -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Box -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.foundation.text.BasicTextField -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Visibility -import androidx.compose.material.icons.filled.VisibilityOff -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.LocalTextStyle -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.OutlinedTextFieldDefaults -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.PasswordVisualTransformation -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.text.input.VisualTransformation -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.mifospay.core.designsystem.theme.MifosTheme - -@Composable -fun MfOutlinedTextField( - value: String, - label: String, - onValueChange: (String) -> Unit, - modifier: Modifier = Modifier, - isError: Boolean = false, - errorMessage: String = "", - singleLine: Boolean = false, - onKeyboardActions: (() -> Unit)? = null, - trailingIcon: @Composable (() -> Unit)? = null, - keyboardOptions: KeyboardOptions = KeyboardOptions.Default, -) { - OutlinedTextField( - modifier = modifier, - value = value, - onValueChange = onValueChange, - label = { Text(label) }, - supportingText = { - if (isError) { - Text(text = errorMessage) - } - }, - singleLine = singleLine, - trailingIcon = trailingIcon, - keyboardActions = KeyboardActions { - onKeyboardActions?.invoke() - }, - keyboardOptions = keyboardOptions, - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = MaterialTheme.colorScheme.onSurface, - focusedLabelColor = MaterialTheme.colorScheme.onSurface, - ), - textStyle = LocalDensity.current.run { - TextStyle(fontSize = 18.sp, color = MaterialTheme.colorScheme.onSurface) - }, - ) -} - -@Composable -fun MfPasswordTextField( - password: String, - label: String, - isError: Boolean, - isPasswordVisible: Boolean, - onTogglePasswordVisibility: () -> Unit, - onPasswordChange: (String) -> Unit, - modifier: Modifier = Modifier, - errorMessage: String? = null, -) { - OutlinedTextField( - modifier = modifier, - value = password, - onValueChange = onPasswordChange, - label = { Text(label) }, - isError = isError, - visualTransformation = if (isPasswordVisible) { - VisualTransformation.None - } else { - PasswordVisualTransformation() - }, - supportingText = { - errorMessage?.let { Text(text = it) } - }, - trailingIcon = { - IconButton(onClick = onTogglePasswordVisibility) { - Icon( - if (isPasswordVisible) Icons.Filled.Visibility else Icons.Filled.VisibilityOff, - contentDescription = "Show password", - ) - } - }, - ) -} - -@Composable -fun MifosOutlinedTextField( - label: Int, - value: TextFieldValue, - onValueChange: (TextFieldValue) -> Unit, - modifier: Modifier = Modifier, - maxLines: Int = 1, - singleLine: Boolean = true, - icon: Int? = null, - visualTransformation: VisualTransformation = VisualTransformation.None, - trailingIcon: @Composable (() -> Unit)? = null, - keyboardActions: KeyboardActions = KeyboardActions.Default, - error: Boolean = false, -) { - OutlinedTextField( - value = value, - onValueChange = onValueChange, - label = { Text(stringResource(id = label)) }, - modifier = modifier, - leadingIcon = if (icon != null) { - { - Image( - painter = painterResource(id = icon), - contentDescription = null, - colorFilter = ColorFilter.tint( - MaterialTheme.colorScheme.onSurface, - ), - ) - } - } else { - null - }, - trailingIcon = trailingIcon, - maxLines = maxLines, - singleLine = singleLine, - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = MaterialTheme.colorScheme.onSurface, - focusedLabelColor = MaterialTheme.colorScheme.onSurface, - ), - textStyle = LocalDensity.current.run { - TextStyle(fontSize = 18.sp, color = MaterialTheme.colorScheme.onSurface) - }, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), - keyboardActions = keyboardActions, - visualTransformation = visualTransformation, - isError = error, - ) -} - -@Composable -fun MifosTextField( - value: String, - onValueChange: (String) -> Unit, - label: String, - modifier: Modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 20.dp), - enabled: Boolean = true, - readOnly: Boolean = false, - textStyle: TextStyle = LocalTextStyle.current, - visualTransformation: VisualTransformation = VisualTransformation.None, - keyboardActions: KeyboardActions = KeyboardActions.Default, - singleLine: Boolean = true, - maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, - minLines: Int = 1, - interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, - keyboardOptions: KeyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), - trailingIcon: @Composable (() -> Unit)? = null, - leadingIcon: @Composable (() -> Unit)? = null, - indicatorColor: Color? = null, -) { - var isFocused by rememberSaveable { mutableStateOf(false) } - - BasicTextField( - value = value, - onValueChange = onValueChange, - textStyle = textStyle, - modifier = modifier - .fillMaxWidth() - .padding(top = 10.dp) - .onFocusChanged { focusState -> - isFocused = focusState.isFocused - } - .semantics(mergeDescendants = true) {}, - enabled = enabled, - readOnly = readOnly, - visualTransformation = visualTransformation, - keyboardOptions = keyboardOptions, - keyboardActions = keyboardActions, - interactionSource = interactionSource, - singleLine = singleLine, - maxLines = maxLines, - minLines = minLines, - cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), - decorationBox = { innerTextField -> - Column { - Text( - text = label, - color = MaterialTheme.colorScheme.primary, - style = MaterialTheme.typography.labelLarge, - modifier = Modifier.align(alignment = Alignment.Start), - ) - - Spacer(modifier = Modifier.height(5.dp)) - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth(), - ) { - if (leadingIcon != null) { - leadingIcon() - } - - Box(modifier = Modifier.weight(1f)) { - innerTextField() - } - - if (trailingIcon != null) { - trailingIcon() - } - } - indicatorColor?.let { color -> - HorizontalDivider( - thickness = 1.dp, - color = if (isFocused) { - color - } else { - MaterialTheme.colorScheme.onSurface.copy(alpha = 0.05f) - }, - ) - } ?: run { - HorizontalDivider( - thickness = 1.dp, - color = if (isFocused) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.onSurface.copy(alpha = 0.05f) - }, - ) - } - } - }, - - ) -} - -@Composable -@Preview -fun MfTextFieldPreview(modifier: Modifier = Modifier) { - MifosTheme { - Box( - modifier = modifier.background(color = Color.White), - ) { - MifosTextField( - value = "Text Field Value", - onValueChange = {}, - label = "Text Field", - ) - } - } -} - -@Preview -@Composable -fun MfOutlinedTextFieldPreview() { - MifosTheme { - Box( - modifier = Modifier.background(color = MaterialTheme.colorScheme.surface), - ) { - MfOutlinedTextField( - value = "Text Field Value", - label = "Text Field", - onValueChange = { }, - modifier = Modifier, - isError = true, - errorMessage = "Error Message", - onKeyboardActions = { }, - ) - } - } -} - -@Preview -@Composable -fun MfPasswordTextFieldPreview() { - MifosTheme { - val password = " " - Box( - modifier = Modifier.background(color = Color.White), - ) { - MfPasswordTextField( - password = password, - label = "Password", - isError = true, - isPasswordVisible = true, - onTogglePasswordVisibility = { }, - onPasswordChange = { }, - modifier = Modifier.fillMaxWidth(), - errorMessage = "Password must be at least 6 characters", - ) - } - } -} diff --git a/mifospay/.gitignore b/core/domain/.gitignore similarity index 100% rename from mifospay/.gitignore rename to core/domain/.gitignore diff --git a/core/domain/README.md b/core/domain/README.md new file mode 100644 index 000000000..5d30f1638 --- /dev/null +++ b/core/domain/README.md @@ -0,0 +1,3 @@ +# :core:data module +## Dependency graph +![Dependency graph](../../docs/images/graphs/dep_graph_core_data.svg) diff --git a/core/domain/build.gradle.kts b/core/domain/build.gradle.kts new file mode 100644 index 000000000..6ceb3c24d --- /dev/null +++ b/core/domain/build.gradle.kts @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +plugins { + alias(libs.plugins.mifospay.kmp.library) +} + +android { + namespace = "org.mifospay.core.domain" +} + +kotlin { + sourceSets { + commonMain.dependencies { + implementation(projects.core.common) + implementation(projects.core.data) + implementation(projects.core.model) + } + } +} \ No newline at end of file diff --git a/core/network/proguard-rules.pro b/core/domain/proguard-rules.pro similarity index 69% rename from core/network/proguard-rules.pro rename to core/domain/proguard-rules.pro index c60ff3215..918d3d0ef 100644 --- a/core/network/proguard-rules.pro +++ b/core/domain/proguard-rules.pro @@ -1,10 +1,14 @@ # Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. +# By default, the flags in this file are appended to flags specified +# in /home/naman/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle.kts. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html +# Add any project specific keep options here: + # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: @@ -19,6 +23,3 @@ # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile - --keep class io.ktor.** { *; } --keep class kotlinx.serialization.** { *; } \ No newline at end of file diff --git a/core/domain/src/commonMain/kotlin/org/mifospay/core/domain/LoginUseCase.kt b/core/domain/src/commonMain/kotlin/org/mifospay/core/domain/LoginUseCase.kt new file mode 100644 index 000000000..c65442218 --- /dev/null +++ b/core/domain/src/commonMain/kotlin/org/mifospay/core/domain/LoginUseCase.kt @@ -0,0 +1,78 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.domain + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.withContext +import org.mifospay.core.common.DataState +import org.mifospay.core.data.repository.AuthenticationRepository +import org.mifospay.core.data.repository.ClientRepository +import org.mifospay.core.datastore.UserPreferencesRepository +import org.mifospay.core.model.user.UserInfo + +class LoginUseCase( + private val repository: AuthenticationRepository, + private val clientRepository: ClientRepository, + private val userPreferencesRepository: UserPreferencesRepository, + private val ioDispatcher: CoroutineDispatcher, +) { + suspend operator fun invoke(username: String, password: String): DataState { + val result = withContext(ioDispatcher) { + repository.authenticate(username, password) + } + + return when (result) { + is DataState.Loading -> DataState.Loading + is DataState.Error -> DataState.Error(Exception("Invalid credentials")) + is DataState.Success -> { + if (result.data.clients.isEmpty()) { + return DataState.Error(Exception("No clients found")) + } + updateUserInfo(result.data) + } + } + } + + private suspend fun updateUserInfo(userInfo: UserInfo): DataState { + val updateResult = withContext(ioDispatcher) { + userPreferencesRepository.updateToken(userInfo.base64EncodedAuthenticationKey) + } + + return when (updateResult) { + is DataState.Success -> updateClientInfo(userInfo) + is DataState.Error -> DataState.Error(Exception("Something went wrong")) + is DataState.Loading -> DataState.Loading + } + } + + private suspend fun updateClientInfo(userInfo: UserInfo): DataState { + val clientInfo = withContext(ioDispatcher) { + clientRepository.getClient(userInfo.clients.first()) + } + + return when (clientInfo) { + is DataState.Success -> { + withContext(ioDispatcher) { + userPreferencesRepository.updateClientInfo(clientInfo.data) + userPreferencesRepository.updateUserInfo(userInfo) + } + + DataState.Success(userInfo) + } + + is DataState.Error -> { + userPreferencesRepository.logOut() + DataState.Error(Exception("No client found")) + } + + is DataState.Loading -> DataState.Loading + } + } +} diff --git a/core/domain/src/commonMain/kotlin/org/mifospay/core/domain/di/DomainModule.kt b/core/domain/src/commonMain/kotlin/org/mifospay/core/domain/di/DomainModule.kt new file mode 100644 index 000000000..a601156df --- /dev/null +++ b/core/domain/src/commonMain/kotlin/org/mifospay/core/domain/di/DomainModule.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.domain.di + +import org.koin.core.qualifier.named +import org.koin.dsl.module +import org.mifospay.core.common.MifosDispatchers +import org.mifospay.core.domain.LoginUseCase + +val DomainModule = module { + single { + LoginUseCase( + repository = get(), + clientRepository = get(), + userPreferencesRepository = get(), + ioDispatcher = get(named(MifosDispatchers.IO.name)), + ) + } +} diff --git a/core/model/build.gradle.kts b/core/model/build.gradle.kts index fb199f33d..a9a929e86 100644 --- a/core/model/build.gradle.kts +++ b/core/model/build.gradle.kts @@ -8,7 +8,7 @@ * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ plugins { - alias(libs.plugins.mifospay.android.library) + alias(libs.plugins.mifospay.kmp.library) alias(libs.plugins.kotlin.parcelize) id("kotlinx-serialization") } @@ -17,10 +17,11 @@ android { namespace = "org.mifospay.core.model" } -dependencies { - api(libs.kotlinx.datetime) - - // For Serialized name - implementation(libs.squareup.retrofit.converter.gson) - implementation(libs.kotlinx.serialization.json) -} +kotlin { + sourceSets { + commonMain.dependencies { + implementation(projects.core.common) + implementation(libs.kotlinx.serialization.json) + } + } +} \ No newline at end of file diff --git a/core/model/consumer-rules.pro b/core/model/consumer-rules.pro deleted file mode 100644 index e69de29bb..000000000 diff --git a/core/model/proguard-rules.pro b/core/model/proguard-rules.pro deleted file mode 100644 index 481bb4348..000000000 --- a/core/model/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/Account.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/Account.kt new file mode 100644 index 000000000..e81dcef65 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/Account.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.account + +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize +import org.mifospay.core.model.savingsaccount.Currency +import org.mifospay.core.model.savingsaccount.Status + +@Parcelize +data class Account( + val image: String = "", + val name: String, + val number: String, + val balance: Double = 0.0, + val id: Long = 0L, + val productId: Long = 0L, + val currency: Currency, + val status: Status, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountContent.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountContent.kt new file mode 100644 index 000000000..5073b7d44 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountContent.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.account + +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize +import org.mifospay.core.model.beneficiary.Beneficiary + +@Parcelize +data class AccountContent( + val accounts: List, + val beneficiaries: List, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountTransferPayload.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountTransferPayload.kt new file mode 100644 index 000000000..4dcfaa612 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountTransferPayload.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.account + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class AccountTransferPayload( + val fromOfficeId: Long, + val fromClientId: Long, + val fromAccountType: Long, + val fromAccountId: Long, + + val toOfficeId: Long, + val toClientId: Long, + val toAccountType: Long, + val toAccountId: Long, + + val transferAmount: String, + val transferDescription: String, + + val locale: String, + val dateFormat: String, + val transferDate: String, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountsWithTransactions.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountsWithTransactions.kt new file mode 100644 index 000000000..e332db448 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/AccountsWithTransactions.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.account + +import org.mifospay.core.model.savingsaccount.Transaction + +data class AccountsWithTransactions( + val accounts: List, + val transactions: List, +) diff --git a/core/model/src/main/java/com/mifospay/core/model/entity/client/Status.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/DefaultAccount.kt similarity index 51% rename from core/model/src/main/java/com/mifospay/core/model/entity/client/Status.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/account/DefaultAccount.kt index a8d079182..884ec1c40 100644 --- a/core/model/src/main/java/com/mifospay/core/model/entity/client/Status.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/DefaultAccount.kt @@ -7,21 +7,22 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.entity.client +package org.mifospay.core.model.account -import com.google.gson.annotations.SerializedName import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize @Serializable -data class Status( - @SerializedName("id") - var id: Int? = null, - - @SerializedName("code") - var code: String? = null, - - @SerializedName("value") - var value: String? = null, -) { - constructor() : this(null, null, null) +@Parcelize +data class DefaultAccount( + val accountId: Long, + val accountNo: String, +) : Parcelable { + companion object { + val DEFAULT = DefaultAccount( + accountId = 0, + accountNo = "", + ) + } } diff --git a/core/model/src/main/java/com/mifospay/core/model/domain/NewAccount.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/NewAccount.kt similarity index 56% rename from core/model/src/main/java/com/mifospay/core/model/domain/NewAccount.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/account/NewAccount.kt index a276663aa..f24e7c7dc 100644 --- a/core/model/src/main/java/com/mifospay/core/model/domain/NewAccount.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/account/NewAccount.kt @@ -7,14 +7,15 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.domain +package org.mifospay.core.model.account + +import kotlinx.datetime.LocalDate -import java.util.Date data class NewAccount( - var clientId: Int, - var productId: String? = null, - var submittedOnDate: Date? = null, - var accountNo: String, - var locale: String? = null, - var dateFormat: String? = null, + val clientId: Int, + val productId: String? = null, + val submittedOnDate: LocalDate? = null, + val accountNo: String, + val locale: String? = null, + val dateFormat: String? = null, ) diff --git a/core/model/src/main/java/com/mifospay/core/model/domain/Bank.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/bank/Bank.kt similarity index 73% rename from core/model/src/main/java/com/mifospay/core/model/domain/Bank.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/bank/Bank.kt index 1c2c9a868..caefece0f 100644 --- a/core/model/src/main/java/com/mifospay/core/model/domain/Bank.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/bank/Bank.kt @@ -7,13 +7,17 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.domain +package org.mifospay.core.model.bank -class Bank( +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +data class Bank( val name: String, val image: Int, val bankType: BankType = BankType.OTHER, -) +) : Parcelable enum class BankType { POPULAR, diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/bank/BankAccountDetails.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/bank/BankAccountDetails.kt new file mode 100644 index 000000000..52c204642 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/bank/BankAccountDetails.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.bank + +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +data class BankAccountDetails( + val accountNo: String, + val bankName: String?, + val accountHolderName: String?, + val branch: String?, + val ifsc: String?, + val type: String?, + val isUpiEnabled: Boolean = false, + val upiPin: String?, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/beneficiary/Beneficiary.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/beneficiary/Beneficiary.kt new file mode 100644 index 000000000..7f09f88d1 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/beneficiary/Beneficiary.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.beneficiary + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class Beneficiary( + val id: Long, + val name: String, + val officeName: String, + val clientName: String, + val accountType: AccountType, + val accountNumber: String, + val transferLimit: Int = 0, +) : Parcelable { + + @Serializable + @Parcelize + data class AccountType( + val id: Int, + val code: String, + val value: String, + ) : Parcelable +} diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/beneficiary/BeneficiaryPayload.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/beneficiary/BeneficiaryPayload.kt new file mode 100644 index 000000000..0bdcadb4b --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/beneficiary/BeneficiaryPayload.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.beneficiary + +import kotlinx.serialization.Serializable + +@Serializable +data class BeneficiaryPayload( + val locale: String? = "en_GB", + val name: String? = null, + val accountNumber: String? = null, + val accountType: Int = 0, + val transferLimit: Int = 0, + val officeName: String? = null, +) { + constructor() : this( + locale = null, + name = null, + accountNumber = null, + accountType = 0, + transferLimit = 0, + officeName = null, + ) +} diff --git a/core/model/src/main/java/com/mifospay/core/model/domain/Currency.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/beneficiary/BeneficiaryUpdatePayload.kt similarity index 67% rename from core/model/src/main/java/com/mifospay/core/model/domain/Currency.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/beneficiary/BeneficiaryUpdatePayload.kt index b17050b84..0213b6d6f 100644 --- a/core/model/src/main/java/com/mifospay/core/model/domain/Currency.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/beneficiary/BeneficiaryUpdatePayload.kt @@ -7,15 +7,12 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.domain +package org.mifospay.core.model.beneficiary import kotlinx.serialization.Serializable @Serializable -data class Currency( - var code: String, - var displaySymbol: String, - var displayLabel: String, -) { - constructor() : this("", "", "") -} +data class BeneficiaryUpdatePayload( + val name: String? = null, + val transferLimit: Int = 0, +) diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/Client.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/Client.kt new file mode 100644 index 000000000..81a6b41fb --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/Client.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.client + +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +data class Client( + val id: Long, + val accountNo: String, + val externalId: String, + val active: Boolean, + val activationDate: List, + val firstname: String, + val lastname: String, + val displayName: String, + val mobileNo: String, + val emailAddress: String, + val dateOfBirth: List, + val isStaff: Boolean, + val officeId: Long, + val officeName: String, + val savingsProductName: String, + val timeline: ClientTimeline = ClientTimeline(), + val status: ClientStatus = ClientStatus(), + val legalForm: ClientStatus = ClientStatus(), +) : Parcelable diff --git a/core/model/src/main/java/com/mifospay/core/model/entity/Page.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientAccount.kt similarity index 65% rename from core/model/src/main/java/com/mifospay/core/model/entity/Page.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientAccount.kt index 2cd34f259..734c83bd5 100644 --- a/core/model/src/main/java/com/mifospay/core/model/entity/Page.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientAccount.kt @@ -7,9 +7,10 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.entity +package org.mifospay.core.model.client -data class Page( - var totalFilteredRecords: Int = 0, - var pageItems: MutableList = ArrayList(), +import org.mifospay.core.model.savingsaccount.SavingAccount + +data class ClientAccount( + val savingAccounts: List, ) diff --git a/core/model/src/main/java/com/mifospay/core/model/entity/SearchedEntity.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientAddress.kt similarity index 51% rename from core/model/src/main/java/com/mifospay/core/model/entity/SearchedEntity.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientAddress.kt index 6ce6d00a7..758db66b9 100644 --- a/core/model/src/main/java/com/mifospay/core/model/entity/SearchedEntity.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientAddress.kt @@ -7,17 +7,17 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.entity +package org.mifospay.core.model.client -import android.os.Parcelable -import kotlinx.parcelize.Parcelize +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize @Parcelize -data class SearchedEntity( - var entityId: Int = 0, - var entityAccountNo: String = " ", - var entityName: String = " ", - var entityType: String = " ", - var parentId: Int = 0, - var parentName: String = " ", +data class ClientAddress( + val addressLine1: String, + val addressLine2: String, + val postalCode: String, + val stateProvinceId: String, + val countryId: String, + val addressTypeId: Int = 805, ) : Parcelable diff --git a/core/model/src/main/java/com/mifospay/core/model/domain/NotificationPayload.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientStatus.kt similarity index 60% rename from core/model/src/main/java/com/mifospay/core/model/domain/NotificationPayload.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientStatus.kt index f89982818..5477923ba 100644 --- a/core/model/src/main/java/com/mifospay/core/model/domain/NotificationPayload.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientStatus.kt @@ -7,14 +7,14 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.domain +package org.mifospay.core.model.client -import android.os.Parcelable -import kotlinx.parcelize.Parcelize +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize @Parcelize -data class NotificationPayload( - var title: String? = null, - var body: String? = null, - var timestamp: String? = null, +data class ClientStatus( + val id: Int = 0, + val code: String = "", + val value: String = "", ) : Parcelable diff --git a/core/model/src/main/java/com/mifospay/core/model/entity/templates/beneficiary/BeneficiaryTemplate.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientTimeline.kt similarity index 51% rename from core/model/src/main/java/com/mifospay/core/model/entity/templates/beneficiary/BeneficiaryTemplate.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientTimeline.kt index 4468f9756..5922c4a66 100644 --- a/core/model/src/main/java/com/mifospay/core/model/entity/templates/beneficiary/BeneficiaryTemplate.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/ClientTimeline.kt @@ -7,14 +7,16 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.entity.templates.beneficiary +package org.mifospay.core.model.client -import android.os.Parcelable -import com.google.gson.annotations.SerializedName -import kotlinx.parcelize.Parcelize +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize @Parcelize -data class BeneficiaryTemplate( - @SerializedName("accountTypeOptions") - var accountTypeOptions: List? = null, +data class ClientTimeline( + val submittedOnDate: List = emptyList(), + val activatedOnDate: List = emptyList(), + val activatedByUsername: String? = null, + val activatedByFirstname: String? = null, + val activatedByLastname: String? = null, ) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/NewClient.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/NewClient.kt new file mode 100644 index 000000000..fac3c47c9 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/NewClient.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.client + +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +data class NewClient( + val firstname: String, + val lastname: String, + val externalId: String, + val mobileNo: String, + val address: ClientAddress, + val savingsProductId: Int, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/UpdatedClient.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/UpdatedClient.kt new file mode 100644 index 000000000..d5237614b --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/client/UpdatedClient.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.client + +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +data class UpdatedClient( + val firstname: String, + val lastname: String, + val externalId: String, + val mobileNo: String, + val emailAddress: String, +) : Parcelable diff --git a/core/model/src/main/java/com/mifospay/core/model/entity/invoice/Invoice.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/datatables/invoice/Invoice.kt similarity index 66% rename from core/model/src/main/java/com/mifospay/core/model/entity/invoice/Invoice.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/datatables/invoice/Invoice.kt index ea7ced4bc..a12dcf1f7 100644 --- a/core/model/src/main/java/com/mifospay/core/model/entity/invoice/Invoice.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/datatables/invoice/Invoice.kt @@ -7,29 +7,31 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.entity.invoice +package org.mifospay.core.model.datatables.invoice -import android.os.Parcelable -import com.google.gson.annotations.SerializedName -import kotlinx.parcelize.Parcelize +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize +@Serializable @Parcelize data class Invoice( val id: Long, - @SerializedName("client_id") + @SerialName("client_id") val clientId: Long, val consumerId: String, val consumerName: String, val amount: Double, - @SerializedName("itemsbought") + @SerialName("itemsbought") val itemsBought: String, val status: Long, val transactionId: String, val invoiceId: Long, val title: String, val date: String, - @SerializedName("created_at") + @SerialName("created_at") val createdAt: List, - @SerializedName("updated_at") + @SerialName("updated_at") val updatedAt: List, ) : Parcelable diff --git a/core/model/src/main/java/com/mifospay/core/model/entity/invoice/InvoiceEntity.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/datatables/invoice/InvoiceEntity.kt similarity index 93% rename from core/model/src/main/java/com/mifospay/core/model/entity/invoice/InvoiceEntity.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/datatables/invoice/InvoiceEntity.kt index cad568d46..c051ed137 100644 --- a/core/model/src/main/java/com/mifospay/core/model/entity/invoice/InvoiceEntity.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/datatables/invoice/InvoiceEntity.kt @@ -7,7 +7,7 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.entity.invoice +package org.mifospay.core.model.datatables.invoice import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/kyc/KYCLevel1Details.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/kyc/KYCLevel1Details.kt new file mode 100644 index 000000000..af9233c20 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/kyc/KYCLevel1Details.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.kyc + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class KYCLevel1Details( + val firstName: String, + val lastName: String, + val addressLine1: String, + val addressLine2: String, + val mobileNo: String, + val dob: String, + val currentLevel: String, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/notification/Notification.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/notification/Notification.kt new file mode 100644 index 000000000..73599ae19 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/notification/Notification.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.notification + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.DateHelper.toFormattedDateTime +import org.mifospay.core.common.IgnoredOnParcel +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class Notification( + val id: Long, + val objectType: String, + val objectId: Long, + val action: String, + val actorId: Long, + val content: String, + val isRead: Boolean, + val isSystemGenerated: Boolean, + val createdAt: String, +) : Parcelable { + @IgnoredOnParcel + val formattedDate = createdAt.toFormattedDateTime() +} diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/notification/NotificationPayload.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/notification/NotificationPayload.kt new file mode 100644 index 000000000..bdb94d26a --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/notification/NotificationPayload.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.notification + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class NotificationPayload( + val totalFilteredRecords: Long, + val pageItems: List, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savedcards/CardPayload.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savedcards/CardPayload.kt new file mode 100644 index 000000000..3d173c4dc --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savedcards/CardPayload.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savedcards + +import kotlinx.serialization.Serializable + +@Serializable +data class CardPayload( + val firstName: String, + val lastName: String, + val cardNumber: String, + val cvv: String, + val expiryDate: String, + val backgroundColor: String? = null, +) diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savedcards/SavedCard.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savedcards/SavedCard.kt new file mode 100644 index 000000000..eda505446 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savedcards/SavedCard.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savedcards + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import org.mifospay.core.common.IgnoredOnParcel +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class SavedCard( + val id: Long = 0, + @SerialName("client_id") + val clientId: Long, + val firstName: String, + val lastName: String, + val cardNumber: String, + val cvv: String, + val expiryDate: String, + val backgroundColor: String, + @SerialName("created_at") + val createdAt: List, + @SerialName("updated_at") + val updatedAt: List, +) : Parcelable { + @IgnoredOnParcel + val fullName = "$firstName $lastName" + + @IgnoredOnParcel + val formattedExpiryDate: String + get() = "${expiryDate.substring(0, 2)}/${expiryDate.substring(2, 4)}" + + @IgnoredOnParcel + val maskedCvv: String + get() = "*".repeat(cvv.length) +} diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/AccountType.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/AccountType.kt new file mode 100644 index 000000000..fe4b12805 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/AccountType.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class AccountType( + val id: Long, + val code: String, + val value: String, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/BlockUnblockResponseEntity.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/BlockUnblockResponseEntity.kt new file mode 100644 index 000000000..0ef5bcc0d --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/BlockUnblockResponseEntity.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable + +@Serializable +data class BlockUnblockResponseEntity( + val officeId: Long, + val clientId: Long, + val savingsId: Long, + val resourceId: Long, + val changes: ChangesEntity, +) + +@Serializable +data class ChangesEntity( + val subStatus: SubStatus, +) diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/CreateNewSavingEntity.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/CreateNewSavingEntity.kt new file mode 100644 index 000000000..5443239c0 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/CreateNewSavingEntity.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class CreateNewSavingEntity( + val clientId: String, + val productId: Long, + val nominalAnnualInterestRate: Double, + val minRequiredOpeningBalance: Long, + val withdrawalFeeForTransfers: Boolean, + val allowOverdraft: Boolean, + val overdraftLimit: String, + val enforceMinRequiredBalance: Boolean, + val withHoldTax: Boolean, + val externalId: String, + val submittedOnDate: String, + val locale: String, + val dateFormat: String, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Currency.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Currency.kt new file mode 100644 index 000000000..2b4889bd7 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Currency.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +@Serializable +data class Currency( + val code: String, + val name: String, + val decimalPlaces: Int, + val inMultiplesOf: Int, + val displaySymbol: String, + val nameCode: String, + val displayLabel: String, +) : Parcelable diff --git a/core/model/src/main/java/com/mifospay/core/model/entity/client/DepositType.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/DepositType.kt similarity index 53% rename from core/model/src/main/java/com/mifospay/core/model/entity/client/DepositType.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/DepositType.kt index b82c3886a..43b79a3c9 100644 --- a/core/model/src/main/java/com/mifospay/core/model/entity/client/DepositType.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/DepositType.kt @@ -7,34 +7,38 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.entity.client +package org.mifospay.core.model.savingsaccount -import com.google.gson.annotations.SerializedName import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize +@Parcelize @Serializable data class DepositType( - @SerializedName("id") - var id: Int? = null, - - @SerializedName("code") - var code: String? = null, - - @SerializedName("value") - var value: String? = null, - -) { + val id: Int, + val code: String, + val value: String, +) : Parcelable { val isRecurring: Boolean get() = ServerTypes.RECURRING.id == id val endpoint: String - get() = ServerTypes.fromId(id!!).endpoint + get() = ServerTypes.fromId( + id!!, + ).endpoint val serverType: ServerTypes - get() = ServerTypes.fromId(id!!) + get() = ServerTypes.fromId( + id!!, + ) enum class ServerTypes(val id: Int, val code: String, val endpoint: String) { - SAVINGS(100, "depositAccountType.savingsDeposit", "savingsaccounts"), - FIXED(200, "depositAccountType.fixedDeposit", "savingsaccounts"), - RECURRING(300, "depositAccountType.recurringDeposit", "recurringdepositaccounts"), + SAVINGS(id = 100, code = "depositAccountType.savingsDeposit", endpoint = "savingsaccounts"), + FIXED(id = 200, code = "depositAccountType.fixedDeposit", endpoint = "savingsaccounts"), + RECURRING( + id = 300, + code = "depositAccountType.recurringDeposit", + endpoint = "recurringdepositaccounts", + ), ; companion object { @@ -44,7 +48,7 @@ data class DepositType( return type } } - return SAVINGS + return ServerTypes.SAVINGS } } } diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/InterestPeriod.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/InterestPeriod.kt new file mode 100644 index 000000000..d7ab4cd0e --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/InterestPeriod.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class InterestPeriod( + val id: Long = 0, + val code: String = "", + val value: String = "", +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/PaymentDetailData.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/PaymentDetailData.kt new file mode 100644 index 000000000..b6293486f --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/PaymentDetailData.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class PaymentDetailData( + val id: Long, + val paymentType: PaymentType, + val accountNumber: String, + val checkNumber: String, + val routingCode: String, + val receiptNumber: String, + val bankNumber: String, +) : Parcelable diff --git a/core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/PaymentType.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/PaymentType.kt similarity index 62% rename from core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/PaymentType.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/PaymentType.kt index 57e449a09..51e07674a 100644 --- a/core/model/src/main/java/com/mifospay/core/model/entity/accounts/savings/PaymentType.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/PaymentType.kt @@ -7,17 +7,16 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.entity.accounts.savings +package org.mifospay.core.model.savingsaccount -import com.google.gson.annotations.SerializedName import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize @Serializable +@Parcelize data class PaymentType( - @SerializedName("id") - var id: Int? = null, - - @SerializedName("name") - var name: String? = null, - -) + val id: Int? = null, + val name: String? = null, + val isSystemDefined: Boolean, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccount.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccount.kt new file mode 100644 index 000000000..bfd7deba4 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccount.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +data class SavingAccount( + val id: Long, + val accountNo: String, + val productId: Long, + val productName: String, + val shortProductName: String, + val status: Status, + val currency: Currency, + val accountBalance: Double, + val accountType: AccountType, + val timeline: Timeline, + val subStatus: SubStatus, + val lastActiveTransactionDate: List, + val depositType: DepositType?, + val externalId: String?, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountDetail.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountDetail.kt new file mode 100644 index 000000000..c5276e122 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountDetail.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize +import org.mifospay.core.model.account.Account + +@Parcelize +data class SavingAccountDetail( + val id: Long, + val accountNo: String, + val depositType: DepositType, + val clientId: Long, + val clientName: String, + val savingsProductId: Long, + val savingsProductName: String, + val fieldOfficerId: Long, + val status: Status, + val timeline: Timeline, + val currency: Currency, + val nominalAnnualInterestRate: Double, + val withdrawalFeeForTransfers: Boolean, + val allowOverdraft: Boolean, + val enforceMinRequiredBalance: Boolean, + val lienAllowed: Boolean, + val withHoldTax: Boolean, + val lastActiveTransactionDate: List, + val isDormancyTrackingActive: Boolean, + val summary: Summary, + val transactions: List, +) : Parcelable + +fun SavingAccountDetail.toAccount(): Account { + return Account( + name = savingsProductName, + number = accountNo, + balance = summary.accountBalance, + id = id, + productId = savingsProductId, + currency = currency, + status = status, + ) +} diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountEntity.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountEntity.kt new file mode 100644 index 000000000..734589faa --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountEntity.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable + +@Serializable +data class SavingAccountEntity( + val id: Long, + val accountNo: String, + val productId: Long, + val productName: String, + val shortProductName: String, + val status: Status, + val currency: Currency, + val accountBalance: Double = 0.0, + val accountType: AccountType, + val timeline: Timeline, + val subStatus: SubStatus, + val lastActiveTransactionDate: List = emptyList(), + val depositType: DepositType?, + val externalId: String?, +) diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountTemplate.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountTemplate.kt new file mode 100644 index 000000000..d95149c96 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingAccountTemplate.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +@Serializable +data class SavingAccountTemplate( + val clientId: String, + val clientName: String, + val nominalAnnualInterestRate: Double, + val withdrawalFeeForTransfers: Boolean, + val allowOverdraft: Boolean, + val enforceMinRequiredBalance: Boolean, + val lienAllowed: Boolean, + val withHoldTax: Boolean, + val isDormancyTrackingActive: Boolean, + val productOptions: List, + val chargeOptions: List = emptyList(), +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingCharge.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingCharge.kt new file mode 100644 index 000000000..9fb84c14d --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingCharge.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +@Serializable +data class SavingCharge( + val chargeId: Long, + val amount: Long, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingProductOption.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingProductOption.kt new file mode 100644 index 000000000..f11628ba4 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingProductOption.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +@Serializable +data class SavingProductOption( + val id: Long, + val name: String, + val withdrawalFeeForTransfers: Boolean, + val allowOverdraft: Boolean, + val enforceMinRequiredBalance: Boolean, + val lienAllowed: Boolean, + val withHoldTax: Boolean, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingsWithAssociationsEntity.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingsWithAssociationsEntity.kt new file mode 100644 index 000000000..a63d016ae --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SavingsWithAssociationsEntity.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable + +@Serializable +data class SavingsWithAssociationsEntity( + val id: Long, + val accountNo: String, + val depositType: DepositType, + val clientId: Long, + val clientName: String, + val savingsProductId: Long, + val savingsProductName: String, + val fieldOfficerId: Long, + val status: Status, + val subStatus: SubStatus, + val timeline: Timeline, + val currency: Currency, + val nominalAnnualInterestRate: Double, + val interestCompoundingPeriodType: InterestPeriod = InterestPeriod(), + val interestPostingPeriodType: InterestPeriod = InterestPeriod(), + val interestCalculationType: InterestPeriod = InterestPeriod(), + val interestCalculationDaysInYearType: InterestPeriod = InterestPeriod(), + val withdrawalFeeForTransfers: Boolean, + val allowOverdraft: Boolean, + val enforceMinRequiredBalance: Boolean, + val lienAllowed: Boolean, + val withHoldTax: Boolean, + val lastActiveTransactionDate: List = emptyList(), + val isDormancyTrackingActive: Boolean, + val summary: Summary, + val transactions: List = emptyList(), +) diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Status.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Status.kt new file mode 100644 index 000000000..787e10074 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Status.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +@Serializable +data class Status( + val id: Int, + val code: String, + val value: String, + val submittedAndPendingApproval: Boolean, + val approved: Boolean, + val rejected: Boolean, + val withdrawnByApplicant: Boolean, + val active: Boolean, + val closed: Boolean, + val prematureClosed: Boolean, + val transferInProgress: Boolean, + val transferOnHold: Boolean, + val matured: Boolean, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SubStatus.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SubStatus.kt new file mode 100644 index 000000000..ecb796aa1 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/SubStatus.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class SubStatus( + val id: Long, + val code: String, + val value: String, + val none: Boolean, + val inactive: Boolean, + val dormant: Boolean, + val escheat: Boolean, + val block: Boolean, + val blockCredit: Boolean, + val blockDebit: Boolean, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Summary.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Summary.kt new file mode 100644 index 000000000..542d2ce44 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Summary.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.CurrencyFormatter +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class Summary( + val currency: Currency, + val totalDeposits: Double = 0.0, + val totalWithdrawals: Double = 0.0, + val totalInterestPosted: Long = 0, + val accountBalance: Double = 0.0, + val totalOverdraftInterestDerived: Long = 0, + val interestNotPosted: Long = 0, + val availableBalance: Double = 0.0, +) : Parcelable + +fun Summary.formatAmount(amount: Double): String { + return CurrencyFormatter.format( + balance = amount, + currencyCode = currency.code, + maximumFractionDigits = null, + ) +} diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Timeline.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Timeline.kt new file mode 100644 index 000000000..18a50c200 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Timeline.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class Timeline( + val submittedOnDate: List = emptyList(), + val submittedByUsername: String = "", + val submittedByFirstname: String = "", + val submittedByLastname: String = "", + val approvedOnDate: List = emptyList(), + val approvedByUsername: String = "", + val approvedByFirstname: String = "", + val approvedByLastname: String = "", + val activatedOnDate: List = emptyList(), + val activatedByUsername: String = "", + val activatedByFirstname: String = "", + val activatedByLastname: String = "", +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Transaction.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Transaction.kt new file mode 100644 index 000000000..032ef6fa4 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Transaction.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +data class Transaction( + val accountId: Long, + val amount: Double, + val date: String, + val currency: Currency, + val transactionType: TransactionType, + val transactionId: Long, + val accountNo: String, + val transferId: Long?, + val originalTransactionId: Long, + val paymentDetailId: Long?, +) : Parcelable { + @Serializable + @Parcelize + data class Type( + val id: Long, + val code: String, + val value: String, + ) : Parcelable +} diff --git a/core/model/src/main/java/com/mifospay/core/model/domain/TransactionType.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/TransactionType.kt similarity index 89% rename from core/model/src/main/java/com/mifospay/core/model/domain/TransactionType.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/TransactionType.kt index ad57f69fb..28303f3d0 100644 --- a/core/model/src/main/java/com/mifospay/core/model/domain/TransactionType.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/TransactionType.kt @@ -7,10 +7,10 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.domain +package org.mifospay.core.model.savingsaccount enum class TransactionType { + OTHER, DEBIT, CREDIT, - OTHER, } diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/TransactionsEntity.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/TransactionsEntity.kt new file mode 100644 index 000000000..481b360c5 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/TransactionsEntity.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable + +@Serializable +data class TransactionsEntity( + val id: Long, + val transactionType: TransactionType, + val entryType: String, + val accountId: Long, + val accountNo: String, + val date: List, + val currency: Currency, + val amount: Double, + val runningBalance: Double, + val reversed: Boolean, + val transfer: Transfer? = null, + val submittedOnDate: List, + val interestedPostedAsOn: Boolean, + val submittedByUsername: String, + val isManualTransaction: Boolean, + val isReversal: Boolean, + val originalTransactionId: Long, + val lienTransaction: Boolean, + val releaseTransactionId: Long, + val paymentDetailData: PaymentDetailData? = null, +) { + @Serializable + data class TransactionType( + val id: Long, + val code: String, + val value: String, + val deposit: Boolean, + val dividendPayout: Boolean, + val withdrawal: Boolean, + val interestPosting: Boolean, + val feeDeduction: Boolean, + val initiateTransfer: Boolean, + val approveTransfer: Boolean, + val withdrawTransfer: Boolean, + val rejectTransfer: Boolean, + val overdraftInterest: Boolean, + val writtenoff: Boolean, + val overdraftFee: Boolean, + val withholdTax: Boolean, + val escheat: Boolean, + val amountHold: Boolean, + val amountRelease: Boolean, + ) +} diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Transfer.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Transfer.kt new file mode 100644 index 000000000..6984f81c9 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/Transfer.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Parcelize +@Serializable +data class Transfer( + val id: Long, + val reversed: Boolean, + val currency: Currency, + val transferAmount: Double, + val transferDate: List, + val transferDescription: String, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/TransferDetail.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/TransferDetail.kt new file mode 100644 index 000000000..3a45e9632 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/TransferDetail.kt @@ -0,0 +1,97 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.savingsaccount + +import kotlinx.serialization.Serializable + +@Serializable +data class TransferDetail( + val id: Long, + val reversed: Boolean = false, + val currency: Currency = Currency(), + val transferAmount: Double = 0.0, + val transferDate: List, + val transferDescription: String? = null, + val fromOffice: FromOffice, + val fromClient: FromClient, + val fromAccountType: FromAccountType, + val fromAccount: FromAccount, + val toOffice: ToOffice, + val toClient: ToClient, + val toAccountType: ToAccountType, + val toAccount: ToAccount, +) { + @Serializable + data class Currency( + val code: String = "", + val name: String = "", + val decimalPlaces: Long = 0L, + val inMultiplesOf: Long = 0L, + val displaySymbol: String = "", + val nameCode: String = "", + val displayLabel: String = "", + ) + + @Serializable + data class FromOffice( + val id: Long = 0, + val name: String = "", + ) + + @Serializable + data class FromClient( + val id: Long = 0, + val displayName: String = "", + val isStaff: Boolean = false, + val officeId: Long = 0, + val officeName: String = "", + ) + + @Serializable + data class FromAccountType( + val id: Long = 0, + val code: String = "", + val value: String = "", + ) + + @Serializable + data class FromAccount( + val id: Long = 0, + val accountNo: String = "", + ) + + @Serializable + data class ToOffice( + val id: Long = 0, + val name: String = "", + ) + + @Serializable + data class ToClient( + val id: Long = 0, + val displayName: String = "", + val isStaff: Boolean = false, + val officeId: Long = 0, + val officeName: String = "", + ) + + @Serializable + data class ToAccountType( + val id: Long = 0, + val code: String = "", + val value: String = "", + ) + + @Serializable + data class ToAccount( + val id: Long = 0, + val accountNo: String = "", + ) +} diff --git a/core/model/src/main/java/com/mifospay/core/model/domain/Account.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/UpdateSavingAccountEntity.kt similarity index 60% rename from core/model/src/main/java/com/mifospay/core/model/domain/Account.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/UpdateSavingAccountEntity.kt index 111a68214..5a71e04d6 100644 --- a/core/model/src/main/java/com/mifospay/core/model/domain/Account.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/savingsaccount/UpdateSavingAccountEntity.kt @@ -7,17 +7,15 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.domain +package org.mifospay.core.model.savingsaccount import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize @Serializable -data class Account( - var image: String = "", - var name: String, - var number: String, - var balance: Double = 0.0, - var id: Long = 0L, - var productId: Long = 0L, - var currency: Currency, -) +@Parcelize +data class UpdateSavingAccountEntity( + val clientId: String, + val productId: Long, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/search/AccountResult.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/search/AccountResult.kt new file mode 100644 index 000000000..397162ebc --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/search/AccountResult.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.search + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize + +@Serializable +@Parcelize +data class AccountResult( + val entityId: Long, + val entityAccountNo: String, + val entityExternalId: String?, + val entityName: String, + val entityType: String, + val parentId: Long, + val parentName: String, + val parentType: String, + val subEntityType: String, +) : Parcelable diff --git a/core/model/src/main/java/com/mifospay/core/model/domain/SearchResult.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/search/SearchResult.kt similarity index 54% rename from core/model/src/main/java/com/mifospay/core/model/domain/SearchResult.kt rename to core/model/src/commonMain/kotlin/org/mifospay/core/model/search/SearchResult.kt index 94d31b09b..e0f8c21cb 100644 --- a/core/model/src/main/java/com/mifospay/core/model/domain/SearchResult.kt +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/search/SearchResult.kt @@ -7,16 +7,17 @@ * * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md */ -package com.mifospay.core.model.domain +package org.mifospay.core.model.search -import android.os.Parcelable -import kotlinx.parcelize.Parcelize +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize @Parcelize data class SearchResult( - var resultId: Int = 0, - var resultName: String, - var resultType: String, -) : Parcelable { - constructor() : this(0, "", "") -} + val entityId: Int, + val entityAccountNo: String, + val entityName: String, + val entityType: String, + val parentId: Int, + val parentName: String, +) : Parcelable diff --git a/core/model/src/commonMain/kotlin/org/mifospay/core/model/standinginstruction/SITemplate.kt b/core/model/src/commonMain/kotlin/org/mifospay/core/model/standinginstruction/SITemplate.kt new file mode 100644 index 000000000..fd853f861 --- /dev/null +++ b/core/model/src/commonMain/kotlin/org/mifospay/core/model/standinginstruction/SITemplate.kt @@ -0,0 +1,120 @@ +/* + * Copyright 2024 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.model.standinginstruction + +import kotlinx.serialization.Serializable +import org.mifospay.core.common.Parcelable +import org.mifospay.core.common.Parcelize +import org.mifospay.core.model.savingsaccount.Currency + +@Serializable +@Parcelize +data class SITemplate( + val fromOffice: FromOffice, + val fromClient: FromClient, + val fromAccountType: Option, + val fromOfficeOptions: List, + val fromClientOptions: List, + val fromAccountTypeOptions: List

+ + \ No newline at end of file diff --git a/mifospay-web/src/jsMain/resources/styles.css b/mifospay-web/src/jsMain/resources/styles.css new file mode 100644 index 000000000..3e82a3d56 --- /dev/null +++ b/mifospay-web/src/jsMain/resources/styles.css @@ -0,0 +1,14 @@ +html, body { + height: 100%; + margin: 0px; + padding: 0px; +} + +canvas { + width: 100vw; + height: 100vh; + display: block; + position: fixed; + top: 0; + left: 0; +} \ No newline at end of file diff --git a/mifospay-web/src/wasmJsMain/kotlin/Main.kt b/mifospay-web/src/wasmJsMain/kotlin/Main.kt new file mode 100644 index 000000000..56eb47cdc --- /dev/null +++ b/mifospay-web/src/wasmJsMain/kotlin/Main.kt @@ -0,0 +1,22 @@ +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.window.CanvasBasedWindow +import org.jetbrains.compose.resources.ExperimentalResourceApi +import org.jetbrains.compose.resources.configureWebResources +import org.mifospay.shared.MifosPaySharedApp +import org.mifospay.shared.di.initKoin + +@OptIn(ExperimentalComposeUiApi::class, ExperimentalResourceApi::class) +fun main() { + initKoin() + + configureWebResources { + resourcePathMapping { path -> "./$path" } + } + + CanvasBasedWindow( + title = "MifosWallet", + canvasElementId = "ComposeTarget", + ) { + MifosPaySharedApp() + } +} \ No newline at end of file diff --git a/mifospay-web/src/wasmJsMain/resources/index.html b/mifospay-web/src/wasmJsMain/resources/index.html new file mode 100644 index 000000000..4948b645f --- /dev/null +++ b/mifospay-web/src/wasmJsMain/resources/index.html @@ -0,0 +1,26 @@ + + + + + + Mifos Wallet + + + + + + + \ No newline at end of file diff --git a/mifospay/dependencies/prodReleaseRuntimeClasspath.tree.txt b/mifospay/dependencies/prodReleaseRuntimeClasspath.tree.txt deleted file mode 100644 index 675d55138..000000000 --- a/mifospay/dependencies/prodReleaseRuntimeClasspath.tree.txt +++ /dev/null @@ -1,2624 +0,0 @@ -+--- androidx.databinding:databinding-common:8.5.2 -+--- androidx.databinding:databinding-runtime:8.5.2 -| +--- androidx.collection:collection:1.0.0 -> 1.4.2 -| | \--- androidx.collection:collection-jvm:1.4.2 -| | +--- androidx.annotation:annotation:1.8.1 -| | | \--- androidx.annotation:annotation-jvm:1.8.1 -| | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 2.0.20 -| | | +--- org.jetbrains:annotations:13.0 -> 23.0.0 -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0 -> 1.9.20 (c) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0 -> 1.9.20 (c) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:2.0.20 (c) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | +--- androidx.collection:collection-ktx:1.4.2 (c) -| | \--- androidx.collection:collection-ktx:1.3.0 -> 1.4.2 (c) -| +--- androidx.databinding:databinding-common:8.5.2 -| +--- androidx.databinding:viewbinding:8.5.2 -| | \--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*) -| \--- androidx.lifecycle:lifecycle-runtime:2.6.1 -> 2.8.4 -| \--- androidx.lifecycle:lifecycle-runtime-android:2.8.4 -| +--- androidx.annotation:annotation:1.8.0 -> 1.8.1 (*) -| +--- androidx.arch.core:core-common:2.2.0 -| | \--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| +--- androidx.arch.core:core-runtime:2.2.0 -| | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | \--- androidx.arch.core:core-common:2.2.0 (*) -| +--- androidx.lifecycle:lifecycle-common:2.8.4 -| | \--- androidx.lifecycle:lifecycle-common-jvm:2.8.4 -| | +--- androidx.annotation:annotation:1.8.0 -> 1.8.1 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 -| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1 -| | | +--- org.jetbrains:annotations:23.0.0 -| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1 -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1 (c) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1 (c) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 (c) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.8.1 (c) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.8.1 (c) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.8.1 (c) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1 (c) -| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.8.1 (c) -| | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -| +--- androidx.profileinstaller:profileinstaller:1.3.1 -| | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | +--- androidx.concurrent:concurrent-futures:1.1.0 -| | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | \--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava -| | +--- androidx.startup:startup-runtime:1.1.1 -| | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | \--- androidx.tracing:tracing:1.0.0 -> 1.3.0-alpha02 -| | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | \--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (c) -| | \--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava -| +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.8.1 -| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 (*) -| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1 (*) -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 2.0.20 (*) -| +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -+--- androidx.databinding:databinding-adapters:8.5.2 -| +--- androidx.databinding:databinding-runtime:8.5.2 (*) -| \--- androidx.databinding:databinding-common:8.5.2 -+--- androidx.databinding:databinding-ktx:8.5.2 -| +--- androidx.databinding:databinding-runtime:8.5.2 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.20 -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.20 -> 2.0.20 (*) -| | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.20 -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.20 -> 2.0.20 (*) -| +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1 -> 1.8.1 (*) -| +--- androidx.lifecycle:lifecycle-runtime-ktx:2.6.1 -> 2.8.4 -| | \--- androidx.lifecycle:lifecycle-runtime-ktx-android:2.8.4 -| | +--- androidx.annotation:annotation:1.8.0 -> 1.8.1 (*) -| | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.8.1 (*) -| | +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-livedata:2.6.1 -> 2.8.4 -| | +--- androidx.arch.core:core-common:2.2.0 (*) -| | +--- androidx.arch.core:core-runtime:2.2.0 (*) -| | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 -| | | +--- androidx.arch.core:core-common:2.2.0 (*) -| | | +--- androidx.arch.core:core-runtime:2.2.0 (*) -| | | +--- androidx.lifecycle:lifecycle-common:2.8.4 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| | | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 -| | | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| | | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-process:2.6.1 -> 2.8.4 -| | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (*) -| | +--- androidx.startup:startup-runtime:1.1.1 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-service:2.6.1 -> 2.8.4 -| | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -| \--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 -> 2.8.4 -| \--- androidx.lifecycle:lifecycle-viewmodel-android:2.8.4 -| +--- androidx.annotation:annotation:1.8.0 -> 1.8.1 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.8.1 (*) -| +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -+--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -+--- androidx.compose:compose-bom:2024.08.00 -| +--- androidx.compose.material3:material3-window-size-class:1.2.1 (c) -| +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-tooling-preview:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.foundation:foundation:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.foundation:foundation-layout:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.material:material-icons-extended:1.6.8 (c) -| +--- androidx.compose.material3:material3:1.2.1 (c) -| +--- androidx.compose.ui:ui-util:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.runtime:runtime-saveable:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.animation:animation:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.material3:material3-window-size-class-android:1.2.1 (c) -| +--- androidx.compose.animation:animation-graphics:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-geometry:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.animation:animation-core:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.foundation:foundation-layout-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.runtime:runtime-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.runtime:runtime-saveable-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.material3:material3-android:1.2.1 (c) -| +--- androidx.compose.material:material-icons-extended-android:1.6.8 (c) -| +--- androidx.compose.animation:animation-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-unit:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-test-junit4:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-tooling:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.animation:animation-core-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-graphics:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-text:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.material:material-icons-core:1.6.8 (c) -| +--- androidx.compose.material:material-ripple:1.6.8 (c) -| +--- androidx.compose.ui:ui-unit-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-util-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.foundation:foundation-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-geometry-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-test-junit4-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-tooling-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-tooling-preview-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-graphics-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-text-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.material:material-icons-core-android:1.6.8 (c) -| +--- androidx.compose.material:material-ripple-android:1.6.8 (c) -| +--- androidx.compose.animation:animation-graphics-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-test:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.material:material:1.6.8 (c) -| +--- androidx.compose.ui:ui-tooling-data:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-test-android:1.6.8 -> 1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-tooling-data-android:1.6.8 -> 1.7.0-rc01 (c) -| \--- androidx.compose.material:material-android:1.6.8 (c) -+--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 -| \--- androidx.compose.ui:ui-tooling-preview-android:1.7.0-rc01 -| +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| +--- androidx.compose.runtime:runtime:1.7.0-rc01 -| | \--- androidx.compose.runtime:runtime-android:1.7.0-rc01 -| | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 -| | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 2.0.20 (*) -| | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.8.1 (*) -| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | \--- androidx.compose.runtime:runtime-saveable:1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui:1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-test:1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-test-junit4:1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-text:1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-tooling:1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-tooling-data:1.7.0-rc01 (c) -| +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (c) -| \--- androidx.compose.ui:ui-util:1.7.0-rc01 (c) -+--- com.google.firebase:firebase-bom:33.1.2 -| +--- com.google.firebase:firebase-perf-ktx:21.0.1 (c) -| +--- com.google.firebase:firebase-crashlytics-ktx:19.0.3 (c) -| +--- com.google.firebase:firebase-analytics-ktx:22.0.2 (c) -| +--- com.google.firebase:firebase-messaging-ktx:24.0.0 (c) -| +--- com.google.firebase:firebase-perf:21.0.1 (c) -| +--- com.google.firebase:firebase-common:21.0.0 (c) -| +--- com.google.firebase:firebase-common-ktx:21.0.0 (c) -| +--- com.google.firebase:firebase-crashlytics:19.0.3 (c) -| +--- com.google.firebase:firebase-analytics:22.0.2 (c) -| +--- com.google.firebase:firebase-messaging:24.0.0 (c) -| +--- com.google.firebase:firebase-encoders:17.0.0 (c) -| +--- com.google.firebase:firebase-config:22.0.0 (c) -| \--- com.google.firebase:firebase-installations:18.0.0 (c) -+--- com.google.firebase:firebase-analytics-ktx -> 22.0.2 -| +--- com.google.firebase:firebase-analytics:22.0.2 -| | +--- com.google.android.gms:play-services-measurement:22.0.2 -| | | +--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | +--- androidx.legacy:legacy-support-core-utils:1.0.0 -| | | | +--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*) -| | | | +--- androidx.core:core:1.0.0 -> 1.13.1 -| | | | | +--- androidx.annotation:annotation:1.6.0 -> 1.8.1 (*) -| | | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | | | +--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | | | +--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0 (*) -| | | | | +--- androidx.interpolator:interpolator:1.0.0 -| | | | | | \--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*) -| | | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.2 -> 2.8.4 (*) -| | | | | +--- androidx.versionedparcelable:versionedparcelable:1.1.1 -| | | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | | \--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | \--- androidx.core:core-ktx:1.13.1 (c) -| | | | +--- androidx.documentfile:documentfile:1.0.0 -| | | | | \--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*) -| | | | +--- androidx.loader:loader:1.0.0 -> 1.1.0 -| | | | | +--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*) -| | | | | +--- androidx.core:core:1.0.0 -> 1.13.1 (*) -| | | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.0.0 -> 2.8.4 (*) -| | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.0.0 -> 2.8.4 (*) -| | | | | \--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | | +--- androidx.localbroadcastmanager:localbroadcastmanager:1.0.0 -| | | | | \--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*) -| | | | \--- androidx.print:print:1.0.0 -| | | | \--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*) -| | | +--- com.google.android.gms:play-services-ads-identifier:18.0.0 -| | | | \--- com.google.android.gms:play-services-basement:18.0.0 -> 18.4.0 -| | | | +--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | | +--- androidx.core:core:1.2.0 -> 1.13.1 (*) -| | | | \--- androidx.fragment:fragment:1.1.0 -> 1.8.2 -| | | | +--- androidx.activity:activity:1.8.1 -> 1.9.1 -| | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | +--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | | | +--- androidx.core:core:1.13.0 -> 1.13.1 (*) -| | | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 -> 2.8.4 (*) -| | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 -> 2.8.4 (*) -| | | | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 -> 2.8.4 -| | | | | | +--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*) -| | | | | | +--- androidx.core:core-ktx:1.2.0 -> 1.13.1 -| | | | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | | | +--- androidx.core:core:1.13.1 (*) -| | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | | | \--- androidx.core:core:1.13.1 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (*) -| | | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (*) -| | | | | | +--- androidx.savedstate:savedstate:1.2.1 -| | | | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | | | +--- androidx.arch.core:core-common:2.1.0 -> 2.2.0 (*) -| | | | | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 -> 2.8.4 (*) -| | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 2.0.20 (*) -| | | | | | | \--- androidx.savedstate:savedstate-ktx:1.2.1 (c) -| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.8.1 (*) -| | | | | | +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | | | | | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| | | | | | \--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| | | | | +--- androidx.profileinstaller:profileinstaller:1.3.1 (*) -| | | | | +--- androidx.savedstate:savedstate:1.2.1 (*) -| | | | | +--- androidx.tracing:tracing:1.0.0 -> 1.3.0-alpha02 (*) -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | +--- androidx.activity:activity-compose:1.9.1 (c) -| | | | | \--- androidx.activity:activity-ktx:1.9.1 (c) -| | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | | +--- androidx.collection:collection:1.1.0 -> 1.4.2 (*) -| | | | +--- androidx.core:core-ktx:1.2.0 -> 1.13.1 (*) -| | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.6.1 -> 2.8.4 (*) -| | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 -> 2.8.4 (*) -| | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 -> 2.8.4 (*) -| | | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 -> 2.8.4 (*) -| | | | +--- androidx.loader:loader:1.0.0 -> 1.1.0 (*) -| | | | +--- androidx.profileinstaller:profileinstaller:1.3.1 (*) -| | | | +--- androidx.savedstate:savedstate:1.2.1 (*) -| | | | +--- androidx.viewpager:viewpager:1.0.0 -| | | | | +--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*) -| | | | | +--- androidx.core:core:1.0.0 -> 1.13.1 (*) -| | | | | \--- androidx.customview:customview:1.0.0 -> 1.1.0 -| | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | +--- androidx.core:core:1.3.0 -> 1.13.1 (*) -| | | | | \--- androidx.collection:collection:1.1.0 -> 1.4.2 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | \--- androidx.fragment:fragment-ktx:1.8.2 (c) -| | | +--- com.google.android.gms:play-services-basement:18.4.0 (*) -| | | +--- com.google.android.gms:play-services-measurement-base:22.0.2 -| | | | \--- com.google.android.gms:play-services-basement:18.4.0 (*) -| | | +--- com.google.android.gms:play-services-measurement-impl:22.0.2 -| | | | +--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | | +--- androidx.core:core:1.9.0 -> 1.13.1 (*) -| | | | +--- androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05 -| | | | | +--- androidx.annotation:annotation:1.6.0 -> 1.8.1 (*) -| | | | | +--- androidx.core:core-ktx:1.8.0 -> 1.13.1 (*) -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.21 -> 2.0.20 (*) -| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | | | \--- androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05 (c) -| | | | +--- androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05 -| | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | | | +--- androidx.concurrent:concurrent-futures:1.1.0 (*) -| | | | | +--- androidx.core:core-ktx:1.8.0 -> 1.13.1 (*) -| | | | | +--- androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05 (*) -| | | | | +--- com.google.guava:guava:31.1-android -| | | | | | +--- com.google.guava:failureaccess:1.0.1 -| | | | | | +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava -| | | | | | +--- com.google.code.findbugs:jsr305:3.0.2 -| | | | | | +--- org.checkerframework:checker-qual:3.12.0 -| | | | | | +--- com.google.errorprone:error_prone_annotations:2.11.0 -> 2.26.0 -| | | | | | \--- com.google.j2objc:j2objc-annotations:1.3 -| | | | | +--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.21 -> 2.0.20 (*) -| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | | | \--- androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05 (c) -| | | | +--- com.google.android.gms:play-services-ads-identifier:18.0.0 (*) -| | | | +--- com.google.android.gms:play-services-basement:18.4.0 (*) -| | | | +--- com.google.android.gms:play-services-measurement-base:22.0.2 (*) -| | | | +--- com.google.android.gms:play-services-stats:17.0.2 -| | | | | +--- androidx.legacy:legacy-support-core-utils:1.0.0 (*) -| | | | | \--- com.google.android.gms:play-services-basement:18.0.0 -> 18.4.0 (*) -| | | | \--- com.google.guava:guava:31.1-android (*) -| | | \--- com.google.android.gms:play-services-stats:17.0.2 (*) -| | +--- com.google.android.gms:play-services-measurement-api:22.0.2 -| | | +--- com.google.android.gms:play-services-ads-identifier:18.0.0 (*) -| | | +--- com.google.android.gms:play-services-basement:18.4.0 (*) -| | | +--- com.google.android.gms:play-services-measurement-base:22.0.2 (*) -| | | +--- com.google.android.gms:play-services-measurement-sdk-api:22.0.2 -| | | | +--- com.google.android.gms:play-services-basement:18.4.0 (*) -| | | | \--- com.google.android.gms:play-services-measurement-base:22.0.2 (*) -| | | +--- com.google.android.gms:play-services-tasks:18.2.0 -| | | | \--- com.google.android.gms:play-services-basement:18.4.0 (*) -| | | +--- com.google.firebase:firebase-common:21.0.0 -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.4 -> 1.8.1 -| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 (*) -| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1 (*) -| | | | | +--- com.google.android.gms:play-services-tasks:16.0.1 -> 18.2.0 (*) -| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 2.0.20 (*) -| | | | +--- com.google.firebase:firebase-components:18.0.0 -| | | | | +--- com.google.firebase:firebase-annotations:16.2.0 -| | | | | | \--- javax.inject:javax.inject:1 -| | | | | +--- androidx.annotation:annotation:1.5.0 -> 1.8.1 (*) -| | | | | \--- com.google.errorprone:error_prone_annotations:2.26.0 -| | | | +--- com.google.firebase:firebase-annotations:16.2.0 (*) -| | | | +--- androidx.annotation:annotation:1.5.0 -> 1.8.1 (*) -| | | | +--- androidx.concurrent:concurrent-futures:1.1.0 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | +--- com.google.android.gms:play-services-basement:18.3.0 -> 18.4.0 (*) -| | | | \--- com.google.android.gms:play-services-tasks:18.1.0 -> 18.2.0 (*) -| | | +--- com.google.firebase:firebase-common-ktx:21.0.0 -| | | | +--- com.google.firebase:firebase-common:21.0.0 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | | +--- com.google.firebase:firebase-components:18.0.0 (*) -| | | | \--- com.google.firebase:firebase-annotations:16.2.0 (*) -| | | +--- com.google.firebase:firebase-components:18.0.0 (*) -| | | +--- com.google.firebase:firebase-installations:17.0.1 -> 18.0.0 -| | | | +--- com.google.android.gms:play-services-tasks:18.0.1 -> 18.2.0 (*) -| | | | +--- com.google.firebase:firebase-annotations:16.2.0 (*) -| | | | +--- com.google.firebase:firebase-common:21.0.0 (*) -| | | | +--- com.google.firebase:firebase-common-ktx:21.0.0 (*) -| | | | +--- com.google.firebase:firebase-components:18.0.0 (*) -| | | | +--- com.google.firebase:firebase-installations-interop:17.1.1 -> 17.2.0 -| | | | | +--- com.google.android.gms:play-services-tasks:18.0.1 -> 18.2.0 (*) -| | | | | \--- com.google.firebase:firebase-annotations:16.2.0 (*) -| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | +--- com.google.firebase:firebase-installations-interop:17.0.0 -> 17.2.0 (*) -| | | +--- com.google.firebase:firebase-measurement-connector:19.0.0 -> 20.0.1 -| | | | +--- com.google.android.gms:play-services-basement:18.0.0 -> 18.4.0 (*) -| | | | \--- com.google.firebase:firebase-annotations:16.0.0 -> 16.2.0 (*) -| | | +--- com.google.guava:guava:31.1-android (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 2.0.20 (*) -| | \--- com.google.android.gms:play-services-measurement-sdk:22.0.2 -| | +--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | +--- com.google.android.gms:play-services-basement:18.4.0 (*) -| | +--- com.google.android.gms:play-services-measurement-base:22.0.2 (*) -| | \--- com.google.android.gms:play-services-measurement-impl:22.0.2 (*) -| +--- com.google.firebase:firebase-common:21.0.0 (*) -| +--- com.google.firebase:firebase-common-ktx:21.0.0 (*) -| +--- com.google.firebase:firebase-components:18.0.0 (*) -| \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 2.0.20 (*) -+--- com.google.firebase:firebase-perf-ktx -> 21.0.1 -| +--- com.google.firebase:firebase-perf:21.0.1 -| | +--- com.google.firebase:firebase-annotations:16.2.0 (*) -| | +--- com.google.firebase:firebase-installations-interop:17.1.0 -> 17.2.0 (*) -| | +--- com.google.firebase:protolite-well-known-types:18.0.0 -| | | \--- com.google.protobuf:protobuf-javalite:3.14.0 -> 4.26.0 -| | +--- com.google.firebase:firebase-common:21.0.0 (*) -| | +--- com.google.firebase:firebase-common-ktx:21.0.0 (*) -| | +--- com.google.firebase:firebase-components:18.0.0 (*) -| | +--- com.google.firebase:firebase-config:21.5.0 -> 22.0.0 -| | | +--- com.google.firebase:firebase-config-interop:16.0.1 -| | | | +--- com.google.firebase:firebase-encoders-json:18.0.1 -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10 -> 1.9.20 (*) -| | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | \--- com.google.firebase:firebase-encoders:17.0.0 -| | | | | \--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | \--- com.google.firebase:firebase-encoders:17.0.0 (*) -| | | +--- com.google.firebase:firebase-annotations:16.2.0 (*) -| | | +--- com.google.firebase:firebase-installations-interop:17.1.0 -> 17.2.0 (*) -| | | +--- com.google.firebase:firebase-abt:21.1.1 -| | | | +--- com.google.firebase:firebase-measurement-connector:18.0.0 -> 20.0.1 (*) -| | | | \--- com.google.android.gms:play-services-basement:18.1.0 -> 18.4.0 (*) -| | | +--- com.google.firebase:firebase-measurement-connector:18.0.0 -> 20.0.1 (*) -| | | +--- com.google.firebase:firebase-common:21.0.0 (*) -| | | +--- com.google.firebase:firebase-common-ktx:21.0.0 (*) -| | | +--- com.google.firebase:firebase-components:18.0.0 (*) -| | | +--- com.google.firebase:firebase-installations:17.2.0 -> 18.0.0 (*) -| | | +--- com.google.android.gms:play-services-tasks:18.0.1 -> 18.2.0 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | \--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | +--- com.google.firebase:firebase-installations:17.2.0 -> 18.0.0 (*) -| | +--- com.google.firebase:firebase-sessions:2.0.0 -> 2.0.3 -| | | +--- com.google.firebase:firebase-common:21.0.0 (*) -| | | +--- com.google.firebase:firebase-common-ktx:21.0.0 (*) -| | | +--- com.google.firebase:firebase-components:18.0.0 (*) -| | | +--- com.google.firebase:firebase-installations-interop:17.2.0 (*) -| | | +--- com.google.firebase:firebase-annotations:16.2.0 (*) -| | | +--- com.google.firebase:firebase-encoders:17.0.0 (*) -| | | +--- com.google.firebase:firebase-encoders-json:18.0.1 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | +--- com.google.firebase:firebase-installations:18.0.0 (*) -| | | +--- com.google.firebase:firebase-datatransport:19.0.0 -| | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | +--- com.google.android.datatransport:transport-api:3.1.0 -> 3.2.0 -| | | | | \--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | +--- com.google.android.datatransport:transport-backend-cct:3.2.0 -> 3.3.0 -| | | | | +--- com.google.android.datatransport:transport-api:3.2.0 (*) -| | | | | +--- com.google.android.datatransport:transport-runtime:3.3.0 -| | | | | | +--- com.google.android.datatransport:transport-api:3.2.0 (*) -| | | | | | +--- androidx.annotation:annotation:1.3.0 -> 1.8.1 (*) -| | | | | | +--- javax.inject:javax.inject:1 -| | | | | | +--- com.google.firebase:firebase-encoders:17.0.0 (*) -| | | | | | \--- com.google.firebase:firebase-encoders-proto:16.0.0 -| | | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | | \--- com.google.firebase:firebase-encoders:17.0.0 (*) -| | | | | +--- com.google.firebase:firebase-encoders:17.0.0 (*) -| | | | | +--- com.google.firebase:firebase-encoders-json:18.0.0 -> 18.0.1 (*) -| | | | | \--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | +--- com.google.android.datatransport:transport-runtime:3.2.0 -> 3.3.0 (*) -| | | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | +--- androidx.datastore:datastore-preferences:1.0.0 -> 1.1.1 -| | | | \--- androidx.datastore:datastore-preferences-android:1.1.1 -| | | | +--- androidx.datastore:datastore:1.1.1 -| | | | | \--- androidx.datastore:datastore-android:1.1.1 -| | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | | | +--- androidx.datastore:datastore-core:1.1.1 -| | | | | | \--- androidx.datastore:datastore-core-android:1.1.1 -| | | | | | +--- androidx.annotation:annotation:1.7.0 -> 1.8.1 (*) -| | | | | | +--- org.jetbrains.kotlin:kotlin-parcelize-runtime:1.9.22 -> 2.0.20 -| | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | | | | | | \--- org.jetbrains.kotlin:kotlin-android-extensions-runtime:2.0.20 -| | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | | | | | +--- androidx.datastore:datastore:1.1.1 (c) -| | | | | | +--- androidx.datastore:datastore-core-okio:1.1.1 (c) -| | | | | | +--- androidx.datastore:datastore-preferences:1.1.1 (c) -| | | | | | \--- androidx.datastore:datastore-preferences-core:1.1.1 (c) -| | | | | +--- androidx.datastore:datastore-core-okio:1.1.1 -| | | | | | \--- androidx.datastore:datastore-core-okio-jvm:1.1.1 -| | | | | | +--- androidx.datastore:datastore-core:1.1.1 (*) -| | | | | | +--- com.squareup.okio:okio:3.4.0 -> 3.9.0 -| | | | | | | \--- com.squareup.okio:okio-jvm:3.9.0 -| | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 2.0.20 (*) -| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | | | | | +--- androidx.datastore:datastore-core:1.1.1 (c) -| | | | | | +--- androidx.datastore:datastore:1.1.1 (c) -| | | | | | +--- androidx.datastore:datastore-preferences:1.1.1 (c) -| | | | | | \--- androidx.datastore:datastore-preferences-core:1.1.1 (c) -| | | | | +--- com.squareup.okio:okio:3.4.0 -> 3.9.0 (*) -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | | | | +--- androidx.datastore:datastore-core:1.1.1 (c) -| | | | | +--- androidx.datastore:datastore-core-okio:1.1.1 (c) -| | | | | +--- androidx.datastore:datastore-preferences:1.1.1 (c) -| | | | | \--- androidx.datastore:datastore-preferences-core:1.1.1 (c) -| | | | +--- androidx.datastore:datastore-preferences-core:1.1.1 -| | | | | \--- androidx.datastore:datastore-preferences-core-jvm:1.1.1 -| | | | | +--- androidx.datastore:datastore-core:1.1.1 (*) -| | | | | +--- androidx.datastore:datastore-core-okio:1.1.1 (*) -| | | | | +--- com.squareup.okio:okio:3.4.0 -> 3.9.0 (*) -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | +--- androidx.datastore:datastore:1.1.1 (c) -| | | | | +--- androidx.datastore:datastore-core:1.1.1 (c) -| | | | | +--- androidx.datastore:datastore-core-okio:1.1.1 (c) -| | | | | \--- androidx.datastore:datastore-preferences:1.1.1 (c) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | | | +--- androidx.datastore:datastore:1.1.1 (c) -| | | | +--- androidx.datastore:datastore-core:1.1.1 (c) -| | | | +--- androidx.datastore:datastore-core-okio:1.1.1 (c) -| | | | \--- androidx.datastore:datastore-preferences-core:1.1.1 (c) -| | | +--- com.google.android.datatransport:transport-api:3.2.0 (*) -| | | \--- androidx.annotation:annotation:1.5.0 -> 1.8.1 (*) -| | +--- com.google.firebase:firebase-datatransport:18.1.8 -> 19.0.0 (*) -| | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | +--- androidx.lifecycle:lifecycle-process:2.3.1 -> 2.8.4 (*) -| | +--- com.google.android.gms:play-services-tasks:18.0.1 -> 18.2.0 (*) -| | +--- com.google.protobuf:protobuf-javalite:3.21.11 -> 4.26.0 -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | +--- androidx.appcompat:appcompat:1.2.0 -> 1.7.0 -| | | +--- androidx.activity:activity:1.7.0 -> 1.9.1 (*) -| | | +--- androidx.annotation:annotation:1.3.0 -> 1.8.1 (*) -| | | +--- androidx.appcompat:appcompat-resources:1.7.0 -| | | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | | +--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | | +--- androidx.core:core:1.6.0 -> 1.13.1 (*) -| | | | +--- androidx.vectordrawable:vectordrawable:1.1.0 -| | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | +--- androidx.core:core:1.1.0 -> 1.13.1 (*) -| | | | | \--- androidx.collection:collection:1.1.0 -> 1.4.2 (*) -| | | | +--- androidx.vectordrawable:vectordrawable-animated:1.1.0 -| | | | | +--- androidx.vectordrawable:vectordrawable:1.1.0 (*) -| | | | | +--- androidx.interpolator:interpolator:1.0.0 (*) -| | | | | \--- androidx.collection:collection:1.1.0 -> 1.4.2 (*) -| | | | \--- androidx.appcompat:appcompat:1.7.0 (c) -| | | +--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | +--- androidx.core:core:1.13.0 -> 1.13.1 (*) -| | | +--- androidx.core:core-ktx:1.13.0 -> 1.13.1 (*) -| | | +--- androidx.cursoradapter:cursoradapter:1.0.0 -| | | | \--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*) -| | | +--- androidx.drawerlayout:drawerlayout:1.0.0 -| | | | +--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*) -| | | | +--- androidx.core:core:1.0.0 -> 1.13.1 (*) -| | | | \--- androidx.customview:customview:1.0.0 -> 1.1.0 (*) -| | | +--- androidx.emoji2:emoji2:1.3.0 -| | | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | | +--- androidx.collection:collection:1.1.0 -> 1.4.2 (*) -| | | | +--- androidx.core:core:1.3.0 -> 1.13.1 (*) -| | | | +--- androidx.lifecycle:lifecycle-process:2.4.1 -> 2.8.4 (*) -| | | | +--- androidx.startup:startup-runtime:1.0.0 -> 1.1.1 (*) -| | | | \--- androidx.emoji2:emoji2-views-helper:1.3.0 (c) -| | | +--- androidx.emoji2:emoji2-views-helper:1.2.0 -> 1.3.0 -| | | | +--- androidx.collection:collection:1.1.0 -> 1.4.2 (*) -| | | | +--- androidx.core:core:1.3.0 -> 1.13.1 (*) -| | | | +--- androidx.emoji2:emoji2:1.3.0 (*) -| | | | \--- androidx.emoji2:emoji2:1.3.0 (c) -| | | +--- androidx.fragment:fragment:1.5.4 -> 1.8.2 (*) -| | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 -> 2.8.4 (*) -| | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 -> 2.8.4 (*) -| | | +--- androidx.profileinstaller:profileinstaller:1.3.1 (*) -| | | +--- androidx.resourceinspection:resourceinspection-annotation:1.0.1 -| | | | \--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | +--- androidx.savedstate:savedstate:1.2.1 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | \--- androidx.appcompat:appcompat-resources:1.7.0 (c) -| | +--- com.google.android.datatransport:transport-api:3.0.0 -> 3.2.0 (*) -| | +--- com.google.dagger:dagger:2.27 -| | | \--- javax.inject:javax.inject:1 -| | \--- com.squareup.okhttp3:okhttp:3.12.1 -> 4.12.0 -| | +--- com.squareup.okio:okio:3.6.0 -> 3.9.0 (*) -| | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21 -> 1.9.20 (*) -| +--- com.google.firebase:firebase-common:21.0.0 (*) -| +--- com.google.firebase:firebase-common-ktx:21.0.0 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| \--- com.google.firebase:firebase-components:18.0.0 (*) -+--- com.google.firebase:firebase-crashlytics-ktx -> 19.0.3 -| +--- com.google.firebase:firebase-crashlytics:19.0.3 -| | +--- com.google.firebase:firebase-sessions:2.0.3 (*) -| | +--- com.google.android.gms:play-services-tasks:18.1.0 -> 18.2.0 (*) -| | +--- com.google.firebase:firebase-annotations:16.2.0 (*) -| | +--- com.google.firebase:firebase-common:21.0.0 (*) -| | +--- com.google.firebase:firebase-common-ktx:21.0.0 (*) -| | +--- com.google.firebase:firebase-components:18.0.0 (*) -| | +--- com.google.firebase:firebase-config-interop:16.0.1 (*) -| | +--- com.google.firebase:firebase-encoders:17.0.0 (*) -| | +--- com.google.firebase:firebase-encoders-json:18.0.1 (*) -| | +--- com.google.firebase:firebase-installations:18.0.0 (*) -| | +--- com.google.firebase:firebase-installations-interop:17.2.0 (*) -| | +--- com.google.firebase:firebase-measurement-connector:20.0.1 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | +--- com.google.android.datatransport:transport-api:3.2.0 (*) -| | +--- com.google.android.datatransport:transport-backend-cct:3.3.0 (*) -| | +--- com.google.android.datatransport:transport-runtime:3.3.0 (*) -| | \--- androidx.annotation:annotation:1.5.0 -> 1.8.1 (*) -| +--- com.google.firebase:firebase-common:21.0.0 (*) -| +--- com.google.firebase:firebase-common-ktx:21.0.0 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| \--- com.google.firebase:firebase-components:18.0.0 (*) -+--- com.google.firebase:firebase-messaging-ktx -> 24.0.0 -| +--- com.google.firebase:firebase-messaging:24.0.0 -| | +--- com.google.firebase:firebase-common:21.0.0 (*) -| | +--- com.google.firebase:firebase-common-ktx:21.0.0 (*) -| | +--- com.google.firebase:firebase-components:18.0.0 (*) -| | +--- com.google.firebase:firebase-datatransport:18.2.0 -> 19.0.0 (*) -| | +--- com.google.firebase:firebase-encoders:17.0.0 (*) -| | +--- com.google.firebase:firebase-encoders-json:18.0.0 -> 18.0.1 (*) -| | +--- com.google.firebase:firebase-encoders-proto:16.0.0 (*) -| | +--- com.google.firebase:firebase-iid-interop:17.1.0 -| | | +--- com.google.android.gms:play-services-basement:17.0.0 -> 18.4.0 (*) -| | | \--- com.google.android.gms:play-services-tasks:17.0.0 -> 18.2.0 (*) -| | +--- com.google.firebase:firebase-installations:17.2.0 -> 18.0.0 (*) -| | +--- com.google.firebase:firebase-installations-interop:17.1.0 -> 17.2.0 (*) -| | +--- com.google.firebase:firebase-measurement-connector:19.0.0 -> 20.0.1 (*) -| | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | +--- com.google.android.datatransport:transport-api:3.1.0 -> 3.2.0 (*) -| | +--- com.google.android.datatransport:transport-backend-cct:3.1.8 -> 3.3.0 (*) -| | +--- com.google.android.datatransport:transport-runtime:3.1.8 -> 3.3.0 (*) -| | +--- com.google.android.gms:play-services-base:18.0.1 -> 18.3.0 -| | | +--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | +--- androidx.core:core:1.2.0 -> 1.13.1 (*) -| | | +--- androidx.fragment:fragment:1.0.0 -> 1.8.2 (*) -| | | +--- com.google.android.gms:play-services-basement:18.3.0 -> 18.4.0 (*) -| | | \--- com.google.android.gms:play-services-tasks:18.1.0 -> 18.2.0 (*) -| | +--- com.google.android.gms:play-services-basement:18.1.0 -> 18.4.0 (*) -| | +--- com.google.android.gms:play-services-cloud-messaging:17.2.0 -| | | +--- com.google.android.gms:play-services-basement:18.3.0 -> 18.4.0 (*) -| | | \--- com.google.android.gms:play-services-tasks:18.1.0 -> 18.2.0 (*) -| | +--- com.google.android.gms:play-services-stats:17.0.2 (*) -| | +--- com.google.android.gms:play-services-tasks:18.0.1 -> 18.2.0 (*) -| | +--- com.google.errorprone:error_prone_annotations:2.9.0 -> 2.26.0 -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| +--- com.google.firebase:firebase-common:21.0.0 (*) -| +--- com.google.firebase:firebase-common-ktx:21.0.0 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| \--- com.google.firebase:firebase-components:18.0.0 (*) -+--- project :shared -| +--- org.jetbrains.compose.ui:ui-tooling-preview:1.6.11 -| | \--- androidx.compose.ui:ui-tooling-preview:1.6.7 -> 1.7.0-rc01 (*) -| +--- androidx.activity:activity-compose:1.9.1 -| | +--- androidx.activity:activity-ktx:1.9.1 -| | | +--- androidx.activity:activity:1.9.1 (*) -| | | +--- androidx.core:core-ktx:1.13.0 -> 1.13.1 (*) -| | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.6.1 -> 2.8.4 (*) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1 -> 2.8.4 -| | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.8.1 (*) -| | | | +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| | | | \--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| | | +--- androidx.savedstate:savedstate-ktx:1.2.1 -| | | | +--- androidx.savedstate:savedstate:1.2.1 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 2.0.20 (*) -| | | | \--- androidx.savedstate:savedstate:1.2.1 (c) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | +--- androidx.activity:activity:1.9.1 (c) -| | | \--- androidx.activity:activity-compose:1.9.1 (c) -| | +--- androidx.compose.runtime:runtime:1.0.1 -> 1.7.0-rc01 (*) -| | +--- androidx.compose.runtime:runtime-saveable:1.0.1 -> 1.7.0-rc01 -| | | \--- androidx.compose.runtime:runtime-saveable-android:1.7.0-rc01 -| | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | \--- androidx.compose.runtime:runtime:1.7.0-rc01 (c) -| | +--- androidx.compose.ui:ui:1.0.1 -> 1.7.0-rc01 -| | | \--- androidx.compose.ui:ui-android:1.7.0-rc01 -| | | +--- androidx.activity:activity-ktx:1.7.0 -> 1.9.1 (*) -| | | +--- androidx.annotation:annotation:1.6.0 -> 1.8.1 (*) -| | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | +--- androidx.autofill:autofill:1.0.0 -| | | | \--- androidx.core:core:1.1.0 -> 1.13.1 (*) -| | | +--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | +--- androidx.compose.runtime:runtime-saveable:1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 -| | | | \--- androidx.compose.ui:ui-geometry-android:1.7.0-rc01 -| | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 -| | | | | \--- androidx.compose.ui:ui-util-android:1.7.0-rc01 -| | | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | +--- androidx.compose.ui:ui:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-test-junit4:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-text:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-tooling:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-test:1.7.0-rc01 (c) -| | | | | \--- androidx.compose.ui:ui-tooling-data:1.7.0-rc01 (c) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | +--- androidx.compose.ui:ui:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-test-junit4:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-text:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-test:1.7.0-rc01 (c) -| | | | \--- androidx.compose.ui:ui-tooling-data:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 -| | | | \--- androidx.compose.ui:ui-graphics-android:1.7.0-rc01 -| | | | +--- androidx.annotation:annotation:1.7.0 -> 1.8.1 (*) -| | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 -| | | | | \--- androidx.compose.ui:ui-unit-android:1.7.0-rc01 -| | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | | | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | | | | +--- androidx.collection:collection-ktx:1.2.0 -> 1.4.2 -| | | | | | +--- androidx.collection:collection:1.4.2 (*) -| | | | | | \--- androidx.collection:collection:1.4.2 (c) -| | | | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | | | +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 (*) -| | | | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (*) -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | +--- androidx.compose.ui:ui:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-test-junit4:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-text:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-tooling:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (c) -| | | | | +--- androidx.compose.ui:ui-test:1.7.0-rc01 (c) -| | | | | \--- androidx.compose.ui:ui-tooling-data:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (*) -| | | | +--- androidx.core:core:1.12.0 -> 1.13.1 (*) -| | | | +--- androidx.graphics:graphics-path:1.0.1 -| | | | | +--- androidx.core:core:1.12.0 -> 1.13.1 (*) -| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | +--- androidx.compose.ui:ui:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-test:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-test-junit4:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-text:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling-data:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (c) -| | | | \--- androidx.compose.ui:ui-util:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-text:1.7.0-rc01 -| | | | \--- androidx.compose.ui:ui-text-android:1.7.0-rc01 -| | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | | +--- androidx.compose.runtime:runtime-saveable:1.6.0 -> 1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (*) -| | | | +--- androidx.core:core:1.7.0 -> 1.13.1 (*) -| | | | +--- androidx.emoji2:emoji2:1.2.0 -> 1.3.0 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | | | +--- androidx.compose.ui:ui:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-test:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-test-junit4:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling-data:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (c) -| | | | \--- androidx.compose.ui:ui-util:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (*) -| | | +--- androidx.core:core:1.12.0 -> 1.13.1 (*) -| | | +--- androidx.customview:customview-poolingcontainer:1.0.0 -| | | | +--- androidx.core:core-ktx:1.5.0 -> 1.13.1 (*) -| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.6.21 -> 2.0.20 (*) -| | | +--- androidx.emoji2:emoji2:1.2.0 -> 1.3.0 (*) -| | | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.3 -> 2.8.4 -| | | | \--- androidx.lifecycle:lifecycle-runtime-compose-android:2.8.4 -| | | | +--- androidx.annotation:annotation:1.8.0 -> 1.8.1 (*) -| | | | +--- androidx.compose.runtime:runtime:1.6.5 -> 1.7.0-rc01 (*) -| | | | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (*) -| | | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (*) -| | | | +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -| | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| | | | \--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 -> 2.8.4 (*) -| | | +--- androidx.profileinstaller:profileinstaller:1.3.1 (*) -| | | +--- androidx.savedstate:savedstate-ktx:1.2.1 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.8.1 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | | +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-test-junit4:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-text:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-tooling:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (c) -| | | +--- androidx.compose.foundation:foundation:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-test:1.7.0-rc01 (c) -| | | \--- androidx.compose.ui:ui-tooling-data:1.7.0-rc01 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 -> 2.8.4 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | +--- androidx.activity:activity:1.9.1 (c) -| | \--- androidx.activity:activity-ktx:1.9.1 (c) -| +--- io.insert-koin:koin-android:4.0.0-RC2 -| | +--- io.insert-koin:koin-core:4.0.0-RC2 -| | | \--- io.insert-koin:koin-core-jvm:4.0.0-RC2 -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | | +--- co.touchlab:stately-concurrency:2.0.7 -| | | | \--- co.touchlab:stately-concurrency-jvm:2.0.7 -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.23 -> 2.0.20 (*) -| | | | \--- co.touchlab:stately-strict:2.0.7 -| | | | \--- co.touchlab:stately-strict-jvm:2.0.7 -| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.23 -> 2.0.20 (*) -| | | \--- co.touchlab:stately-concurrent-collections:2.0.7 -| | | \--- co.touchlab:stately-concurrent-collections-jvm:2.0.7 -| | | +--- co.touchlab:stately-concurrency:2.0.7 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.23 -> 2.0.20 (*) -| | +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 -| | | \--- io.insert-koin:koin-core-viewmodel-jvm:4.0.0-RC2 -| | | +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| | | +--- org.jetbrains.androidx.lifecycle:lifecycle-viewmodel:2.8.0 -| | | | \--- androidx.lifecycle:lifecycle-viewmodel:2.8.0 -> 2.8.4 (*) -| | | +--- org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.0 -| | | | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.0 -> 2.8.4 (*) -| | | +--- org.jetbrains.androidx.core:core-bundle:1.0.0 -| | | | \--- org.jetbrains.androidx.core:core-bundle-android:1.0.0 -| | | | +--- androidx.core:core-ktx:1.2.0 -> 1.13.1 (*) -| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.23 -> 2.0.20 (*) -| | | +--- org.jetbrains.androidx.savedstate:savedstate:1.2.0 -| | | | \--- androidx.savedstate:savedstate:1.2.1 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | +--- androidx.appcompat:appcompat:1.7.0 (*) -| | +--- androidx.activity:activity-ktx:1.9.1 (*) -| | +--- androidx.fragment:fragment-ktx:1.8.2 -| | | +--- androidx.activity:activity-ktx:1.8.1 -> 1.9.1 (*) -| | | +--- androidx.collection:collection-ktx:1.1.0 -> 1.4.2 (*) -| | | +--- androidx.core:core-ktx:1.2.0 -> 1.13.1 (*) -| | | +--- androidx.fragment:fragment:1.8.2 (*) -| | | +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.6.1 -> 2.8.4 (*) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1 -> 2.8.4 (*) -| | | +--- androidx.savedstate:savedstate-ktx:1.2.1 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | \--- androidx.fragment:fragment:1.8.2 (c) -| | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (*) -| | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 -| | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | +--- androidx.lifecycle:lifecycle-common:2.8.4 (*) -| | | +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| | | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -| | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 -| | +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-compose:4.0.0-RC2 -| | | \--- io.insert-koin:koin-compose-jvm:4.0.0-RC2 -| | | +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| | | +--- org.jetbrains.compose.runtime:runtime:1.6.11 -| | | | \--- androidx.compose.runtime:runtime:1.6.7 -> 1.7.0-rc01 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) -| | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 -| | | \--- androidx.lifecycle:lifecycle-viewmodel-compose-android:2.8.4 -| | | +--- androidx.annotation:annotation:1.8.0 -> 1.8.1 (*) -| | | +--- androidx.compose.runtime:runtime:1.6.0 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui:1.6.0 -> 1.7.0-rc01 (*) -| | | +--- androidx.lifecycle:lifecycle-common:2.8.4 (*) -| | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (*) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | +--- androidx.lifecycle:lifecycle-common:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-common-java8:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-livedata:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-process:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-service:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 (c) -| | | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.4 (c) -| | | \--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 (c) -| | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- com.squareup.wire:wire-runtime:5.0.0 -| | \--- com.squareup.wire:wire-runtime-jvm:5.0.0 -| | +--- com.squareup.okio:okio:3.9.0 (*) -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.24 -> 2.0.20 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- org.jetbrains.compose.runtime:runtime:1.6.11 (*) -| +--- org.jetbrains.compose.material3:material3:1.6.11 -| | \--- androidx.compose.material3:material3:1.2.1 -| | \--- androidx.compose.material3:material3-android:1.2.1 -| | +--- androidx.activity:activity-compose:1.5.0 -> 1.9.1 (*) -| | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | +--- androidx.compose.animation:animation-core:1.6.0 -> 1.7.0-rc01 -| | | \--- androidx.compose.animation:animation-core-android:1.7.0-rc01 -| | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui:1.6.0 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-unit:1.6.0 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | | +--- androidx.compose.animation:animation:1.7.0-rc01 (c) -| | | \--- androidx.compose.animation:animation-graphics:1.7.0-rc01 (c) -| | +--- androidx.compose.foundation:foundation:1.6.0 -> 1.7.0-rc01 -| | | \--- androidx.compose.foundation:foundation-android:1.7.0-rc01 -| | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | | +--- androidx.compose.animation:animation:1.7.0-rc01 -| | | | \--- androidx.compose.animation:animation-android:1.7.0-rc01 -| | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | | | +--- androidx.compose.animation:animation-core:1.7.0-rc01 (*) -| | | | +--- androidx.compose.foundation:foundation-layout:1.6.0 -> 1.7.0-rc01 -| | | | | \--- androidx.compose.foundation:foundation-layout-android:1.7.0-rc01 -| | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | | | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | | | | +--- androidx.compose.animation:animation-core:1.2.1 -> 1.7.0-rc01 (*) -| | | | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | | | +--- androidx.compose.ui:ui:1.6.0 -> 1.7.0-rc01 (*) -| | | | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (*) -| | | | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (*) -| | | | | +--- androidx.core:core:1.7.0 -> 1.13.1 (*) -| | | | | \--- androidx.compose.foundation:foundation:1.7.0-rc01 (c) -| | | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-geometry:1.6.0 -> 1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (*) -| | | | +--- androidx.compose.animation:animation-core:1.7.0-rc01 (c) -| | | | \--- androidx.compose.animation:animation-graphics:1.7.0-rc01 (c) -| | | +--- androidx.compose.foundation:foundation-layout:1.7.0-rc01 (*) -| | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui:1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-text:1.6.0 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-util:1.6.0 -> 1.7.0-rc01 (*) -| | | +--- androidx.core:core:1.13.1 (*) -| | | +--- androidx.emoji2:emoji2:1.3.0 (*) -| | | \--- androidx.compose.foundation:foundation-layout:1.7.0-rc01 (c) -| | +--- androidx.compose.foundation:foundation-layout:1.6.0 -> 1.7.0-rc01 (*) -| | +--- androidx.compose.material:material-icons-core:1.6.0 -> 1.6.8 -| | | \--- androidx.compose.material:material-icons-core-android:1.6.8 -| | | +--- androidx.compose.ui:ui:1.6.8 -> 1.7.0-rc01 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | +--- androidx.compose.material:material:1.6.8 (c) -| | | +--- androidx.compose.material:material-icons-extended:1.6.8 (c) -| | | \--- androidx.compose.material:material-ripple:1.6.8 (c) -| | +--- androidx.compose.material:material-ripple:1.6.0 -> 1.6.8 -| | | \--- androidx.compose.material:material-ripple-android:1.6.8 -| | | +--- androidx.compose.animation:animation:1.6.8 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.foundation:foundation:1.6.8 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-util:1.6.8 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.material:material:1.6.8 (c) -| | | +--- androidx.compose.material:material-icons-core:1.6.8 (c) -| | | \--- androidx.compose.material:material-icons-extended:1.6.8 (c) -| | +--- androidx.compose.runtime:runtime:1.6.0 -> 1.7.0-rc01 (*) -| | +--- androidx.compose.ui:ui-graphics:1.6.0 -> 1.7.0-rc01 (*) -| | +--- androidx.compose.ui:ui-text:1.6.0 -> 1.7.0-rc01 (*) -| | +--- androidx.compose.ui:ui-util:1.6.0 -> 1.7.0-rc01 (*) -| | +--- androidx.lifecycle:lifecycle-common-java8:2.6.1 -> 2.8.4 (*) -| | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 -> 2.8.4 (*) -| | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 -> 2.8.4 (*) -| | +--- androidx.savedstate:savedstate-ktx:1.2.1 (*) -| | \--- androidx.compose.material3:material3-window-size-class:1.2.1 (c) -| +--- org.jetbrains.compose.ui:ui:1.6.11 -| | \--- androidx.compose.ui:ui:1.6.7 -> 1.7.0-rc01 (*) -| +--- org.jetbrains.compose.components:components-resources:1.6.11 -| | \--- org.jetbrains.compose.components:components-resources-android:1.6.11 -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.23 -> 2.0.20 (*) -| | +--- org.jetbrains.compose.runtime:runtime:1.6.11 (*) -| | +--- org.jetbrains.compose.foundation:foundation:1.6.11 -| | | \--- androidx.compose.foundation:foundation:1.6.7 -> 1.7.0-rc01 (*) -| | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.8.1 (*) -| +--- org.jetbrains.compose.components:components-ui-tooling-preview:1.6.11 -| | \--- org.jetbrains.compose.components:components-ui-tooling-preview-android:1.6.11 -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.23 -> 2.0.20 (*) -| +--- org.jetbrains.kotlinx:kotlinx-datetime:0.6.0 -| | \--- org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.0 -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 2.0.20 (*) -| +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1 -| | \--- org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.7.1 -| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 -> 2.0.20 (*) -| | +--- org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.1 -| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.1 (c) -| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.7.1 (c) -| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1 (c) -| | | \--- org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.1 (c) -| | \--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.1 -| | \--- org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.1 -| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 -> 2.0.20 (*) -| | +--- org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.1 (*) -| | \--- org.jetbrains.kotlin:kotlin-stdlib-common:2.0.0 -> 2.0.20 -| | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-compose:1.2.0-Beta4 -> 4.0.0-RC2 (*) -| +--- androidx.datastore:datastore-core-okio:1.1.1 (*) -| \--- org.jetbrains.kotlin:kotlin-parcelize-runtime:2.0.20 (*) -+--- project :core:data -| +--- project :core:common -| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | +--- io.insert-koin:koin-bom:4.0.0-RC2 -| | | +--- io.insert-koin:koin-core:4.0.0-RC2 (c) -| | | +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (c) -| | | +--- io.insert-koin:koin-android:4.0.0-RC2 (c) -| | | +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (c) -| | | +--- io.insert-koin:koin-compose:4.0.0-RC2 (c) -| | | \--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (c) -| | +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-annotations:1.4.0-RC4 -| | | \--- io.insert-koin:koin-annotations-jvm:1.4.0-RC4 -| | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.24 -> 2.0.20 (*) -| | +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 -| | | +--- androidx.tracing:tracing:1.3.0-alpha02 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | \--- androidx.tracing:tracing:1.3.0-alpha02 (c) -| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 (*) -| | \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1 (*) -| +--- project :core:model -| | +--- org.jetbrains.kotlinx:kotlinx-datetime:0.6.0 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| | +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| | +--- com.squareup.retrofit2:converter-gson:2.11.0 -| | | +--- com.squareup.retrofit2:retrofit:2.11.0 -| | | | \--- com.squareup.okhttp3:okhttp:3.14.9 -> 4.12.0 (*) -| | | \--- com.google.code.gson:gson:2.10.1 -| | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1 (*) -| | \--- org.jetbrains.kotlin:kotlin-parcelize-runtime:2.0.20 (*) -| +--- project :core:network -| | +--- org.jetbrains.kotlinx:kotlinx-datetime:0.6.0 (*) -| | +--- project :core:common (*) -| | +--- project :core:model (*) -| | +--- project :core:datastore -| | | +--- org.jetbrains.kotlinx:kotlinx-datetime:0.6.0 (*) -| | | +--- androidx.datastore:datastore:1.1.1 (*) -| | | +--- project :core:datastore-proto -| | | | +--- com.google.protobuf:protobuf-kotlin-lite:4.26.0 -| | | | | +--- com.google.protobuf:protobuf-javalite:4.26.0 -| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.6.0 -> 2.0.20 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | | | +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| | | | +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| | | | +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| | | | \--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| | | +--- project :core:common (*) -| | | +--- project :core:model (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | | +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| | | +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| | | +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| | | +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| | | +--- com.squareup.retrofit2:converter-gson:2.11.0 (*) -| | | \--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| | +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| | +--- com.squareup.okhttp3:okhttp:4.12.0 (*) -| | +--- com.squareup.okhttp3:logging-interceptor:4.12.0 -| | | +--- com.squareup.okhttp3:okhttp:4.12.0 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21 -> 1.9.20 (*) -| | +--- com.squareup.retrofit2:retrofit:2.11.0 (*) -| | +--- com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0 -| | | +--- com.squareup.retrofit2:retrofit:2.9.0 -> 2.11.0 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.0 -> 1.7.1 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10 -> 1.9.20 (*) -| | +--- com.squareup.retrofit2:adapter-rxjava:2.11.0 -| | | +--- com.squareup.retrofit2:retrofit:2.11.0 (*) -| | | \--- io.reactivex:rxjava:1.3.8 -| | +--- com.squareup.retrofit2:converter-gson:2.11.0 (*) -| | +--- io.reactivex:rxandroid:1.1.0 -| | | \--- io.reactivex:rxjava:1.1.0 -> 1.3.8 -| | +--- io.reactivex:rxjava:1.3.8 -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.0 -> 2.0.20 (*) -| | +--- io.ktor:ktor-client-core:2.3.4 -| | | \--- io.ktor:ktor-client-core-jvm:2.3.4 -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 (*) -| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1 (*) -| | | +--- org.slf4j:slf4j-api:1.7.36 -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | +--- io.ktor:ktor-http:2.3.4 -| | | | \--- io.ktor:ktor-http-jvm:2.3.4 -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | | +--- org.slf4j:slf4j-api:1.7.36 -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | | +--- io.ktor:ktor-utils:2.3.4 -| | | | | \--- io.ktor:ktor-utils-jvm:2.3.4 -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | | | +--- org.slf4j:slf4j-api:1.7.36 -| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | | | +--- io.ktor:ktor-io:2.3.4 -| | | | | | \--- io.ktor:ktor-io-jvm:2.3.4 -| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | | | | +--- org.slf4j:slf4j-api:1.7.36 -| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | | +--- io.ktor:ktor-events:2.3.4 -| | | | \--- io.ktor:ktor-events-jvm:2.3.4 -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | | +--- org.slf4j:slf4j-api:1.7.36 -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | | +--- io.ktor:ktor-http:2.3.4 (*) -| | | | +--- io.ktor:ktor-utils:2.3.4 (*) -| | | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | | +--- io.ktor:ktor-websocket-serialization:2.3.4 -| | | | \--- io.ktor:ktor-websocket-serialization-jvm:2.3.4 -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | | +--- org.slf4j:slf4j-api:1.7.36 -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | | +--- io.ktor:ktor-http:2.3.4 (*) -| | | | +--- io.ktor:ktor-serialization:2.3.4 -| | | | | \--- io.ktor:ktor-serialization-jvm:2.3.4 -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | | | +--- org.slf4j:slf4j-api:1.7.36 -| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | | | +--- io.ktor:ktor-http:2.3.4 (*) -| | | | | +--- io.ktor:ktor-websockets:2.3.4 -| | | | | | \--- io.ktor:ktor-websockets-jvm:2.3.4 -| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | | | | +--- org.slf4j:slf4j-api:1.7.36 -| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | | | | +--- io.ktor:ktor-http:2.3.4 (*) -| | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.7.2 -> 1.8.1 -| | | +--- org.slf4j:slf4j-api:1.7.32 -> 1.7.36 -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 2.0.20 (*) -| | +--- io.ktor:ktor-client-android:2.3.4 -| | | \--- io.ktor:ktor-client-android-jvm:2.3.4 -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | +--- org.slf4j:slf4j-api:1.7.36 -| | | +--- io.ktor:ktor-client-core:2.3.4 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | +--- io.ktor:ktor-client-serialization:2.3.4 -| | | \--- io.ktor:ktor-client-serialization-jvm:2.3.4 -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | +--- org.slf4j:slf4j-api:1.7.36 -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | +--- io.ktor:ktor-client-core:2.3.4 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1 -> 1.7.1 (*) -| | | +--- io.ktor:ktor-client-json:2.3.4 -| | | | \--- io.ktor:ktor-client-json-jvm:2.3.4 -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | | +--- org.slf4j:slf4j-api:1.7.36 -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | | +--- io.ktor:ktor-client-core:2.3.4 (*) -| | | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | +--- io.ktor:ktor-client-logging:2.3.4 -| | | \--- io.ktor:ktor-client-logging-jvm:2.3.4 -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | +--- org.slf4j:slf4j-api:1.7.36 -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | +--- io.ktor:ktor-client-core:2.3.4 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | +--- io.ktor:ktor-client-content-negotiation:2.3.4 -| | | \--- io.ktor:ktor-client-content-negotiation-jvm:2.3.4 -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | +--- org.slf4j:slf4j-api:1.7.36 -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | +--- io.ktor:ktor-client-core:2.3.4 (*) -| | | +--- io.ktor:ktor-serialization:2.3.4 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | +--- io.ktor:ktor-client-json:2.3.4 (*) -| | +--- io.ktor:ktor-client-websockets:2.3.4 -| | | \--- io.ktor:ktor-client-websockets-jvm:2.3.4 -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | +--- org.slf4j:slf4j-api:1.7.36 -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | +--- io.ktor:ktor-client-core:2.3.4 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | +--- io.ktor:ktor-serialization-kotlinx-json:2.3.4 -| | | \--- io.ktor:ktor-serialization-kotlinx-json-jvm:2.3.4 -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | +--- org.slf4j:slf4j-api:1.7.36 -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | +--- io.ktor:ktor-http:2.3.4 (*) -| | | +--- io.ktor:ktor-serialization-kotlinx:2.3.4 -| | | | \--- io.ktor:ktor-serialization-kotlinx-jvm:2.3.4 -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | | +--- org.slf4j:slf4j-api:1.7.36 -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | | +--- io.ktor:ktor-http:2.3.4 (*) -| | | | +--- io.ktor:ktor-serialization:2.3.4 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1 -> 1.7.1 (*) -| | | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1 -> 1.7.1 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | +--- ch.qos.logback:logback-classic:1.2.3 -| | | +--- ch.qos.logback:logback-core:1.2.3 -| | | \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.36 -| | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1 (*) -| | \--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- com.squareup.retrofit2:retrofit:2.11.0 (*) -| +--- com.squareup.retrofit2:adapter-rxjava:2.11.0 (*) -| +--- com.squareup.retrofit2:converter-gson:2.11.0 (*) -| +--- com.squareup.okhttp3:okhttp:4.12.0 (*) -| +--- com.squareup.okhttp3:logging-interceptor:4.12.0 (*) -| +--- io.reactivex:rxandroid:1.1.0 (*) -| +--- io.reactivex:rxjava:1.3.8 -| +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| \--- org.jetbrains.kotlin:kotlin-parcelize-runtime:2.0.20 (*) -+--- project :core:ui -| +--- project :core:designsystem -| | +--- androidx.compose.ui:ui:1.6.8 -> 1.7.0-rc01 (*) -| | +--- androidx.compose.foundation:foundation -> 1.7.0-rc01 (*) -| | +--- androidx.compose.foundation:foundation-layout -> 1.7.0-rc01 (*) -| | +--- androidx.compose.material:material-icons-extended -> 1.6.8 -| | | \--- androidx.compose.material:material-icons-extended-android:1.6.8 -| | | +--- androidx.compose.material:material-icons-core:1.6.8 (*) -| | | +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.material:material:1.6.8 (c) -| | | +--- androidx.compose.material:material-icons-core:1.6.8 (c) -| | | \--- androidx.compose.material:material-ripple:1.6.8 (c) -| | +--- androidx.compose.material3:material3 -> 1.2.1 (*) -| | +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) -| | +--- androidx.compose.ui:ui-util:1.6.8 -> 1.7.0-rc01 (*) -| | +--- androidx.activity:activity-compose:1.9.1 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| | +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| | +--- androidx.compose:compose-bom:2024.08.00 (*) -| | +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| | \--- project :core:model (*) -| +--- project :core:model (*) -| +--- project :core:common (*) -| +--- androidx.metrics:metrics-performance:1.0.0-beta01 -| | +--- androidx.collection:collection:1.1.0 -> 1.4.2 (*) -| | +--- androidx.core:core:1.5.0 -> 1.13.1 (*) -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| +--- project :core:analytics -| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| | +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| | +--- androidx.compose:compose-bom:2024.08.00 (*) -| | +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| | +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) -| | +--- com.google.firebase:firebase-bom:33.1.2 (*) -| | \--- com.google.firebase:firebase-analytics-ktx -> 22.0.2 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) -| +--- com.google.accompanist:accompanist-pager:0.34.0 -| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 -> 1.8.1 (*) -| | +--- androidx.compose.foundation:foundation:1.6.0 -> 1.7.0-rc01 (*) -| | +--- dev.chrisbanes.snapper:snapper:0.2.2 -> 0.3.0 -| | | +--- androidx.compose.foundation:foundation:1.2.1 -> 1.7.0-rc01 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21 -> 1.9.20 (*) -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.22 -> 2.0.20 (*) -| +--- androidx.browser:browser:1.8.0 -| | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | +--- androidx.collection:collection:1.1.0 -> 1.4.2 (*) -| | +--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0 (*) -| | +--- androidx.core:core:1.1.0 -> 1.13.1 (*) -| | +--- androidx.interpolator:interpolator:1.0.0 (*) -| | \--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava -| +--- io.coil-kt:coil:2.6.0 -| | +--- io.coil-kt:coil-base:2.6.0 -| | | +--- androidx.annotation:annotation:1.7.1 -> 1.8.1 (*) -| | | +--- androidx.appcompat:appcompat-resources:1.6.1 -> 1.7.0 (*) -| | | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | | +--- androidx.core:core-ktx:1.12.0 -> 1.13.1 (*) -| | | +--- androidx.exifinterface:exifinterface:1.3.7 -| | | | \--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | +--- androidx.profileinstaller:profileinstaller:1.3.1 (*) -| | | +--- androidx.lifecycle:lifecycle-runtime:2.7.0 -> 2.8.4 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.8.1 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.22 -> 2.0.20 (*) -| | | +--- com.squareup.okhttp3:okhttp:4.12.0 (*) -| | | \--- com.squareup.okio:okio:3.8.0 -> 3.9.0 (*) -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.22 -> 2.0.20 (*) -| \--- io.coil-kt:coil-compose:2.6.0 -| +--- io.coil-kt:coil-compose-base:2.6.0 -| | +--- androidx.core:core-ktx:1.12.0 -> 1.13.1 (*) -| | +--- com.google.accompanist:accompanist-drawablepainter:0.32.0 -| | | +--- androidx.compose.ui:ui:1.5.0 -> 1.7.0-rc01 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 -> 1.8.1 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0 -> 1.9.20 (*) -| | +--- io.coil-kt:coil-base:2.6.0 (*) -| | +--- androidx.compose.foundation:foundation:1.6.1 -> 1.7.0-rc01 (*) -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.22 -> 2.0.20 (*) -| +--- io.coil-kt:coil:2.6.0 (*) -| \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.22 -> 2.0.20 (*) -+--- project :core:designsystem (*) -+--- project :feature:receipt -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation -| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| | +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| | +--- androidx.compose:compose-bom:2024.08.00 (*) -| | +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| | +--- androidx.navigation:navigation-compose:2.8.0-rc01 -| | | +--- androidx.activity:activity-compose:1.8.0 -> 1.9.1 (*) -| | | +--- androidx.compose.animation:animation:1.7.0-rc01 (*) -| | | +--- androidx.compose.foundation:foundation-layout:1.7.0-rc01 (*) -| | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | +--- androidx.compose.runtime:runtime-saveable:1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui:1.7.0-rc01 (*) -| | | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2 -> 2.8.4 (*) -| | | +--- androidx.navigation:navigation-runtime-ktx:2.8.0-rc01 -| | | | +--- androidx.navigation:navigation-common-ktx:2.8.0-rc01 -| | | | | +--- androidx.navigation:navigation-common:2.8.0-rc01 -| | | | | | +--- androidx.annotation:annotation:1.8.1 (*) -| | | | | | +--- androidx.collection:collection-ktx:1.4.2 (*) -| | | | | | +--- androidx.core:core-ktx:1.1.0 -> 1.13.1 (*) -| | | | | | +--- androidx.lifecycle:lifecycle-common:2.6.2 -> 2.8.4 (*) -| | | | | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.6.2 -> 2.8.4 (*) -| | | | | | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2 -> 2.8.4 (*) -| | | | | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2 -> 2.8.4 (*) -| | | | | | +--- androidx.profileinstaller:profileinstaller:1.3.1 (*) -| | | | | | +--- androidx.savedstate:savedstate-ktx:1.2.1 (*) -| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3 -> 1.7.1 (*) -| | | | | | +--- androidx.navigation:navigation-common-ktx:2.8.0-rc01 (c) -| | | | | | +--- androidx.navigation:navigation-compose:2.8.0-rc01 (c) -| | | | | | +--- androidx.navigation:navigation-fragment:2.8.0-rc01 (c) -| | | | | | +--- androidx.navigation:navigation-fragment-ktx:2.8.0-rc01 (c) -| | | | | | +--- androidx.navigation:navigation-runtime:2.8.0-rc01 (c) -| | | | | | \--- androidx.navigation:navigation-runtime-ktx:2.8.0-rc01 (c) -| | | | | +--- androidx.navigation:navigation-common:2.8.0-rc01 (c) -| | | | | +--- androidx.navigation:navigation-compose:2.8.0-rc01 (c) -| | | | | +--- androidx.navigation:navigation-fragment:2.8.0-rc01 (c) -| | | | | +--- androidx.navigation:navigation-fragment-ktx:2.8.0-rc01 (c) -| | | | | +--- androidx.navigation:navigation-runtime:2.8.0-rc01 (c) -| | | | | \--- androidx.navigation:navigation-runtime-ktx:2.8.0-rc01 (c) -| | | | +--- androidx.navigation:navigation-runtime:2.8.0-rc01 -| | | | | +--- androidx.activity:activity-ktx:1.7.1 -> 1.9.1 (*) -| | | | | +--- androidx.annotation:annotation-experimental:1.4.1 (*) -| | | | | +--- androidx.collection:collection:1.4.2 (*) -| | | | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.6.2 -> 2.8.4 (*) -| | | | | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2 -> 2.8.4 (*) -| | | | | +--- androidx.navigation:navigation-common:2.8.0-rc01 (*) -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3 -> 1.7.1 (*) -| | | | | +--- androidx.navigation:navigation-common:2.8.0-rc01 (c) -| | | | | +--- androidx.navigation:navigation-common-ktx:2.8.0-rc01 (c) -| | | | | +--- androidx.navigation:navigation-compose:2.8.0-rc01 (c) -| | | | | +--- androidx.navigation:navigation-fragment:2.8.0-rc01 (c) -| | | | | +--- androidx.navigation:navigation-fragment-ktx:2.8.0-rc01 (c) -| | | | | \--- androidx.navigation:navigation-runtime-ktx:2.8.0-rc01 (c) -| | | | +--- androidx.navigation:navigation-common-ktx:2.8.0-rc01 (c) -| | | | +--- androidx.navigation:navigation-compose:2.8.0-rc01 (c) -| | | | +--- androidx.navigation:navigation-fragment-ktx:2.8.0-rc01 (c) -| | | | +--- androidx.navigation:navigation-runtime:2.8.0-rc01 (c) -| | | | +--- androidx.navigation:navigation-fragment:2.8.0-rc01 (c) -| | | | \--- androidx.navigation:navigation-common:2.8.0-rc01 (c) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3 -> 1.7.1 (*) -| | | +--- androidx.navigation:navigation-runtime-ktx:2.8.0-rc01 (c) -| | | +--- androidx.navigation:navigation-fragment-ktx:2.8.0-rc01 (c) -| | | +--- androidx.navigation:navigation-common-ktx:2.8.0-rc01 (c) -| | | +--- androidx.navigation:navigation-runtime:2.8.0-rc01 (c) -| | | +--- androidx.navigation:navigation-fragment:2.8.0-rc01 (c) -| | | \--- androidx.navigation:navigation-common:2.8.0-rc01 (c) -| | +--- androidx.compose.material3:material3 -> 1.2.1 (*) -| | +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) -| | \--- androidx.compose.ui:ui-util:1.6.8 -> 1.7.0-rc01 (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 -| | \--- org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.7 -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 2.0.20 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 -| | +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| | +--- androidx.navigation:navigation-fragment-ktx:2.7.7 -> 2.8.0-rc01 -| | | +--- androidx.navigation:navigation-fragment:2.8.0-rc01 -| | | | +--- androidx.fragment:fragment-ktx:1.6.2 -> 1.8.2 (*) -| | | | +--- androidx.navigation:navigation-runtime:2.8.0-rc01 (*) -| | | | +--- androidx.slidingpanelayout:slidingpanelayout:1.2.0 -| | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | +--- androidx.customview:customview:1.1.0 (*) -| | | | | +--- androidx.core:core:1.1.0 -> 1.13.1 (*) -| | | | | +--- androidx.window:window:1.0.0 -> 1.3.0-rc01 -| | | | | | +--- androidx.annotation:annotation:1.3.0 -> 1.8.1 (*) -| | | | | | +--- androidx.collection:collection:1.1.0 -> 1.4.2 (*) -| | | | | | +--- androidx.core:core:1.8.0 -> 1.13.1 (*) -| | | | | | +--- androidx.window.extensions.core:core:1.0.0 -| | | | | | | +--- androidx.annotation:annotation:1.6.0 -> 1.8.1 (*) -| | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.20 -> 2.0.20 (*) -| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.8.1 (*) -| | | | | | \--- androidx.window:window-core:1.3.0-rc01 (c) -| | | | | \--- androidx.transition:transition:1.4.1 -| | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | | +--- androidx.core:core:1.1.0 -> 1.13.1 (*) -| | | | | \--- androidx.collection:collection:1.1.0 -> 1.4.2 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3 -> 1.7.1 (*) -| | | | +--- androidx.navigation:navigation-common:2.8.0-rc01 (c) -| | | | +--- androidx.navigation:navigation-common-ktx:2.8.0-rc01 (c) -| | | | +--- androidx.navigation:navigation-compose:2.8.0-rc01 (c) -| | | | +--- androidx.navigation:navigation-fragment-ktx:2.8.0-rc01 (c) -| | | | +--- androidx.navigation:navigation-runtime:2.8.0-rc01 (c) -| | | | \--- androidx.navigation:navigation-runtime-ktx:2.8.0-rc01 (c) -| | | +--- androidx.navigation:navigation-runtime-ktx:2.8.0-rc01 (*) -| | | +--- androidx.navigation:navigation-common-ktx:2.8.0-rc01 (c) -| | | +--- androidx.navigation:navigation-compose:2.8.0-rc01 (c) -| | | +--- androidx.navigation:navigation-fragment:2.8.0-rc01 (c) -| | | +--- androidx.navigation:navigation-runtime:2.8.0-rc01 (c) -| | | +--- androidx.navigation:navigation-runtime-ktx:2.8.0-rc01 (c) -| | | \--- androidx.navigation:navigation-common:2.8.0-rc01 (c) -| | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| \--- com.squareup.okhttp3:okhttp:4.12.0 (*) -+--- project :feature:profile -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| +--- project :libs:country-code-picker -| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| | +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| | +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| | +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| | +--- androidx.compose:compose-bom:2024.08.00 (*) -| | +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| | +--- androidx.compose.foundation:foundation -> 1.7.0-rc01 (*) -| | +--- androidx.compose.foundation:foundation-layout -> 1.7.0-rc01 (*) -| | +--- androidx.compose.material:material-icons-extended -> 1.6.8 (*) -| | +--- androidx.compose.material3:material3 -> 1.2.1 (*) -| | +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) -| | +--- androidx.compose.ui:ui-util:1.6.8 -> 1.7.0-rc01 (*) -| | +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| | \--- io.michaelrocks:libphonenumber-android:8.13.35 -| +--- network.chaintech:qr-kit:2.0.0 -| | \--- network.chaintech:qr-kit-android:2.0.0 -| | +--- androidx.compose.ui:ui-test-junit4:1.6.8 -> 1.7.0-rc01 -| | | \--- androidx.compose.ui:ui-test-junit4-android:1.7.0-rc01 -| | | +--- androidx.activity:activity:1.2.1 -> 1.9.1 (*) -| | | +--- androidx.activity:activity-compose:1.3.0 -> 1.9.1 (*) -| | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | +--- androidx.compose.runtime:runtime-saveable:1.6.0 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-test:1.7.0-rc01 -| | | | \--- androidx.compose.ui:ui-test-android:1.7.0-rc01 -| | | | +--- androidx.activity:activity-compose:1.3.0 -> 1.9.1 (*) -| | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-text:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (*) -| | | | +--- androidx.core:core-ktx:1.12.0 -> 1.13.1 (*) -| | | | +--- androidx.test:monitor:1.6.1 -| | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | | | +--- androidx.test:annotation:1.0.1 -| | | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | | | | \--- androidx.annotation:annotation-experimental:1.1.0 -> 1.4.1 (*) -| | | | | \--- androidx.tracing:tracing:1.0.0 -> 1.3.0-alpha02 (*) -| | | | +--- androidx.test.espresso:espresso-core:3.5.0 -| | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | | | +--- androidx.test:core:1.5.0 -| | | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | | | | +--- androidx.test:monitor:1.6.0 -> 1.6.1 (*) -| | | | | | +--- androidx.test.services:storage:1.4.2 -| | | | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | | | | | +--- androidx.test:monitor:1.6.0 -> 1.6.1 (*) -| | | | | | | +--- com.google.code.findbugs:jsr305:2.0.2 -> 3.0.2 -| | | | | | | \--- androidx.test:annotation:1.0.1 (*) -| | | | | | +--- androidx.lifecycle:lifecycle-common:2.3.1 -> 2.8.4 (*) -| | | | | | +--- androidx.tracing:tracing:1.0.0 -> 1.3.0-alpha02 (*) -| | | | | | +--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava -| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 2.0.20 (*) -| | | | | | \--- androidx.concurrent:concurrent-futures:1.1.0 (*) -| | | | | +--- androidx.test:runner:1.5.0 -| | | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | | | | +--- androidx.test:annotation:1.0.1 (*) -| | | | | | +--- androidx.test:monitor:1.6.0 -> 1.6.1 (*) -| | | | | | +--- androidx.test.services:storage:1.4.2 (*) -| | | | | | +--- androidx.tracing:tracing:1.0.0 -> 1.3.0-alpha02 (*) -| | | | | | \--- junit:junit:4.13.2 -| | | | | | \--- org.hamcrest:hamcrest-core:1.3 -| | | | | +--- androidx.test.espresso:espresso-idling-resource:3.5.0 -| | | | | +--- com.squareup:javawriter:2.1.1 -| | | | | +--- javax.inject:javax.inject:1 -| | | | | +--- org.hamcrest:hamcrest-library:1.3 -| | | | | | \--- org.hamcrest:hamcrest-core:1.3 -| | | | | +--- org.hamcrest:hamcrest-integration:1.3 -| | | | | | \--- org.hamcrest:hamcrest-library:1.3 (*) -| | | | | +--- com.google.code.findbugs:jsr305:2.0.2 -> 3.0.2 -| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 2.0.20 (*) -| | | | | \--- androidx.test:annotation:1.0.1 (*) -| | | | +--- androidx.test.espresso:espresso-idling-resource:3.5.0 -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3 -> 1.8.1 -| | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.8.1 -| | | | | +--- org.jetbrains:annotations:23.0.0 -| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1 (*) -| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 (*) -| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 2.0.20 (*) -| | | | +--- androidx.compose.ui:ui:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-test-junit4:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-text:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling-data:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (c) -| | | | \--- androidx.compose.ui:ui-util:1.7.0-rc01 (c) -| | | +--- androidx.lifecycle:lifecycle-common:2.5.1 -> 2.8.4 (*) -| | | +--- androidx.lifecycle:lifecycle-runtime:2.5.1 -> 2.8.4 (*) -| | | +--- androidx.test:core:1.5.0 (*) -| | | +--- androidx.test:monitor:1.6.1 (*) -| | | +--- androidx.test.ext:junit:1.1.5 -| | | | +--- junit:junit:4.13.2 (*) -| | | | +--- androidx.test:core:1.5.0 (*) -| | | | +--- androidx.test:monitor:1.6.1 (*) -| | | | \--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | +--- junit:junit:4.13.2 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3 -> 1.8.1 (*) -| | | +--- androidx.compose.ui:ui:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-test:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-text:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-tooling:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (c) -| | | \--- androidx.compose.ui:ui-tooling-data:1.7.0-rc01 (c) -| | +--- androidx.core:core-ktx:1.13.1 (*) -| | +--- androidx.activity:activity-compose:1.9.1 (*) -| | +--- androidx.appcompat:appcompat:1.7.0 (*) -| | +--- androidx.compose.ui:ui-tooling:1.6.8 -> 1.7.0-rc01 -| | | \--- androidx.compose.ui:ui-tooling-android:1.7.0-rc01 -| | | +--- androidx.activity:activity-compose:1.7.0 -> 1.9.1 (*) -| | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | +--- androidx.compose.animation:animation:1.7.0-rc01 (*) -| | | +--- androidx.compose.material:material:1.0.0 -> 1.6.8 -| | | | \--- androidx.compose.material:material-android:1.6.8 -| | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | +--- androidx.compose.animation:animation:1.6.8 -> 1.7.0-rc01 (*) -| | | | +--- androidx.compose.animation:animation-core:1.6.8 -> 1.7.0-rc01 (*) -| | | | +--- androidx.compose.foundation:foundation:1.6.8 -> 1.7.0-rc01 (*) -| | | | +--- androidx.compose.foundation:foundation-layout:1.6.8 -> 1.7.0-rc01 (*) -| | | | +--- androidx.compose.material:material-icons-core:1.6.8 (*) -| | | | +--- androidx.compose.material:material-ripple:1.6.8 (*) -| | | | +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui:1.6.8 -> 1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-text:1.6.8 -> 1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui-util:1.6.8 -> 1.7.0-rc01 (*) -| | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 -> 2.8.4 (*) -| | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 -> 2.8.4 (*) -| | | | +--- androidx.savedstate:savedstate:1.2.1 (*) -| | | | +--- androidx.compose.material:material-icons-core:1.6.8 (c) -| | | | +--- androidx.compose.material:material-icons-extended:1.6.8 (c) -| | | | \--- androidx.compose.material:material-ripple:1.6.8 (c) -| | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui:1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-tooling-data:1.7.0-rc01 -| | | | \--- androidx.compose.ui:ui-tooling-data-android:1.7.0-rc01 -| | | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | | +--- androidx.compose.ui:ui:1.7.0-rc01 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | | +--- androidx.compose.ui:ui:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-test:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-test-junit4:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-text:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 (c) -| | | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (c) -| | | | \--- androidx.compose.ui:ui-util:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 (*) -| | | +--- androidx.lifecycle:lifecycle-common:2.6.1 -> 2.8.4 (*) -| | | +--- androidx.savedstate:savedstate-ktx:1.2.1 (*) -| | | +--- androidx.compose.ui:ui:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-geometry:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-graphics:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-test:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-test-junit4:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-text:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-tooling-data:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 (c) -| | | +--- androidx.compose.ui:ui-unit:1.7.0-rc01 (c) -| | | \--- androidx.compose.ui:ui-util:1.7.0-rc01 (c) -| | +--- androidx.camera:camera-core:1.3.4 -| | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | +--- androidx.annotation:annotation-experimental:1.1.0 -> 1.4.1 (*) -| | | +--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0 (*) -| | | +--- androidx.core:core:1.1.0 -> 1.13.1 (*) -| | | +--- androidx.exifinterface:exifinterface:1.3.2 -> 1.3.7 (*) -| | | +--- androidx.lifecycle:lifecycle-common:2.1.0 -> 2.8.4 (*) -| | | +--- androidx.lifecycle:lifecycle-livedata:2.1.0 -> 2.8.4 (*) -| | | +--- com.google.auto.value:auto-value-annotations:1.6.3 -| | | +--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | | +--- androidx.camera:camera-camera2:1.3.4 (c) -| | | +--- androidx.camera:camera-lifecycle:1.3.4 (c) -| | | +--- androidx.camera:camera-video:1.3.4 (c) -| | | \--- androidx.camera:camera-view:1.3.4 (c) -| | +--- androidx.camera:camera-camera2:1.3.4 -| | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | +--- androidx.camera:camera-core:1.3.4 (*) -| | | +--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0 (*) -| | | +--- androidx.core:core:1.1.0 -> 1.13.1 (*) -| | | +--- com.google.auto.value:auto-value-annotations:1.6.3 -| | | +--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava -| | | +--- androidx.camera:camera-core:1.3.4 (c) -| | | +--- androidx.camera:camera-lifecycle:1.3.4 (c) -| | | +--- androidx.camera:camera-video:1.3.4 (c) -| | | \--- androidx.camera:camera-view:1.3.4 (c) -| | +--- androidx.camera:camera-lifecycle:1.3.4 -| | | +--- androidx.camera:camera-core:1.3.4 (*) -| | | +--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0 (*) -| | | +--- androidx.core:core:1.1.0 -> 1.13.1 (*) -| | | +--- androidx.lifecycle:lifecycle-common:2.1.0 -> 2.8.4 (*) -| | | +--- com.google.auto.value:auto-value-annotations:1.6.3 -| | | +--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava -| | | +--- androidx.camera:camera-core:1.3.4 (c) -| | | +--- androidx.camera:camera-video:1.3.4 (c) -| | | +--- androidx.camera:camera-view:1.3.4 (c) -| | | \--- androidx.camera:camera-camera2:1.3.4 (c) -| | +--- androidx.camera:camera-view:1.3.4 -| | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | +--- androidx.annotation:annotation-experimental:1.3.1 -> 1.4.1 (*) -| | | +--- androidx.appcompat:appcompat:1.1.0 -> 1.7.0 (*) -| | | +--- androidx.camera:camera-core:1.3.4 (*) -| | | +--- androidx.camera:camera-lifecycle:1.3.4 (*) -| | | +--- androidx.camera:camera-video:1.3.4 -| | | | +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| | | | +--- androidx.camera:camera-core:1.3.4 (*) -| | | | +--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0 (*) -| | | | +--- androidx.core:core:1.1.0 -> 1.13.1 (*) -| | | | +--- com.google.auto.value:auto-value-annotations:1.6.3 -| | | | +--- androidx.camera:camera-camera2:1.3.4 (c) -| | | | +--- androidx.camera:camera-core:1.3.4 (c) -| | | | +--- androidx.camera:camera-lifecycle:1.3.4 (c) -| | | | \--- androidx.camera:camera-view:1.3.4 (c) -| | | +--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0 (*) -| | | +--- androidx.core:core:1.3.2 -> 1.13.1 (*) -| | | +--- androidx.lifecycle:lifecycle-common:2.0.0 -> 2.8.4 (*) -| | | +--- com.google.auto.value:auto-value-annotations:1.6.3 -| | | +--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava -| | | +--- androidx.camera:camera-core:1.3.4 (c) -| | | +--- androidx.camera:camera-lifecycle:1.3.4 (c) -| | | +--- androidx.camera:camera-video:1.3.4 (c) -| | | \--- androidx.camera:camera-camera2:1.3.4 (c) -| | +--- com.google.mlkit:barcode-scanning:17.2.0 -| | | +--- com.google.android.gms:play-services-basement:18.1.0 -> 18.4.0 (*) -| | | +--- com.google.android.gms:play-services-mlkit-barcode-scanning:18.3.0 -| | | | +--- com.google.android.datatransport:transport-api:2.2.1 -> 3.2.0 (*) -| | | | +--- com.google.android.datatransport:transport-backend-cct:2.3.3 -> 3.3.0 (*) -| | | | +--- com.google.android.datatransport:transport-runtime:2.2.6 -> 3.3.0 (*) -| | | | +--- com.google.android.gms:play-services-base:18.1.0 -> 18.3.0 (*) -| | | | +--- com.google.android.gms:play-services-basement:18.1.0 -> 18.4.0 (*) -| | | | +--- com.google.android.gms:play-services-tasks:18.0.2 -> 18.2.0 (*) -| | | | +--- com.google.android.odml:image:1.0.0-beta1 -| | | | +--- com.google.firebase:firebase-components:16.1.0 -> 18.0.0 (*) -| | | | +--- com.google.firebase:firebase-encoders:16.1.0 -> 17.0.0 (*) -| | | | +--- com.google.firebase:firebase-encoders-json:17.1.0 -> 18.0.1 (*) -| | | | +--- com.google.mlkit:barcode-scanning-common:17.0.0 -| | | | | +--- com.google.android.gms:play-services-basement:18.0.0 -> 18.4.0 (*) -| | | | | \--- com.google.mlkit:vision-common:17.0.0 -> 17.3.0 -| | | | | +--- androidx.exifinterface:exifinterface:1.0.0 -> 1.3.7 (*) -| | | | | +--- com.google.android.datatransport:transport-api:2.2.1 -> 3.2.0 (*) -| | | | | +--- com.google.android.datatransport:transport-backend-cct:2.3.3 -> 3.3.0 (*) -| | | | | +--- com.google.android.datatransport:transport-runtime:2.2.6 -> 3.3.0 (*) -| | | | | +--- com.google.android.gms:play-services-base:18.1.0 -> 18.3.0 (*) -| | | | | +--- com.google.android.gms:play-services-basement:18.1.0 -> 18.4.0 (*) -| | | | | +--- com.google.android.gms:play-services-tasks:18.0.2 -> 18.2.0 (*) -| | | | | +--- com.google.android.odml:image:1.0.0-beta1 -| | | | | +--- com.google.firebase:firebase-components:16.1.0 -> 18.0.0 (*) -| | | | | +--- com.google.firebase:firebase-encoders:16.1.0 -> 17.0.0 (*) -| | | | | +--- com.google.firebase:firebase-encoders-json:17.1.0 -> 18.0.1 (*) -| | | | | \--- com.google.mlkit:common:18.6.0 -> 18.9.0 -| | | | | +--- androidx.core:core:1.0.0 -> 1.13.1 (*) -| | | | | +--- com.google.android.datatransport:transport-api:2.2.1 -> 3.2.0 (*) -| | | | | +--- com.google.android.datatransport:transport-backend-cct:2.3.3 -> 3.3.0 (*) -| | | | | +--- com.google.android.datatransport:transport-runtime:2.2.6 -> 3.3.0 (*) -| | | | | +--- com.google.android.gms:play-services-base:18.1.0 -> 18.3.0 (*) -| | | | | +--- com.google.android.gms:play-services-basement:18.1.0 -> 18.4.0 (*) -| | | | | +--- com.google.android.gms:play-services-tasks:18.0.2 -> 18.2.0 (*) -| | | | | +--- com.google.firebase:firebase-components:16.1.0 -> 18.0.0 (*) -| | | | | +--- com.google.firebase:firebase-encoders:16.1.0 -> 17.0.0 (*) -| | | | | \--- com.google.firebase:firebase-encoders-json:17.1.0 -> 18.0.1 (*) -| | | | +--- com.google.mlkit:common:18.9.0 (*) -| | | | +--- com.google.mlkit:vision-common:17.3.0 (*) -| | | | \--- com.google.mlkit:vision-interfaces:16.2.0 -| | | | +--- com.google.android.gms:play-services-basement:18.1.0 -> 18.4.0 (*) -| | | | \--- com.google.android.gms:play-services-tasks:18.0.2 -> 18.2.0 (*) -| | | +--- com.google.mlkit:barcode-scanning-common:17.0.0 (*) -| | | +--- com.google.mlkit:common:18.9.0 (*) -| | | \--- com.google.mlkit:vision-common:17.3.0 (*) -| | +--- com.google.accompanist:accompanist-permissions:0.34.0 -| | | +--- androidx.activity:activity-compose:1.7.2 -> 1.9.1 (*) -| | | +--- androidx.compose.foundation:foundation:1.6.0 -> 1.7.0-rc01 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 -> 1.8.1 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.22 -> 2.0.20 (*) -| | +--- com.google.zxing:core:3.5.2 -> 3.5.3 -| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 -> 2.0.20 (*) -| | +--- org.jetbrains.compose.runtime:runtime:1.6.11 (*) -| | +--- org.jetbrains.compose.material3:material3:1.6.11 (*) -| | +--- org.jetbrains.compose.material:material-icons-extended:1.6.11 -| | | \--- androidx.compose.material:material-icons-extended:1.6.7 -> 1.6.8 (*) -| | +--- org.jetbrains.compose.components:components-resources:1.6.11 (*) -| | +--- io.github.qdsfdhvh:image-loader:1.6.4 -| | | \--- io.github.qdsfdhvh:image-loader-android:1.6.4 -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20 -> 1.9.20 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2 -> 1.8.1 (*) -| | | +--- androidx.core:core-ktx:1.10.1 -> 1.13.1 (*) -| | | +--- androidx.appcompat:appcompat-resources:1.6.1 -> 1.7.0 (*) -| | | +--- androidx.exifinterface:exifinterface:1.3.6 -> 1.3.7 (*) -| | | +--- com.caverock:androidsvg-aar:1.4 -| | | +--- org.jetbrains.compose.ui:ui:1.4.3 -> 1.6.11 (*) -| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2 -> 1.8.1 (*) -| | | +--- com.squareup.okio:okio:3.4.0 -> 3.9.0 (*) -| | | +--- io.ktor:ktor-client-core:2.3.3 -> 2.3.4 (*) -| | | +--- com.eygraber:uri-kmp:0.0.12 -| | | | \--- com.eygraber:uri-kmp-android:0.0.12 -| | | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | +--- io.ktor:ktor-client-okhttp:2.3.3 -| | | | \--- io.ktor:ktor-client-okhttp-jvm:2.3.3 -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.20 (*) -| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1 -> 1.8.1 (*) -| | | | +--- org.slf4j:slf4j-api:1.7.36 -| | | | +--- io.ktor:ktor-client-core:2.3.3 -> 2.3.4 (*) -| | | | +--- com.squareup.okhttp3:okhttp:4.11.0 -> 4.12.0 (*) -| | | | +--- com.squareup.okio:okio:3.4.0 -> 3.9.0 (*) -| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.8.1 (*) -| | | \--- androidx.collection:collection:1.3.0-alpha04 -> 1.4.2 (*) -| | \--- network.chaintech:cmp-image-pick-n-crop:1.0.1 -| | \--- network.chaintech:cmp-image-pick-n-crop-android:1.0.1 -| | +--- androidx.compose.ui:ui-test-junit4:1.6.8 -> 1.7.0-rc01 (*) -| | +--- org.jetbrains.compose.ui:ui-tooling:1.6.11 -| | | \--- androidx.compose.ui:ui-tooling:1.6.7 -> 1.7.0-rc01 (*) -| | +--- androidx.activity:activity-compose:1.9.0 -> 1.9.1 (*) -| | +--- com.google.accompanist:accompanist-permissions:0.34.0 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 -> 2.0.20 (*) -| | +--- org.jetbrains.compose.runtime:runtime:1.6.11 (*) -| | +--- org.jetbrains.compose.foundation:foundation:1.6.11 (*) -| | +--- org.jetbrains.compose.material3:material3:1.6.11 (*) -| | +--- org.jetbrains.compose.components:components-resources:1.6.11 (*) -| | \--- org.jetbrains.compose.components:components-ui-tooling-preview:1.6.11 (*) -| +--- com.squareup.okhttp3:okhttp:4.12.0 (*) -| \--- io.coil-kt:coil-compose:2.6.0 (*) -+--- project :feature:auth -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| +--- project :libs:country-code-picker (*) -| +--- androidx.credentials:credentials:1.2.2 -> 1.3.0-beta01 -| | +--- androidx.annotation:annotation:1.5.0 -> 1.8.1 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | \--- androidx.credentials:credentials-play-services-auth:1.3.0-beta01 (c) -| +--- androidx.credentials:credentials-play-services-auth:1.2.2 -> 1.3.0-beta01 -| | +--- androidx.credentials:credentials:1.3.0-beta01 (*) -| | +--- com.google.android.gms:play-services-auth:21.1.1 -> 21.2.0 -| | | +--- androidx.fragment:fragment:1.5.7 -> 1.8.2 (*) -| | | +--- androidx.loader:loader:1.1.0 (*) -| | | +--- com.google.android.gms:play-services-auth-api-phone:18.0.2 -| | | | +--- com.google.android.gms:play-services-base:18.0.1 -> 18.3.0 (*) -| | | | +--- com.google.android.gms:play-services-basement:18.0.2 -> 18.4.0 (*) -| | | | \--- com.google.android.gms:play-services-tasks:18.0.1 -> 18.2.0 (*) -| | | +--- com.google.android.gms:play-services-auth-base:18.0.10 -| | | | +--- androidx.collection:collection:1.0.0 -> 1.4.2 (*) -| | | | +--- com.google.android.gms:play-services-base:18.0.1 -> 18.3.0 (*) -| | | | +--- com.google.android.gms:play-services-basement:18.2.0 -> 18.4.0 (*) -| | | | \--- com.google.android.gms:play-services-tasks:18.0.1 -> 18.2.0 (*) -| | | +--- com.google.android.gms:play-services-base:18.3.0 (*) -| | | +--- com.google.android.gms:play-services-basement:18.3.0 -> 18.4.0 (*) -| | | +--- com.google.android.gms:play-services-fido:20.0.1 -> 21.0.0 -| | | | +--- com.google.android.gms:play-services-base:18.3.0 (*) -| | | | +--- com.google.android.gms:play-services-basement:18.3.0 -> 18.4.0 (*) -| | | | +--- com.google.android.gms:play-services-tasks:18.1.0 -> 18.2.0 (*) -| | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0 -> 1.9.20 (*) -| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.8.1 (*) -| | | \--- com.google.android.gms:play-services-tasks:18.1.0 -> 18.2.0 (*) -| | +--- com.google.android.gms:play-services-fido:21.0.0 (*) -| | +--- com.google.android.libraries.identity.googleid:googleid:1.1.0 -> 1.1.1 -| | | +--- androidx.credentials:credentials:1.3.0-beta01 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.0 -> 2.0.20 (*) -| | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0 -> 1.9.20 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | \--- androidx.credentials:credentials:1.3.0-beta01 (c) -| +--- com.google.android.libraries.identity.googleid:googleid:1.1.1 (*) -| \--- com.google.android.gms:play-services-auth:21.2.0 (*) -+--- project :feature:make-transfer -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| \--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -+--- project :feature:faq -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| \--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -+--- project :feature:editpassword -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| \--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -+--- project :feature:notification -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| \--- project :libs:pullrefresh -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| +--- androidx.compose.animation:animation -> 1.7.0-rc01 (*) -| +--- androidx.compose.material3:material3 -> 1.2.1 (*) -| +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) -| \--- androidx.compose.ui:ui-util:1.6.8 -> 1.7.0-rc01 (*) -+--- project :feature:request-money -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| +--- com.google.zxing:core:3.5.3 -| \--- io.coil-kt:coil-compose:2.6.0 (*) -+--- project :feature:upi-setup -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| \--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -+--- project :feature:settings -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| \--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -+--- project :feature:savedcards -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| \--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -+--- project :feature:qr -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| +--- com.google.zxing:core:3.5.3 -| +--- androidx.camera:camera-view:1.3.4 (*) -| +--- androidx.camera:camera-lifecycle:1.3.4 (*) -| \--- com.google.guava:guava:27.0.1-android -> 31.1-android (*) -+--- project :feature:invoices -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| \--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -+--- project :feature:merchants -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| \--- project :libs:pullrefresh (*) -+--- project :feature:history -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| \--- project :libs:pullrefresh (*) -+--- project :feature:kyc -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| +--- project :libs:country-code-picker (*) -| +--- project :libs:pullrefresh (*) -| +--- com.maxkeppeler.sheets-compose-dialogs:core:1.3.0 -| | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.10 -> 1.9.20 (*) -| | +--- androidx.core:core-ktx:1.9.0 -> 1.13.1 (*) -| | +--- androidx.compose:compose-bom:2024.02.00 -> 2024.08.00 (*) -| | +--- androidx.compose.ui:ui -> 1.7.0-rc01 (*) -| | +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| | +--- androidx.compose.animation:animation -> 1.7.0-rc01 (*) -| | +--- androidx.compose.animation:animation-graphics -> 1.7.0-rc01 -| | | \--- androidx.compose.animation:animation-graphics-android:1.7.0-rc01 -| | | +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| | | +--- androidx.collection:collection:1.4.0 -> 1.4.2 (*) -| | | +--- androidx.compose.animation:animation:1.7.0-rc01 (*) -| | | +--- androidx.compose.foundation:foundation-layout:1.6.0 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.runtime:runtime:1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui:1.6.0 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-geometry:1.6.0 -> 1.7.0-rc01 (*) -| | | +--- androidx.compose.ui:ui-util:1.7.0-rc01 (*) -| | | +--- androidx.core:core-ktx:1.5.0 -> 1.13.1 (*) -| | | +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| | | +--- androidx.compose.animation:animation:1.7.0-rc01 (c) -| | | \--- androidx.compose.animation:animation-core:1.7.0-rc01 (c) -| | +--- androidx.compose.runtime:runtime -> 1.7.0-rc01 (*) -| | \--- androidx.compose.material3:material3 -> 1.2.1 (*) -| +--- com.maxkeppeler.sheets-compose-dialogs:calendar:1.3.0 -| | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.10 -> 1.9.20 (*) -| | +--- androidx.core:core-ktx:1.9.0 -> 1.13.1 (*) -| | +--- androidx.compose:compose-bom:2024.02.00 -> 2024.08.00 (*) -| | +--- androidx.compose.ui:ui -> 1.7.0-rc01 (*) -| | +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| | +--- androidx.compose.animation:animation -> 1.7.0-rc01 (*) -| | +--- androidx.compose.animation:animation-graphics -> 1.7.0-rc01 (*) -| | +--- androidx.compose.runtime:runtime -> 1.7.0-rc01 (*) -| | +--- androidx.compose.material3:material3 -> 1.2.1 (*) -| | +--- dev.chrisbanes.snapper:snapper:0.3.0 (*) -| | \--- com.maxkeppeler.sheets-compose-dialogs:core:1.3.0 (*) -| \--- com.squareup.okhttp3:okhttp:4.12.0 (*) -+--- project :feature:home -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| \--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -+--- project :feature:accounts -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| +--- project :libs:pullrefresh (*) -| \--- com.google.android.gms:play-services-auth:21.2.0 (*) -+--- project :feature:finance -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| \--- com.google.accompanist:accompanist-pager:0.34.0 (*) -+--- project :feature:payments -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| \--- com.google.accompanist:accompanist-pager:0.34.0 (*) -+--- project :feature:send-money -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| +--- project :libs:country-code-picker (*) -| \--- com.google.android.gms:play-services-code-scanner:16.1.0 -| +--- androidx.activity:activity:1.3.1 -> 1.9.1 (*) -| +--- com.google.android.datatransport:transport-api:2.2.1 -> 3.2.0 (*) -| +--- com.google.android.datatransport:transport-backend-cct:2.3.3 -> 3.3.0 (*) -| +--- com.google.android.datatransport:transport-runtime:2.2.6 -> 3.3.0 (*) -| +--- com.google.android.gms:play-services-base:18.1.0 -> 18.3.0 (*) -| +--- com.google.android.gms:play-services-basement:18.1.0 -> 18.4.0 (*) -| +--- com.google.android.gms:play-services-tasks:18.0.2 -> 18.2.0 (*) -| +--- com.google.firebase:firebase-components:16.1.0 -> 18.0.0 (*) -| +--- com.google.firebase:firebase-encoders:16.1.0 -> 17.0.0 (*) -| +--- com.google.firebase:firebase-encoders-json:17.1.0 -> 18.0.1 (*) -| +--- com.google.mlkit:barcode-scanning-common:17.0.0 (*) -| \--- com.google.mlkit:common:18.9.0 (*) -+--- project :feature:standing-instruction -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| \--- com.google.android.gms:play-services-code-scanner:16.1.0 (*) -+--- project :feature:search -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- project :core:ui (*) -| +--- project :core:designsystem (*) -| +--- project :core:data (*) -| +--- project :libs:material3-navigation (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| \--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -+--- project :libs:mifos-passcode -| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 (*) -| +--- io.insert-koin:koin-bom:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-core:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*) -| +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -| +--- androidx.compose:compose-bom:2024.08.00 (*) -| +--- androidx.compose.ui:ui-tooling-preview -> 1.7.0-rc01 (*) -| +--- androidx.core:core-ktx:1.13.1 (*) -| +--- androidx.compose.foundation:foundation -> 1.7.0-rc01 (*) -| +--- androidx.compose.foundation:foundation-layout -> 1.7.0-rc01 (*) -| +--- androidx.compose.material:material-icons-extended -> 1.6.8 (*) -| +--- androidx.compose.material3:material3 -> 1.2.1 (*) -| +--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) -| +--- androidx.compose.ui:ui-util:1.6.8 -> 1.7.0-rc01 (*) -| +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -| +--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -| +--- io.insert-koin:koin-android:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-navigation:4.0.0-RC2 (*) -| +--- io.insert-koin:koin-androidx-compose:4.0.0-RC2 (*) -| \--- io.insert-koin:koin-core-viewmodel:4.0.0-RC2 (*) -+--- project :libs:material3-navigation (*) -+--- androidx.core:core-ktx:1.13.1 (*) -+--- androidx.appcompat:appcompat:1.7.0 (*) -+--- androidx.activity:activity-compose:1.9.1 (*) -+--- androidx.activity:activity-ktx:1.9.1 (*) -+--- androidx.core:core-splashscreen:1.0.1 -| +--- androidx.annotation:annotation:1.2.0 -> 1.8.1 (*) -| \--- org.jetbrains.kotlin:kotlin-stdlib:1.6.21 -> 2.0.20 (*) -+--- androidx.compose.material3.adaptive:adaptive:1.0.0-rc01 -| \--- androidx.compose.material3.adaptive:adaptive-android:1.0.0-rc01 -| +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| +--- androidx.compose.foundation:foundation:1.6.5 -> 1.7.0-rc01 (*) -| +--- androidx.compose.ui:ui-geometry:1.6.5 -> 1.7.0-rc01 (*) -| +--- androidx.window:window:1.3.0-rc01 (*) -| +--- androidx.window:window-core:1.3.0-rc01 -| | \--- androidx.window:window-core-android:1.3.0-rc01 -| | +--- androidx.annotation:annotation:1.7.0 -> 1.8.1 (*) -| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| | \--- androidx.window:window:1.3.0-rc01 (c) -| +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| +--- androidx.compose.material3.adaptive:adaptive-layout:1.0.0-rc01 (c) -| \--- androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-rc01 (c) -+--- androidx.compose.material3.adaptive:adaptive-layout:1.0.0-rc01 -| \--- androidx.compose.material3.adaptive:adaptive-layout-android:1.0.0-rc01 -| +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| +--- androidx.compose.animation:animation:1.7.0-rc01 (*) -| +--- androidx.compose.animation:animation-core:1.7.0-rc01 (*) -| +--- androidx.compose.foundation:foundation:1.6.5 -> 1.7.0-rc01 (*) -| +--- androidx.compose.foundation:foundation-layout:1.6.5 -> 1.7.0-rc01 (*) -| +--- androidx.compose.material3.adaptive:adaptive:1.0.0-rc01 (*) -| +--- androidx.compose.ui:ui:1.7.0-rc01 (*) -| +--- androidx.compose.ui:ui-geometry:1.6.5 -> 1.7.0-rc01 (*) -| +--- androidx.compose.ui:ui-util:1.6.5 -> 1.7.0-rc01 (*) -| +--- androidx.window:window-core:1.3.0-rc01 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| +--- androidx.compose.material3.adaptive:adaptive:1.0.0-rc01 (c) -| \--- androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-rc01 (c) -+--- androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-rc01 -| \--- androidx.compose.material3.adaptive:adaptive-navigation-android:1.0.0-rc01 -| +--- androidx.activity:activity-compose:1.8.2 -> 1.9.1 (*) -| +--- androidx.annotation:annotation:1.1.0 -> 1.8.1 (*) -| +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| +--- androidx.compose.foundation:foundation:1.6.5 -> 1.7.0-rc01 (*) -| +--- androidx.compose.material3.adaptive:adaptive-layout:1.0.0-rc01 (*) -| +--- androidx.compose.ui:ui-util:1.6.5 -> 1.7.0-rc01 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.0.20 (*) -| +--- androidx.compose.material3.adaptive:adaptive:1.0.0-rc01 (c) -| \--- androidx.compose.material3.adaptive:adaptive-layout:1.0.0-rc01 (c) -+--- androidx.compose.material3:material3-window-size-class -> 1.2.1 -| \--- androidx.compose.material3:material3-window-size-class-android:1.2.1 -| +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) -| +--- androidx.compose.runtime:runtime:1.6.0 -> 1.7.0-rc01 (*) -| +--- androidx.compose.ui:ui:1.6.0 -> 1.7.0-rc01 (*) -| +--- androidx.compose.ui:ui-unit:1.6.0 -> 1.7.0-rc01 (*) -| +--- androidx.compose.ui:ui-util:1.6.0 -> 1.7.0-rc01 (*) -| +--- androidx.window:window:1.0.0 -> 1.3.0-rc01 (*) -| +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| \--- androidx.compose.material3:material3:1.2.1 (c) -+--- androidx.compose.runtime:runtime-tracing:1.0.0-beta01 -| +--- androidx.annotation:annotation:1.3.0 -> 1.8.1 (*) -| +--- androidx.compose.runtime:runtime:1.3.3 -> 1.7.0-rc01 (*) -| +--- androidx.startup:startup-runtime:1.1.1 (*) -| +--- androidx.tracing:tracing-perfetto:1.0.0 -| | +--- androidx.annotation:annotation:1.3.0 -> 1.8.1 (*) -| | +--- androidx.startup:startup-runtime:1.1.1 (*) -| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -| \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.0.20 (*) -+--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 (*) -+--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1 (*) -+--- androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*) -+--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 (*) -+--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 (*) -+--- androidx.lifecycle:lifecycle-extensions:2.2.0 -| +--- androidx.lifecycle:lifecycle-runtime:2.2.0 -> 2.8.4 (*) -| +--- androidx.arch.core:core-common:2.1.0 -> 2.2.0 (*) -| +--- androidx.arch.core:core-runtime:2.1.0 -> 2.2.0 (*) -| +--- androidx.fragment:fragment:1.2.0 -> 1.8.2 (*) -| +--- androidx.lifecycle:lifecycle-common:2.2.0 -> 2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-livedata:2.2.0 -> 2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-process:2.2.0 -> 2.8.4 (*) -| +--- androidx.lifecycle:lifecycle-service:2.2.0 -> 2.8.4 (*) -| \--- androidx.lifecycle:lifecycle-viewmodel:2.2.0 -> 2.8.4 (*) -+--- androidx.navigation:navigation-compose:2.8.0-rc01 (*) -+--- androidx.profileinstaller:profileinstaller:1.3.1 (*) -+--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*) -+--- io.insert-koin:koin-android:4.0.0-RC2 (*) -+--- io.ktor:ktor-client-core:2.3.4 (*) -\--- androidx.compose.runtime:runtime:1.6.8 -> 1.7.0-rc01 (*) diff --git a/mifospay/dependencies/prodReleaseRuntimeClasspath.txt b/mifospay/dependencies/prodReleaseRuntimeClasspath.txt deleted file mode 100644 index 8567dba4d..000000000 --- a/mifospay/dependencies/prodReleaseRuntimeClasspath.txt +++ /dev/null @@ -1,408 +0,0 @@ -:core:analytics -:core:common -:core:data -:core:datastore -:core:datastore-proto -:core:designsystem -:core:model -:core:network -:core:ui -:feature:accounts -:feature:auth -:feature:editpassword -:feature:faq -:feature:finance -:feature:history -:feature:home -:feature:invoices -:feature:kyc -:feature:make-transfer -:feature:merchants -:feature:notification -:feature:payments -:feature:profile -:feature:qr -:feature:receipt -:feature:request-money -:feature:savedcards -:feature:search -:feature:send-money -:feature:settings -:feature:standing-instruction -:feature:upi-setup -:libs:country-code-picker -:libs:material3-navigation -:libs:mifos-passcode -:libs:pullrefresh -:shared -androidx.activity:activity-compose:1.9.1 -androidx.activity:activity-ktx:1.9.1 -androidx.activity:activity:1.9.1 -androidx.annotation:annotation-experimental:1.4.1 -androidx.annotation:annotation-jvm:1.8.1 -androidx.annotation:annotation:1.8.1 -androidx.appcompat:appcompat-resources:1.7.0 -androidx.appcompat:appcompat:1.7.0 -androidx.arch.core:core-common:2.2.0 -androidx.arch.core:core-runtime:2.2.0 -androidx.autofill:autofill:1.0.0 -androidx.browser:browser:1.8.0 -androidx.camera:camera-camera2:1.3.4 -androidx.camera:camera-core:1.3.4 -androidx.camera:camera-lifecycle:1.3.4 -androidx.camera:camera-video:1.3.4 -androidx.camera:camera-view:1.3.4 -androidx.collection:collection-jvm:1.4.2 -androidx.collection:collection-ktx:1.4.2 -androidx.collection:collection:1.4.2 -androidx.compose.animation:animation-android:1.7.0-rc01 -androidx.compose.animation:animation-core-android:1.7.0-rc01 -androidx.compose.animation:animation-core:1.7.0-rc01 -androidx.compose.animation:animation-graphics-android:1.7.0-rc01 -androidx.compose.animation:animation-graphics:1.7.0-rc01 -androidx.compose.animation:animation:1.7.0-rc01 -androidx.compose.foundation:foundation-android:1.7.0-rc01 -androidx.compose.foundation:foundation-layout-android:1.7.0-rc01 -androidx.compose.foundation:foundation-layout:1.7.0-rc01 -androidx.compose.foundation:foundation:1.7.0-rc01 -androidx.compose.material3.adaptive:adaptive-android:1.0.0-rc01 -androidx.compose.material3.adaptive:adaptive-layout-android:1.0.0-rc01 -androidx.compose.material3.adaptive:adaptive-layout:1.0.0-rc01 -androidx.compose.material3.adaptive:adaptive-navigation-android:1.0.0-rc01 -androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-rc01 -androidx.compose.material3.adaptive:adaptive:1.0.0-rc01 -androidx.compose.material3:material3-android:1.2.1 -androidx.compose.material3:material3-window-size-class-android:1.2.1 -androidx.compose.material3:material3-window-size-class:1.2.1 -androidx.compose.material3:material3:1.2.1 -androidx.compose.material:material-android:1.6.8 -androidx.compose.material:material-icons-core-android:1.6.8 -androidx.compose.material:material-icons-core:1.6.8 -androidx.compose.material:material-icons-extended-android:1.6.8 -androidx.compose.material:material-icons-extended:1.6.8 -androidx.compose.material:material-ripple-android:1.6.8 -androidx.compose.material:material-ripple:1.6.8 -androidx.compose.material:material:1.6.8 -androidx.compose.runtime:runtime-android:1.7.0-rc01 -androidx.compose.runtime:runtime-saveable-android:1.7.0-rc01 -androidx.compose.runtime:runtime-saveable:1.7.0-rc01 -androidx.compose.runtime:runtime-tracing:1.0.0-beta01 -androidx.compose.runtime:runtime:1.7.0-rc01 -androidx.compose.ui:ui-android:1.7.0-rc01 -androidx.compose.ui:ui-geometry-android:1.7.0-rc01 -androidx.compose.ui:ui-geometry:1.7.0-rc01 -androidx.compose.ui:ui-graphics-android:1.7.0-rc01 -androidx.compose.ui:ui-graphics:1.7.0-rc01 -androidx.compose.ui:ui-test-android:1.7.0-rc01 -androidx.compose.ui:ui-test-junit4-android:1.7.0-rc01 -androidx.compose.ui:ui-test-junit4:1.7.0-rc01 -androidx.compose.ui:ui-test:1.7.0-rc01 -androidx.compose.ui:ui-text-android:1.7.0-rc01 -androidx.compose.ui:ui-text:1.7.0-rc01 -androidx.compose.ui:ui-tooling-android:1.7.0-rc01 -androidx.compose.ui:ui-tooling-data-android:1.7.0-rc01 -androidx.compose.ui:ui-tooling-data:1.7.0-rc01 -androidx.compose.ui:ui-tooling-preview-android:1.7.0-rc01 -androidx.compose.ui:ui-tooling-preview:1.7.0-rc01 -androidx.compose.ui:ui-tooling:1.7.0-rc01 -androidx.compose.ui:ui-unit-android:1.7.0-rc01 -androidx.compose.ui:ui-unit:1.7.0-rc01 -androidx.compose.ui:ui-util-android:1.7.0-rc01 -androidx.compose.ui:ui-util:1.7.0-rc01 -androidx.compose.ui:ui:1.7.0-rc01 -androidx.compose:compose-bom:2024.08.00 -androidx.concurrent:concurrent-futures:1.1.0 -androidx.core:core-ktx:1.13.1 -androidx.core:core-splashscreen:1.0.1 -androidx.core:core:1.13.1 -androidx.credentials:credentials-play-services-auth:1.3.0-beta01 -androidx.credentials:credentials:1.3.0-beta01 -androidx.cursoradapter:cursoradapter:1.0.0 -androidx.customview:customview-poolingcontainer:1.0.0 -androidx.customview:customview:1.1.0 -androidx.databinding:databinding-adapters:8.5.2 -androidx.databinding:databinding-common:8.5.2 -androidx.databinding:databinding-ktx:8.5.2 -androidx.databinding:databinding-runtime:8.5.2 -androidx.databinding:viewbinding:8.5.2 -androidx.datastore:datastore-android:1.1.1 -androidx.datastore:datastore-core-android:1.1.1 -androidx.datastore:datastore-core-okio-jvm:1.1.1 -androidx.datastore:datastore-core-okio:1.1.1 -androidx.datastore:datastore-core:1.1.1 -androidx.datastore:datastore-preferences-android:1.1.1 -androidx.datastore:datastore-preferences-core-jvm:1.1.1 -androidx.datastore:datastore-preferences-core:1.1.1 -androidx.datastore:datastore-preferences:1.1.1 -androidx.datastore:datastore:1.1.1 -androidx.documentfile:documentfile:1.0.0 -androidx.drawerlayout:drawerlayout:1.0.0 -androidx.emoji2:emoji2-views-helper:1.3.0 -androidx.emoji2:emoji2:1.3.0 -androidx.exifinterface:exifinterface:1.3.7 -androidx.fragment:fragment-ktx:1.8.2 -androidx.fragment:fragment:1.8.2 -androidx.graphics:graphics-path:1.0.1 -androidx.interpolator:interpolator:1.0.0 -androidx.legacy:legacy-support-core-utils:1.0.0 -androidx.lifecycle:lifecycle-common-java8:2.8.4 -androidx.lifecycle:lifecycle-common-jvm:2.8.4 -androidx.lifecycle:lifecycle-common:2.8.4 -androidx.lifecycle:lifecycle-extensions:2.2.0 -androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.4 -androidx.lifecycle:lifecycle-livedata-core:2.8.4 -androidx.lifecycle:lifecycle-livedata:2.8.4 -androidx.lifecycle:lifecycle-process:2.8.4 -androidx.lifecycle:lifecycle-runtime-android:2.8.4 -androidx.lifecycle:lifecycle-runtime-compose-android:2.8.4 -androidx.lifecycle:lifecycle-runtime-compose:2.8.4 -androidx.lifecycle:lifecycle-runtime-ktx-android:2.8.4 -androidx.lifecycle:lifecycle-runtime-ktx:2.8.4 -androidx.lifecycle:lifecycle-runtime:2.8.4 -androidx.lifecycle:lifecycle-service:2.8.4 -androidx.lifecycle:lifecycle-viewmodel-android:2.8.4 -androidx.lifecycle:lifecycle-viewmodel-compose-android:2.8.4 -androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4 -androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4 -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.4 -androidx.lifecycle:lifecycle-viewmodel:2.8.4 -androidx.loader:loader:1.1.0 -androidx.localbroadcastmanager:localbroadcastmanager:1.0.0 -androidx.metrics:metrics-performance:1.0.0-beta01 -androidx.navigation:navigation-common-ktx:2.8.0-rc01 -androidx.navigation:navigation-common:2.8.0-rc01 -androidx.navigation:navigation-compose:2.8.0-rc01 -androidx.navigation:navigation-fragment-ktx:2.8.0-rc01 -androidx.navigation:navigation-fragment:2.8.0-rc01 -androidx.navigation:navigation-runtime-ktx:2.8.0-rc01 -androidx.navigation:navigation-runtime:2.8.0-rc01 -androidx.print:print:1.0.0 -androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05 -androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05 -androidx.profileinstaller:profileinstaller:1.3.1 -androidx.resourceinspection:resourceinspection-annotation:1.0.1 -androidx.savedstate:savedstate-ktx:1.2.1 -androidx.savedstate:savedstate:1.2.1 -androidx.slidingpanelayout:slidingpanelayout:1.2.0 -androidx.startup:startup-runtime:1.1.1 -androidx.test.espresso:espresso-core:3.5.0 -androidx.test.espresso:espresso-idling-resource:3.5.0 -androidx.test.ext:junit:1.1.5 -androidx.test.services:storage:1.4.2 -androidx.test:annotation:1.0.1 -androidx.test:core:1.5.0 -androidx.test:monitor:1.6.1 -androidx.test:runner:1.5.0 -androidx.tracing:tracing-ktx:1.3.0-alpha02 -androidx.tracing:tracing-perfetto:1.0.0 -androidx.tracing:tracing:1.3.0-alpha02 -androidx.transition:transition:1.4.1 -androidx.vectordrawable:vectordrawable-animated:1.1.0 -androidx.vectordrawable:vectordrawable:1.1.0 -androidx.versionedparcelable:versionedparcelable:1.1.1 -androidx.viewpager:viewpager:1.0.0 -androidx.window.extensions.core:core:1.0.0 -androidx.window:window-core-android:1.3.0-rc01 -androidx.window:window-core:1.3.0-rc01 -androidx.window:window:1.3.0-rc01 -ch.qos.logback:logback-classic:1.2.3 -ch.qos.logback:logback-core:1.2.3 -co.touchlab:stately-concurrency-jvm:2.0.7 -co.touchlab:stately-concurrency:2.0.7 -co.touchlab:stately-concurrent-collections-jvm:2.0.7 -co.touchlab:stately-concurrent-collections:2.0.7 -co.touchlab:stately-strict-jvm:2.0.7 -co.touchlab:stately-strict:2.0.7 -com.caverock:androidsvg-aar:1.4 -com.eygraber:uri-kmp-android:0.0.12 -com.eygraber:uri-kmp:0.0.12 -com.google.accompanist:accompanist-drawablepainter:0.32.0 -com.google.accompanist:accompanist-pager:0.34.0 -com.google.accompanist:accompanist-permissions:0.34.0 -com.google.android.datatransport:transport-api:3.2.0 -com.google.android.datatransport:transport-backend-cct:3.3.0 -com.google.android.datatransport:transport-runtime:3.3.0 -com.google.android.gms:play-services-ads-identifier:18.0.0 -com.google.android.gms:play-services-auth-api-phone:18.0.2 -com.google.android.gms:play-services-auth-base:18.0.10 -com.google.android.gms:play-services-auth:21.2.0 -com.google.android.gms:play-services-base:18.3.0 -com.google.android.gms:play-services-basement:18.4.0 -com.google.android.gms:play-services-cloud-messaging:17.2.0 -com.google.android.gms:play-services-code-scanner:16.1.0 -com.google.android.gms:play-services-fido:21.0.0 -com.google.android.gms:play-services-measurement-api:22.0.2 -com.google.android.gms:play-services-measurement-base:22.0.2 -com.google.android.gms:play-services-measurement-impl:22.0.2 -com.google.android.gms:play-services-measurement-sdk-api:22.0.2 -com.google.android.gms:play-services-measurement-sdk:22.0.2 -com.google.android.gms:play-services-measurement:22.0.2 -com.google.android.gms:play-services-mlkit-barcode-scanning:18.3.0 -com.google.android.gms:play-services-stats:17.0.2 -com.google.android.gms:play-services-tasks:18.2.0 -com.google.android.libraries.identity.googleid:googleid:1.1.1 -com.google.android.odml:image:1.0.0-beta1 -com.google.auto.value:auto-value-annotations:1.6.3 -com.google.code.findbugs:jsr305:3.0.2 -com.google.code.gson:gson:2.10.1 -com.google.dagger:dagger:2.27 -com.google.errorprone:error_prone_annotations:2.26.0 -com.google.firebase:firebase-abt:21.1.1 -com.google.firebase:firebase-analytics-ktx:22.0.2 -com.google.firebase:firebase-analytics:22.0.2 -com.google.firebase:firebase-annotations:16.2.0 -com.google.firebase:firebase-bom:33.1.2 -com.google.firebase:firebase-common-ktx:21.0.0 -com.google.firebase:firebase-common:21.0.0 -com.google.firebase:firebase-components:18.0.0 -com.google.firebase:firebase-config-interop:16.0.1 -com.google.firebase:firebase-config:22.0.0 -com.google.firebase:firebase-crashlytics-ktx:19.0.3 -com.google.firebase:firebase-crashlytics:19.0.3 -com.google.firebase:firebase-datatransport:19.0.0 -com.google.firebase:firebase-encoders-json:18.0.1 -com.google.firebase:firebase-encoders-proto:16.0.0 -com.google.firebase:firebase-encoders:17.0.0 -com.google.firebase:firebase-iid-interop:17.1.0 -com.google.firebase:firebase-installations-interop:17.2.0 -com.google.firebase:firebase-installations:18.0.0 -com.google.firebase:firebase-measurement-connector:20.0.1 -com.google.firebase:firebase-messaging-ktx:24.0.0 -com.google.firebase:firebase-messaging:24.0.0 -com.google.firebase:firebase-perf-ktx:21.0.1 -com.google.firebase:firebase-perf:21.0.1 -com.google.firebase:firebase-sessions:2.0.3 -com.google.firebase:protolite-well-known-types:18.0.0 -com.google.guava:failureaccess:1.0.1 -com.google.guava:guava:31.1-android -com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava -com.google.j2objc:j2objc-annotations:1.3 -com.google.mlkit:barcode-scanning-common:17.0.0 -com.google.mlkit:barcode-scanning:17.2.0 -com.google.mlkit:common:18.9.0 -com.google.mlkit:vision-common:17.3.0 -com.google.mlkit:vision-interfaces:16.2.0 -com.google.protobuf:protobuf-javalite:4.26.0 -com.google.protobuf:protobuf-kotlin-lite:4.26.0 -com.google.zxing:core:3.5.3 -com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0 -com.maxkeppeler.sheets-compose-dialogs:calendar:1.3.0 -com.maxkeppeler.sheets-compose-dialogs:core:1.3.0 -com.squareup.okhttp3:logging-interceptor:4.12.0 -com.squareup.okhttp3:okhttp:4.12.0 -com.squareup.okio:okio-jvm:3.9.0 -com.squareup.okio:okio:3.9.0 -com.squareup.retrofit2:adapter-rxjava:2.11.0 -com.squareup.retrofit2:converter-gson:2.11.0 -com.squareup.retrofit2:retrofit:2.11.0 -com.squareup.wire:wire-runtime-jvm:5.0.0 -com.squareup.wire:wire-runtime:5.0.0 -com.squareup:javawriter:2.1.1 -dev.chrisbanes.snapper:snapper:0.3.0 -io.coil-kt:coil-base:2.6.0 -io.coil-kt:coil-compose-base:2.6.0 -io.coil-kt:coil-compose:2.6.0 -io.coil-kt:coil:2.6.0 -io.github.qdsfdhvh:image-loader-android:1.6.4 -io.github.qdsfdhvh:image-loader:1.6.4 -io.insert-koin:koin-android:4.0.0-RC2 -io.insert-koin:koin-androidx-compose:4.0.0-RC2 -io.insert-koin:koin-androidx-navigation:4.0.0-RC2 -io.insert-koin:koin-annotations-jvm:1.4.0-RC4 -io.insert-koin:koin-annotations:1.4.0-RC4 -io.insert-koin:koin-bom:4.0.0-RC2 -io.insert-koin:koin-compose-jvm:4.0.0-RC2 -io.insert-koin:koin-compose:4.0.0-RC2 -io.insert-koin:koin-core-jvm:4.0.0-RC2 -io.insert-koin:koin-core-viewmodel-jvm:4.0.0-RC2 -io.insert-koin:koin-core-viewmodel:4.0.0-RC2 -io.insert-koin:koin-core:4.0.0-RC2 -io.ktor:ktor-client-android-jvm:2.3.4 -io.ktor:ktor-client-android:2.3.4 -io.ktor:ktor-client-content-negotiation-jvm:2.3.4 -io.ktor:ktor-client-content-negotiation:2.3.4 -io.ktor:ktor-client-core-jvm:2.3.4 -io.ktor:ktor-client-core:2.3.4 -io.ktor:ktor-client-json-jvm:2.3.4 -io.ktor:ktor-client-json:2.3.4 -io.ktor:ktor-client-logging-jvm:2.3.4 -io.ktor:ktor-client-logging:2.3.4 -io.ktor:ktor-client-okhttp-jvm:2.3.3 -io.ktor:ktor-client-okhttp:2.3.3 -io.ktor:ktor-client-serialization-jvm:2.3.4 -io.ktor:ktor-client-serialization:2.3.4 -io.ktor:ktor-client-websockets-jvm:2.3.4 -io.ktor:ktor-client-websockets:2.3.4 -io.ktor:ktor-events-jvm:2.3.4 -io.ktor:ktor-events:2.3.4 -io.ktor:ktor-http-jvm:2.3.4 -io.ktor:ktor-http:2.3.4 -io.ktor:ktor-io-jvm:2.3.4 -io.ktor:ktor-io:2.3.4 -io.ktor:ktor-serialization-jvm:2.3.4 -io.ktor:ktor-serialization-kotlinx-json-jvm:2.3.4 -io.ktor:ktor-serialization-kotlinx-json:2.3.4 -io.ktor:ktor-serialization-kotlinx-jvm:2.3.4 -io.ktor:ktor-serialization-kotlinx:2.3.4 -io.ktor:ktor-serialization:2.3.4 -io.ktor:ktor-utils-jvm:2.3.4 -io.ktor:ktor-utils:2.3.4 -io.ktor:ktor-websocket-serialization-jvm:2.3.4 -io.ktor:ktor-websocket-serialization:2.3.4 -io.ktor:ktor-websockets-jvm:2.3.4 -io.ktor:ktor-websockets:2.3.4 -io.michaelrocks:libphonenumber-android:8.13.35 -io.reactivex:rxandroid:1.1.0 -io.reactivex:rxjava:1.3.8 -javax.inject:javax.inject:1 -junit:junit:4.13.2 -network.chaintech:cmp-image-pick-n-crop-android:1.0.1 -network.chaintech:cmp-image-pick-n-crop:1.0.1 -network.chaintech:qr-kit-android:2.0.0 -network.chaintech:qr-kit:2.0.0 -org.checkerframework:checker-qual:3.12.0 -org.hamcrest:hamcrest-core:1.3 -org.hamcrest:hamcrest-integration:1.3 -org.hamcrest:hamcrest-library:1.3 -org.jetbrains.androidx.core:core-bundle-android:1.0.0 -org.jetbrains.androidx.core:core-bundle:1.0.0 -org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.0 -org.jetbrains.androidx.lifecycle:lifecycle-viewmodel:2.8.0 -org.jetbrains.androidx.savedstate:savedstate:1.2.0 -org.jetbrains.compose.components:components-resources-android:1.6.11 -org.jetbrains.compose.components:components-resources:1.6.11 -org.jetbrains.compose.components:components-ui-tooling-preview-android:1.6.11 -org.jetbrains.compose.components:components-ui-tooling-preview:1.6.11 -org.jetbrains.compose.foundation:foundation:1.6.11 -org.jetbrains.compose.material3:material3:1.6.11 -org.jetbrains.compose.material:material-icons-extended:1.6.11 -org.jetbrains.compose.runtime:runtime:1.6.11 -org.jetbrains.compose.ui:ui-tooling-preview:1.6.11 -org.jetbrains.compose.ui:ui-tooling:1.6.11 -org.jetbrains.compose.ui:ui:1.6.11 -org.jetbrains.kotlin:kotlin-android-extensions-runtime:2.0.20 -org.jetbrains.kotlin:kotlin-parcelize-runtime:2.0.20 -org.jetbrains.kotlin:kotlin-stdlib-common:2.0.20 -org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.20 -org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.20 -org.jetbrains.kotlin:kotlin-stdlib:2.0.20 -org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.7 -org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7 -org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1 -org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1 -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1 -org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 -org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.8.1 -org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.8.1 -org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.8.1 -org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.8.1 -org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1 -org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.0 -org.jetbrains.kotlinx:kotlinx-datetime:0.6.0 -org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.1 -org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.1 -org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.1 -org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.7.1 -org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1 -org.jetbrains:annotations:23.0.0 -org.slf4j:slf4j-api:1.7.36 diff --git a/mifospay/src/main/java/org/mifospay/MainActivity.kt b/mifospay/src/main/java/org/mifospay/MainActivity.kt deleted file mode 100644 index e17923bd8..000000000 --- a/mifospay/src/main/java/org/mifospay/MainActivity.kt +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay - -import android.os.Bundle -import android.view.Window -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge -import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi -import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.lifecycle.lifecycleScope -import androidx.lifecycle.repeatOnLifecycle -import androidx.metrics.performance.JankStats -import androidx.navigation.compose.rememberNavController -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import org.koin.android.ext.android.inject -import org.koin.androidx.viewmodel.ext.android.viewModel -import org.koin.core.parameter.parametersOf -import org.mifospay.MainActivityUiState.Loading -import org.mifospay.MainActivityUiState.Success -import org.mifospay.core.analytics.AnalyticsHelper -import org.mifospay.core.analytics.LocalAnalyticsHelper -import org.mifospay.core.data.util.NetworkMonitor -import org.mifospay.core.data.util.TimeZoneMonitor -import org.mifospay.core.designsystem.theme.MifosTheme -import org.mifospay.core.ui.LocalTimeZone -import org.mifospay.navigation.MifosNavGraph.LOGIN_GRAPH -import org.mifospay.navigation.MifosNavGraph.PASSCODE_GRAPH -import org.mifospay.navigation.RootNavGraph -import org.mifospay.ui.rememberMifosAppState - -@OptIn(ExperimentalMaterial3WindowSizeClassApi::class) -class MainActivity : ComponentActivity() { - - /** - * Lazily inject [JankStats], which is used to track jank throughout the app. - */ - - private val networkMonitor: NetworkMonitor by inject() - - private val timeZoneMonitor: TimeZoneMonitor by inject() - - private val analyticsHelper: AnalyticsHelper by inject() - - private val viewModel: MainActivityViewModel by viewModel() - - private val myWindow: Window by inject { parametersOf(this) } - - private val lazyStats: JankStats by inject { parametersOf(myWindow) } - - override fun onCreate(savedInstanceState: Bundle?) { - val splashScreen = installSplashScreen() - super.onCreate(savedInstanceState) - - var uiState: MainActivityUiState by mutableStateOf(Loading) - - // Update the uiState - lifecycleScope.launch { - lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.uiState - .onEach { uiState = it } - .collect() - } - } - - splashScreen.setKeepOnScreenCondition { - when (uiState) { - Loading -> true - is Success -> false - } - } - - enableEdgeToEdge() - - setContent { - val navController = rememberNavController() - - val appState = rememberMifosAppState( - windowSizeClass = calculateWindowSizeClass(this), - networkMonitor = networkMonitor, - timeZoneMonitor = timeZoneMonitor, - ) - - val currentTimeZone by appState.currentTimeZone.collectAsStateWithLifecycle() - - val navDestination = when (uiState) { - is Success -> if ((uiState as Success).userData.isAuthenticated) { - PASSCODE_GRAPH - } else { - LOGIN_GRAPH - } - - else -> LOGIN_GRAPH - } - - CompositionLocalProvider( - LocalAnalyticsHelper provides analyticsHelper, - LocalTimeZone provides currentTimeZone, - ) { - MifosTheme { - RootNavGraph( - appState = appState, - navHostController = navController, - startDestination = navDestination, - onClickLogout = { - viewModel.logOut() - navController.navigate(LOGIN_GRAPH) { - popUpTo(navController.graph.id) { - inclusive = true - } - } - }, - ) - } - } - } - } - - override fun onResume() { - super.onResume() - lazyStats.isTrackingEnabled = true - } - - override fun onPause() { - super.onPause() - lazyStats.isTrackingEnabled = false - } -} diff --git a/mifospay/src/main/java/org/mifospay/MifosPayApp.kt b/mifospay/src/main/java/org/mifospay/MifosPayApp.kt deleted file mode 100644 index e7403cf44..000000000 --- a/mifospay/src/main/java/org/mifospay/MifosPayApp.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay - -import android.app.Application -import org.koin.android.ext.koin.androidContext -import org.koin.core.context.startKoin -import org.koin.core.logger.Level -import org.mifospay.di.KoinModules - -class MifosPayApp : Application() { - override fun onCreate() { - super.onCreate() - val koinModules = KoinModules() - - startKoin { - printLogger(Level.ERROR) - androidContext(this@MifosPayApp) - modules( - listOf( - koinModules.dataModules, - koinModules.mifosPayModule, - koinModules - .coreDataStoreModules, - koinModules.featureModules, - koinModules.networkModules, - koinModules - .analyticsModules, - koinModules.commonModules, - koinModules.libsModule, - ), - ) - } - } -} diff --git a/mifospay/src/main/java/org/mifospay/data/firebase/api/services/MifosPayMessagingService.kt b/mifospay/src/main/java/org/mifospay/data/firebase/api/services/MifosPayMessagingService.kt deleted file mode 100644 index 09e7d9732..000000000 --- a/mifospay/src/main/java/org/mifospay/data/firebase/api/services/MifosPayMessagingService.kt +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright 2016 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.data.firebase.api.services - -import android.app.NotificationChannel -import android.app.NotificationManager -import android.app.PendingIntent -import android.content.Context -import android.content.Intent -import android.media.RingtoneManager -import android.util.Log -import androidx.core.app.NotificationCompat -import com.google.firebase.messaging.FirebaseMessagingService -import com.google.firebase.messaging.RemoteMessage -import org.json.JSONException -import org.json.JSONObject -import org.mifospay.MainActivity -import org.mifospay.R -import org.mifospay.utils.NotificationUtils - -@Suppress("UnusedPrivateMember") -class MifosPayMessagingService : FirebaseMessagingService() { - /** - * Called if InstanceID token is updated. This may occur if the security of - * the previous token had been compromised. Note that this is called when the InstanceID token - * is initially generated so this is where you would retrieve the token. - */ - override fun onNewToken(token: String) { - super.onNewToken(token) - Log.d(TAG, "Refreshed token: $token") - // If you want to send messages to this application instance or - // manage this apps subscriptions on the server side, send the - // Instance ID token to your app server. - } - - /** - * Called when message is received. - * - * @param remoteMessage Object representing the message received from Firebase Cloud Messaging. - */ - // [START receive_message] - override fun onMessageReceived(remoteMessage: RemoteMessage) { - // [START_EXCLUDE] - // There are two types of messages data messages and notification messages. Data messages - // are handled - // here in onMessageReceived whether the app is in the foreground or background. Data - // messages are the type - // traditionally used with GCM. Notification messages are only received here in - // onMessageReceived when the app - // is in the foreground. When the app is in the background an automatically generated - // notification is displayed. - // When the user taps on the notification they are returned to the app. Messages - // containing both notification - // and data payloads are treated as notification messages. The Firebase console always - // sends notification - // messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options - // [END_EXCLUDE] - - // Not getting messages here? See why this may be: https://goo.gl/39bRNJ - Log.d(TAG, "From: " + remoteMessage.from) - - // Check if message contains a data payload. - // We will use data messages and hence our messages will be handled here - if (remoteMessage.data.isNotEmpty()) { - Log.d(TAG, "Message data payload: " + remoteMessage.data) - try { - val json = JSONObject(remoteMessage.data.toString()) - handleDataMessage(json) - } catch (e: Exception) { - Log.e(TAG, "Exception: " + e.message) - } - -// if (/* Check if data needs to be processed by long running job */ true) { -// // For long-running tasks (10 seconds or more) use Firebase Job Dispatcher. -// scheduleJob(); -// } else { -// // Handle message within 10 seconds -// / handleNow(); -// } - } - - // Check if message contains a notification payload. - // We will not use Firebase Notification Message but keeping the code for that won't harm. -// if (remoteMessage.getNotification() != null) { -// Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody()); -// // handleNotification(remoteMessage.getNotification().getBody()); -// sendNotification(remoteMessage.getNotification().getTitle(), -// remoteMessage.getNotification().getBody()); -// } - - // Also if you intend on generating your own notifications as a result of a received FCM - // message, here is where that should be initiated. See sendNotification method below. - } - - // [END receive_message] - override fun onDeletedMessages() { - super.onDeletedMessages() - } - - /** - * Schedule a job using FirebaseJobDispatcher. - */ - private fun scheduleJob() { - // [START dispatch_job] -// FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(this)); -// Job myJob = dispatcher.newJobBuilder() -// .setService(MyJobService.class) -// .setTag("my-job-tag") -// .build(); -// dispatcher.schedule(myJob); - // [END dispatch_job] - } - - /** - * Handle time allotted to BroadcastReceivers. - */ - private fun handleNow() { - Log.d(TAG, "Short lived task is done.") - } - - /** - * Create and show a simple notification containing the received FCM message. - * - * @param messageBody FCM message body received. - */ - private fun sendNotification(title: String, messageBody: String) { - val intent = Intent(this, MainActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - val pendingIntent: PendingIntent = PendingIntent.getActivity( - this, - 0, - intent, - PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_ONE_SHOT, - ) - val channelId = getString(R.string.app_name) - val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) - val notificationBuilder = NotificationCompat.Builder(this, channelId) - .setSmallIcon(R.drawable.feature_accounts_ic_bank) - .setContentTitle(title) - .setContentText(messageBody) - .setAutoCancel(true) - .setSound(defaultSoundUri) - .setContentIntent(pendingIntent) - val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager - - // Since android Oreo notification channel is needed. - val channel = NotificationChannel( - channelId, - "Channel human readable title", - NotificationManager.IMPORTANCE_DEFAULT, - ) - notificationManager.createNotificationChannel(channel) - notificationManager.notify(0, notificationBuilder.build()) - } - - /** - * Handles notification messages. - */ - private fun handleNotification(title: String, message: String) {} - - /** - * Handles data messages. - */ - private fun handleDataMessage(json: JSONObject) { - Log.e(TAG, "push json: $json") - try { - val data = json.getJSONObject("data") - val title = data.getString("title") - val message = data.getString("message") - val imageUrl = data.getString("image") - val type = data.getString("type") - val timestamp = data.getString("timestamp") - val payload = data.getJSONObject("payload") - Log.e(TAG, "title: $title") - Log.e(TAG, "message: $message") - Log.e(TAG, "type: $type") - // payload can be used when one needs to show specific notification with some data - // and process it - Log.e(TAG, "payload: $payload") - Log.e(TAG, "imageUrl: $imageUrl") - Log.e(TAG, "timestamp: $timestamp") - sendNotification(title, message) - - // Below code can be used when you want to show notification with Image. - -// Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class); -// resultIntent.putExtra("message", message); - -// // check for image attachment -// if (TextUtils.isEmpty(imageUrl)) { -// showNotificationMessage(getApplicationContext(), title, message, timestamp, -// resultIntent); -// } else { -// // image is present, show notification with image -// showNotificationMessageWithBigImage(getApplicationContext(), title, message, -// timestamp, resultIntent, imageUrl); -// } - } catch (e: JSONException) { - Log.e(TAG, "Json Exception: " + e.message) - } catch (e: Exception) { - Log.e(TAG, "Exception: " + e.message) - } - } - - /** - * Showing notification with text only - */ - private fun showNotificationMessage( - context: Context, - title: String, - message: String, - timeStamp: String, - intent: Intent, - ) { - val notificationUtils = NotificationUtils(context) - intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK - notificationUtils.showNotificationMessage(title, message, timeStamp, intent) - } - - /** - * Showing notification with text and image - */ - private fun showNotificationMessageWithBigImage( - context: Context, - title: String, - message: String, - timeStamp: String, - intent: Intent, - imageUrl: String, - ) { - val notificationUtils = NotificationUtils(context) - intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK - notificationUtils.showNotificationMessage(title, message, timeStamp, intent, imageUrl) - } - - companion object { - private const val TAG = "MifosPayFCM" - } -} diff --git a/mifospay/src/main/java/org/mifospay/di/JankStatsModule.kt b/mifospay/src/main/java/org/mifospay/di/JankStatsModule.kt deleted file mode 100644 index aa1210bf6..000000000 --- a/mifospay/src/main/java/org/mifospay/di/JankStatsModule.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.di - -import android.app.Activity -import android.util.Log -import android.view.Window -import androidx.metrics.performance.JankStats -import org.koin.core.module.dsl.viewModel -import org.koin.dsl.module -import org.mifospay.MainActivityViewModel - -val JankStatsModule = module { - - factory { (activity: Activity) -> activity.window } - factory { (window: Window) -> - JankStats.createAndTrack(window) { frameData -> - // Make sure to only log janky frames. - if (frameData.isJank) { - // We're currently logging this but would better report it to a backend. - Log.v("Mifos Jank", frameData.toString()) - } - } - } - - viewModel { - MainActivityViewModel(userDataRepository = get(), passcodeManager = get()) - } -} diff --git a/mifospay/src/main/java/org/mifospay/di/KoinModules.kt b/mifospay/src/main/java/org/mifospay/di/KoinModules.kt deleted file mode 100644 index c3ad261cb..000000000 --- a/mifospay/src/main/java/org/mifospay/di/KoinModules.kt +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.di - -import org.koin.dsl.module -import org.mifos.library.passcode.di.ApplicationModule -import org.mifospay.core.analytics.di.AnalyticsModule -import org.mifospay.core.data.di.DataModule -import org.mifospay.core.data.di.LocalDataModule -import org.mifospay.core.datastore.di.CoreDataStoreModule -import org.mifospay.core.network.di.CoroutineScopesModule -import org.mifospay.core.network.di.DispatchersModule -import org.mifospay.core.network.di.LocalModule -import org.mifospay.core.network.di.NetworkModule -import org.mifospay.feature.auth.di.AuthModule -import org.mifospay.feature.bank.accounts.di.AccountsModule -import org.mifospay.feature.di.HistoryModule -import org.mifospay.feature.editpassword.di.EditPasswordModule -import org.mifospay.feature.faq.di.FaqModule -import org.mifospay.feature.home.di.HomeModule -import org.mifospay.feature.invoices.di.InvoicesModule -import org.mifospay.feature.kyc.di.KYCModule -import org.mifospay.feature.make.transfer.di.MakeTransferModule -import org.mifospay.feature.merchants.di.MerchantsModule -import org.mifospay.feature.notification.di.NotificationModule -import org.mifospay.feature.payments.di.PaymentsModule -import org.mifospay.feature.profile.di.ProfileModule -import org.mifospay.feature.read.qr.di.QrModule -import org.mifospay.feature.receipt.di.ReceiptModule -import org.mifospay.feature.request.money.di.RequestMoneyModule -import org.mifospay.feature.savedcards.di.SavedCardsModule -import org.mifospay.feature.search.di.SearchModule -import org.mifospay.feature.send.money.di.SendMoneyModule -import org.mifospay.feature.settings.di.SettingsModule -import org.mifospay.feature.standing.instruction.di.StandingInstructionModule -import org.mifospay.feature.upiSetup.di.UpiSetupModule - -class KoinModules { - val analyticsModules = module { - includes(AnalyticsModule) - } - val commonModules = module { - includes(CoroutineScopesModule, DispatchersModule) - } - val dataModules = module { - includes(DataModule, LocalDataModule) - } - val coreDataStoreModules = module { - includes(CoreDataStoreModule) - } - val networkModules = module { - includes(LocalModule, NetworkModule) - } - val featureModules = module { - includes( - AuthModule, AccountsModule, EditPasswordModule, FaqModule, HistoryModule, HomeModule, - InvoicesModule, KYCModule, MakeTransferModule, MerchantsModule, NotificationModule, - PaymentsModule, ProfileModule, QrModule, ReceiptModule, RequestMoneyModule, - SavedCardsModule, SearchModule, SendMoneyModule, SettingsModule, - StandingInstructionModule, UpiSetupModule, - ) - } - val mifosPayModule = module { - includes(JankStatsModule) - } - val libsModule = module { - includes(ApplicationModule) - } -} diff --git a/mifospay/src/main/java/org/mifospay/navigation/MifosNavHost.kt b/mifospay/src/main/java/org/mifospay/navigation/MifosNavHost.kt deleted file mode 100644 index 745f43a20..000000000 --- a/mifospay/src/main/java/org/mifospay/navigation/MifosNavHost.kt +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.navigation - -import android.content.Context -import android.net.Uri -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.core.content.FileProvider -import androidx.navigation.compose.NavHost -import com.mifos.library.material3.navigation.ModalBottomSheetLayout -import org.mifospay.common.Constants -import org.mifospay.core.ui.utility.TabContent -import org.mifospay.feature.bank.accounts.AccountsScreen -import org.mifospay.feature.bank.accounts.navigation.bankAccountDetailScreen -import org.mifospay.feature.bank.accounts.navigation.linkBankAccountScreen -import org.mifospay.feature.bank.accounts.navigation.navigateToBankAccountDetail -import org.mifospay.feature.bank.accounts.navigation.navigateToLinkBankAccount -import org.mifospay.feature.editpassword.navigation.editPasswordScreen -import org.mifospay.feature.editpassword.navigation.navigateToEditPassword -import org.mifospay.feature.faq.navigation.faqScreen -import org.mifospay.feature.faq.navigation.navigateToFAQ -import org.mifospay.feature.finance.FinanceScreenContents -import org.mifospay.feature.finance.navigation.financeScreen -import org.mifospay.feature.history.HistoryScreen -import org.mifospay.feature.home.navigation.HOME_ROUTE -import org.mifospay.feature.home.navigation.homeScreen -import org.mifospay.feature.invoices.InvoiceScreenRoute -import org.mifospay.feature.invoices.navigation.invoiceDetailScreen -import org.mifospay.feature.invoices.navigation.navigateToInvoiceDetail -import org.mifospay.feature.kyc.KYCScreen -import org.mifospay.feature.kyc.navigation.kycLevel1Screen -import org.mifospay.feature.kyc.navigation.kycLevel2Screen -import org.mifospay.feature.kyc.navigation.kycLevel3Screen -import org.mifospay.feature.kyc.navigation.kycScreen -import org.mifospay.feature.kyc.navigation.navigateToKYCLevel1 -import org.mifospay.feature.kyc.navigation.navigateToKYCLevel2 -import org.mifospay.feature.kyc.navigation.navigateToKYCLevel3 -import org.mifospay.feature.make.transfer.navigation.makeTransferScreen -import org.mifospay.feature.make.transfer.navigation.navigateToMakeTransferScreen -import org.mifospay.feature.merchants.navigation.merchantTransferScreen -import org.mifospay.feature.merchants.ui.MerchantScreen -import org.mifospay.feature.notification.notificationScreen -import org.mifospay.feature.payments.PaymentsScreenContents -import org.mifospay.feature.payments.RequestScreen -import org.mifospay.feature.payments.paymentsScreen -import org.mifospay.feature.profile.navigation.editProfileScreen -import org.mifospay.feature.profile.navigation.navigateToEditProfile -import org.mifospay.feature.profile.navigation.profileScreen -import org.mifospay.feature.read.qr.navigation.readQrScreen -import org.mifospay.feature.receipt.navigation.navigateToReceipt -import org.mifospay.feature.receipt.navigation.receiptScreen -import org.mifospay.feature.request.money.navigation.navigateToShowQrScreen -import org.mifospay.feature.request.money.navigation.showQrScreen -import org.mifospay.feature.savedcards.CardsScreen -import org.mifospay.feature.savedcards.navigation.addCardScreen -import org.mifospay.feature.search.searchScreen -import org.mifospay.feature.send.money.SendScreenRoute -import org.mifospay.feature.send.money.navigation.navigateToSendMoneyScreen -import org.mifospay.feature.send.money.navigation.sendMoneyScreen -import org.mifospay.feature.settings.navigation.settingsScreen -import org.mifospay.feature.specific.transactions.navigation.navigateToSpecificTransactions -import org.mifospay.feature.specific.transactions.navigation.specificTransactionsScreen -import org.mifospay.feature.standing.instruction.StandingInstructionsScreenRoute -import org.mifospay.feature.standing.instruction.navigateToNewSiScreen -import org.mifospay.feature.standing.instruction.newSiScreen -import org.mifospay.feature.standing.instruction.siDetailsScreen -import org.mifospay.feature.upiSetup.navigation.navigateToSetupUpiPin -import org.mifospay.feature.upiSetup.navigation.setupUpiPinScreen -import org.mifospay.ui.MifosAppState -import java.io.File -import java.util.Objects - -/** - * Top-level navigation graph. Navigation is organized as explained at - * https://d.android.com/jetpack/compose/nav-adaptive - * - * The navigation graph defined in this file defines the different top level routes. Navigation - * within each route is handled using state and Back Handlers. - */ -@Suppress("MaxLineLength", "LongMethod") -@Composable -internal fun MifosNavHost( - appState: MifosAppState, - onClickLogout: () -> Unit, - modifier: Modifier = Modifier, -) { - val navController = appState.navController - - val tabContents = listOf( - TabContent(FinanceScreenContents.ACCOUNTS.name) { - AccountsScreen( - navigateToBankAccountDetailScreen = navController::navigateToBankAccountDetail, - navigateToLinkBankAccountScreen = navController::navigateToLinkBankAccount, - ) - }, - TabContent(FinanceScreenContents.CARDS.name) { - CardsScreen(onEditCard = {}) - }, - TabContent(FinanceScreenContents.MERCHANTS.name) { - MerchantScreen() - }, - TabContent(FinanceScreenContents.KYC.name) { - KYCScreen( - onLevel1Clicked = navController::navigateToKYCLevel1, - onLevel2Clicked = navController::navigateToKYCLevel2, - onLevel3Clicked = navController::navigateToKYCLevel3, - ) - }, - ) - - val paymentsTabContents = listOf( - TabContent(PaymentsScreenContents.SEND.name) { - SendScreenRoute( - onBackClick = {}, - showToolBar = false, - proceedWithMakeTransferFlow = navController::navigateToMakeTransferScreen, - ) - }, - TabContent(PaymentsScreenContents.REQUEST.name) { - RequestScreen(showQr = navController::navigateToShowQrScreen) - }, - TabContent(PaymentsScreenContents.HISTORY.name) { - HistoryScreen( - accountClicked = navController::navigateToSpecificTransactions, - viewReceipt = { - navController - .navigateToReceipt(Uri.parse(Constants.RECEIPT_DOMAIN + it)) - }, - ) - }, - TabContent(PaymentsScreenContents.SI.name) { - StandingInstructionsScreenRoute( - onNewSI = navController::navigateToNewSiScreen, - onBackPress = navController::popBackStack, - ) - }, - TabContent(PaymentsScreenContents.INVOICES.name) { - InvoiceScreenRoute( - navigateToInvoiceDetailScreen = { - navController.navigateToInvoiceDetail(it.toString()) - }, - ) - }, - ) - - ModalBottomSheetLayout( - bottomSheetNavigator = appState.bottomSheetNavigator, - modifier = modifier, - ) { - NavHost( - route = MifosNavGraph.MAIN_GRAPH, - startDestination = HOME_ROUTE, - navController = navController, - ) { - homeScreen( - onRequest = navController::navigateToShowQrScreen, - onPay = navController::navigateToSendMoneyScreen, - ) - paymentsScreen( - tabContents = paymentsTabContents, - ) - financeScreen( - tabContents = tabContents, - ) - addCardScreen( - onDismiss = navController::popBackStack, - onAddCard = { - // Handle adding the cards - navController.popBackStack() - }, - ) - profileScreen(onEditProfile = navController::navigateToEditProfile) - - sendMoneyScreen( - onBackClick = navController::popBackStack, - proceedWithMakeTransferFlow = navController::navigateToMakeTransferScreen, - ) - makeTransferScreen( - onDismiss = navController::popBackStack, - ) - showQrScreen( - onBackClick = navController::popBackStack, - ) - merchantTransferScreen( - proceedWithMakeTransferFlow = navController::navigateToMakeTransferScreen, - onBackPressed = navController::popBackStack, - ) - settingsScreen( - onBackPress = navController::popBackStack, - navigateToEditPasswordScreen = navController::navigateToEditPassword, - onLogout = onClickLogout, - onChangePasscode = { - // TODO:: Implement change passcode screen - }, - navigateToFaqScreen = navController::navigateToFAQ, - ) - - kycScreen( - onLevel1Clicked = navController::navigateToKYCLevel1, - onLevel2Clicked = navController::navigateToKYCLevel2, - onLevel3Clicked = navController::navigateToKYCLevel3, - ) - kycLevel1Screen( - navigateToKycLevel2 = navController::navigateToKYCLevel2, - ) - kycLevel2Screen( - onSuccessKyc2 = navController::navigateToKYCLevel3, - ) - - kycLevel3Screen() - - newSiScreen(onBackClick = navController::popBackStack) - - siDetailsScreen( - onClickCreateNew = navController::navigateToNewSiScreen, - onBackPress = navController::popBackStack, - ) - - editProfileScreen( - onBackPress = navController::popBackStack, - getUri = ::getUri, - ) - - faqScreen( - navigateBack = navController::popBackStack, - ) - readQrScreen( - onBackClick = navController::popBackStack, - ) - - specificTransactionsScreen( - onBackClick = navController::popBackStack, - onTransactionItemClicked = { transactionId -> - navController.navigateToReceipt(Uri.parse(Constants.RECEIPT_DOMAIN + transactionId)) - }, - ) - invoiceDetailScreen( - onBackPress = navController::popBackStack, -// navigateToReceiptScreen = { uri -> -// navController.navigateToReceipt(Uri.parse(Constants.RECEIPT_DOMAIN + uri)) -// }, - ) - receiptScreen( - openPassCodeActivity = { - // TODO: Implement Passcode Screen for Receipt - }, - onBackClick = navController::popBackStack, - ) - setupUpiPinScreen( - onBackPress = navController::popBackStack, - ) - - bankAccountDetailScreen( - onSetupUpiPin = { bankAccountDetails, index -> - navController.navigateToSetupUpiPin(bankAccountDetails, index, Constants.SETUP) - }, - onChangeUpiPin = { bankAccountDetails, index -> - navController.navigateToSetupUpiPin(bankAccountDetails, index, Constants.CHANGE) - }, - onForgotUpiPin = { bankAccountDetails, index -> - navController.navigateToSetupUpiPin(bankAccountDetails, index, Constants.FORGOT) - }, - onBackClick = { bankAccountDetails, index -> - navController.previousBackStackEntry?.savedStateHandle?.set( - Constants.UPDATED_BANK_ACCOUNT, - bankAccountDetails, - ) - navController.previousBackStackEntry?.savedStateHandle?.set( - Constants.INDEX, - index, - ) - navController.popBackStack() - }, - ) - linkBankAccountScreen( - onBackClick = navController::popBackStack, - ) - editPasswordScreen( - onBackPress = navController::popBackStack, - onCancelChanges = navController::popBackStack, - ) - - notificationScreen() - - searchScreen(onBackClick = navController::popBackStack) - } - } -} - -fun getUri(context: Context, file: File): Uri { - val uri = FileProvider.getUriForFile( - Objects.requireNonNull(context), - org.mifospay.BuildConfig.APPLICATION_ID + ".provider", - file, - ) - return uri -} diff --git a/mifospay/src/main/java/org/mifospay/utils/NotificationUtils.kt b/mifospay/src/main/java/org/mifospay/utils/NotificationUtils.kt deleted file mode 100644 index 2bdb7c4bd..000000000 --- a/mifospay/src/main/java/org/mifospay/utils/NotificationUtils.kt +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.utils - -import android.app.ActivityManager -import android.app.ActivityManager.RunningAppProcessInfo -import android.app.Notification -import android.app.NotificationManager -import android.app.PendingIntent -import android.content.Context -import android.content.Intent -import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.media.RingtoneManager -import android.net.Uri -import android.os.Build -import android.text.Html -import android.text.TextUtils -import android.util.Log -import android.util.Patterns -import androidx.core.app.NotificationCompat -import org.mifospay.R -import org.mifospay.common.Constants -import java.io.IOException -import java.net.HttpURLConnection -import java.net.URL -import java.text.ParseException -import java.text.SimpleDateFormat - -/** - * Created by ankur on 23/July/2018 - */ -@Suppress("NestedBlockDepth") -class NotificationUtils(private val mContext: Context) { - @JvmOverloads - fun showNotificationMessage( - title: String, - message: String?, - timeStamp: String, - intent: Intent, - imageUrl: String? = null, - ) { - // Check for empty push message - if (TextUtils.isEmpty(message)) { - return - } - - // notification icon - val icon = R.drawable.feature_accounts_ic_bank - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) - val resultPendingIntent = PendingIntent.getActivity( - mContext, - 0, - intent, - PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE, - ) - val mBuilder = NotificationCompat.Builder( - mContext, - ) - -// final Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE -// + "://" + mContext.getPackageName() + "/raw/notification"); - val alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) - if (!TextUtils.isEmpty(imageUrl)) { - if (imageUrl != null && imageUrl.length > 4 && Patterns.WEB_URL.matcher( - imageUrl, - ).matches() - ) { - val bitmap = getBitmapFromURL(imageUrl) - if (bitmap != null) { - showBigNotification( - bitmap, - mBuilder, - icon, - title, - message, - timeStamp, - resultPendingIntent, - alarmSound, - ) - } else { - showSmallNotification( - mBuilder, - icon, - title, - message, - timeStamp, - resultPendingIntent, - alarmSound, - ) - } - } - } else { - showSmallNotification( - mBuilder, - icon, - title, - message, - timeStamp, - resultPendingIntent, - alarmSound, - ) - playNotificationSound() - } - } - - private fun showSmallNotification( - mBuilder: NotificationCompat.Builder, - icon: Int, - title: String, - message: String?, - timeStamp: String, - resultPendingIntent: PendingIntent, - alarmSound: Uri, - ) { - val inboxStyle = NotificationCompat.InboxStyle() - inboxStyle.addLine(message) - val notification: Notification - notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0) - .setAutoCancel(true) - .setContentTitle(title) - .setContentIntent(resultPendingIntent) - .setSound(alarmSound) - .setStyle(inboxStyle) - .setWhen(getTimeMilliSec(timeStamp)) - .setSmallIcon(R.mipmap.ic_launcher) - .setLargeIcon(BitmapFactory.decodeResource(mContext.resources, icon)) - .setContentText(message) - .build() - val notificationManager = mContext.getSystemService( - Context.NOTIFICATION_SERVICE, - ) as NotificationManager - notificationManager.notify(Constants.NOTIFICATION_ID, notification) - } - - private fun showBigNotification( - bitmap: Bitmap, - mBuilder: NotificationCompat.Builder, - icon: Int, - title: String, - message: String?, - timeStamp: String, - resultPendingIntent: PendingIntent, - alarmSound: Uri, - ) { - val bigPictureStyle = NotificationCompat.BigPictureStyle() - bigPictureStyle.setBigContentTitle(title) - bigPictureStyle.setSummaryText(Html.fromHtml(message).toString()) - bigPictureStyle.bigPicture(bitmap) - val notification: Notification - notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0) - .setAutoCancel(true) - .setContentTitle(title) - .setContentIntent(resultPendingIntent) - .setSound(alarmSound) - .setStyle(bigPictureStyle) - .setWhen(getTimeMilliSec(timeStamp)) - .setSmallIcon(R.mipmap.ic_launcher) - .setLargeIcon(BitmapFactory.decodeResource(mContext.resources, icon)) - .setContentText(message) - .build() - val notificationManager = mContext.getSystemService( - Context.NOTIFICATION_SERVICE, - ) as NotificationManager - notificationManager.notify(Constants.NOTIFICATION_ID_BIG_IMAGE, notification) - } - - /** - * Downloading push notification image before displaying it in - * the notification tray - */ - fun getBitmapFromURL(strURL: String?): Bitmap? { - return try { - val url = URL(strURL) - val connection = url.openConnection() as HttpURLConnection - connection.doInput = true - connection.connect() - val input = connection.inputStream - BitmapFactory.decodeStream(input) - } catch (e: IOException) { - Log.e(TAG, "Unable to create bitmap", e) - null - } - } - - // Playing notification sound - fun playNotificationSound() { - try { -// Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE -// + "://" + mContext.getPackageName() + "/raw/notification"); - val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) - val r = RingtoneManager.getRingtone(mContext, defaultSoundUri) - r.play() - } catch (e: Exception) { - Log.d(TAG, "playNotificationSound: " + e.message) - } - } - - companion object { - private val TAG = NotificationUtils::class.java.simpleName - - /** - * Method checks if the app is in background or not - */ - fun isAppIsInBackground(context: Context): Boolean { - var isInBackground = true - val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) { - val runningProcesses = am.runningAppProcesses - for (processInfo in runningProcesses) { - if (processInfo.importance - == RunningAppProcessInfo.IMPORTANCE_FOREGROUND - ) { - for (activeProcess in processInfo.pkgList) { - if (activeProcess == context.packageName) { - isInBackground = false - } - } - } - } - } else { - val taskInfo = am.getRunningTasks(1) - val componentInfo = taskInfo[0].topActivity - if (componentInfo!!.packageName == context.packageName) { - isInBackground = false - } - } - return isInBackground - } - - // Clears notification tray messages - fun clearNotifications(context: Context) { - val notificationManager = context.getSystemService( - Context.NOTIFICATION_SERVICE, - ) as NotificationManager - notificationManager.cancelAll() - } - - fun getTimeMilliSec(timeStamp: String?): Long { - val format = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") - try { - val date = format.parse(timeStamp) - return date.time - } catch (e: ParseException) { - Log.e(TAG, "Unable to parse the timestamp", e) - } - return 0 - } - } -} diff --git a/mifospay/src/test/java/org/mifospay/KoinModulesCheck.kt b/mifospay/src/test/java/org/mifospay/KoinModulesCheck.kt deleted file mode 100644 index 0c69be164..000000000 --- a/mifospay/src/test/java/org/mifospay/KoinModulesCheck.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay - -import android.content.Context -import androidx.lifecycle.SavedStateHandle -import io.ktor.client.HttpClientConfig -import io.ktor.client.engine.HttpClientEngine -import org.koin.test.AutoCloseKoinTest -import org.koin.test.verify.verify -import org.mifos.library.passcode.data.PasscodeManager -import org.mifospay.core.data.repository.auth.UserDataRepository -import org.mifospay.core.datastore.PreferencesHelper -import org.mifospay.core.network.FineractApiManager -import org.mifospay.core.network.SelfServiceApiManager -import org.mifospay.core.network.services.KtorAuthenticationService -import org.mifospay.di.KoinModules -import kotlin.test.Test - -class KoinModulesCheck : AutoCloseKoinTest() { - - @Test - fun checkKoinModules() { - val koinModules = KoinModules() - - koinModules.libsModule.verify( - extraTypes = listOf(Context::class), - ) - koinModules.commonModules.verify() - koinModules.analyticsModules.verify() - koinModules.networkModules.verify( - extraTypes = listOf( - HttpClientEngine::class, - HttpClientConfig::class, - ), - ) - koinModules.featureModules.verify( - extraTypes = listOf( - PreferencesHelper::class, - FineractApiManager::class, - SelfServiceApiManager::class, - KtorAuthenticationService::class, - SavedStateHandle::class, - Context::class, - ), - ) - koinModules.coreDataStoreModules.verify( - extraTypes = listOf( - PreferencesHelper::class, - Context::class, - ), - ) - koinModules.mifosPayModule.verify( - extraTypes = listOf( - UserDataRepository::class, - PasscodeManager::class, - Context::class, - ), - ) - koinModules.dataModules.verify( - extraTypes = listOf( - FineractApiManager::class, - SelfServiceApiManager::class, - KtorAuthenticationService::class, - PreferencesHelper::class, - Map::class, - ), - ) - } -} diff --git a/scripts/pre-commit.sh b/scripts/pre-commit.sh index c49bfe109..2f87f220e 100644 --- a/scripts/pre-commit.sh +++ b/scripts/pre-commit.sh @@ -74,26 +74,6 @@ run_detekt_checks() { fi } -# Function to run Version Catalog checks -run_version_catalog_checks() { - echo "\nšŸš€ Version catalog linter is now analyzing your catalog for potential issues!" - ./gradlew formatVersionCatalog > /tmp/catalog-result - DETEKT_EXIT_CODE=$? - - if [ ${DETEKT_EXIT_CODE} -ne 0 ]; then - cat /tmp/catalog-result - rm /tmp/catalog-result - echo "\n*********************************************************************************" - echo " šŸ’„ Oh no! Version Catalog found issues in the code! Time to fix those issues! šŸ’„" - echo " šŸ’” Tip: Review the Version Catalog logs to resolve these issues. šŸ› ļø" - echo "*********************************************************************************" - exit ${DETEKT_EXIT_CODE} - else - rm /tmp/catalog-result - echo "šŸŽ‰ Fantastic work! Your Version catalog has been formatted successfully šŸš€šŸŒŸ" - fi -} - # Function to print success message print_success_message() { GIT_USERNAME=$(git config user.name) @@ -109,7 +89,6 @@ check_current_branch run_spotless_checks run_detekt_checks run_dependency_guard -run_version_catalog_checks print_success_message exit 0 diff --git a/scripts/pre-push.sh b/scripts/pre-push.sh index cad5ba9a1..d628bc07b 100644 --- a/scripts/pre-push.sh +++ b/scripts/pre-push.sh @@ -80,29 +80,6 @@ run_dependency_guard() { fi } -# Function to run Version Catalog checks -run_version_catalog_checks() { - echo "\nšŸš€ Version catalog linter is now analyzing your catalog for potential issues!" - ./gradlew checkVersionCatalog > /tmp/catalog-result - DETEKT_EXIT_CODE=$? - - if [ ${DETEKT_EXIT_CODE} -ne 0 ]; then - cat /tmp/catalog-result - rm /tmp/catalog-result - echo "\n*********************************************************************************" - echo " šŸ’„ Oh no! Version Catalog found issues in the code! Time to fix those issues! šŸ’„" - echo " šŸ’” Tip: Review the Version Catalog logs to resolve these issues. šŸ› ļø" - echo "*********************************************************************************" - echo "šŸš€ Attempting to format the Version Catalog again..." - ./gradlew formatVersionCatalog > /tmp/catalog-result - rm /tmp/catalog-result - echo "šŸŽ‰ Fantastic work! Your Version catalog has been formatted successfully šŸš€šŸŒŸ" - else - rm /tmp/catalog-result - echo "šŸŽ‰ Fantastic work! Your Version catalog has been formatted properly šŸš€šŸŒŸ" - fi -} - # Function to print success message print_success_message() { GIT_USERNAME=$(git config user.name) @@ -118,7 +95,6 @@ check_current_branch run_spotless_checks run_detekt_checks run_dependency_guard -run_version_catalog_checks print_success_message exit 0 diff --git a/settings.gradle.kts b/settings.gradle.kts index 9cb771d36..19df9d5f1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,7 +17,7 @@ dependencyResolutionManagement { } } - plugins { +plugins { id("org.gradle.toolchains.foojay-resolver-convention") version("0.8.0") id("org.ajoberstar.reckon.settings") version("0.18.3") } @@ -34,9 +34,14 @@ extensions.configure { rootProject.name = "mobile-wallet" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") -include(":mifospay") + +include(":mifospay-shared") +include(":mifospay-android") +include(":mifospay-desktop") +include(":mifospay-web") include(":core:data") +include(":core:domain") include(":core:datastore") include(":core:designsystem") include(":core:ui") @@ -47,8 +52,6 @@ include(":core:model") include(":core:datastore-proto") include(":core:analytics") -include(":lint") - include(":feature:home") include(":feature:history") include(":feature:receipt") @@ -72,12 +75,5 @@ include(":feature:payments") include(":feature:request-money") include(":feature:upi-setup") include(":feature:qr") -include(":feature:search") -include(":libs:country-code-picker") -include(":libs:pullrefresh") -include(":libs:material3-navigation") include(":libs:mifos-passcode") - -include(":shared") -include(":desktop") diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts deleted file mode 100644 index fec478782..000000000 --- a/shared/build.gradle.kts +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -plugins { - alias(libs.plugins.kotlinMultiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.compose.compiler) - alias(libs.plugins.jetbrainsCompose) - alias(libs.plugins.wire) - id("kotlin-parcelize") -} - -kotlin { - androidTarget { - @OptIn(ExperimentalKotlinGradlePluginApi::class) - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } - } - - jvm("desktop") - - listOf( - iosX64(), - iosArm64(), - iosSimulatorArm64() - ).forEach { - it.binaries.framework { - baseName = "shared" - isStatic = true - } - } - - sourceSets { - androidMain.dependencies { - implementation(compose.preview) - implementation(libs.androidx.activity.compose) - - implementation(libs.koin.android) - implementation(libs.koin.androidx.compose) - } - - commonMain.dependencies { - //put your multiplatform dependencies here - implementation(compose.runtime) - implementation(compose.material3) - implementation(compose.ui) - implementation(compose.components.resources) - implementation(compose.components.uiToolingPreview) - - implementation(libs.kotlinx.datetime) - implementation(libs.kotlinx.serialization.json) - - api(libs.koin.core) - implementation(libs.koin.compose) - - implementation(libs.datastore) - } - - val desktopMain by getting { - dependencies { - // Desktop specific dependencies - implementation(compose.desktop.currentOs) - implementation(compose.desktop.common) - } - } - } - - task("testClasses") -} - -wire { - kotlin {} - sourcePath { - srcDir("src/commonMain/proto") - } -} - -android { - namespace = "org.mifospay.shared" - compileSdk = 34 - - defaultConfig { - minSdk = 24 - } - - packaging { - resources { - excludes += "/META-INF/{AL2.0,LGPL2.1}" - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - - dependencies { - debugImplementation(compose.uiTooling) - } -} diff --git a/shared/src/androidMain/kotlin/org/mifospay/shared/MainActivity.kt b/shared/src/androidMain/kotlin/org/mifospay/shared/MainActivity.kt deleted file mode 100644 index e65339b5a..000000000 --- a/shared/src/androidMain/kotlin/org/mifospay/shared/MainActivity.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared - -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.compose.runtime.Composable -import androidx.compose.ui.tooling.preview.Preview - -class MainActivity : ComponentActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - setContent { - App() - } - } -} - -@Preview -@Composable -fun AppAndroidPreview() { - App() -} diff --git a/shared/src/androidMain/kotlin/org/mifospay/shared/Platform.android.kt b/shared/src/androidMain/kotlin/org/mifospay/shared/Platform.android.kt deleted file mode 100644 index 909044b97..000000000 --- a/shared/src/androidMain/kotlin/org/mifospay/shared/Platform.android.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared - -import android.os.Parcelable -import kotlinx.parcelize.Parcelize - -class AndroidPlatform : Platform { - override val name: String = "Android ${android.os.Build.VERSION.SDK_INT}" -} - -actual fun getPlatform(): Platform = AndroidPlatform() - -actual typealias CommonParcelize = Parcelize -actual typealias CommonParcelable = Parcelable diff --git a/shared/src/androidMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.android.kt b/shared/src/androidMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.android.kt deleted file mode 100644 index 7976d9c2b..000000000 --- a/shared/src/androidMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.android.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared.preferences - -import androidx.datastore.core.DataStore -import okio.FileSystem -import okio.Path.Companion.toPath -import org.mifospay.shared.commonMain.proto.UserPreferences -import org.mifospay.shared.di.AndroidPlatformContextProvider - -actual fun getDataStore(): DataStore { - val content = requireNotNull(AndroidPlatformContextProvider.context) - val producePath = { content.filesDir.resolve(DATA_STORE_FILE_NAME).absolutePath.toPath() } - - return createDataStore(fileSystem = FileSystem.SYSTEM, producePath = producePath) -} diff --git a/shared/src/commonMain/kotlin/org/mifospay/shared/App.kt b/shared/src/commonMain/kotlin/org/mifospay/shared/App.kt deleted file mode 100644 index 8e9fb5365..000000000 --- a/shared/src/commonMain/kotlin/org/mifospay/shared/App.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import org.koin.compose.KoinContext - -@Composable -fun App() { - KoinContext { - Box( - modifier = Modifier - .fillMaxSize(), - contentAlignment = Alignment.Center, - ) { - Text( - text = "MifosWallet", - style = MaterialTheme.typography.titleLarge.copy(fontWeight = FontWeight.Bold), - color = MaterialTheme.colorScheme.onSurface, - ) - } - } -} diff --git a/shared/src/commonMain/kotlin/org/mifospay/shared/Platform.kt b/shared/src/commonMain/kotlin/org/mifospay/shared/Platform.kt deleted file mode 100644 index 00ed0030d..000000000 --- a/shared/src/commonMain/kotlin/org/mifospay/shared/Platform.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared - -interface Platform { - val name: String -} - -expect fun getPlatform(): Platform - -// For Android @Parcelize -@OptIn(ExperimentalMultiplatform::class) -@OptionalExpectation -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.BINARY) -expect annotation class CommonParcelize() - -// For Android Parcelable -expect interface CommonParcelable diff --git a/shared/src/commonMain/kotlin/org/mifospay/shared/di/KoinModule.kt b/shared/src/commonMain/kotlin/org/mifospay/shared/di/KoinModule.kt deleted file mode 100644 index 1af847cd6..000000000 --- a/shared/src/commonMain/kotlin/org/mifospay/shared/di/KoinModule.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared.di - -import org.koin.core.context.startKoin -import org.koin.dsl.KoinAppDeclaration - -fun initKoin(config: KoinAppDeclaration? = null) { - startKoin { - config?.invoke(this) - modules(sharedModule, platformModule) - } -} diff --git a/shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/Client.kt b/shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/Client.kt deleted file mode 100644 index 60f1e2d05..000000000 --- a/shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/Client.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared.modal.domain - -data class Client( - var name: String? = null, - var image: String, - var externalId: String? = null, - var clientId: Long = 0L, - var displayName: String, - var mobileNo: String, -) diff --git a/shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/Role.kt b/shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/Role.kt deleted file mode 100644 index 29bd13e8d..000000000 --- a/shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/Role.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared.modal.domain - -data class Role( - var id: String? = null, - var name: String? = null, - var description: String? = null, - val disabled: Boolean, -) diff --git a/shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/UserData.kt b/shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/UserData.kt deleted file mode 100644 index 4191ecd67..000000000 --- a/shared/src/commonMain/kotlin/org/mifospay/shared/modal/domain/UserData.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared.modal.domain - -data class UserData( - val authToken: String, - val user: String, - val userEmail: String, - val client: String, -) diff --git a/shared/src/commonMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.kt b/shared/src/commonMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.kt deleted file mode 100644 index 2c7fbe6f2..000000000 --- a/shared/src/commonMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared.preferences - -import androidx.datastore.core.DataStore -import androidx.datastore.core.DataStoreFactory -import androidx.datastore.core.okio.OkioStorage -import okio.FileSystem -import okio.Path -import org.mifospay.shared.commonMain.proto.UserPreferences -internal const val DATA_STORE_FILE_NAME = "user.preferences_pb" - -expect fun getDataStore(): DataStore - -fun createDataStore( - fileSystem: FileSystem, - producePath: () -> Path, -): DataStore = - DataStoreFactory.create( - storage = OkioStorage( - fileSystem = fileSystem, - producePath = producePath, - serializer = UserPreferenceSerializer, - ), - ) diff --git a/shared/src/commonMain/kotlin/org/mifospay/shared/preferences/UserPreferenceRepository.kt b/shared/src/commonMain/kotlin/org/mifospay/shared/preferences/UserPreferenceRepository.kt deleted file mode 100644 index 294905f01..000000000 --- a/shared/src/commonMain/kotlin/org/mifospay/shared/preferences/UserPreferenceRepository.kt +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared.preferences - -import androidx.datastore.core.DataStore -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map -import org.mifospay.shared.commonMain.proto.Client -import org.mifospay.shared.commonMain.proto.User -import org.mifospay.shared.commonMain.proto.UserPreferences - -interface UserPreferenceRepository { - suspend fun saveToken(token: String) - fun getToken(): Flow - suspend fun saveFullName(name: String) - fun getFullName(): Flow - suspend fun saveUsername(name: String) - fun getUsername(): Flow - suspend fun saveEmail(email: String) - fun getEmail(): Flow - suspend fun saveMobile(mobile: String) - fun getMobile(): Flow - fun getUserId(): Flow - suspend fun setUserId(id: Int) - fun getClientId(): Flow - suspend fun setClientId(clientId: Int) - fun getClientVpa(): Flow - suspend fun setClientVpa(vpa: String) - fun getAccountId(): Flow - suspend fun setAccountId(accountId: Int) - fun getFirebaseRegId(): Flow - suspend fun setFirebaseRegId(firebaseRegId: String) - fun getUser(): Flow - suspend fun setUser(user: User) - fun getClient(): Flow - suspend fun setClient(client: Client) -} - -class UserPreferenceRepositoryImpl( - private val dataStore: DataStore = getDataStore(), -) : UserPreferenceRepository { - - override suspend fun saveToken(token: String) { - dataStore.updateData { preferences -> - preferences.copy(token = token) - } - } - - override fun getToken(): Flow { - return dataStore.data.map { it.token } - } - - override suspend fun saveFullName(name: String) { - dataStore.updateData { preferences -> - preferences.copy(name = name) - } - } - - override fun getFullName(): Flow { - return dataStore.data.map { it.name } - } - - override suspend fun saveUsername(name: String) { - dataStore.updateData { preferences -> - preferences.copy(username = name) - } - } - - override fun getUsername(): Flow { - return dataStore.data.map { it.username } - } - - override suspend fun saveEmail(email: String) { - dataStore.updateData { preferences -> - preferences.copy(email = email) - } - } - - override fun getEmail(): Flow { - return dataStore.data.map { it.email } - } - - override suspend fun saveMobile(mobile: String) { - dataStore.updateData { preferences -> - preferences.copy(mobile_no = mobile) - } - } - - override fun getMobile(): Flow { - return dataStore.data.map { it.mobile_no } - } - - override fun getUserId(): Flow { - return dataStore.data.map { it.user_id } - } - - override suspend fun setUserId(id: Int) { - dataStore.updateData { preferences -> - preferences.copy(user_id = id) - } - } - - override fun getClientId(): Flow { - return dataStore.data.map { it.client_id } - } - - override suspend fun setClientId(clientId: Int) { - dataStore.updateData { preferences -> - preferences.copy(client_id = clientId) - } - } - - override fun getClientVpa(): Flow { - return dataStore.data.map { it.client_vpa } - } - - override suspend fun setClientVpa(vpa: String) { - dataStore.updateData { preferences -> - preferences.copy(client_vpa = vpa) - } - } - - override fun getAccountId(): Flow { - return dataStore.data.map { it.account_id } - } - - override suspend fun setAccountId(accountId: Int) { - dataStore.updateData { preferences -> - preferences.copy(account_id = accountId) - } - } - - override fun getFirebaseRegId(): Flow { - return dataStore.data.map { it.firebase_reg_id } - } - - override suspend fun setFirebaseRegId(firebaseRegId: String) { - dataStore.updateData { preferences -> - preferences.copy(firebase_reg_id = firebaseRegId) - } - } - - override fun getUser(): Flow { - return dataStore.data.map { it.user!! } - } - - override suspend fun setUser(user: User) { - dataStore.updateData { preferences -> - preferences.copy(user = user) - } - } - - override fun getClient(): Flow { - return dataStore.data.map { it.client!! } - } - - override suspend fun setClient(client: Client) { - dataStore.updateData { preferences -> - preferences.copy(client = client) - } - } -} diff --git a/shared/src/commonMain/kotlin/org/mifospay/shared/preferences/UserPreferenceSerializer.kt b/shared/src/commonMain/kotlin/org/mifospay/shared/preferences/UserPreferenceSerializer.kt deleted file mode 100644 index 803b106af..000000000 --- a/shared/src/commonMain/kotlin/org/mifospay/shared/preferences/UserPreferenceSerializer.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared.preferences - -import androidx.datastore.core.okio.OkioSerializer -import okio.BufferedSink -import okio.BufferedSource -import okio.IOException -import org.mifospay.shared.commonMain.proto.UserPreferences - -object UserPreferenceSerializer : OkioSerializer { - override val defaultValue: UserPreferences - get() = UserPreferences() - - override suspend fun readFrom(source: BufferedSource): UserPreferences { - try { - return UserPreferences.ADAPTER.decode(source) - } catch (exception: IOException) { - throw Exception(exception.message ?: "Serialization Exception") - } - } - - override suspend fun writeTo(t: UserPreferences, sink: BufferedSink) { - sink.write(t.encode()) - } -} diff --git a/shared/src/commonMain/proto/user_preferences.proto b/shared/src/commonMain/proto/user_preferences.proto deleted file mode 100644 index 1a7a43dc5..000000000 --- a/shared/src/commonMain/proto/user_preferences.proto +++ /dev/null @@ -1,49 +0,0 @@ -syntax = "proto3"; - -option java_package = "org.mifospay.shared.commonMain.proto"; -option java_multiple_files = true; - -message UserPreferences { - string token = 1; - string name = 2; - string username = 3; - string email = 4; - string mobile_no = 5; - int32 user_id = 6; - int32 client_id = 7; - string client_vpa = 8; - int32 account_id = 9; - string firebase_reg_id = 10; - Client client = 11; - User user = 12; -} - -message Client { - string name = 1; - string image = 2; - string external_id = 3; - int64 clientId = 4; - string display_name = 5; - string mobileNo = 6; -} - -message User { - string username = 1; - int64 userId = 2; - string base64EncodedAuthenticationKey = 3; - bool authenticated = 4; - int32 officeId = 5; - string officeName = 6; - repeated Role roles = 7; - repeated string permissions = 8; - repeated int64 clients = 9; - bool shouldRenewPassword = 10; - bool isTwoFactorAuthenticationRequired = 11; -} - -message Role { - string id = 1; - string name = 2; - string description = 3; - bool disabled = 4; -} \ No newline at end of file diff --git a/shared/src/desktopMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.desktop.kt b/shared/src/desktopMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.desktop.kt deleted file mode 100644 index 64fe263b0..000000000 --- a/shared/src/desktopMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.desktop.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared.preferences - -import androidx.datastore.core.DataStore -import okio.FileSystem -import okio.Path.Companion.toPath -import org.mifospay.shared.commonMain.proto.UserPreferences -import java.io.File - -actual fun getDataStore(): DataStore { - val dbFile = File(System.getProperty("java.io.tmpdir"), DATA_STORE_FILE_NAME) - - return createDataStore( - fileSystem = FileSystem.SYSTEM, - producePath = { dbFile.absolutePath.toPath() }, - ) -} diff --git a/shared/src/iosMain/kotlin/org/mifospay/shared/MainViewController.kt b/shared/src/iosMain/kotlin/org/mifospay/shared/MainViewController.kt deleted file mode 100644 index 1f5f6765a..000000000 --- a/shared/src/iosMain/kotlin/org/mifospay/shared/MainViewController.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared - -import androidx.compose.ui.window.ComposeUIViewController -import org.mifospay.shared.di.initKoin - -fun mainViewController() = ComposeUIViewController( - configure = { - initKoin() - }, -) { - App() -} diff --git a/shared/src/iosMain/kotlin/org/mifospay/shared/Platform.ios.kt b/shared/src/iosMain/kotlin/org/mifospay/shared/Platform.ios.kt deleted file mode 100644 index 22fb77da7..000000000 --- a/shared/src/iosMain/kotlin/org/mifospay/shared/Platform.ios.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared - -import platform.UIKit.UIDevice - -class IOSPlatform : Platform { - override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion -} - -actual fun getPlatform(): Platform = IOSPlatform() - -actual interface CommonParcelable diff --git a/shared/src/iosMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.ios.kt b/shared/src/iosMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.ios.kt deleted file mode 100644 index 6e7e19d38..000000000 --- a/shared/src/iosMain/kotlin/org/mifospay/shared/preferences/DataStoreModule.ios.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md - */ -package org.mifospay.shared.preferences - -import androidx.datastore.core.DataStore -import okio.FileSystem -import okio.Path.Companion.toPath -import org.mifospay.shared.commonMain.proto.UserPreferences - -actual fun getDataStore(): DataStore { - return createDataStore( - fileSystem = FileSystem.SYSTEM, - producePath = { "${documentDirectory()}/$DATA_STORE_FILE_NAME".toPath() }, - ) -} - -private fun documentDirectory(): String { - val documentDirectory = NSFileManager.defaultManager.URLForDirectory( - directory = NSDocumentDirectory, - inDomain = NSUserDomainMask, - appropriateForURL = null, - create = false, - error = null, - ) - return requireNotNull(documentDirectory?.path) -}