From 6e17bbb3dca6de068a7c3f71a18b2ff91af91acd Mon Sep 17 00:00:00 2001 From: Rajan Maurya Date: Sun, 28 Jan 2024 08:44:28 -0500 Subject: [PATCH] fix: login and refactor code architecture --- .../kotlin/AndroidFeatureConventionPlugin.kt | 3 + build.gradle.kts | 1 + .../core/data/fineract/api/ApiInterceptor.kt | 53 +-- .../data/fineract/api/FineractApiManager.kt | 266 ++++-------- .../fineract/api/MifosWalletOkHttpClient.kt | 75 ++++ .../fineract/api/SelfServiceApiManager.kt | 122 ++---- .../data/fineract}/local/PreferencesHelper.kt | 2 +- .../fineract/repository/FineractRepository.kt | 398 +++++++++--------- .../mifos/mobilewallet/core/di/Qualifier.kt | 11 + feature/auth/.gitignore | 1 + feature/auth/build.gradle.kts | 22 + feature/auth/consumer-rules.pro | 0 feature/auth/proguard-rules.pro | 21 + .../mifospay/auth/ExampleInstrumentedTest.kt | 24 ++ feature/auth/src/main/AndroidManifest.xml | 4 + .../mifospay/auth/login/AuthContract.kt | 24 ++ .../mifospay/auth/login/LoginActivity.kt | 158 +++++++ .../mifospay/auth/login/LoginScreen.kt | 172 ++++++++ .../mifospay/auth/login/LoginViewModel.kt | 111 +++++ feature/auth/src/main/res/values/strings.xml | 8 + .../mifospay/auth/ExampleUnitTest.kt | 17 + gradle/libs.versions.toml | 10 +- main-core/common/.gitignore | 1 + main-core/common/build.gradle.kts | 44 ++ main-core/common/consumer-rules.pro | 0 main-core/common/proguard-rules.pro | 21 + .../common/ExampleInstrumentedTest.kt | 24 ++ main-core/common/src/main/AndroidManifest.xml | 4 + .../mobilewallet/mifospay/common/DebugUtil.kt | 17 + .../mifospay/common/ExampleUnitTest.kt | 17 + main-core/data/.gitignore | 1 + main-core/data/build.gradle.kts | 29 ++ main-core/data/proguard-rules.pro | 21 + .../mifospay/data/ExampleInstrumentedTest.kt | 24 ++ main-core/data/src/main/AndroidManifest.xml | 12 + .../mifospay/data/ExampleUnitTest.kt | 17 + .../datastore/PreferencesHelper.kt | 122 ++++++ main-core/designsystem/.gitignore | 1 + main-core/designsystem/build.gradle.kts | 25 ++ main-core/designsystem/consumer-rules.pro | 0 main-core/designsystem/proguard-rules.pro | 21 + .../designsystem/ExampleInstrumentedTest.kt | 24 ++ .../designsystem/src/main/AndroidManifest.xml | 4 + .../designsystem/component/TextField.kt | 68 +++ .../mifospay/designsystem/theme/Color.kt | 19 + .../designsystem/theme/MifosTextStyle.kt | 27 ++ .../mifospay/designsystem/theme/Theme.kt | 67 +++ .../mifospay/designsystem/theme/Type.kt | 34 ++ .../mifospay/designsystem/ExampleUnitTest.kt | 17 + main-core/ui/.gitignore | 1 + main-core/ui/build.gradle.kts | 44 ++ main-core/ui/consumer-rules.pro | 0 main-core/ui/proguard-rules.pro | 21 + .../mifospay/ui/ExampleInstrumentedTest.kt | 24 ++ main-core/ui/src/main/AndroidManifest.xml | 4 + .../mifospay/ui/ExampleUnitTest.kt | 17 + mifospay/build.gradle.kts | 2 +- .../mifospay/auth/presenter/LoginPresenter.kt | 7 +- .../mifospay/data/local/LocalRepository.kt | 1 + .../mifospay/di/ApplicationModule.kt | 94 ++++- .../mobilewallet/mifospay/di/NetworkModule.kt | 220 ++++++++++ .../presenter/EditProfilePresenter.kt | 2 +- .../mifospay/home/presenter/HomeViewModel.kt | 2 +- .../home/presenter/ProfilePresenter.kt | 2 +- .../invoice/presenter/InvoicePresenter.kt | 2 +- .../invoice/presenter/InvoicesPresenter.kt | 2 +- .../kyc/presenter/KYCLevel2Presenter.kt | 2 +- .../presenter/MerchantTransferPresenter.kt | 2 +- .../passcode/presenter/PassCodePresenter.kt | 12 +- .../mifospay/passcode/ui/PassCodeActivity.kt | 1 - .../presenter/EditPasswordPresenter.kt | 2 +- .../receipt/presenter/ReceiptPresenter.kt | 2 +- .../registration/presenter/SignupPresenter.kt | 6 +- .../presenter/NewSIPresenter.kt | 5 +- settings.gradle.kts | 5 + 75 files changed, 2100 insertions(+), 546 deletions(-) create mode 100644 core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/MifosWalletOkHttpClient.kt rename {mifospay/src/main/java/org/mifos/mobilewallet/mifospay/data => core/src/main/java/org/mifos/mobilewallet/core/data/fineract}/local/PreferencesHelper.kt (98%) create mode 100644 core/src/main/java/org/mifos/mobilewallet/core/di/Qualifier.kt create mode 100644 feature/auth/.gitignore create mode 100644 feature/auth/build.gradle.kts create mode 100644 feature/auth/consumer-rules.pro create mode 100644 feature/auth/proguard-rules.pro create mode 100644 feature/auth/src/androidTest/java/org/mifos/mobilewallet/mifospay/auth/ExampleInstrumentedTest.kt create mode 100644 feature/auth/src/main/AndroidManifest.xml create mode 100644 feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/AuthContract.kt create mode 100644 feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginActivity.kt create mode 100644 feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginScreen.kt create mode 100644 feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginViewModel.kt create mode 100644 feature/auth/src/main/res/values/strings.xml create mode 100644 feature/auth/src/test/java/org/mifos/mobilewallet/mifospay/auth/ExampleUnitTest.kt create mode 100644 main-core/common/.gitignore create mode 100644 main-core/common/build.gradle.kts create mode 100644 main-core/common/consumer-rules.pro create mode 100644 main-core/common/proguard-rules.pro create mode 100644 main-core/common/src/androidTest/java/org/mifos/mobilewallet/mifospay/common/ExampleInstrumentedTest.kt create mode 100644 main-core/common/src/main/AndroidManifest.xml create mode 100644 main-core/common/src/main/java/org/mifos/mobilewallet/mifospay/common/DebugUtil.kt create mode 100644 main-core/common/src/test/java/org/mifos/mobilewallet/mifospay/common/ExampleUnitTest.kt create mode 100644 main-core/data/.gitignore create mode 100644 main-core/data/build.gradle.kts create mode 100644 main-core/data/proguard-rules.pro create mode 100644 main-core/data/src/androidTest/java/org/mifos/mobilewallet/mifospay/data/ExampleInstrumentedTest.kt create mode 100644 main-core/data/src/main/AndroidManifest.xml create mode 100644 main-core/data/src/test/java/org/mifos/mobilewallet/mifospay/data/ExampleUnitTest.kt create mode 100644 main-core/datastore/src/main/java/org/mifos/mobilewallet/datastore/PreferencesHelper.kt create mode 100644 main-core/designsystem/.gitignore create mode 100644 main-core/designsystem/build.gradle.kts create mode 100644 main-core/designsystem/consumer-rules.pro create mode 100644 main-core/designsystem/proguard-rules.pro create mode 100644 main-core/designsystem/src/androidTest/java/org/mifos/mobilewallet/mifospay/designsystem/ExampleInstrumentedTest.kt create mode 100644 main-core/designsystem/src/main/AndroidManifest.xml create mode 100644 main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/component/TextField.kt create mode 100644 main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Color.kt create mode 100644 main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/MifosTextStyle.kt create mode 100644 main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Theme.kt create mode 100644 main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Type.kt create mode 100644 main-core/designsystem/src/test/java/org/mifos/mobilewallet/mifospay/designsystem/ExampleUnitTest.kt create mode 100644 main-core/ui/.gitignore create mode 100644 main-core/ui/build.gradle.kts create mode 100644 main-core/ui/consumer-rules.pro create mode 100644 main-core/ui/proguard-rules.pro create mode 100644 main-core/ui/src/androidTest/java/org/mifos/mobilewallet/mifospay/ui/ExampleInstrumentedTest.kt create mode 100644 main-core/ui/src/main/AndroidManifest.xml create mode 100644 main-core/ui/src/test/java/org/mifos/mobilewallet/mifospay/ui/ExampleUnitTest.kt create mode 100644 mifospay/src/main/java/org/mifos/mobilewallet/mifospay/di/NetworkModule.kt diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt index 6613433d5..c16daae4d 100644 --- a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt @@ -20,6 +20,9 @@ class AndroidFeatureConventionPlugin : Plugin { } dependencies { + add("implementation", project(":main-core:ui")) + add("implementation", project(":main-core:designsystem")) + add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get()) add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get()) add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get()) diff --git a/build.gradle.kts b/build.gradle.kts index c5507a374..eb7590ace 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,4 +27,5 @@ plugins { 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 } \ No newline at end of file diff --git a/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/ApiInterceptor.kt b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/ApiInterceptor.kt index e1a5739bc..c142810e3 100644 --- a/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/ApiInterceptor.kt +++ b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/ApiInterceptor.kt @@ -1,41 +1,30 @@ -package org.mifos.mobilewallet.core.data.fineract.api; +package org.mifos.mobilewallet.core.data.fineract.api -import android.text.TextUtils; - -import java.io.IOException; - -import okhttp3.Interceptor; -import okhttp3.Request; -import okhttp3.Request.Builder; -import okhttp3.Response; +import android.text.TextUtils +import okhttp3.Interceptor +import okhttp3.Response +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper +import java.io.IOException /** * Created by naman on 17/6/17. */ - -public class ApiInterceptor implements Interceptor { - - public static final String HEADER_TENANT = "Fineract-Platform-TenantId"; - public static final String HEADER_AUTH = "Authorization"; - private String authToken; - private String headerTenant; - - public ApiInterceptor(String authToken, String headerTenant) { - this.authToken = authToken; - this.headerTenant = headerTenant; - } - - @Override - public Response intercept(Chain chain) throws IOException { - Request chainRequest = chain.request(); - Builder builder = chainRequest.newBuilder() - .header(HEADER_TENANT, headerTenant); - - if (!TextUtils.isEmpty(authToken)) { - builder.header(HEADER_AUTH, authToken); +class ApiInterceptor(val preferencesHelper: PreferencesHelper) : Interceptor { + @Throws(IOException::class) + override fun intercept(chain: Interceptor.Chain): Response { + val chainRequest = chain.request() + val builder = chainRequest.newBuilder().header(HEADER_TENANT, DEFAULT) + val authToken = preferencesHelper.token + if (!authToken.isNullOrEmpty()) { + builder.header(HEADER_AUTH, authToken) } + val request = builder.build() + return chain.proceed(request) + } - Request request = builder.build(); - return chain.proceed(request); + companion object { + const val HEADER_TENANT = "Fineract-Platform-TenantId" + const val HEADER_AUTH = "Authorization" + const val DEFAULT = "default" } } diff --git a/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/FineractApiManager.kt b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/FineractApiManager.kt index 6a473e369..6cb0fba33 100644 --- a/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/FineractApiManager.kt +++ b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/FineractApiManager.kt @@ -1,190 +1,90 @@ -package org.mifos.mobilewallet.core.data.fineract.api; - -import android.util.Base64; - -import org.mifos.mobilewallet.core.data.fineract.api.services.AccountTransfersService; -import org.mifos.mobilewallet.core.data.fineract.api.services.AuthenticationService; -import org.mifos.mobilewallet.core.data.fineract.api.services.ClientService; -import org.mifos.mobilewallet.core.data.fineract.api.services.DocumentService; -import org.mifos.mobilewallet.core.data.fineract.api.services.InvoiceService; -import org.mifos.mobilewallet.core.data.fineract.api.services.KYCLevel1Service; -import org.mifos.mobilewallet.core.data.fineract.api.services.NotificationService; -import org.mifos.mobilewallet.core.data.fineract.api.services.RegistrationService; -import org.mifos.mobilewallet.core.data.fineract.api.services.RunReportService; -import org.mifos.mobilewallet.core.data.fineract.api.services.SavedCardService; -import org.mifos.mobilewallet.core.data.fineract.api.services.SavingsAccountsService; -import org.mifos.mobilewallet.core.data.fineract.api.services.SearchService; -import org.mifos.mobilewallet.core.data.fineract.api.services.StandingInstructionService; -import org.mifos.mobilewallet.core.data.fineract.api.services.ThirdPartyTransferService; -import org.mifos.mobilewallet.core.data.fineract.api.services.TwoFactorAuthService; -import org.mifos.mobilewallet.core.data.fineract.api.services.UserService; -import org.mifos.mobilewallet.core.utils.Constants; - -import java.nio.charset.Charset; -import java.util.concurrent.TimeUnit; - -import okhttp3.OkHttpClient; -import okhttp3.logging.HttpLoggingInterceptor; -import retrofit2.Retrofit; -import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; -import retrofit2.converter.gson.GsonConverterFactory; +package org.mifos.mobilewallet.core.data.fineract.api + +import org.mifos.mobilewallet.core.data.fineract.api.services.AccountTransfersService +import org.mifos.mobilewallet.core.data.fineract.api.services.AuthenticationService +import org.mifos.mobilewallet.core.data.fineract.api.services.ClientService +import org.mifos.mobilewallet.core.data.fineract.api.services.DocumentService +import org.mifos.mobilewallet.core.data.fineract.api.services.InvoiceService +import org.mifos.mobilewallet.core.data.fineract.api.services.KYCLevel1Service +import org.mifos.mobilewallet.core.data.fineract.api.services.NotificationService +import org.mifos.mobilewallet.core.data.fineract.api.services.RegistrationService +import org.mifos.mobilewallet.core.data.fineract.api.services.RunReportService +import org.mifos.mobilewallet.core.data.fineract.api.services.SavedCardService +import org.mifos.mobilewallet.core.data.fineract.api.services.SavingsAccountsService +import org.mifos.mobilewallet.core.data.fineract.api.services.SearchService +import org.mifos.mobilewallet.core.data.fineract.api.services.StandingInstructionService +import org.mifos.mobilewallet.core.data.fineract.api.services.ThirdPartyTransferService +import org.mifos.mobilewallet.core.data.fineract.api.services.TwoFactorAuthService +import org.mifos.mobilewallet.core.data.fineract.api.services.UserService +import javax.inject.Inject /** * Created by naman on 17/6/17. */ +class FineractApiManager @Inject constructor( + private val authenticationService: AuthenticationService, + private val clientService: ClientService, + private val savingsAccountsService: SavingsAccountsService, + private val registrationService: RegistrationService, + private val searchService: SearchService, + private val documentService: DocumentService, + private val runReportService: RunReportService, + private val twoFactorAuthService: TwoFactorAuthService, + private val accountTransfersService: AccountTransfersService, + private val savedCardService: SavedCardService, + private val kYCLevel1Service: KYCLevel1Service, + private val invoiceService: InvoiceService, + private val userService: UserService, + private val thirdPartyTransferService: ThirdPartyTransferService, + private val standingInstructionService: StandingInstructionService, + private val notificationService: NotificationService, +) { -public class FineractApiManager { - - public static final String DEFAULT = "default"; - public static final String BASIC = "Basic "; - private static BaseURL baseUrl = new BaseURL(); - private static final String BASE_URL = baseUrl.getUrl(); - - private static Retrofit retrofit; - private static AuthenticationService authenticationApi; - private static ClientService clientsApi; - private static SavingsAccountsService savingsAccountsApi; - private static RegistrationService registrationAPi; - private static SearchService searchApi; - private static SavedCardService savedCardApi; - private static DocumentService documentApi; - private static TwoFactorAuthService twoFactorAuthApi; - private static AccountTransfersService accountTransfersApi; - private static RunReportService runReportApi; - private static KYCLevel1Service kycLevel1Api; - private static InvoiceService invoiceApi; - private static UserService userApi; - private static ThirdPartyTransferService thirdPartyTransferApi; - private static NotificationService notificationApi; - private static StandingInstructionService standingInstructionService; - private static SelfServiceApiManager sSelfInstance; - - public FineractApiManager() { - String authToken = BASIC + Base64.encodeToString(Constants.MIFOS_PASSWORD - .getBytes(Charset.forName("UTF-8")), Base64.NO_WRAP); - createService(authToken); - - if (sSelfInstance == null) { - sSelfInstance = new SelfServiceApiManager(); - } - } - - private static void init() { - authenticationApi = createApi(AuthenticationService.class); - clientsApi = createApi(ClientService.class); - savingsAccountsApi = createApi(SavingsAccountsService.class); - registrationAPi = createApi(RegistrationService.class); - searchApi = createApi(SearchService.class); - savedCardApi = createApi(SavedCardService.class); - documentApi = createApi(DocumentService.class); - twoFactorAuthApi = createApi(TwoFactorAuthService.class); - accountTransfersApi = createApi(AccountTransfersService.class); - runReportApi = createApi(RunReportService.class); - kycLevel1Api = createApi(KYCLevel1Service.class); - invoiceApi = createApi(InvoiceService.class); - userApi = createApi(UserService.class); - thirdPartyTransferApi = createApi(ThirdPartyTransferService.class); - notificationApi = createApi(NotificationService.class); - standingInstructionService = createApi(StandingInstructionService.class); - } - - private static T createApi(Class clazz) { - return retrofit.create(clazz); - } - - public static void createService(String authToken) { - - HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); - - OkHttpClient okHttpClient = new OkHttpClient.Builder() - .readTimeout(60, TimeUnit.SECONDS) - .connectTimeout(60, TimeUnit.SECONDS) - .writeTimeout(60, TimeUnit.SECONDS) - .addInterceptor(interceptor) - .addInterceptor(new ApiInterceptor(authToken, DEFAULT)) - .build(); - - retrofit = new Retrofit.Builder() - .baseUrl(BASE_URL) - .addConverterFactory(GsonConverterFactory.create()) - .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) - .client(okHttpClient) - .build(); - - init(); - } - - public static void createSelfService(String authToken) { - SelfServiceApiManager.createService(authToken); - } - - public static SelfServiceApiManager getSelfApiManager() { - return sSelfInstance; - } - - public AuthenticationService getAuthenticationApi() { - return authenticationApi; - } - - public ClientService getClientsApi() { - return clientsApi; - } - - public SavingsAccountsService getSavingAccountsListApi() { - return savingsAccountsApi; - } - - public RegistrationService getRegistrationAPi() { - return registrationAPi; - } - - public SearchService getSearchApi() { - return searchApi; - } - - public DocumentService getDocumentApi() { - return documentApi; - } - - public RunReportService getRunReportApi() { - return runReportApi; - } - - public TwoFactorAuthService getTwoFactorAuthApi() { - return twoFactorAuthApi; - } - - public AccountTransfersService getAccountTransfersApi() { - return accountTransfersApi; - } - - public SavedCardService getSavedCardApi() { - return savedCardApi; - } - - public KYCLevel1Service getKycLevel1Api() { - return kycLevel1Api; - } - - public InvoiceService getInvoiceApi() { - return invoiceApi; - } - - public UserService getUserApi() { - return userApi; - } - - public ThirdPartyTransferService getThirdPartyTransferApi() { - return thirdPartyTransferApi; - } - - public NotificationService getNotificationApi() { - return notificationApi; - } - - public StandingInstructionService getStandingInstructionApi() { - return standingInstructionService; - } + val authenticationApi: AuthenticationService + get() = authenticationService + val clientsApi: ClientService + get() = clientService + + val registrationAPi: RegistrationService + get() = registrationService + + val searchApi: SearchService + get() = searchService + + val documentApi: DocumentService + get() = documentService + + val runReportApi: RunReportService + get() = runReportService + + val twoFactorAuthApi: TwoFactorAuthService + get() = twoFactorAuthService + + val accountTransfersApi: AccountTransfersService + get() = accountTransfersService + + val savedCardApi: SavedCardService + get() = savedCardService + + val kycLevel1Api: KYCLevel1Service + get() = kYCLevel1Service + + val invoiceApi: InvoiceService + get() = invoiceService + + val userApi: UserService + get() = userService + + val thirdPartyTransferApi: ThirdPartyTransferService + get() = thirdPartyTransferService + + val notificationApi: NotificationService + get() = notificationService + + val savingsAccountsApi: SavingsAccountsService + get() = savingsAccountsService + + val standingInstructionApi: StandingInstructionService + get() = standingInstructionService } diff --git a/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/MifosWalletOkHttpClient.kt b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/MifosWalletOkHttpClient.kt new file mode 100644 index 000000000..35ba2a48f --- /dev/null +++ b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/MifosWalletOkHttpClient.kt @@ -0,0 +1,75 @@ +package org.mifos.mobilewallet.core.data.fineract.api + +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper +import java.security.SecureRandom +import java.security.cert.CertificateException +import java.security.cert.X509Certificate +import java.util.concurrent.TimeUnit +import javax.net.ssl.SSLContext +import javax.net.ssl.TrustManager +import javax.net.ssl.X509TrustManager + +class MifosWalletOkHttpClient(private val preferences: PreferencesHelper) { + // Create a trust manager that does not validate certificate chains + val mifosOkHttpClient: OkHttpClient + //Interceptor :> Full Body Logger and ApiRequest Header + get() { + val builder = OkHttpClient.Builder() + try { + // Create a trust manager that does not validate certificate chains + val trustAllCerts = arrayOf( + object : X509TrustManager { + @Throws(CertificateException::class) + override fun checkClientTrusted( + chain: Array, + authType: String + ) { + } + + @Throws(CertificateException::class) + override fun checkServerTrusted( + chain: Array, + authType: String + ) { + } + + override fun getAcceptedIssuers(): Array { + return emptyArray() + } + } + ) + + // Install the all-trusting trust manager + val sslContext = SSLContext.getInstance("SSL") + sslContext.init(null, trustAllCerts, SecureRandom()) + // Create an ssl socket factory with our all-trusting manager + val sslSocketFactory = sslContext.socketFactory + + //Enable Full Body Logging + val logger = HttpLoggingInterceptor() + logger.level = HttpLoggingInterceptor.Level.BODY + + //Set SSL certificate to OkHttpClient Builder +// builder.sslSocketFactory(sslSocketFactory) + builder.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager) + builder.hostnameVerifier { hostname, session -> true } + } catch (e: Exception) { + throw RuntimeException(e) + } + + // Enable Full Body Logging + val logger = HttpLoggingInterceptor() + logger.level = HttpLoggingInterceptor.Level.BODY + + // Setting Timeout 30 Seconds + builder.connectTimeout(60, TimeUnit.SECONDS) + builder.readTimeout(60, TimeUnit.SECONDS) + + // Interceptor :> Full Body Logger and ApiRequest Header + builder.addInterceptor(logger) + builder.addInterceptor(ApiInterceptor(preferences)) + return builder.build() + } +} diff --git a/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/SelfServiceApiManager.kt b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/SelfServiceApiManager.kt index 0141b3bd9..562fadb8a 100644 --- a/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/SelfServiceApiManager.kt +++ b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/api/SelfServiceApiManager.kt @@ -1,100 +1,34 @@ -package org.mifos.mobilewallet.core.data.fineract.api; +package org.mifos.mobilewallet.core.data.fineract.api -import org.mifos.mobilewallet.core.data.fineract.api.services.AuthenticationService; -import org.mifos.mobilewallet.core.data.fineract.api.services.BeneficiaryService; -import org.mifos.mobilewallet.core.data.fineract.api.services.ClientService; -import org.mifos.mobilewallet.core.data.fineract.api.services.RegistrationService; -import org.mifos.mobilewallet.core.data.fineract.api.services.SavingsAccountsService; -import org.mifos.mobilewallet.core.data.fineract.api.services.ThirdPartyTransferService; - -import java.util.concurrent.TimeUnit; - -import okhttp3.OkHttpClient; -import okhttp3.logging.HttpLoggingInterceptor; -import retrofit2.Retrofit; -import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; -import retrofit2.converter.gson.GsonConverterFactory; +import org.mifos.mobilewallet.core.data.fineract.api.services.AuthenticationService +import org.mifos.mobilewallet.core.data.fineract.api.services.BeneficiaryService +import org.mifos.mobilewallet.core.data.fineract.api.services.ClientService +import org.mifos.mobilewallet.core.data.fineract.api.services.RegistrationService +import org.mifos.mobilewallet.core.data.fineract.api.services.SavingsAccountsService +import org.mifos.mobilewallet.core.data.fineract.api.services.ThirdPartyTransferService +import javax.inject.Inject /** * Created by naman on 20/8/17. */ - -public class SelfServiceApiManager { - - public static final String DEFAULT = "default"; - private static BaseURL baseUrl = new BaseURL(); - private static final String BASE_URL = baseUrl.getSelfServiceUrl(); - - private static Retrofit retrofit; - private static AuthenticationService authenticationApi; - private static ClientService clientsApi; - private static SavingsAccountsService savingAccountsListApi; - private static RegistrationService registrationAPi; - private static BeneficiaryService beneficiaryApi; - private static ThirdPartyTransferService thirdPartyTransferApi; - - public SelfServiceApiManager() { - String authToken = ""; - createService(authToken); - } - - private static void init() { - authenticationApi = createApi(AuthenticationService.class); - clientsApi = createApi(ClientService.class); - savingAccountsListApi = createApi(SavingsAccountsService.class); - registrationAPi = createApi(RegistrationService.class); - beneficiaryApi = createApi(BeneficiaryService.class); - thirdPartyTransferApi = createApi(ThirdPartyTransferService.class); - } - - private static T createApi(Class clazz) { - return retrofit.create(clazz); - } - - public static void createService(String authToken) { - - HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); - - OkHttpClient okHttpClient = new OkHttpClient.Builder() - .readTimeout(60, TimeUnit.SECONDS) - .connectTimeout(60, TimeUnit.SECONDS) - .writeTimeout(60, TimeUnit.SECONDS) - .addInterceptor(interceptor) - .addInterceptor(new ApiInterceptor(authToken, DEFAULT)) - .build(); - - retrofit = new Retrofit.Builder() - .baseUrl(BASE_URL) - .addConverterFactory(GsonConverterFactory.create()) - .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) - .client(okHttpClient) - .build(); - init(); - } - - public AuthenticationService getAuthenticationApi() { - return authenticationApi; - } - - public ClientService getClientsApi() { - return clientsApi; - } - - public SavingsAccountsService getSavingAccountsListApi() { - return savingAccountsListApi; - } - - public RegistrationService getRegistrationAPi() { - return registrationAPi; - } - - public BeneficiaryService getBeneficiaryApi() { - return beneficiaryApi; - } - - public ThirdPartyTransferService getThirdPartyTransferApi() { - return thirdPartyTransferApi; - } - +class SelfServiceApiManager @Inject constructor( + private val authenticationService: AuthenticationService, + private val clientService: ClientService, + private val savingsAccountsService: SavingsAccountsService, + private val registrationService: RegistrationService, + private val beneficiaryService: BeneficiaryService, + private val thirdPartyTransferService: ThirdPartyTransferService, +) { + val authenticationApi: AuthenticationService + get() = authenticationService + val clientsApi: ClientService + get() = clientService + val savingAccountsListApi: SavingsAccountsService + get() = savingsAccountsService + val registrationAPi: RegistrationService + get() = registrationService + val beneficiaryApi: BeneficiaryService + get() = beneficiaryService + val thirdPartyTransferApi: ThirdPartyTransferService + get() = thirdPartyTransferService } diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/data/local/PreferencesHelper.kt b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/local/PreferencesHelper.kt similarity index 98% rename from mifospay/src/main/java/org/mifos/mobilewallet/mifospay/data/local/PreferencesHelper.kt rename to core/src/main/java/org/mifos/mobilewallet/core/data/fineract/local/PreferencesHelper.kt index f9064a2ea..5d6dcf957 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/data/local/PreferencesHelper.kt +++ b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/local/PreferencesHelper.kt @@ -1,4 +1,4 @@ -package org.mifos.mobilewallet.mifospay.data.local +package org.mifos.mobilewallet.core.data.fineract.local import android.content.Context import android.content.SharedPreferences diff --git a/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/repository/FineractRepository.kt b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/repository/FineractRepository.kt index 5e621eb7a..61ecbf366 100644 --- a/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/repository/FineractRepository.kt +++ b/core/src/main/java/org/mifos/mobilewallet/core/data/fineract/repository/FineractRepository.kt @@ -1,296 +1,304 @@ -package org.mifos.mobilewallet.core.data.fineract.repository; - -import org.mifos.mobilewallet.core.data.fineract.api.FineractApiManager; -import org.mifos.mobilewallet.core.data.fineract.api.GenericResponse; -import org.mifos.mobilewallet.core.data.fineract.api.SelfServiceApiManager; -import org.mifos.mobilewallet.core.data.fineract.entity.Invoice; -import org.mifos.mobilewallet.core.data.fineract.entity.Page; -import org.mifos.mobilewallet.core.data.fineract.entity.SearchedEntity; -import org.mifos.mobilewallet.core.data.fineract.entity.TPTResponse; -import org.mifos.mobilewallet.core.data.fineract.entity.UserEntity; -import org.mifos.mobilewallet.core.data.fineract.entity.UserWithRole; -import org.mifos.mobilewallet.core.data.fineract.entity.accounts.savings.SavingsWithAssociations; -import org.mifos.mobilewallet.core.data.fineract.entity.accounts.savings.Transactions; -import org.mifos.mobilewallet.core.data.fineract.entity.accounts.savings.TransferDetail; -import org.mifos.mobilewallet.core.data.fineract.entity.authentication.AuthenticationPayload; -import org.mifos.mobilewallet.core.data.fineract.entity.beneficary.Beneficiary; -import org.mifos.mobilewallet.core.data.fineract.entity.beneficary.BeneficiaryPayload; -import org.mifos.mobilewallet.core.data.fineract.entity.beneficary.BeneficiaryUpdatePayload; -import org.mifos.mobilewallet.core.data.fineract.entity.client.Client; -import org.mifos.mobilewallet.core.data.fineract.entity.client.ClientAccounts; -import org.mifos.mobilewallet.core.data.fineract.entity.kyc.KYCLevel1Details; -import org.mifos.mobilewallet.core.data.fineract.entity.payload.StandingInstructionPayload; -import org.mifos.mobilewallet.core.data.fineract.entity.payload.TransferPayload; -import org.mifos.mobilewallet.core.data.fineract.entity.register.RegisterPayload; -import org.mifos.mobilewallet.core.data.fineract.entity.register.UserVerify; -import org.mifos.mobilewallet.core.data.fineract.entity.savedcards.Card; -import org.mifos.mobilewallet.core.data.fineract.entity.standinginstruction.SDIResponse; -import org.mifos.mobilewallet.core.data.fineract.entity.standinginstruction.StandingInstruction; -import org.mifos.mobilewallet.core.domain.model.NewAccount; -import org.mifos.mobilewallet.core.domain.model.NotificationPayload; -import org.mifos.mobilewallet.core.domain.model.client.NewClient; -import org.mifos.mobilewallet.core.domain.model.twofactor.AccessToken; -import org.mifos.mobilewallet.core.domain.model.twofactor.DeliveryMethod; -import org.mifos.mobilewallet.core.domain.model.user.NewUser; -import org.mifos.mobilewallet.core.domain.usecase.client.CreateClient; -import org.mifos.mobilewallet.core.domain.usecase.user.CreateUser; -import org.mifos.mobilewallet.core.utils.Constants; - -import java.util.List; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import okhttp3.MultipartBody; -import okhttp3.ResponseBody; -import rx.Observable; -import rx.functions.Func1; +package org.mifos.mobilewallet.core.data.fineract.repository + +import okhttp3.MultipartBody +import okhttp3.ResponseBody +import org.mifos.mobilewallet.core.data.fineract.api.FineractApiManager +import org.mifos.mobilewallet.core.data.fineract.api.GenericResponse +import org.mifos.mobilewallet.core.data.fineract.api.SelfServiceApiManager +import org.mifos.mobilewallet.core.data.fineract.entity.Invoice +import org.mifos.mobilewallet.core.data.fineract.entity.Page +import org.mifos.mobilewallet.core.data.fineract.entity.SearchedEntity +import org.mifos.mobilewallet.core.data.fineract.entity.TPTResponse +import org.mifos.mobilewallet.core.data.fineract.entity.UserEntity +import org.mifos.mobilewallet.core.data.fineract.entity.UserWithRole +import org.mifos.mobilewallet.core.data.fineract.entity.accounts.savings.SavingsWithAssociations +import org.mifos.mobilewallet.core.data.fineract.entity.accounts.savings.Transactions +import org.mifos.mobilewallet.core.data.fineract.entity.accounts.savings.TransferDetail +import org.mifos.mobilewallet.core.data.fineract.entity.authentication.AuthenticationPayload +import org.mifos.mobilewallet.core.data.fineract.entity.beneficary.Beneficiary +import org.mifos.mobilewallet.core.data.fineract.entity.beneficary.BeneficiaryPayload +import org.mifos.mobilewallet.core.data.fineract.entity.beneficary.BeneficiaryUpdatePayload +import org.mifos.mobilewallet.core.data.fineract.entity.client.Client +import org.mifos.mobilewallet.core.data.fineract.entity.client.ClientAccounts +import org.mifos.mobilewallet.core.data.fineract.entity.kyc.KYCLevel1Details +import org.mifos.mobilewallet.core.data.fineract.entity.payload.StandingInstructionPayload +import org.mifos.mobilewallet.core.data.fineract.entity.payload.TransferPayload +import org.mifos.mobilewallet.core.data.fineract.entity.register.RegisterPayload +import org.mifos.mobilewallet.core.data.fineract.entity.register.UserVerify +import org.mifos.mobilewallet.core.data.fineract.entity.savedcards.Card +import org.mifos.mobilewallet.core.data.fineract.entity.standinginstruction.SDIResponse +import org.mifos.mobilewallet.core.data.fineract.entity.standinginstruction.StandingInstruction +import org.mifos.mobilewallet.core.domain.model.NewAccount +import org.mifos.mobilewallet.core.domain.model.NotificationPayload +import org.mifos.mobilewallet.core.domain.model.client.NewClient +import org.mifos.mobilewallet.core.domain.model.twofactor.AccessToken +import org.mifos.mobilewallet.core.domain.model.twofactor.DeliveryMethod +import org.mifos.mobilewallet.core.domain.model.user.NewUser +import org.mifos.mobilewallet.core.domain.usecase.client.CreateClient +import org.mifos.mobilewallet.core.domain.usecase.user.CreateUser +import org.mifos.mobilewallet.core.utils.Constants +import rx.Observable +import javax.inject.Inject +import javax.inject.Singleton /** * Created by naman on 16/6/17. */ - @Singleton -public class FineractRepository { - - private final FineractApiManager fineractApiManager; - private final SelfServiceApiManager selfApiManager; - - @Inject - public FineractRepository(FineractApiManager fineractApiManager) { - this.fineractApiManager = fineractApiManager; - this.selfApiManager = FineractApiManager.getSelfApiManager(); +class FineractRepository @Inject constructor( + private val fineractApiManager: FineractApiManager, + private val selfApiManager: SelfServiceApiManager +) { + fun createClient(newClient: NewClient): Observable { + return fineractApiManager.clientsApi.createClient(newClient) } - public Observable createClient(NewClient newClient) { - return fineractApiManager.getClientsApi().createClient(newClient); + fun createUser(user: NewUser): Observable { + return fineractApiManager.userApi.createUser(user) } - public Observable createUser(NewUser user) { - return fineractApiManager.getUserApi().createUser(user); + fun updateUser(updateUserEntity: Any, userId: Int): Observable { + return fineractApiManager.userApi.updateUser(userId, updateUserEntity) } - public Observable updateUser(Object updateUserEntity, int userId) { - return fineractApiManager.getUserApi().updateUser(userId, updateUserEntity); + fun registerUser(registerPayload: RegisterPayload): Observable { + return fineractApiManager.registrationAPi.registerUser(registerPayload) } - public Observable registerUser(RegisterPayload registerPayload) { - return fineractApiManager.getRegistrationAPi().registerUser(registerPayload); + fun deleteUser(userId: Int): Observable { + return fineractApiManager.userApi.deleteUser(userId) } - public Observable deleteUser(int userId) { - return fineractApiManager.getUserApi().deleteUser(userId); + fun verifyUser(userVerify: UserVerify): Observable { + return fineractApiManager.registrationAPi.verifyUser(userVerify) } - public Observable verifyUser(UserVerify userVerify) { - return fineractApiManager.getRegistrationAPi().verifyUser(userVerify); + fun searchResources( + query: String, resources: String, + exactMatch: Boolean + ): Observable> { + return fineractApiManager.searchApi.searchResources(query, resources, exactMatch) } - public Observable> searchResources(String query, String resources, - Boolean exactMatch) { - return fineractApiManager.getSearchApi().searchResources(query, resources, exactMatch); + fun updateClient(clientId: Long, payload: Any): Observable { + return fineractApiManager.clientsApi.updateClient(clientId, payload) + .map { responseBody -> responseBody } } - public Observable updateClient(long clientId, Object payload) { - return fineractApiManager.getClientsApi().updateClient(clientId, payload) - .map(new Func1() { - @Override - public ResponseBody call(ResponseBody responseBody) { - return responseBody; - } - }); + fun createSavingsAccount(newAccount: NewAccount?): Observable { + return fineractApiManager.clientsApi.createAccount(newAccount) } - public Observable createSavingsAccount(NewAccount newAccount) { - return fineractApiManager.getClientsApi().createAccount(newAccount); + fun getAccounts(clientId: Long): Observable { + return fineractApiManager.clientsApi.getAccounts(clientId, Constants.SAVINGS) } - public Observable getAccounts(long clientId) { - return fineractApiManager.getClientsApi().getAccounts(clientId, Constants.SAVINGS); - } - - public Observable> getSavingsAccounts() { - return fineractApiManager.getSavingAccountsListApi().getSavingsAccounts(-1); - } + val savingsAccounts: Observable> + get() = fineractApiManager.savingsAccountsApi.getSavingsAccounts(-1) - public Observable blockUnblockAccount(long accountId, String command) { - return fineractApiManager.getSavingAccountsListApi().blockUnblockAccount(accountId, - command); + fun blockUnblockAccount(accountId: Long, command: String?): Observable { + return fineractApiManager.savingsAccountsApi.blockUnblockAccount( + accountId, + command + ) } - public Observable getClientDetails(long clientId) { - return fineractApiManager.getClientsApi().getClientForId(clientId); + fun getClientDetails(clientId: Long): Observable { + return fineractApiManager.clientsApi.getClientForId(clientId) } - public Observable getClientImage(long clientId) { - return fineractApiManager.getClientsApi().getClientImage(clientId); + fun getClientImage(clientId: Long): Observable { + return fineractApiManager.clientsApi.getClientImage(clientId) } - public Observable addSavedCards(long clientId, - Card card) { - return fineractApiManager.getSavedCardApi().addSavedCard((int) clientId, card); + fun addSavedCards( + clientId: Long, + card: Card + ): Observable { + return fineractApiManager.savedCardApi.addSavedCard(clientId.toInt(), card) } - public Observable> fetchSavedCards(long clientId) { - return fineractApiManager.getSavedCardApi().getSavedCards((int) clientId); + fun fetchSavedCards(clientId: Long): Observable> { + return fineractApiManager.savedCardApi.getSavedCards(clientId.toInt()) } - public Observable editSavedCard(int clientId, Card card) { - return fineractApiManager.getSavedCardApi().updateCard(clientId, card.getId(), card); + fun editSavedCard(clientId: Int, card: Card): Observable { + return fineractApiManager.savedCardApi.updateCard(clientId, card.id, card) } - public Observable deleteSavedCard(int clientId, int cardId) { - return fineractApiManager.getSavedCardApi().deleteCard(clientId, cardId); + fun deleteSavedCard(clientId: Int, cardId: Int): Observable { + return fineractApiManager.savedCardApi.deleteCard(clientId, cardId) } - public Observable uploadKYCDocs(String entityType, long entityId, String name, - String desc, MultipartBody.Part file) { - return fineractApiManager.getDocumentApi().createDocument(entityType, entityId, name, desc, - file); + fun uploadKYCDocs( + entityType: String, entityId: Long, name: String, + desc: String, file: MultipartBody.Part + ): Observable { + return fineractApiManager.documentApi.createDocument( + entityType, entityId, name, desc, + file + ) } - public Observable getAccountTransfer(long transferId) { - return fineractApiManager.getAccountTransfersApi().getAccountTransfer(transferId); + fun getAccountTransfer(transferId: Long): Observable { + return fineractApiManager.accountTransfersApi.getAccountTransfer(transferId) } - public Observable uploadKYCLevel1Details(int clientId, - KYCLevel1Details kycLevel1Details) { - return fineractApiManager.getKycLevel1Api().addKYCLevel1Details(clientId, - kycLevel1Details); + fun uploadKYCLevel1Details( + clientId: Int, + kycLevel1Details: KYCLevel1Details + ): Observable { + return fineractApiManager.kycLevel1Api.addKYCLevel1Details( + clientId, + kycLevel1Details + ) } - public Observable> fetchKYCLevel1Details(int clientId) { - return fineractApiManager.getKycLevel1Api().fetchKYCLevel1Details(clientId); + fun fetchKYCLevel1Details(clientId: Int): Observable> { + return fineractApiManager.kycLevel1Api.fetchKYCLevel1Details(clientId) } - public Observable updateKYCLevel1Details(int clientId, - KYCLevel1Details kycLevel1Details) { - return fineractApiManager.getKycLevel1Api().updateKYCLevel1Details(clientId, - kycLevel1Details); + fun updateKYCLevel1Details( + clientId: Int, + kycLevel1Details: KYCLevel1Details + ): Observable { + return fineractApiManager.kycLevel1Api.updateKYCLevel1Details( + clientId, + kycLevel1Details + ) } - public Observable> fetchNotifications(long clientId) { - return fineractApiManager.getNotificationApi().fetchNotifications(clientId); + fun fetchNotifications(clientId: Long): Observable> { + return fineractApiManager.notificationApi.fetchNotifications(clientId) } - public Observable> getDeliveryMethods() { - return fineractApiManager.getTwoFactorAuthApi().getDeliveryMethods(); - } + val deliveryMethods: Observable> + get() = fineractApiManager.twoFactorAuthApi.deliveryMethods - public Observable requestOTP(String deliveryMethod) { - return fineractApiManager.getTwoFactorAuthApi().requestOTP(deliveryMethod); + fun requestOTP(deliveryMethod: String): Observable { + return fineractApiManager.twoFactorAuthApi.requestOTP(deliveryMethod) } - public Observable validateToken(String token) { - return fineractApiManager.getTwoFactorAuthApi().validateToken(token); + fun validateToken(token: String): Observable { + return fineractApiManager.twoFactorAuthApi.validateToken(token) } - public Observable getTransactionReceipt(String outputType, - String transactionId) { - return fineractApiManager.getRunReportApi().getTransactionReceipt(outputType, - transactionId); + fun getTransactionReceipt( + outputType: String, + transactionId: String + ): Observable { + return fineractApiManager.runReportApi.getTransactionReceipt( + outputType, + transactionId + ) } - public Observable addInvoice(String clientId, Invoice invoice) { - return fineractApiManager.getInvoiceApi().addInvoice(clientId, invoice); + fun addInvoice(clientId: String, invoice: Invoice?): Observable { + return fineractApiManager.invoiceApi.addInvoice(clientId, invoice) } - public Observable> fetchInvoices(String clientId) { - return fineractApiManager.getInvoiceApi().getInvoices(clientId); + fun fetchInvoices(clientId: String): Observable> { + return fineractApiManager.invoiceApi.getInvoices(clientId) } - public Observable> fetchInvoice(String clientId, String invoiceId) { - return fineractApiManager.getInvoiceApi().getInvoice(clientId, invoiceId); + fun fetchInvoice(clientId: String, invoiceId: String): Observable> { + return fineractApiManager.invoiceApi.getInvoice(clientId, invoiceId) } - - public Observable editInvoice(String clientId, Invoice invoice) { - return fineractApiManager.getInvoiceApi().updateInvoice(clientId, invoice.getId(), invoice); + fun editInvoice(clientId: String, invoice: Invoice): Observable { + return fineractApiManager.invoiceApi.updateInvoice(clientId, invoice.id, invoice) } - public Observable deleteInvoice(String clientId, int invoiceId) { - return fineractApiManager.getInvoiceApi().deleteInvoice(clientId, invoiceId); + fun deleteInvoice(clientId: String, invoiceId: Int): Observable { + return fineractApiManager.invoiceApi.deleteInvoice(clientId, invoiceId) } - public Observable> getUsers() { - return fineractApiManager.getUserApi().getUsers(); - } + val users: Observable> + get() = fineractApiManager.userApi.users - public Observable getUser(long userId) { - return fineractApiManager.getUserApi().getUser(userId); + fun getUser(userId: Long): Observable { + return fineractApiManager.userApi.getUser(userId) } - public Observable makeThirdPartyTransfer(TransferPayload transferPayload) { - return fineractApiManager.getThirdPartyTransferApi().makeTransfer(transferPayload); + fun makeThirdPartyTransfer(transferPayload: TransferPayload): Observable { + return fineractApiManager.thirdPartyTransferApi.makeTransfer(transferPayload) } - public Observable createStandingInstruction( - StandingInstructionPayload standingInstructionPayload) { - return fineractApiManager.getStandingInstructionApi() - .createStandingInstruction(standingInstructionPayload); + fun createStandingInstruction( + standingInstructionPayload: StandingInstructionPayload + ): Observable { + return fineractApiManager.standingInstructionApi + .createStandingInstruction(standingInstructionPayload) } - public Observable> getAllStandingInstructions(long clientId) { - return fineractApiManager.getStandingInstructionApi().getAllStandingInstructions(clientId); + fun getAllStandingInstructions(clientId: Long): Observable> { + return fineractApiManager.standingInstructionApi.getAllStandingInstructions(clientId) } - public Observable getStandingInstruction(long standingInstructionId) { - return fineractApiManager.getStandingInstructionApi() - .getStandingInstruction(standingInstructionId); + fun getStandingInstruction(standingInstructionId: Long): Observable { + return fineractApiManager.standingInstructionApi + .getStandingInstruction(standingInstructionId) } - public Observable updateStandingInstruction(long standingInstructionId, - StandingInstructionPayload data) { - return fineractApiManager.getStandingInstructionApi().updateStandingInstruction( - standingInstructionId, data, "update"); + fun updateStandingInstruction( + standingInstructionId: Long, + data: StandingInstructionPayload + ): Observable { + return fineractApiManager.standingInstructionApi.updateStandingInstruction( + standingInstructionId, data, "update" + ) } - public Observable deleteStandingInstruction(long standingInstruction) { - return fineractApiManager.getStandingInstructionApi().deleteStandingInstruction( - standingInstruction, "delete"); + fun deleteStandingInstruction(standingInstruction: Long): Observable { + return fineractApiManager.standingInstructionApi.deleteStandingInstruction( + standingInstruction, "delete" + ) } //self user apis - - public Observable loginSelf(AuthenticationPayload payload) { - return selfApiManager.getAuthenticationApi().authenticate(payload); + fun loginSelf(payload: AuthenticationPayload): Observable { + return selfApiManager.authenticationApi.authenticate(payload) } - public Observable getSelfClientDetails(long clientId) { - return selfApiManager.getClientsApi().getClientForId(clientId); + fun getSelfClientDetails(clientId: Long): Observable { + return selfApiManager.clientsApi.getClientForId(clientId) } - public Observable> getSelfClientDetails() { - return selfApiManager.getClientsApi().getClients(); - } + val selfClientDetails: Observable> + get() = selfApiManager.clientsApi.clients - public Observable getSelfAccountTransactions(long accountId) { - return selfApiManager - .getSavingAccountsListApi().getSavingsWithAssociations(accountId, - Constants.TRANSACTIONS); + fun getSelfAccountTransactions(accountId: Long): Observable { + return selfApiManager.savingAccountsListApi.getSavingsWithAssociations( + accountId, + Constants.TRANSACTIONS + ) } - public Observable getSelfAccountTransactionFromId(long accountId, - long transactionId) { - return selfApiManager - .getSavingAccountsListApi().getSavingAccountTransaction(accountId, - transactionId); + fun getSelfAccountTransactionFromId( + accountId: Long, + transactionId: Long + ): Observable { + return selfApiManager.savingAccountsListApi.getSavingAccountTransaction( + accountId, + transactionId + ) } - public Observable getSelfAccounts(long clientId) { - return selfApiManager.getClientsApi().getAccounts(clientId, Constants.SAVINGS); + fun getSelfAccounts(clientId: Long): Observable { + return selfApiManager.clientsApi.getAccounts(clientId, Constants.SAVINGS) } - public Observable> getBeneficiaryList() { - return selfApiManager.getBeneficiaryApi().getBeneficiaryList(); - } + val beneficiaryList: Observable> + get() = selfApiManager.beneficiaryApi.beneficiaryList - public Observable createBeneficiary(BeneficiaryPayload beneficiaryPayload) { - return selfApiManager.getBeneficiaryApi().createBeneficiary(beneficiaryPayload); + fun createBeneficiary(beneficiaryPayload: BeneficiaryPayload): Observable { + return selfApiManager.beneficiaryApi.createBeneficiary(beneficiaryPayload) } - public Observable updateBeneficiary(long beneficiaryId, - BeneficiaryUpdatePayload payload) { - return selfApiManager.getBeneficiaryApi().updateBeneficiary(beneficiaryId, payload); + fun updateBeneficiary( + beneficiaryId: Long, + payload: BeneficiaryUpdatePayload + ): Observable { + return selfApiManager.beneficiaryApi.updateBeneficiary(beneficiaryId, payload) } } diff --git a/core/src/main/java/org/mifos/mobilewallet/core/di/Qualifier.kt b/core/src/main/java/org/mifos/mobilewallet/core/di/Qualifier.kt new file mode 100644 index 000000000..c74d26a18 --- /dev/null +++ b/core/src/main/java/org/mifos/mobilewallet/core/di/Qualifier.kt @@ -0,0 +1,11 @@ +package org.mifos.mobilewallet.core.di + +import javax.inject.Qualifier + +@Qualifier +@Retention(AnnotationRetention.BINARY) +annotation class SelfServiceApi + +@Qualifier +@Retention(AnnotationRetention.BINARY) +annotation class FineractApi diff --git a/feature/auth/.gitignore b/feature/auth/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/feature/auth/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/auth/build.gradle.kts b/feature/auth/build.gradle.kts new file mode 100644 index 000000000..d2bfba9ad --- /dev/null +++ b/feature/auth/build.gradle.kts @@ -0,0 +1,22 @@ +plugins { + alias(libs.plugins.mifospay.android.feature) + alias(libs.plugins.mifospay.android.library.compose) +} + +android { + namespace = "org.mifos.mobilewallet.mifospay.auth" +} + +dependencies { + implementation(projects.core) + implementation(projects.mainCore.data) + + implementation("com.mifos.mobile:mifos-passcode:0.3.0") + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.appcompat) + implementation(libs.material) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.espresso.core) +} \ No newline at end of file diff --git a/feature/auth/consumer-rules.pro b/feature/auth/consumer-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/feature/auth/proguard-rules.pro b/feature/auth/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/feature/auth/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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/feature/auth/src/androidTest/java/org/mifos/mobilewallet/mifospay/auth/ExampleInstrumentedTest.kt b/feature/auth/src/androidTest/java/org/mifos/mobilewallet/mifospay/auth/ExampleInstrumentedTest.kt new file mode 100644 index 000000000..3ca3753e4 --- /dev/null +++ b/feature/auth/src/androidTest/java/org/mifos/mobilewallet/mifospay/auth/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package org.mifos.mobilewallet.mifospay.auth + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("org.mifos.mobilewallet.mifospay.auth.test", appContext.packageName) + } +} \ No newline at end of file diff --git a/feature/auth/src/main/AndroidManifest.xml b/feature/auth/src/main/AndroidManifest.xml new file mode 100644 index 000000000..a5918e68a --- /dev/null +++ b/feature/auth/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/AuthContract.kt b/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/AuthContract.kt new file mode 100644 index 000000000..7f77ac440 --- /dev/null +++ b/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/AuthContract.kt @@ -0,0 +1,24 @@ +package org.mifos.mobilewallet.mifospay.auth.login + +import org.mifos.mobilewallet.mifospay.base.BasePresenter +import org.mifos.mobilewallet.mifospay.base.BaseView + +/** + * Created by naman on 16/6/17. + */ +/** + * This specifies the contract between the view and the presenter. + */ +interface AuthContract { + interface LoginView : BaseView { + fun disableLoginButton() + fun enableLoginButton() + fun loginSuccess() + fun loginFail(message: String?) + } + + interface LoginPresenter : BasePresenter { + fun handleLoginButtonStatus(usernameContent: String?, passwordContent: String?) + fun loginUser(username: String?, password: String?) + } +} \ No newline at end of file diff --git a/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginActivity.kt b/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginActivity.kt new file mode 100644 index 000000000..4d748901f --- /dev/null +++ b/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginActivity.kt @@ -0,0 +1,158 @@ +package org.mifos.mobilewallet.mifospay.auth.login + +import android.content.Intent +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import com.mifos.mobile.passcode.utils.PasscodePreferencesHelper +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch +import org.mifos.mobilewallet.mifospay.designsystem.theme.MifosTheme + +/** + * Created by naman on 16/6/17. + */ +@AndroidEntryPoint +class LoginActivity : ComponentActivity() { + + private val viewModel by viewModels() + + // private var googleSignInClient: GoogleSignInClient? = null + // private var account: GoogleSignInAccount? = null + private var mMifosSavingProductId = 0 + + private var usernameContent: String = "" + private var passwordContent: String = "" + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + MifosTheme { + LoginScreen({ username, password -> + usernameContent = username + passwordContent = password + onLoginClicked() + }, { + onSignupClicked() + }) + } + } + + val pref = PasscodePreferencesHelper(applicationContext) + if (pref.passCode.isNotEmpty()) { + startPassCodeActivity() + } + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.uiState.collect { uiState -> + when(uiState) { + is LoginViewModel.LoginUiState.Success -> { + loginSuccess() + } + + is LoginViewModel.LoginUiState.Error -> { + + } + + is LoginViewModel.LoginUiState.Loading -> { + + } + + is LoginViewModel.LoginUiState.None -> { + + } + } + } + } + } + } + + private fun loginSuccess() { + //hideProgressDialog() + //hideSoftKeyboard(this) + startPassCodeActivity() + } + + private fun onLoginClicked() { + // hideSoftKeyboard(this) + // showProgressDialog(Constants.LOGGING_IN) + viewModel.loginUser(usernameContent, passwordContent) + } + + private fun onSignupClicked() { + /*val signupMethod = SignupMethod() + signupMethod.show(supportFragmentManager, Constants.CHOOSE_SIGNUP_METHOD)*/ + } + + fun loginFail(message: String?) { + /*hideSoftKeyboard(this) + hideProgressDialog() + Toast.makeText(this, message, Toast.LENGTH_SHORT).show()*/ + } + + /** + * Starts [PassCodeActivity] with `Constans.INTIAL_LOGIN` as true + */ + private fun startPassCodeActivity() { + /*val intent = Intent(this@LoginActivity, PassCodeActivity::class.java) + intent.putExtra(PassCodeConstants.PASSCODE_INITIAL_LOGIN, true) + startActivity(intent)*/ + } + + fun signupUsingGoogleAccount(mifosSavingsProductId: Int) { + /*showProgressDialog(Constants.PLEASE_WAIT) + mMifosSavingProductId = mifosSavingsProductId + val gso = GoogleSignInOptions.Builder( + GoogleSignInOptions.DEFAULT_SIGN_IN + ).requestIdToken(getString(R.string.default_web_client_id)).requestEmail().build() + googleSignInClient = GoogleSignIn.getClient(this, gso) + val signInIntent = googleSignInClient!!.getSignInIntent() + hideProgressDialog() + startActivityForResult(signInIntent, 11)*/ + } + + public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + /*showProgressDialog(Constants.PLEASE_WAIT) + // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); + if (requestCode == 11) { + val task = GoogleSignIn.getSignedInAccountFromIntent(data) + try { + // Google Sign In was successful, authenticate with Firebase + account = task.getResult(ApiException::class.java) + hideProgressDialog() + signup(mMifosSavingProductId) + } catch (e: Exception) { + // Google Sign In failed, update UI appropriately + DebugUtil.log(Constants.GOOGLE_SIGN_IN_FAILED, e.message) + Toaster.showToast(this, Constants.GOOGLE_SIGN_IN_FAILED) + hideProgressDialog() + } + }*/ + } + + fun signup(mifosSavingsProductId: Int) { + /*showProgressDialog(Constants.PLEASE_WAIT) + val intent = Intent(this@LoginActivity, MobileVerificationActivity::class.java) + mMifosSavingProductId = mifosSavingsProductId + intent.putExtra(Constants.MIFOS_SAVINGS_PRODUCT_ID, mMifosSavingProductId) + if (account != null) { + intent.putExtra(Constants.GOOGLE_PHOTO_URI, account!!.photoUrl) + intent.putExtra(Constants.GOOGLE_DISPLAY_NAME, account!!.displayName) + intent.putExtra(Constants.GOOGLE_EMAIL, account!!.email) + intent.putExtra(Constants.GOOGLE_FAMILY_NAME, account!!.familyName) + intent.putExtra(Constants.GOOGLE_GIVEN_NAME, account!!.givenName) + } + hideProgressDialog() + startActivity(intent) + if (googleSignInClient != null) { + googleSignInClient!!.signOut() + .addOnCompleteListener(this, OnCompleteListener { account = null }) + }*/ + } +} \ No newline at end of file diff --git a/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginScreen.kt b/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginScreen.kt new file mode 100644 index 000000000..c12f55c11 --- /dev/null +++ b/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginScreen.kt @@ -0,0 +1,172 @@ +package org.mifos.mobilewallet.mifospay.auth.login + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Visibility +import androidx.compose.material.icons.filled.VisibilityOff +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +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.graphics.Color +import androidx.compose.ui.res.stringResource +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.text.style.TextDecoration +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import org.mifos.mobilewallet.mifospay.auth.R +import org.mifos.mobilewallet.mifospay.designsystem.component.MifosOutlinedTextField +import org.mifos.mobilewallet.mifospay.designsystem.theme.MifosTheme +import org.mifos.mobilewallet.mifospay.designsystem.theme.grey +import org.mifos.mobilewallet.mifospay.designsystem.theme.styleMedium16sp +import org.mifos.mobilewallet.mifospay.designsystem.theme.styleMedium30sp +import org.mifos.mobilewallet.mifospay.designsystem.theme.styleNormal18sp + +@Composable +fun LoginScreen( + login: (username: String, password: String) -> Unit, + signUp: () -> Unit +) { + var userName by rememberSaveable(stateSaver = TextFieldValue.Saver) { + mutableStateOf( + TextFieldValue("") + ) + } + var password by rememberSaveable(stateSaver = TextFieldValue.Saver) { + mutableStateOf( + TextFieldValue("") + ) + } + var passwordVisibility: Boolean by remember { mutableStateOf(false) } + + MifosTheme { + Column( + modifier = Modifier + .fillMaxWidth() + .background(Color.White) + .verticalScroll(rememberScrollState()) + .padding(top = 100.dp, start = 48.dp, end = 48.dp), + horizontalAlignment = Alignment.Start + ) { + Text( + text = stringResource(id = R.string.feature_auth_login), + style = styleMedium30sp + ) + Text( + modifier = Modifier + .padding(top = 32.dp), + text = stringResource(id = R.string.feature_auth_welcome_back), + style = styleNormal18sp.copy(color = grey) + ) + Spacer(modifier = Modifier.padding(top = 32.dp)) + MifosOutlinedTextField( + modifier = Modifier.fillMaxWidth(), + value = userName, + onValueChange = { + userName = it + }, + label = R.string.feature_auth_username + ) + Spacer(modifier = Modifier.padding(top = 16.dp)) + MifosOutlinedTextField( + modifier = Modifier.fillMaxWidth(), + value = password, + onValueChange = { + password = it + }, + label = R.string.feature_auth_password, + visualTransformation = if (passwordVisibility) VisualTransformation.None else PasswordVisualTransformation(), + trailingIcon = { + val image = if (passwordVisibility) + Icons.Filled.Visibility + else Icons.Filled.VisibilityOff + IconButton(onClick = { passwordVisibility = !passwordVisibility }) { + Icon(imageVector = image, null) + } + } + ) + Button( + modifier = Modifier + .fillMaxWidth() + .padding(top = 16.dp), + colors = ButtonDefaults.buttonColors(containerColor = Color.Black), + enabled = userName.text.isNotEmpty() && password.text.isNotEmpty(), + onClick = { + login.invoke(userName.text, password.text) + }, + contentPadding = PaddingValues(12.dp) + ) { + Text( + text = stringResource(id = R.string.feature_auth_login).uppercase(), + style = styleMedium16sp.copy(color = Color.White) + ) + } + // Hide reset password for now + /*Text( + modifier = Modifier + .fillMaxWidth() + .padding(top = 32.dp), + text = "Forgot Password", + textAlign = TextAlign.Center, + style = styleMedium16sp.copy( + textDecoration = TextDecoration.Underline, + ) + ) + Text( + modifier = Modifier + .fillMaxWidth() + .padding(top = 24.dp), + text = "OR", + textAlign = TextAlign.Center, + style = styleMedium16sp.copy(color = grey) + )*/ + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 24.dp), + horizontalArrangement = Arrangement.Center + ) { + Text( + text = "Don’t have an account yet? ", + style = styleMedium16sp + ) + Text( + modifier = Modifier.clickable { + signUp.invoke() + }, + text = stringResource(id = R.string.feature_auth_sign_up), + style = styleMedium16sp.copy( + textDecoration = TextDecoration.Underline, + ), + ) + } + } + } +} + +@Preview(showSystemUi = true, device = "id:pixel_5") +@Composable +fun LoanScreenPreview() { + LoginScreen({ _, _ -> }, {}) +} diff --git a/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginViewModel.kt b/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginViewModel.kt new file mode 100644 index 000000000..808dd7f9c --- /dev/null +++ b/feature/auth/src/main/kotlin/org/mifos/mobilewallet/mifospay/auth/login/LoginViewModel.kt @@ -0,0 +1,111 @@ +package org.mifos.mobilewallet.mifospay.auth.login + +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import org.mifos.mobilewallet.core.base.UseCase +import org.mifos.mobilewallet.core.base.UseCaseHandler +import org.mifos.mobilewallet.core.data.fineract.api.FineractApiManager +import org.mifos.mobilewallet.core.data.fineract.entity.UserWithRole +import org.mifos.mobilewallet.core.domain.model.client.Client +import org.mifos.mobilewallet.core.domain.model.user.User +import org.mifos.mobilewallet.core.domain.usecase.client.FetchClientData +import org.mifos.mobilewallet.core.domain.usecase.user.AuthenticateUser +import org.mifos.mobilewallet.core.domain.usecase.user.FetchUserDetails +import org.mifos.mobilewallet.core.utils.Constants +import org.mifos.mobilewallet.datastore.PreferencesHelper +import org.mifos.mobilewallet.mifospay.common.DebugUtil +import javax.inject.Inject + +@HiltViewModel +class LoginViewModel @Inject constructor( + private val savedStateHandle: SavedStateHandle, + private val mUsecaseHandler: UseCaseHandler, + private val authenticateUserUseCase: AuthenticateUser, + private val fetchClientDataUseCase: FetchClientData, + private var fetchUserDetailsUseCase: FetchUserDetails, + private val preferencesHelper: PreferencesHelper +) : ViewModel() { + + private val _uiState = MutableStateFlow(LoginUiState.None) + val uiState: StateFlow = _uiState + + fun loginUser(username: String?, password: String?) { + authenticateUserUseCase.requestValues = AuthenticateUser.RequestValues(username, password) + val requestValue = authenticateUserUseCase.requestValues + mUsecaseHandler.execute(authenticateUserUseCase, requestValue, + object : UseCase.UseCaseCallback { + override fun onSuccess(response: AuthenticateUser.ResponseValue) { + createAuthenticatedService(response.user) + fetchClientData() + fetchUserDetails(response.user) + } + + override fun onError(message: String) { + _uiState.value = LoginUiState.Error(message) + } + }) + } + + private fun fetchUserDetails(user: User) { + mUsecaseHandler.execute(fetchUserDetailsUseCase, + FetchUserDetails.RequestValues(user.userId), + object : UseCase.UseCaseCallback { + override fun onSuccess(response: FetchUserDetails.ResponseValue) { + saveUserDetails(user, response.userWithRole) + } + + override fun onError(message: String) { + DebugUtil.log(message) + } + }) + } + + private fun fetchClientData() { + mUsecaseHandler.execute(fetchClientDataUseCase, null, + object : UseCase.UseCaseCallback { + override fun onSuccess(response: FetchClientData.ResponseValue) { + saveClientDetails(response.userDetails) + if (response.userDetails.name != "") { + _uiState.value = LoginUiState.Success + } + } + + override fun onError(message: String) {} + }) + } + + private fun createAuthenticatedService(user: User) { + val authToken = Constants.BASIC + + user.authenticationKey + preferencesHelper.saveToken(authToken) + FineractApiManager.createSelfService(preferencesHelper.token) + } + + private fun saveUserDetails( + user: User, + userWithRole: UserWithRole + ) { + val userName = user.userName + val userID = user.userId + preferencesHelper.saveUsername(userName) + preferencesHelper.userId = userID + preferencesHelper.saveEmail(userWithRole.email) + } + + private fun saveClientDetails(client: Client) { + preferencesHelper.saveFullName(client.name) + preferencesHelper.clientId = client.clientId + preferencesHelper.saveMobile(client.mobileNo) + } + + // Represents different states for the LatestNews screen + sealed interface LoginUiState { + data object None: LoginUiState + data object Loading: LoginUiState + data object Success : LoginUiState + data class Error(val exception: String) : LoginUiState + } +} \ No newline at end of file diff --git a/feature/auth/src/main/res/values/strings.xml b/feature/auth/src/main/res/values/strings.xml new file mode 100644 index 000000000..a474fe937 --- /dev/null +++ b/feature/auth/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + + Login + Welcome back! + Sign up. + Password + Username + \ No newline at end of file diff --git a/feature/auth/src/test/java/org/mifos/mobilewallet/mifospay/auth/ExampleUnitTest.kt b/feature/auth/src/test/java/org/mifos/mobilewallet/mifospay/auth/ExampleUnitTest.kt new file mode 100644 index 000000000..367125261 --- /dev/null +++ b/feature/auth/src/test/java/org/mifos/mobilewallet/mifospay/auth/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package org.mifos.mobilewallet.mifospay.auth + +import org.junit.Test + +import org.junit.Assert.* + +/** + * 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) + } +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 108d189f4..90fa81ada 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,6 +40,9 @@ googleOss = "17.0.1" googleOssPlugin = "0.10.6" firebaseBom = "32.7.1" androidDesugarJdkLibs = "2.0.4" +androidx-test-ext-junit = "1.1.5" +espresso-core = "3.5.1" +material = "1.11.0" [libraries] androidx-activity-ktx = { module = "androidx.activity:activity-ktx", version.ref = "activityVersion" } @@ -51,7 +54,10 @@ android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidxActivity" } androidx-compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "androidxComposeCompiler" } +androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" } +androidx-compose-foundation-layout = { group = "androidx.compose.foundation", name = "foundation-layout" } androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3"} +androidx-compose-material-iconsExtended = { group = "androidx.compose.material", name = "material-icons-extended" } androidx-compose-ui = { group = "androidx.compose.ui", name = "ui"} androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4"} androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest"} @@ -59,7 +65,6 @@ androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-toolin androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime" } hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } hilt-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" } -androidx-compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended"} androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview"} androidx-compose-ui-util = { group = "androidx.compose.ui", name = "ui-util"} androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "androidxHilt" } @@ -96,6 +101,9 @@ kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-pl ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } room-gradlePlugin = { group = "androidx.room", name = "room-gradle-plugin", version.ref = "room" } work-testing = { group = "androidx.work", name = "work-testing", version = "2.8.1" } +androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" } +espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso-core" } +material = { group = "com.google.android.material", name = "material", version.ref = "material" } [plugins] android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } diff --git a/main-core/common/.gitignore b/main-core/common/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/main-core/common/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/main-core/common/build.gradle.kts b/main-core/common/build.gradle.kts new file mode 100644 index 000000000..bd6d591d4 --- /dev/null +++ b/main-core/common/build.gradle.kts @@ -0,0 +1,44 @@ +@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) +} + +android { + namespace = "org.mifos.mobilewallet.mifospay.common" + compileSdk = 34 + + defaultConfig { + minSdk = 24 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } +} + +dependencies { + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.appcompat) + implementation(libs.material) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.espresso.core) +} \ No newline at end of file diff --git a/main-core/common/consumer-rules.pro b/main-core/common/consumer-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/main-core/common/proguard-rules.pro b/main-core/common/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/main-core/common/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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/main-core/common/src/androidTest/java/org/mifos/mobilewallet/mifospay/common/ExampleInstrumentedTest.kt b/main-core/common/src/androidTest/java/org/mifos/mobilewallet/mifospay/common/ExampleInstrumentedTest.kt new file mode 100644 index 000000000..63adeee8f --- /dev/null +++ b/main-core/common/src/androidTest/java/org/mifos/mobilewallet/mifospay/common/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package org.mifos.mobilewallet.mifospay.common + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("org.mifos.mobilewallet.mifospay.common.test", appContext.packageName) + } +} \ No newline at end of file diff --git a/main-core/common/src/main/AndroidManifest.xml b/main-core/common/src/main/AndroidManifest.xml new file mode 100644 index 000000000..a5918e68a --- /dev/null +++ b/main-core/common/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/main-core/common/src/main/java/org/mifos/mobilewallet/mifospay/common/DebugUtil.kt b/main-core/common/src/main/java/org/mifos/mobilewallet/mifospay/common/DebugUtil.kt new file mode 100644 index 000000000..7682c29b5 --- /dev/null +++ b/main-core/common/src/main/java/org/mifos/mobilewallet/mifospay/common/DebugUtil.kt @@ -0,0 +1,17 @@ +package org.mifos.mobilewallet.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/main-core/common/src/test/java/org/mifos/mobilewallet/mifospay/common/ExampleUnitTest.kt b/main-core/common/src/test/java/org/mifos/mobilewallet/mifospay/common/ExampleUnitTest.kt new file mode 100644 index 000000000..cc7e94d38 --- /dev/null +++ b/main-core/common/src/test/java/org/mifos/mobilewallet/mifospay/common/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package org.mifos.mobilewallet.mifospay.common + +import org.junit.Test + +import org.junit.Assert.* + +/** + * 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) + } +} \ No newline at end of file diff --git a/main-core/data/.gitignore b/main-core/data/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/main-core/data/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/main-core/data/build.gradle.kts b/main-core/data/build.gradle.kts new file mode 100644 index 000000000..416590546 --- /dev/null +++ b/main-core/data/build.gradle.kts @@ -0,0 +1,29 @@ +plugins { + alias(libs.plugins.mifospay.android.library) + alias(libs.plugins.mifospay.android.hilt) +} + +android { + namespace = "org.mifos.mobilewallet.mifospay.data" + + defaultConfig { + testOptions { + unitTests { + isIncludeAndroidResources = true + isReturnDefaultValues = true + } + } + } +} + +dependencies { + api(projects.mainCore.common) + api(projects.mainCore.datastore) + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.appcompat) + implementation(libs.material) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.espresso.core) +} \ No newline at end of file diff --git a/main-core/data/proguard-rules.pro b/main-core/data/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/main-core/data/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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/main-core/data/src/androidTest/java/org/mifos/mobilewallet/mifospay/data/ExampleInstrumentedTest.kt b/main-core/data/src/androidTest/java/org/mifos/mobilewallet/mifospay/data/ExampleInstrumentedTest.kt new file mode 100644 index 000000000..33f5eeebb --- /dev/null +++ b/main-core/data/src/androidTest/java/org/mifos/mobilewallet/mifospay/data/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package org.mifos.mobilewallet.mifospay.data + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("org.mifos.mobilewallet.mifospay.data", appContext.packageName) + } +} \ No newline at end of file diff --git a/main-core/data/src/main/AndroidManifest.xml b/main-core/data/src/main/AndroidManifest.xml new file mode 100644 index 000000000..b9a855db8 --- /dev/null +++ b/main-core/data/src/main/AndroidManifest.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/main-core/data/src/test/java/org/mifos/mobilewallet/mifospay/data/ExampleUnitTest.kt b/main-core/data/src/test/java/org/mifos/mobilewallet/mifospay/data/ExampleUnitTest.kt new file mode 100644 index 000000000..7559264ca --- /dev/null +++ b/main-core/data/src/test/java/org/mifos/mobilewallet/mifospay/data/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package org.mifos.mobilewallet.mifospay.data + +import org.junit.Test + +import org.junit.Assert.* + +/** + * 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) + } +} \ No newline at end of file diff --git a/main-core/datastore/src/main/java/org/mifos/mobilewallet/datastore/PreferencesHelper.kt b/main-core/datastore/src/main/java/org/mifos/mobilewallet/datastore/PreferencesHelper.kt new file mode 100644 index 000000000..c5251ef7b --- /dev/null +++ b/main-core/datastore/src/main/java/org/mifos/mobilewallet/datastore/PreferencesHelper.kt @@ -0,0 +1,122 @@ +package org.mifos.mobilewallet.datastore + +import android.content.Context +import android.content.SharedPreferences +import android.preference.PreferenceManager +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class PreferencesHelper @Inject constructor(@ApplicationContext context: Context?) { + private val sharedPreferences: SharedPreferences + + init { + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) + } + + fun clear() { + sharedPreferences.edit().clear().apply() + } + + fun getInt(preferenceKey: String?, preferenceDefaultValue: Int): Int { + return sharedPreferences.getInt(preferenceKey, preferenceDefaultValue) + } + + fun putInt(preferenceKey: String?, preferenceValue: Int) { + sharedPreferences.edit().putInt(preferenceKey, preferenceValue).apply() + } + + fun getLong(preferenceKey: String?, preferenceDefaultValue: Long): Long { + return sharedPreferences.getLong(preferenceKey, preferenceDefaultValue) + } + + fun putLong(preferenceKey: String?, preferenceValue: Long) { + sharedPreferences.edit().putLong(preferenceKey, preferenceValue).apply() + } + + fun getString(preferenceKey: String?, preferenceDefaultValue: String?): String? { + return sharedPreferences.getString(preferenceKey, preferenceDefaultValue) + } + + fun putString(preferenceKey: String?, preferenceValue: String?) { + sharedPreferences.edit().putString(preferenceKey, preferenceValue).apply() + } + + fun saveToken(token: String?) { + putString(TOKEN, token) + } + + fun clearToken() { + putString(TOKEN, "") + } + + val token: String? + get() = getString(TOKEN, "") + + fun saveFullName(name: String?) { + putString(NAME, name) + } + + val fullName: String? + get() = getString(NAME, "") + + fun saveUsername(name: String?) { + putString(USERNAME, name) + } + + val username: String? + get() = getString(USERNAME, "") + + fun saveEmail(email: String?) { + putString(EMAIL, email) + } + + val email: String? + get() = getString(EMAIL, "") + + fun saveMobile(mobile: String?) { + putString(MOBILE_NO, mobile) + } + + val mobile: String? + get() = getString(MOBILE_NO, "") + var userId: Long + get() = getLong(USER_ID, -1) + set(id) { + putLong(USER_ID, id) + } + var clientId: Long + get() = getLong(CLIENT_ID, 1) + set(clientId) { + putLong(CLIENT_ID, clientId) + } + var clientVpa: String? + get() = getString(CLIENT_VPA, "") + set(vpa) { + putString(CLIENT_VPA, vpa) + } + var accountId: Long + get() = getLong(ACCOUNT_ID, 0) + set(accountId) { + putLong(ACCOUNT_ID, accountId) + } + var firebaseRegId: String? + get() = getString(FIREBASE_REG_ID, "") + set(firebaseRegId) { + putString(FIREBASE_REG_ID, firebaseRegId) + } + + companion object { + private const val TOKEN = "preferences_token" + private const val NAME = "preferences_name" + private const val USERNAME = "preferences_user_name" + private const val EMAIL = "preferences_email" + private const val CLIENT_ID = "preferences_client" + private const val USER_ID = "preferences_user_id" + private const val CLIENT_VPA = "preferences_client_vpa" + private const val MOBILE_NO = "preferences_mobile_no" + private const val FIREBASE_REG_ID = "preferences_firebase_reg_id" + private const val ACCOUNT_ID = "preferences_account_id" + } +} \ No newline at end of file diff --git a/main-core/designsystem/.gitignore b/main-core/designsystem/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/main-core/designsystem/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/main-core/designsystem/build.gradle.kts b/main-core/designsystem/build.gradle.kts new file mode 100644 index 000000000..9b6915a60 --- /dev/null +++ b/main-core/designsystem/build.gradle.kts @@ -0,0 +1,25 @@ +plugins { + alias(libs.plugins.mifospay.android.library) + alias(libs.plugins.mifospay.android.library.compose) +} + +android { + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + namespace = "org.mifos.mobilewallet.mifospay.designsystem" +} + +dependencies { + implementation(projects.core) + + 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.tooling.preview) + api(libs.androidx.compose.ui.util) + + debugApi(libs.androidx.compose.ui.tooling) +} \ No newline at end of file diff --git a/main-core/designsystem/consumer-rules.pro b/main-core/designsystem/consumer-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/main-core/designsystem/proguard-rules.pro b/main-core/designsystem/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/main-core/designsystem/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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/main-core/designsystem/src/androidTest/java/org/mifos/mobilewallet/mifospay/designsystem/ExampleInstrumentedTest.kt b/main-core/designsystem/src/androidTest/java/org/mifos/mobilewallet/mifospay/designsystem/ExampleInstrumentedTest.kt new file mode 100644 index 000000000..1ae9b939b --- /dev/null +++ b/main-core/designsystem/src/androidTest/java/org/mifos/mobilewallet/mifospay/designsystem/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package org.mifos.mobilewallet.mifospay.designsystem + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("org.mifos.mobilewallet.mifospay.designsystem.test", appContext.packageName) + } +} \ No newline at end of file diff --git a/main-core/designsystem/src/main/AndroidManifest.xml b/main-core/designsystem/src/main/AndroidManifest.xml new file mode 100644 index 000000000..a5918e68a --- /dev/null +++ b/main-core/designsystem/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/component/TextField.kt b/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/component/TextField.kt new file mode 100644 index 000000000..96fab2237 --- /dev/null +++ b/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/component/TextField.kt @@ -0,0 +1,68 @@ +package org.mifos.mobilewallet.mifospay.designsystem.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.text.KeyboardOptions +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.Color +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.TextFieldValue +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.unit.sp + +@Composable +fun MifosOutlinedTextField( + value: TextFieldValue, + onValueChange: (TextFieldValue) -> Unit, + maxLines: Int = 1, + modifier: Modifier, + singleLine: Boolean = true, + icon: Int? = null, + label: Int, + visualTransformation: VisualTransformation = VisualTransformation.None, + trailingIcon: @Composable (() -> Unit)? = null, + 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 = if (isSystemInDarkTheme()) { + ColorFilter.tint(Color.White) + } else ColorFilter.tint( + Color.Black + ) + ) + } + } else null, + trailingIcon = trailingIcon, + maxLines = maxLines, + singleLine = singleLine, + colors = OutlinedTextFieldDefaults.colors( + focusedBorderColor = Color.Black, + focusedLabelColor = Color.Black + ), + textStyle = LocalDensity.current.run { + TextStyle(fontSize = 18.sp, color = Color.Black) + }, + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), + visualTransformation = visualTransformation, + isError = error + ) +} diff --git a/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Color.kt b/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Color.kt new file mode 100644 index 000000000..f52351e7a --- /dev/null +++ b/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Color.kt @@ -0,0 +1,19 @@ +package org.mifos.mobilewallet.mifospay.designsystem.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFF7D5260) + +// colors +val black = Color(0xFF000000) +val grey = Color(0xFF757074) +val lightGrey = Color(0xFFD9D9D9) +val border = Color(0x66000000) +val green = Color(0xFF008135) +val red = Color(0xFFCD0000) \ No newline at end of file diff --git a/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/MifosTextStyle.kt b/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/MifosTextStyle.kt new file mode 100644 index 000000000..84c4191ba --- /dev/null +++ b/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/MifosTextStyle.kt @@ -0,0 +1,27 @@ +package org.mifos.mobilewallet.mifospay.designsystem.theme + +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +val styleMedium16sp = TextStyle( + fontSize = 16.sp, + fontFamily = FontFamily.SansSerif, + fontWeight = FontWeight.Medium, + color = black, +) + +val styleNormal18sp = TextStyle( + fontSize = 18.sp, + fontFamily = FontFamily.SansSerif, + fontWeight = FontWeight.Normal, + color = black, +) + +val styleMedium30sp = TextStyle( + fontSize = 30.sp, + fontFamily = FontFamily.SansSerif, + fontWeight = FontWeight.Medium, + color = black, +) diff --git a/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Theme.kt b/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Theme.kt new file mode 100644 index 000000000..e2ae9b422 --- /dev/null +++ b/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Theme.kt @@ -0,0 +1,67 @@ +package org.mifos.mobilewallet.mifospay.designsystem.theme + +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun MifosTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + + // TODO see use case and implement + /*val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + }*/ + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Type.kt b/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Type.kt new file mode 100644 index 000000000..aeadec042 --- /dev/null +++ b/main-core/designsystem/src/main/java/org/mifos/mobilewallet/mifospay/designsystem/theme/Type.kt @@ -0,0 +1,34 @@ +package org.mifos.mobilewallet.mifospay.designsystem.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/main-core/designsystem/src/test/java/org/mifos/mobilewallet/mifospay/designsystem/ExampleUnitTest.kt b/main-core/designsystem/src/test/java/org/mifos/mobilewallet/mifospay/designsystem/ExampleUnitTest.kt new file mode 100644 index 000000000..749d46955 --- /dev/null +++ b/main-core/designsystem/src/test/java/org/mifos/mobilewallet/mifospay/designsystem/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package org.mifos.mobilewallet.mifospay.designsystem + +import org.junit.Test + +import org.junit.Assert.* + +/** + * 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) + } +} \ No newline at end of file diff --git a/main-core/ui/.gitignore b/main-core/ui/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/main-core/ui/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/main-core/ui/build.gradle.kts b/main-core/ui/build.gradle.kts new file mode 100644 index 000000000..a781ab91c --- /dev/null +++ b/main-core/ui/build.gradle.kts @@ -0,0 +1,44 @@ +@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) +} + +android { + namespace = "org.mifos.mobilewallet.mifospay.ui" + compileSdk = 34 + + defaultConfig { + minSdk = 24 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } +} + +dependencies { + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.appcompat) + implementation(libs.material) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.espresso.core) +} \ No newline at end of file diff --git a/main-core/ui/consumer-rules.pro b/main-core/ui/consumer-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/main-core/ui/proguard-rules.pro b/main-core/ui/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/main-core/ui/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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/main-core/ui/src/androidTest/java/org/mifos/mobilewallet/mifospay/ui/ExampleInstrumentedTest.kt b/main-core/ui/src/androidTest/java/org/mifos/mobilewallet/mifospay/ui/ExampleInstrumentedTest.kt new file mode 100644 index 000000000..c42303a7a --- /dev/null +++ b/main-core/ui/src/androidTest/java/org/mifos/mobilewallet/mifospay/ui/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package org.mifos.mobilewallet.mifospay.ui + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("org.mifos.mobilewallet.mifospay.ui.test", appContext.packageName) + } +} \ No newline at end of file diff --git a/main-core/ui/src/main/AndroidManifest.xml b/main-core/ui/src/main/AndroidManifest.xml new file mode 100644 index 000000000..a5918e68a --- /dev/null +++ b/main-core/ui/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/main-core/ui/src/test/java/org/mifos/mobilewallet/mifospay/ui/ExampleUnitTest.kt b/main-core/ui/src/test/java/org/mifos/mobilewallet/mifospay/ui/ExampleUnitTest.kt new file mode 100644 index 000000000..a812a1574 --- /dev/null +++ b/main-core/ui/src/test/java/org/mifos/mobilewallet/mifospay/ui/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package org.mifos.mobilewallet.mifospay.ui + +import org.junit.Test + +import org.junit.Assert.* + +/** + * 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) + } +} \ No newline at end of file diff --git a/mifospay/build.gradle.kts b/mifospay/build.gradle.kts index 67dbca6fe..44bbd439b 100644 --- a/mifospay/build.gradle.kts +++ b/mifospay/build.gradle.kts @@ -64,7 +64,7 @@ dependencies { implementation(libs.androidx.hilt.navigation.compose) implementation(libs.androidx.lifecycle.runtimeCompose) implementation(libs.androidx.lifecycle.viewModelCompose) - implementation(libs.androidx.compose.material.icons.extended) + implementation(libs.androidx.compose.material.iconsExtended) // ViewModel diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/auth/presenter/LoginPresenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/auth/presenter/LoginPresenter.kt index 279361506..2b6efa01c 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/auth/presenter/LoginPresenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/auth/presenter/LoginPresenter.kt @@ -2,7 +2,6 @@ package org.mifos.mobilewallet.mifospay.auth.presenter import org.mifos.mobilewallet.core.base.UseCase.UseCaseCallback import org.mifos.mobilewallet.core.base.UseCaseHandler -import org.mifos.mobilewallet.core.data.fineract.api.FineractApiManager import org.mifos.mobilewallet.core.data.fineract.entity.UserWithRole import org.mifos.mobilewallet.core.domain.model.client.Client import org.mifos.mobilewallet.core.domain.model.user.User @@ -12,7 +11,7 @@ import org.mifos.mobilewallet.core.domain.usecase.user.FetchUserDetails import org.mifos.mobilewallet.mifospay.auth.AuthContract import org.mifos.mobilewallet.mifospay.auth.AuthContract.LoginView import org.mifos.mobilewallet.mifospay.base.BaseView -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.utils.Constants import org.mifos.mobilewallet.mifospay.utils.DebugUtil import javax.inject.Inject @@ -97,10 +96,8 @@ class LoginPresenter @Inject constructor( } private fun createAuthenticatedService(user: User) { - val authToken = Constants.BASIC + - user.authenticationKey + val authToken = Constants.BASIC + user.authenticationKey preferencesHelper.saveToken(authToken) - FineractApiManager.createSelfService(preferencesHelper.token) } private fun saveUserDetails( diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/data/local/LocalRepository.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/data/local/LocalRepository.kt index de407b015..12dcf4ffd 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/data/local/LocalRepository.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/data/local/LocalRepository.kt @@ -1,5 +1,6 @@ package org.mifos.mobilewallet.mifospay.data.local +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.core.domain.model.client.Client import javax.inject.Inject import javax.inject.Singleton diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/di/ApplicationModule.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/di/ApplicationModule.kt index 0285c4171..df4439500 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/di/ApplicationModule.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/di/ApplicationModule.kt @@ -9,16 +9,37 @@ import dagger.hilt.components.SingletonComponent import org.mifos.mobilewallet.core.base.UseCaseHandler import org.mifos.mobilewallet.core.base.UseCaseThreadPoolScheduler import org.mifos.mobilewallet.core.data.fineract.api.FineractApiManager +import org.mifos.mobilewallet.core.data.fineract.api.SelfServiceApiManager +import org.mifos.mobilewallet.core.data.fineract.api.services.AccountTransfersService +import org.mifos.mobilewallet.core.data.fineract.api.services.AuthenticationService +import org.mifos.mobilewallet.core.data.fineract.api.services.BeneficiaryService +import org.mifos.mobilewallet.core.data.fineract.api.services.ClientService +import org.mifos.mobilewallet.core.data.fineract.api.services.DocumentService +import org.mifos.mobilewallet.core.data.fineract.api.services.InvoiceService +import org.mifos.mobilewallet.core.data.fineract.api.services.KYCLevel1Service +import org.mifos.mobilewallet.core.data.fineract.api.services.NotificationService +import org.mifos.mobilewallet.core.data.fineract.api.services.RegistrationService +import org.mifos.mobilewallet.core.data.fineract.api.services.RunReportService +import org.mifos.mobilewallet.core.data.fineract.api.services.SavedCardService +import org.mifos.mobilewallet.core.data.fineract.api.services.SavingsAccountsService +import org.mifos.mobilewallet.core.data.fineract.api.services.SearchService +import org.mifos.mobilewallet.core.data.fineract.api.services.StandingInstructionService +import org.mifos.mobilewallet.core.data.fineract.api.services.ThirdPartyTransferService +import org.mifos.mobilewallet.core.data.fineract.api.services.TwoFactorAuthService +import org.mifos.mobilewallet.core.data.fineract.api.services.UserService import org.mifos.mobilewallet.core.data.fineract.repository.FineractRepository import org.mifos.mobilewallet.mifospay.data.local.LocalRepository -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper +import javax.inject.Named +import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) class ApplicationModule { @Provides - fun provideUseCaseThreadPoolScheduler() : UseCaseThreadPoolScheduler = UseCaseThreadPoolScheduler() + fun provideUseCaseThreadPoolScheduler(): UseCaseThreadPoolScheduler = + UseCaseThreadPoolScheduler() @Provides fun providesUseCaseHandler(useCaseThreadPoolScheduler: UseCaseThreadPoolScheduler): UseCaseHandler { @@ -26,16 +47,75 @@ class ApplicationModule { } @Provides - fun providesFineractApiManager(): FineractApiManager { - return FineractApiManager() + @Singleton + fun providesFineractApiManager( + @Named("FineractAuthenticationService") authenticationService: AuthenticationService, + @Named("FineractClientService") clientService: ClientService, + @Named("FineractSavingsAccountsService") savingsAccountsService: SavingsAccountsService, + @Named("FineractRegistrationService") registrationService: RegistrationService, + searchService: SearchService, + documentService: DocumentService, + runReportService: RunReportService, + twoFactorAuthService: TwoFactorAuthService, + accountTransfersService: AccountTransfersService, + savedCardService: SavedCardService, + kYCLevel1Service: KYCLevel1Service, + invoiceService: InvoiceService, + userService: UserService, + @Named("FineractThirdPartyTransferService") thirdPartyTransferService: ThirdPartyTransferService, + standingInstructionService: StandingInstructionService, + notificationService: NotificationService, + ): FineractApiManager { + return FineractApiManager( + authenticationService, + clientService, + savingsAccountsService, + registrationService, + searchService, + documentService, + runReportService, + twoFactorAuthService, + accountTransfersService, + savedCardService, + kYCLevel1Service, + invoiceService, + userService, + thirdPartyTransferService, + standingInstructionService, + notificationService + ) } @Provides - fun providesFineractRepository(fineractApiManager: FineractApiManager): FineractRepository { - return FineractRepository(fineractApiManager) + @Singleton + fun providesSelfServiceApiManager( + @Named("SelfServiceAuthenticationService") authenticationService: AuthenticationService, + @Named("SelfServiceClientService") clientService: ClientService, + @Named("SelfServiceSavingsAccountsService") savingsAccountsService: SavingsAccountsService, + @Named("SelfServiceRegistrationService") registrationService: RegistrationService, + beneficiaryService: BeneficiaryService, + @Named("SelfServiceThirdPartyTransferService") thirdPartyTransferService: ThirdPartyTransferService, + ): SelfServiceApiManager { + return SelfServiceApiManager( + authenticationService, + clientService, + savingsAccountsService, + registrationService, + beneficiaryService, + thirdPartyTransferService + ) } @Provides + fun providesFineractRepository( + fineractApiManager: FineractApiManager, + selfServiceApiManager: SelfServiceApiManager + ): FineractRepository { + return FineractRepository(fineractApiManager, selfServiceApiManager) + } + + @Provides + @Singleton fun prefManager(@ApplicationContext context: Context): PreferencesHelper { return PreferencesHelper(context) } @@ -44,4 +124,4 @@ class ApplicationModule { fun providesLocalRepository(preferencesHelper: PreferencesHelper): LocalRepository { return LocalRepository(preferencesHelper) } -} \ No newline at end of file +} diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/di/NetworkModule.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/di/NetworkModule.kt new file mode 100644 index 000000000..250d0b53c --- /dev/null +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/di/NetworkModule.kt @@ -0,0 +1,220 @@ +package org.mifos.mobilewallet.mifospay.di + +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import org.mifos.mobilewallet.core.data.fineract.api.BaseURL +import org.mifos.mobilewallet.core.data.fineract.api.MifosWalletOkHttpClient +import org.mifos.mobilewallet.core.data.fineract.api.services.AccountTransfersService +import org.mifos.mobilewallet.core.data.fineract.api.services.AuthenticationService +import org.mifos.mobilewallet.core.data.fineract.api.services.BeneficiaryService +import org.mifos.mobilewallet.core.data.fineract.api.services.ClientService +import org.mifos.mobilewallet.core.data.fineract.api.services.DocumentService +import org.mifos.mobilewallet.core.data.fineract.api.services.InvoiceService +import org.mifos.mobilewallet.core.data.fineract.api.services.KYCLevel1Service +import org.mifos.mobilewallet.core.data.fineract.api.services.NotificationService +import org.mifos.mobilewallet.core.data.fineract.api.services.RegistrationService +import org.mifos.mobilewallet.core.data.fineract.api.services.RunReportService +import org.mifos.mobilewallet.core.data.fineract.api.services.SavedCardService +import org.mifos.mobilewallet.core.data.fineract.api.services.SavingsAccountsService +import org.mifos.mobilewallet.core.data.fineract.api.services.SearchService +import org.mifos.mobilewallet.core.data.fineract.api.services.StandingInstructionService +import org.mifos.mobilewallet.core.data.fineract.api.services.ThirdPartyTransferService +import org.mifos.mobilewallet.core.data.fineract.api.services.TwoFactorAuthService +import org.mifos.mobilewallet.core.data.fineract.api.services.UserService +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper +import org.mifos.mobilewallet.core.di.FineractApi +import org.mifos.mobilewallet.core.di.SelfServiceApi +import retrofit2.Retrofit +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory +import retrofit2.converter.gson.GsonConverterFactory +import javax.inject.Named +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +class NetworkModule { + + @Provides + @Singleton + @SelfServiceApi + fun providesRetrofitSelfService(preferencesHelper: PreferencesHelper): Retrofit { + return Retrofit.Builder() + .baseUrl(BaseURL().selfServiceUrl) + .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(MifosWalletOkHttpClient(preferencesHelper).mifosOkHttpClient) + .build() + } + + @Provides + @Singleton + @FineractApi + fun providesRetrofitFineract(preferencesHelper: PreferencesHelper): Retrofit { + return Retrofit.Builder() + .baseUrl(BaseURL().url) + .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(MifosWalletOkHttpClient(preferencesHelper).mifosOkHttpClient) + .build() + } + + //-----Fineract API Service---------// + + @Provides + @Singleton + @Named("FineractAuthenticationService") + fun providesAuthenticationService(@FineractApi retrofit: Retrofit): AuthenticationService { + return retrofit.create(AuthenticationService::class.java) + } + + @Provides + @Singleton + @Named("FineractClientService") + fun providesClientService(@FineractApi retrofit: Retrofit): ClientService { + return retrofit.create(ClientService::class.java) + } + + @Provides + @Singleton + @Named("FineractSavingsAccountsService") + fun providesSavingsAccountsService(@FineractApi retrofit: Retrofit): SavingsAccountsService { + return retrofit.create(SavingsAccountsService::class.java) + } + + @Provides + @Singleton + @Named("FineractRegistrationService") + fun providesRegistrationService(@FineractApi retrofit: Retrofit): RegistrationService { + return retrofit.create(RegistrationService::class.java) + } + + @Provides + @Singleton + fun providesSearchService(@FineractApi retrofit: Retrofit): SearchService { + return retrofit.create(SearchService::class.java) + } + + @Provides + @Singleton + fun providesSavedCardService(@FineractApi retrofit: Retrofit): SavedCardService { + return retrofit.create(SavedCardService::class.java) + } + + @Provides + @Singleton + fun providesDocumentService(@FineractApi retrofit: Retrofit): DocumentService { + return retrofit.create(DocumentService::class.java) + } + + @Provides + @Singleton + fun provideTwoFactorAuthService(@FineractApi retrofit: Retrofit): TwoFactorAuthService { + return retrofit.create(TwoFactorAuthService::class.java) + } + + @Provides + @Singleton + fun providesAccountTransfersService(@FineractApi retrofit: Retrofit): AccountTransfersService { + return retrofit.create(AccountTransfersService::class.java) + } + + @Provides + @Singleton + fun providesRunReportService(@FineractApi retrofit: Retrofit): RunReportService { + return retrofit.create(RunReportService::class.java) + } + + @Provides + @Singleton + fun providesKYCLevel1Service(@FineractApi retrofit: Retrofit): KYCLevel1Service { + return retrofit.create(KYCLevel1Service::class.java) + } + + @Provides + @Singleton + fun providesInvoiceService(@FineractApi retrofit: Retrofit): InvoiceService { + return retrofit.create(InvoiceService::class.java) + } + + @Provides + @Singleton + fun providesUserService(@FineractApi retrofit: Retrofit): UserService { + return retrofit.create(UserService::class.java) + } + + @Provides + @Singleton + @Named("FineractThirdPartyTransferService") + fun providesThirdPartyTransferService(@FineractApi retrofit: Retrofit): ThirdPartyTransferService { + return retrofit.create(ThirdPartyTransferService::class.java) + } + + @Provides + @Singleton + fun providesNotificationService(@FineractApi retrofit: Retrofit): NotificationService { + return retrofit.create(NotificationService::class.java) + } + + @Provides + @Singleton + fun providesStandingInstructionService(@FineractApi retrofit: Retrofit): StandingInstructionService { + return retrofit.create(StandingInstructionService::class.java) + } + + //-------SelfService API Service-------// + + @Provides + @Singleton + @Named("SelfServiceAuthenticationService") + fun providesSelfServiceAuthenticationService( + @SelfServiceApi retrofit: Retrofit + ): AuthenticationService { + return retrofit.create(AuthenticationService::class.java) + } + + @Provides + @Singleton + @Named("SelfServiceClientService") + fun providesSelfServiceClientService( + @SelfServiceApi retrofit: Retrofit + ): ClientService { + return retrofit.create(ClientService::class.java) + } + + @Provides + @Singleton + @Named("SelfServiceSavingsAccountsService") + fun providesSelfServiceSavingsAccountsService( + @SelfServiceApi retrofit: Retrofit + ): SavingsAccountsService { + return retrofit.create(SavingsAccountsService::class.java) + } + + @Provides + @Singleton + @Named("SelfServiceRegistrationService") + fun providesSelfServiceRegistrationService( + @SelfServiceApi retrofit: Retrofit + ): RegistrationService { + return retrofit.create(RegistrationService::class.java) + } + + @Provides + @Singleton + fun providesSelfServiceBeneficiaryService( + @SelfServiceApi retrofit: Retrofit + ): BeneficiaryService { + return retrofit.create(BeneficiaryService::class.java) + } + + @Provides + @Singleton + @Named("SelfServiceThirdPartyTransferService") + fun providesSelfServiceThirdPartyTransferService( + @SelfServiceApi retrofit: Retrofit + ): ThirdPartyTransferService { + return retrofit.create(ThirdPartyTransferService::class.java) + } +} \ No newline at end of file diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/editprofile/presenter/EditProfilePresenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/editprofile/presenter/EditProfilePresenter.kt index 082848dc2..9e1fe3ff3 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/editprofile/presenter/EditProfilePresenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/editprofile/presenter/EditProfilePresenter.kt @@ -9,7 +9,7 @@ import org.mifos.mobilewallet.core.domain.usecase.user.AuthenticateUser import org.mifos.mobilewallet.core.domain.usecase.user.UpdateUser import org.mifos.mobilewallet.mifospay.R import org.mifos.mobilewallet.mifospay.base.BaseView -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.editprofile.EditProfileContract import org.mifos.mobilewallet.mifospay.editprofile.EditProfileContract.EditProfileView import javax.inject.Inject diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/home/presenter/HomeViewModel.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/home/presenter/HomeViewModel.kt index cd39ebf8a..2725556de 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/home/presenter/HomeViewModel.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/home/presenter/HomeViewModel.kt @@ -16,7 +16,7 @@ import org.mifos.mobilewallet.core.domain.usecase.account.FetchAccount import org.mifos.mobilewallet.core.domain.usecase.account.FetchAccountTransactions import org.mifos.mobilewallet.mifospay.base.BaseView import org.mifos.mobilewallet.mifospay.data.local.LocalRepository -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.history.HistoryContract.TransactionsHistoryAsync import org.mifos.mobilewallet.mifospay.history.TransactionsHistory import org.mifos.mobilewallet.mifospay.home.BaseHomeContract diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/home/presenter/ProfilePresenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/home/presenter/ProfilePresenter.kt index fc726722c..5ab079acf 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/home/presenter/ProfilePresenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/home/presenter/ProfilePresenter.kt @@ -5,7 +5,7 @@ import org.mifos.mobilewallet.core.base.UseCaseHandler import org.mifos.mobilewallet.core.domain.usecase.client.FetchClientImage import org.mifos.mobilewallet.mifospay.base.BaseView import org.mifos.mobilewallet.mifospay.data.local.LocalRepository -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.home.BaseHomeContract import org.mifos.mobilewallet.mifospay.home.BaseHomeContract.ProfileView import org.mifos.mobilewallet.mifospay.utils.DebugUtil diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/invoice/presenter/InvoicePresenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/invoice/presenter/InvoicePresenter.kt index c34c3625e..0d06efb8d 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/invoice/presenter/InvoicePresenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/invoice/presenter/InvoicePresenter.kt @@ -5,7 +5,7 @@ import org.mifos.mobilewallet.core.base.UseCase.UseCaseCallback import org.mifos.mobilewallet.core.base.UseCaseHandler import org.mifos.mobilewallet.core.domain.usecase.invoice.FetchInvoice import org.mifos.mobilewallet.mifospay.base.BaseView -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.invoice.InvoiceContract import org.mifos.mobilewallet.mifospay.invoice.InvoiceContract.InvoiceView import javax.inject.Inject diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/invoice/presenter/InvoicesPresenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/invoice/presenter/InvoicesPresenter.kt index d69a1f87f..36b8a4995 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/invoice/presenter/InvoicesPresenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/invoice/presenter/InvoicesPresenter.kt @@ -6,7 +6,7 @@ import org.mifos.mobilewallet.core.base.UseCaseHandler import org.mifos.mobilewallet.core.domain.usecase.invoice.FetchInvoices import org.mifos.mobilewallet.mifospay.R import org.mifos.mobilewallet.mifospay.base.BaseView -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.invoice.InvoiceContract import org.mifos.mobilewallet.mifospay.invoice.InvoiceContract.InvoicesView import org.mifos.mobilewallet.mifospay.utils.Constants diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/kyc/presenter/KYCLevel2Presenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/kyc/presenter/KYCLevel2Presenter.kt index 3220cd1ff..b7a512748 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/kyc/presenter/KYCLevel2Presenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/kyc/presenter/KYCLevel2Presenter.kt @@ -12,7 +12,7 @@ import org.mifos.mobilewallet.core.base.UseCaseHandler import org.mifos.mobilewallet.core.domain.usecase.kyc.UploadKYCDocs import org.mifos.mobilewallet.mifospay.MifosPayApp import org.mifos.mobilewallet.mifospay.base.BaseView -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.kyc.KYCContract import org.mifos.mobilewallet.mifospay.kyc.KYCContract.KYCLevel2View import org.mifos.mobilewallet.mifospay.utils.Constants diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/merchants/presenter/MerchantTransferPresenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/merchants/presenter/MerchantTransferPresenter.kt index 589d2eca8..f2e66b8c6 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/merchants/presenter/MerchantTransferPresenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/merchants/presenter/MerchantTransferPresenter.kt @@ -12,7 +12,7 @@ import org.mifos.mobilewallet.core.domain.usecase.account.FetchAccountTransfer import org.mifos.mobilewallet.mifospay.R import org.mifos.mobilewallet.mifospay.base.BaseView import org.mifos.mobilewallet.mifospay.data.local.LocalRepository -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.history.HistoryContract.TransactionsHistoryAsync import org.mifos.mobilewallet.mifospay.history.TransactionsHistory import org.mifos.mobilewallet.mifospay.home.BaseHomeContract diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/passcode/presenter/PassCodePresenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/passcode/presenter/PassCodePresenter.kt index 35fba34fd..d752ed4fa 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/passcode/presenter/PassCodePresenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/passcode/presenter/PassCodePresenter.kt @@ -13,7 +13,7 @@ import org.mifos.mobilewallet.core.domain.usecase.user.AuthenticateUser import org.mifos.mobilewallet.mifospay.base.BaseView -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.passcode.PassCodeContract @@ -62,14 +62,4 @@ class PassCodePresenter @Inject constructor( mPassCodeView?.setPresenter(this) } - - - - - fun createAuthenticatedService() { - - FineractApiManager.createSelfService(preferencesHelper.token) - - } - } \ No newline at end of file diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/passcode/ui/PassCodeActivity.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/passcode/ui/PassCodeActivity.kt index a891f1026..65b5a8fc8 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/passcode/ui/PassCodeActivity.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/passcode/ui/PassCodeActivity.kt @@ -59,7 +59,6 @@ class PassCodeActivity : MifosPassCodeActivity(), PassCodeView { override fun startNextActivity() { // authenticate user with saved Preferences - mPresenter?.createAuthenticatedService() if (deepLinkURI != null) { val uri = Uri.parse(deepLinkURI) val intent = Intent(this@PassCodeActivity, ReceiptActivity::class.java) diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/password/presenter/EditPasswordPresenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/password/presenter/EditPasswordPresenter.kt index ddfa237f9..1efbcc91d 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/password/presenter/EditPasswordPresenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/password/presenter/EditPasswordPresenter.kt @@ -6,7 +6,7 @@ import org.mifos.mobilewallet.core.domain.model.user.UpdateUserEntityPassword import org.mifos.mobilewallet.core.domain.usecase.user.AuthenticateUser import org.mifos.mobilewallet.core.domain.usecase.user.UpdateUser import org.mifos.mobilewallet.mifospay.base.BaseView -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.password.EditPasswordContract import org.mifos.mobilewallet.mifospay.password.EditPasswordContract.EditPasswordView import org.mifos.mobilewallet.mifospay.utils.Constants diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/receipt/presenter/ReceiptPresenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/receipt/presenter/ReceiptPresenter.kt index 0f68c994f..7af65c992 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/receipt/presenter/ReceiptPresenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/receipt/presenter/ReceiptPresenter.kt @@ -6,7 +6,7 @@ import org.mifos.mobilewallet.core.domain.usecase.account.DownloadTransactionRec import org.mifos.mobilewallet.core.domain.usecase.account.FetchAccountTransaction import org.mifos.mobilewallet.core.domain.usecase.account.FetchAccountTransfer import org.mifos.mobilewallet.mifospay.base.BaseView -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.receipt.ReceiptContract import org.mifos.mobilewallet.mifospay.receipt.ReceiptContract.ReceiptView import org.mifos.mobilewallet.mifospay.utils.Constants diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/registration/presenter/SignupPresenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/registration/presenter/SignupPresenter.kt index e984a156a..e4085d564 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/registration/presenter/SignupPresenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/registration/presenter/SignupPresenter.kt @@ -18,7 +18,7 @@ import org.mifos.mobilewallet.core.domain.usecase.user.DeleteUser import org.mifos.mobilewallet.core.domain.usecase.user.FetchUserDetails import org.mifos.mobilewallet.core.domain.usecase.user.UpdateUser import org.mifos.mobilewallet.mifospay.base.BaseView -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.registration.RegistrationContract import org.mifos.mobilewallet.mifospay.registration.RegistrationContract.SignupView import org.mifos.mobilewallet.mifospay.utils.Constants @@ -240,10 +240,8 @@ class SignupPresenter @Inject constructor( } private fun createAuthenticatedService(user: User) { - val authToken = Constants.BASIC + - user.authenticationKey + val authToken = Constants.BASIC + user.authenticationKey mPreferencesHelper.saveToken(authToken) - FineractApiManager.createSelfService(mPreferencesHelper.token) } private fun saveUserDetails( diff --git a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/standinginstruction/presenter/NewSIPresenter.kt b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/standinginstruction/presenter/NewSIPresenter.kt index f325506bb..125672e3d 100644 --- a/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/standinginstruction/presenter/NewSIPresenter.kt +++ b/mifospay/src/main/java/org/mifos/mobilewallet/mifospay/standinginstruction/presenter/NewSIPresenter.kt @@ -6,7 +6,7 @@ import org.mifos.mobilewallet.core.domain.model.SearchResult import org.mifos.mobilewallet.core.domain.usecase.client.SearchClient import org.mifos.mobilewallet.core.domain.usecase.standinginstruction.CreateStandingTransaction import org.mifos.mobilewallet.mifospay.base.BaseView -import org.mifos.mobilewallet.mifospay.data.local.PreferencesHelper +import org.mifos.mobilewallet.core.data.fineract.local.PreferencesHelper import org.mifos.mobilewallet.mifospay.standinginstruction.StandingInstructionContract import java.text.SimpleDateFormat import java.util.* @@ -16,7 +16,8 @@ import javax.inject.Inject * Created by Shivansh */ class NewSIPresenter @Inject constructor (val mUseCaseHandler: UseCaseHandler, - val preferencesHelper: PreferencesHelper) + val preferencesHelper: PreferencesHelper +) : StandingInstructionContract.NewSIPresenter { lateinit var mNewSIView: StandingInstructionContract.NewSIView diff --git a/settings.gradle.kts b/settings.gradle.kts index 7fc14186a..f686e35b9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -23,3 +23,8 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") include(":mifospay") include(":core") include(":main-core:datastore") +include(":feature:auth") +include(":main-core:designsystem") +include(":main-core:ui") +include(":main-core:data") +include(":main-core:common")