Refactor - [:core:common] Apply & Fix Ktlint & Detekt Rules (#2672)

* Refactor - [:core:common] Apply & Fix Ktlint & Detekt Rules

Jira tasks - [MM-56](https://mifosforge.jira.com/browse/MM-56)

* feat: add getTodayFormatted function

Added a new function `getTodayFormatted` to `DateHelper.kt` which returns today's date in "
dd-MM-yyyy" format.

* Refactor - [:core:common] Apply & Fix Ktlint & Detekt Rules

Jira tasks - [MM-56](https://mifosforge.jira.com/browse/MM-56)
This commit is contained in:
Sk Niyaj Ali 2024-08-27 22:28:10 +05:30 committed by GitHub
parent eb0f4b4f31
commit de8a26b992
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
68 changed files with 1326 additions and 282 deletions

7
.editorconfig Normal file
View File

@ -0,0 +1,7 @@
# https://editorconfig.org/
# This configuration is used by ktlint when spotless invokes it
[*.{kt,kts}]
ij_kotlin_allow_trailing_comma=true
ij_kotlin_allow_trailing_comma_on_call_site=true
ktlint_function_naming_ignore_when_annotated_with=Composable, Test, Preview

View File

@ -18,7 +18,7 @@
<application
android:name=".MifosSelfServiceApp"
android:allowBackup="true"
android:icon="@mipmap/mifos_icon"
android:icon="@mipmap/core_common_mifos_icon"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"

View File

@ -26,7 +26,6 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import org.mifos.mobile.R
import org.mifos.mobile.core.datastore.model.MifosNotification
import org.mifos.mobile.ui.activities.HomeActivity
class MifosFirebaseMessagingService : FirebaseMessagingService() {
@ -62,7 +61,7 @@ class MifosFirebaseMessagingService : FirebaseMessagingService() {
)
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.mifos_icon)
.setSmallIcon(R.mipmap.core_common_mifos_icon)
.setContentTitle(getString(R.string.app_name))
.setContentText(message)
.setAutoCancel(true)

View File

@ -10,7 +10,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<include layout="@layout/core_common_toolbar" />
<FrameLayout style="@style/FrameLayout.Container" />
</LinearLayout>

View File

@ -14,7 +14,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<include layout="@layout/core_common_toolbar" />
<FrameLayout style="@style/FrameLayout.Container" />
</LinearLayout>

View File

@ -8,7 +8,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<include layout="@layout/core_common_toolbar" />
<FrameLayout
android:id="@+id/container"

View File

@ -12,7 +12,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<include layout="@layout/core_common_toolbar" />
<FrameLayout style="@style/FrameLayout.Container" />
</LinearLayout>

View File

@ -9,7 +9,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<include layout="@layout/core_common_toolbar" />
<FrameLayout style="@style/FrameLayout.Container" />
</LinearLayout>

View File

@ -10,7 +10,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<include layout="@layout/core_common_toolbar" />
<FrameLayout style="@style/FrameLayout.Container" />
</LinearLayout>

View File

@ -9,7 +9,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<include layout="@layout/core_common_toolbar" />
<WebView
android:id="@+id/webView"

View File

@ -4,7 +4,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<include layout="@layout/core_common_toolbar" />
<FrameLayout style="@style/FrameLayout.Container" />

View File

@ -8,7 +8,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<include layout="@layout/core_common_toolbar" />
<FrameLayout style="@style/FrameLayout.Container" />
</LinearLayout>

View File

@ -1,4 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2024 Mifos Initiative
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file,
You can obtain one at https://mozilla.org/MPL/2.0/.
See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
-->
<com.google.android.material.appbar.MaterialToolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"

View File

@ -37,7 +37,7 @@
<string name="share">شارك</string>
<string name="share_account">حصة الحساب</string>
<string name="clients_list">شيء العميل</string>
<string name="working">العمل</string>
<string name="core_common_working">العمل</string>
<string name="status_image">صورة الحالة</string>
<string name="loan_repayment_schedule">جدول الدفع</string>
<string name="last_transaction">آخر معاملة</string>

View File

@ -35,7 +35,7 @@
<string name="share">শেয়ার</string>
<string name="share_account">আপনার অ্যাকাউন্ট শেয়ার করুন</string>
<string name="clients_list">একটি গ্রাহক চয়ন করুন</string>
<string name="working">কাজ</string>
<string name="core_common_working">কাজ</string>
<string name="status_image">রাষ্ট্রের ছবি</string>
<string name="loan_repayment_schedule">পরিশোধের সময়সূচী</string>
<string name="last_transaction">শেষ লেনদেন</string>

View File

@ -35,7 +35,7 @@
<string name="share">Cuota</string>
<string name="share_account">Comparte tu cuenta</string>
<string name="clients_list">Elige un cliente</string>
<string name="working">Laboral</string>
<string name="core_common_working">Laboral</string>
<string name="status_image">Imagen del estado</string>
<string name="loan_repayment_schedule">Calendario de reembolso</string>
<string name="last_transaction">Ultima transaccion</string>

View File

@ -421,7 +421,7 @@
<string name="withdrawal_date">تاریخ برداشت</string>
<string name="withdrawal_transfer">انتقال برداشت</string>
<string name="withdrawn">برداشت</string>
<string name="working">کار کردن</string>
<string name="core_common_working">کار کردن</string>
<string name="yes">بلي</string>
<string name="app_info">اطلاعات برنامه</string>
<string name="login_failed">ورود ناموفق بود، لطفاً بعداً دوباره امتحان کنید.</string>

View File

@ -35,7 +35,7 @@
<string name="share">Part</string>
<string name="share_account">Partagez votre compte</string>
<string name="clients_list">Choisissez un client</string>
<string name="working">Travail</string>
<string name="core_common_working">Travail</string>
<string name="status_image">Image de l\'état</string>
<string name="loan_repayment_schedule">Calendrier de remboursement</string>
<string name="last_transaction">Dernière transaction</string>

View File

@ -39,7 +39,7 @@
<string name="share">शेयर</string>
<string name="share_account">शेयर खाता</string>
<string name="clients_list">एक ग्राहक चुनें</string>
<string name="working">काम कर रहे</string>
<string name="core_common_working">काम कर रहे</string>
<string name="submitted">जमा किया गया</string>
<string name="disbursement">अदायगी</string>
<string name="status_image">स्थिति छवि</string>

View File

@ -35,7 +35,7 @@
<string name="share">Saham</string>
<string name="share_account">Bagikan akun Anda</string>
<string name="clients_list">Pilih pelanggan</string>
<string name="working">Kerja</string>
<string name="core_common_working">Kerja</string>
<string name="status_image">Citra negara</string>
<string name="loan_repayment_schedule">Jadwal pembayaran kembali</string>
<string name="last_transaction">Transaksi terakhir</string>

View File

@ -35,7 +35,7 @@
<string name="share">ចែករំលែក</string>
<string name="share_account">ចែករំលែកគណនីរបស់អ្នក</string>
<string name="clients_list">ជ្រើសរើសអតិថិជន</string>
<string name="working">ធ្វើការ</string>
<string name="core_common_working">ធ្វើការ</string>
<string name="status_image">រូបភាពរបស់រដ្ឋ</string>
<string name="loan_repayment_schedule">កាលវិភាគសងប្រាក់</string>
<string name="last_transaction">កិច្ចការចុងក្រោយ</string>

View File

@ -35,7 +35,7 @@
<string name="share">ಹಂಚಿಕೊಳ್ಳಿ</string>
<string name="share_account">ನಿಮ್ಮ ಖಾತೆಯನ್ನು ಹಂಚಿಕೊಳ್ಳಿ</string>
<string name="clients_list">ಗ್ರಾಹಕರನ್ನು ಆಯ್ಕೆ ಮಾಡಿ</string>
<string name="working">ಕೆಲಸ</string>
<string name="core_common_working">ಕೆಲಸ</string>
<string name="status_image">ರಾಜ್ಯದ ಚಿತ್ರ</string>
<string name="loan_repayment_schedule">ಮರುಪಾವತಿಯ ವೇಳಾಪಟ್ಟಿ</string>
<string name="last_transaction">ಕೊನೆಯ ವಹಿವಾಟು</string>

View File

@ -37,7 +37,7 @@
<string name="share">ဝေစု</string>
<string name="share_account">ဝေမျှမယ်အကောင့်</string>
<string name="clients_list">တစ်ဦးကို client ကို ရွေးချယ်.</string>
<string name="working">အလုပ်အဖွဲ့</string>
<string name="core_common_working">အလုပ်အဖွဲ့</string>
<string name="status_image">အဆင့်အတန်းပုံရိပ်</string>
<string name="loan_repayment_schedule">ပြန်ဆပ်ဇယား</string>
<string name="last_transaction">နောက်ဆုံးငွေသွင်းငွေထုတ်</string>

View File

@ -35,7 +35,7 @@
<string name="share">Udostępnij</string>
<string name="share_account">Udostępnij konto</string>
<string name="clients_list">Wybierz klienta</string>
<string name="working">Pracujący</string>
<string name="core_common_working">Pracujący</string>
<string name="status_image">Obraz stanu</string>
<string name="loan_repayment_schedule">Harmonogram spłaty</string>
<string name="last_transaction">Ostatnia transakcja</string>

View File

@ -35,7 +35,7 @@
<string name="share">Partilhar</string>
<string name="share_account">Partilhar conta</string>
<string name="clients_list">Escolheu um cliente</string>
<string name="working">A trabalhar</string>
<string name="core_common_working">A trabalhar</string>
<string name="status_image">Imagem de Status</string>
<string name="loan_repayment_schedule">Cronograma de Reembolso</string>
<string name="last_transaction">Última Transação </string>

View File

@ -35,7 +35,7 @@
<string name="share">Доля</string>
<string name="share_account">Поделитесь своим аккаунтом</string>
<string name="clients_list">Выберите клиента</string>
<string name="working">Работа</string>
<string name="core_common_working">Работа</string>
<string name="status_image">Изображение государства</string>
<string name="loan_repayment_schedule">График погашения</string>
<string name="last_transaction">Последняя сделка</string>

View File

@ -35,7 +35,7 @@
<string name="share">Kushiriki</string>
<string name="share_account">Shiriki akaunti yako</string>
<string name="clients_list">Chagua mteja</string>
<string name="working">Kazi</string>
<string name="core_common_working">Kazi</string>
<string name="status_image">Picha ya hali</string>
<string name="loan_repayment_schedule">Ratiba ya kulipa</string>
<string name="last_transaction">Shughuli ya mwisho</string>

View File

@ -36,7 +36,7 @@
<string name="share">వాటా</string>
<string name="share_account">వాటా ఖాతా</string>
<string name="clients_list">ఒక క్లయింట్ ఎంచుకోండి</string>
<string name="working">వర్కింగ్</string>
<string name="core_common_working">వర్కింగ్</string>
<string name="status_image">స్థితి చిత్రం</string>
<string name="loan_repayment_schedule">తిరిగి చెల్లింపు షెడ్యూల్</string>
<string name="last_transaction">చివరి లావాదేవీ</string>

View File

@ -36,7 +36,7 @@
<string name="share">اشتراک کریں</string>
<string name="share_account">اکاؤنٹ کا اشتراک کریں</string>
<string name="clients_list">کسٹمر چیز</string>
<string name="working">کام کر رہے ہیں</string>
<string name="core_common_working">کام کر رہے ہیں</string>
<string name="status_image">موجودہ حالت کی تصویر</string>
<string name="loan_repayment_schedule">قرض کی ادائیگی کی شیڈول</string>
<string name="last_transaction">پچھلا ٹرانزیکشن</string>

View File

@ -81,8 +81,8 @@
<!-- Dimen values for Account Status-->
<dimen name="account_status_width">25dp</dimen>
<dimen name="account_status_height">25dp</dimen>
<dimen name="core_common_account_status_width">25dp</dimen>
<dimen name="core_common_account_status_height">25dp</dimen>
<!-- Dimen values for Account Status-->
<dimen name="dashboard_status_width">55dp</dimen>

View File

@ -37,7 +37,7 @@
<string name="share">Share</string>
<string name="share_account">Share Account</string>
<string name="clients_list">Chose a client</string>
<string name="working">Working</string>
<string name="core_common_working">Working</string>
<string name="status_image">Status Image</string>
<string name="loan_repayment_schedule">Repayment Schedule</string>
<string name="last_transaction">Last Transaction</string>
@ -510,8 +510,8 @@
<string name="scan_your_fingerprint">Scan your fingerprint</string>
<string name="language_type" translatable="false">language_type</string>
<string name="default_system_language" translatable="false">default_system_language</string>
<string name="core_common_language_type" translatable="false">language_type</string>
<string name="core_common_default_system_language" translatable="false">default_system_language</string>
<string name="theme_type" translatable="false">theme_type</string>
<string name="total_saving_balance">Total Savings Balance</string>
<string name="total_loan_balance">Total Loan Balance</string>
@ -599,7 +599,7 @@
<item>فارسی</item>
</string-array>
<string-array name="languages_value" translatable="false">
<string-array name="core_common_languages_value" translatable="false">
<item>System_Language</item>
<item>en</item>
<item>hi</item>

View File

@ -21,9 +21,9 @@
<androidx.preference.ListPreference
android:defaultValue="System_Language"
android:entries="@array/languages"
android:entryValues="@array/languages_value"
android:entryValues="@array/core_common_languages_value"
android:icon="@drawable/ic_translate"
android:key="@string/language_type"
android:key="@string/core_common_language_type"
android:summary="@string/choose_language"
android:title="@string/language" />

985
config/detekt/detekt.yml Normal file
View File

@ -0,0 +1,985 @@
build:
maxIssues: 0
excludeCorrectable: false
weights:
# complexity: 2
# LongParameterList: 1
# style: 1
# comments: 1
config:
validation: true
warningsAsErrors: false
checkExhaustiveness: false
# when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]'
excludes: ""
processors:
active: true
exclude:
- "DetektProgressListener"
# - 'KtFileCountProcessor'
# - 'PackageCountProcessor'
# - 'ClassCountProcessor'
# - 'FunctionCountProcessor'
# - 'PropertyCountProcessor'
# - 'ProjectComplexityProcessor'
# - 'ProjectCognitiveComplexityProcessor'
# - 'ProjectLLOCProcessor'
# - 'ProjectCLOCProcessor'
# - 'ProjectLOCProcessor'
# - 'ProjectSLOCProcessor'
# - 'LicenseHeaderLoaderExtension'
console-reports:
active: true
exclude:
- "ProjectStatisticsReport"
- "ComplexityReport"
- "NotificationReport"
- "FindingsReport"
- "FileBasedFindingsReport"
# - 'LiteFindingsReport'
output-reports:
active: true
exclude: []
# - 'TxtOutputReport'
# - 'XmlOutputReport'
# - 'HtmlOutputReport'
# - 'MdOutputReport'
# - 'SarifOutputReport'
comments:
active: true
AbsentOrWrongFileLicense:
active: false
licenseTemplateFile: "license.template"
licenseTemplateIsRegex: false
CommentOverPrivateFunction:
active: false
CommentOverPrivateProperty:
active: false
DeprecatedBlockTag:
active: false
EndOfSentenceFormat:
active: false
endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)'
KDocReferencesNonPublicProperty:
active: false
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
OutdatedDocumentation:
active: false
matchTypeParameters: true
matchDeclarationsOrder: true
allowParamOnConstructorProperties: false
UndocumentedPublicClass:
active: false
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
searchInNestedClass: true
searchInInnerClass: true
searchInInnerObject: true
searchInInnerInterface: true
searchInProtectedClass: false
UndocumentedPublicFunction:
active: false
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
searchProtectedFunction: false
UndocumentedPublicProperty:
active: false
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
searchProtectedProperty: false
complexity:
active: true
CognitiveComplexMethod:
active: false
threshold: 15
ComplexCondition:
active: true
threshold: 4
ComplexInterface:
active: false
threshold: 10
includeStaticDeclarations: false
includePrivateDeclarations: false
ignoreOverloaded: false
CyclomaticComplexMethod:
active: true
threshold: 15
ignoreSingleWhenExpression: false
ignoreSimpleWhenEntries: false
ignoreNestingFunctions: false
nestingFunctions:
- "also"
- "apply"
- "forEach"
- "isNotNull"
- "ifNull"
- "let"
- "run"
- "use"
- "with"
LabeledExpression:
active: false
ignoredLabels: []
LargeClass:
active: true
threshold: 600
LongMethod:
active: true
threshold: 150 #60
LongParameterList:
active: true
# Updating Common values based on current scenario
functionThreshold: 20 #6
constructorThreshold: 30 #7
ignoreDefaultParameters: false
ignoreDataClasses: true
ignoreAnnotatedParameter: []
MethodOverloading:
active: false
threshold: 6
NamedArguments:
active: false
threshold: 3
ignoreArgumentsMatchingNames: false
NestedBlockDepth:
active: true
threshold: 4
NestedScopeFunctions:
active: false
threshold: 1
functions:
- "kotlin.apply"
- "kotlin.run"
- "kotlin.with"
- "kotlin.let"
- "kotlin.also"
ReplaceSafeCallChainWithRun:
active: false
StringLiteralDuplication:
active: false
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
threshold: 3
ignoreAnnotation: true
excludeStringsWithLessThan5Characters: true
ignoreStringsRegex: "$^"
TooManyFunctions:
active: true
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
# Modifying default values 11 to 20
thresholdInFiles: 20
thresholdInClasses: 20
thresholdInInterfaces: 20
thresholdInObjects: 20
thresholdInEnums: 20
ignoreDeprecated: false
ignorePrivate: false
ignoreOverridden: false
coroutines:
active: true
GlobalCoroutineUsage:
active: false
InjectDispatcher:
active: true
dispatcherNames:
- "IO"
- "Default"
- "Unconfined"
RedundantSuspendModifier:
active: true
SleepInsteadOfDelay:
active: true
SuspendFunSwallowedCancellation:
active: false
SuspendFunWithCoroutineScopeReceiver:
active: false
SuspendFunWithFlowReturnType:
active: true
empty-blocks:
active: true
EmptyCatchBlock:
active: true
allowedExceptionNameRegex: "_|(ignore|expected).*"
EmptyClassBlock:
active: true
EmptyDefaultConstructor:
active: true
EmptyDoWhileBlock:
active: true
EmptyElseBlock:
active: true
EmptyFinallyBlock:
active: true
EmptyForBlock:
active: true
EmptyFunctionBlock:
active: false # Turning off for current implementation
ignoreOverridden: false
EmptyIfBlock:
active: true
EmptyInitBlock:
active: true
EmptyKtFile:
active: true
EmptySecondaryConstructor:
active: true
EmptyTryBlock:
active: true
EmptyWhenBlock:
active: true
EmptyWhileBlock:
active: true
exceptions:
active: true
ExceptionRaisedInUnexpectedLocation:
active: true
methodNames:
- "equals"
- "finalize"
- "hashCode"
- "toString"
InstanceOfCheckForException:
active: true
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
NotImplementedDeclaration:
active: false
ObjectExtendsThrowable:
active: false
PrintStackTrace:
active: true
RethrowCaughtException:
active: true
ReturnFromFinally:
active: true
ignoreLabeled: false
SwallowedException:
active: false # Turning off for current implementation
ignoredExceptionTypes:
- "InterruptedException"
- "MalformedURLException"
- "NumberFormatException"
- "ParseException"
allowedExceptionNameRegex: "_|(ignore|expected).*"
ThrowingExceptionFromFinally:
active: true
ThrowingExceptionInMain:
active: false
ThrowingExceptionsWithoutMessageOrCause:
active: true
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
exceptions:
- "ArrayIndexOutOfBoundsException"
- "Exception"
- "IllegalArgumentException"
- "IllegalMonitorStateException"
- "IllegalStateException"
- "IndexOutOfBoundsException"
- "NullPointerException"
- "RuntimeException"
- "Throwable"
ThrowingNewInstanceOfSameException:
active: true
TooGenericExceptionCaught:
active: false
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
exceptionNames:
- "ArrayIndexOutOfBoundsException"
- "Error"
- "Exception"
- "IllegalMonitorStateException"
- "IndexOutOfBoundsException"
- "NullPointerException"
- "RuntimeException"
- "Throwable"
allowedExceptionNameRegex: "_|(ignore|expected).*"
TooGenericExceptionThrown:
active: false
exceptionNames:
- "Error"
- "Exception"
- "RuntimeException"
- "Throwable"
naming:
active: true
BooleanPropertyNaming:
active: false
allowedPattern: "^(is|has|are)"
ClassNaming:
active: true
classPattern: "[A-Z][a-zA-Z0-9]*"
ConstructorParameterNaming:
active: true
parameterPattern: "[a-z][A-Za-z0-9]*"
privateParameterPattern: "[a-z][A-Za-z0-9]*"
excludeClassPattern: "$^"
EnumNaming:
active: true
enumEntryPattern: "[A-Z][_a-zA-Z0-9]*"
ForbiddenClassName:
active: false
forbiddenName: []
FunctionMaxLength:
active: false
maximumFunctionNameLength: 30
FunctionMinLength:
active: false
minimumFunctionNameLength: 3
FunctionNaming:
active: true
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
functionPattern: "[a-z][a-zA-Z0-9]*"
excludeClassPattern: "$^"
ignoreAnnotated: ["Composable"]
FunctionParameterNaming:
active: true
parameterPattern: "[a-z][A-Za-z0-9]*"
excludeClassPattern: "$^"
InvalidPackageDeclaration:
active: true
rootPackage: ""
requireRootInDeclaration: false
LambdaParameterNaming:
active: false
parameterPattern: "[a-z][A-Za-z0-9]*|_"
MatchingDeclarationName:
active: true
mustBeFirst: true
MemberNameEqualsClassName:
active: true
ignoreOverridden: true
NoNameShadowing:
active: true
NonBooleanPropertyPrefixedWithIs:
active: false
ObjectPropertyNaming:
active: true
constantPattern: "[A-Za-z][_A-Za-z0-9]*"
propertyPattern: "[A-Za-z][_A-Za-z0-9]*"
privatePropertyPattern: "(_)?[A-Za-z][_A-Za-z0-9]*"
PackageNaming:
active: true
packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*'
TopLevelPropertyNaming:
active: true
constantPattern: "[A-Z][_A-Z0-9]*"
propertyPattern: "[A-Za-z][_A-Za-z0-9]*"
privatePropertyPattern: "_?[A-Za-z][_A-Za-z0-9]*"
VariableMaxLength:
active: false
maximumVariableNameLength: 100 #64
VariableMinLength:
active: false
minimumVariableNameLength: 1
VariableNaming:
active: true
variablePattern: "[a-z][A-Za-z0-9]*"
privateVariablePattern: "(_)?[a-z][A-Za-z0-9]*"
excludeClassPattern: "$^"
performance:
active: true
ArrayPrimitive:
active: true
CouldBeSequence:
active: false
threshold: 3
ForEachOnRange:
active: true
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
SpreadOperator:
active: true
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
UnnecessaryPartOfBinaryExpression:
active: false
UnnecessaryTemporaryInstantiation:
active: true
potential-bugs:
active: true
AvoidReferentialEquality:
active: true
forbiddenTypePatterns:
- "kotlin.String"
CastNullableToNonNullableType:
active: false
CastToNullableType:
active: false
Deprecation:
active: false
DontDowncastCollectionTypes:
active: false
DoubleMutabilityForCollection:
active: true
mutableTypes:
- "kotlin.collections.MutableList"
- "kotlin.collections.MutableMap"
- "kotlin.collections.MutableSet"
- "java.util.ArrayList"
- "java.util.LinkedHashSet"
- "java.util.HashSet"
- "java.util.LinkedHashMap"
- "java.util.HashMap"
ElseCaseInsteadOfExhaustiveWhen:
active: false
ignoredSubjectTypes: []
EqualsAlwaysReturnsTrueOrFalse:
active: true
EqualsWithHashCodeExist:
active: true
ExitOutsideMain:
active: false
ExplicitGarbageCollectionCall:
active: true
HasPlatformType:
active: true
IgnoredReturnValue:
active: true
restrictToConfig: true
returnValueAnnotations:
- "CheckResult"
- "*.CheckResult"
- "CheckReturnValue"
- "*.CheckReturnValue"
ignoreReturnValueAnnotations:
- "CanIgnoreReturnValue"
- "*.CanIgnoreReturnValue"
returnValueTypes:
- "kotlin.sequences.Sequence"
- "kotlinx.coroutines.flow.*Flow"
- "java.util.stream.*Stream"
ignoreFunctionCall: []
ImplicitDefaultLocale:
active: true
ImplicitUnitReturnType:
active: false
allowExplicitReturnType: true
InvalidRange:
active: true
IteratorHasNextCallsNextMethod:
active: true
IteratorNotThrowingNoSuchElementException:
active: true
LateinitUsage:
active: false
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
ignoreOnClassesPattern: ""
MapGetWithNotNullAssertionOperator:
active: true
MissingPackageDeclaration:
active: false
excludes: ["**/*.kts"]
NullCheckOnMutableProperty:
active: false
NullableToStringCall:
active: false
PropertyUsedBeforeDeclaration:
active: false
UnconditionalJumpStatementInLoop:
active: false
UnnecessaryNotNullCheck:
active: false
UnnecessaryNotNullOperator:
active: true
UnnecessarySafeCall:
active: true
UnreachableCatchBlock:
active: true
UnreachableCode:
active: true
UnsafeCallOnNullableType:
active: true
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
]
UnsafeCast:
active: true
UnusedUnaryOperator:
active: true
UselessPostfixExpression:
active: true
WrongEqualsTypeParameter:
active: true
style:
active: true
AlsoCouldBeApply:
active: false
BracesOnIfStatements:
active: false
singleLine: "never"
multiLine: "always"
BracesOnWhenStatements:
active: false
singleLine: "necessary"
multiLine: "consistent"
CanBeNonNullable:
active: false
CascadingCallWrapping:
active: false
includeElvis: true
ClassOrdering:
active: false
CollapsibleIfStatements:
active: false
DataClassContainsFunctions:
active: false
conversionFunctionPrefix:
- "to"
allowOperators: false
DataClassShouldBeImmutable:
active: false
DestructuringDeclarationWithTooManyEntries:
active: true
maxDestructuringEntries: 3
DoubleNegativeLambda:
active: false
negativeFunctions:
- reason: "Use `takeIf` instead."
value: "takeUnless"
- reason: "Use `all` instead."
value: "none"
negativeFunctionNameParts:
- "not"
- "non"
EqualsNullCall:
active: true
EqualsOnSignatureLine:
active: false
ExplicitCollectionElementAccessMethod:
active: false
ExplicitItLambdaParameter:
active: true
ExpressionBodySyntax:
active: false
includeLineWrapping: false
ForbiddenAnnotation:
active: false
annotations:
- reason: "it is a java annotation. Use `Suppress` instead."
value: "java.lang.SuppressWarnings"
- reason: "it is a java annotation. Use `kotlin.Deprecated` instead."
value: "java.lang.Deprecated"
- reason: "it is a java annotation. Use `kotlin.annotation.MustBeDocumented` instead."
value: "java.lang.annotation.Documented"
- reason: "it is a java annotation. Use `kotlin.annotation.Target` instead."
value: "java.lang.annotation.Target"
- reason: "it is a java annotation. Use `kotlin.annotation.Retention` instead."
value: "java.lang.annotation.Retention"
- reason: "it is a java annotation. Use `kotlin.annotation.Repeatable` instead."
value: "java.lang.annotation.Repeatable"
- reason: "Kotlin does not support @Inherited annotation, see https://youtrack.jetbrains.com/issue/KT-22265"
value: "java.lang.annotation.Inherited"
ForbiddenComment:
active: false # Turning off for this implementation
comments:
- reason: "Forbidden FIXME todo marker in comment, please fix the problem."
value: "FIXME:"
- reason: "Forbidden STOPSHIP todo marker in comment, please address the problem before shipping the code."
value: "STOPSHIP:"
- reason: "Forbidden TODO todo marker in comment, please do the changes."
value: "TODO:"
allowedPatterns: ""
ForbiddenImport:
active: false
imports: []
forbiddenPatterns: ""
ForbiddenMethodCall:
active: false
methods:
- reason: "print does not allow you to configure the output stream. Use a logger instead."
value: "kotlin.io.print"
- reason: "println does not allow you to configure the output stream. Use a logger instead."
value: "kotlin.io.println"
ForbiddenSuppress:
active: false
rules: []
ForbiddenVoid:
active: true
ignoreOverridden: false
ignoreUsageInGenerics: false
FunctionOnlyReturningConstant:
active: true
ignoreOverridableFunction: true
ignoreActualFunction: true
excludedFunctions: []
LoopWithTooManyJumpStatements:
active: true
maxJumpCount: 1
MagicNumber:
active: false # true
excludes:
[
"**/test/**",
"**/androidTest/**",
"**/commonTest/**",
"**/jvmTest/**",
"**/androidUnitTest/**",
"**/androidInstrumentedTest/**",
"**/jsTest/**",
"**/iosTest/**",
"**/*.kts",
]
ignoreNumbers:
- "-1"
- "0"
- "1"
- "2"
ignoreHashCodeFunction: true
ignorePropertyDeclaration: false
ignoreLocalVariableDeclaration: false
ignoreConstantDeclaration: true
ignoreCompanionObjectPropertyDeclaration: true
ignoreAnnotation: false
ignoreNamedArgument: true
ignoreEnums: false
ignoreRanges: false
ignoreExtensionFunctions: true
MandatoryBracesLoops:
active: false
MaxChainedCallsOnSameLine:
active: false
maxChainedCalls: 5
MaxLineLength:
active: true
maxLineLength: 120
excludePackageStatements: true
excludeImportStatements: true
excludeCommentStatements: false
excludeRawStrings: true
MayBeConst:
active: true
ModifierOrder:
active: true
MultilineLambdaItParameter:
active: false
MultilineRawStringIndentation:
active: false
indentSize: 4
trimmingMethods:
- "trimIndent"
- "trimMargin"
NestedClassesVisibility:
active: true
NewLineAtEndOfFile:
active: true
NoTabs:
active: false
NullableBooleanCheck:
active: false
ObjectLiteralToLambda:
active: true
OptionalAbstractKeyword:
active: true
OptionalUnit:
active: false
PreferToOverPairSyntax:
active: false
ProtectedMemberInFinalClass:
active: true
RedundantExplicitType:
active: false
RedundantHigherOrderMapUsage:
active: true
RedundantVisibilityModifierRule:
active: false
ReturnCount:
active: true
max: 2
excludedFunctions:
- "equals"
excludeLabeled: false
excludeReturnFromLambda: true
excludeGuardClauses: false
SafeCast:
active: true
SerialVersionUIDInSerializableClass:
active: true
SpacingBetweenPackageAndImports:
active: false
StringShouldBeRawString:
active: false
maxEscapedCharacterCount: 2
ignoredCharacters: []
ThrowsCount:
active: true
max: 2
excludeGuardClauses: false
TrailingWhitespace:
active: false
TrimMultilineRawString:
active: false
trimmingMethods:
- "trimIndent"
- "trimMargin"
UnderscoresInNumericLiterals:
active: false
acceptableLength: 4
allowNonStandardGrouping: false
UnnecessaryAbstractClass:
active: true
UnnecessaryAnnotationUseSiteTarget:
active: false
UnnecessaryApply:
active: true
UnnecessaryBackticks:
active: false
UnnecessaryBracesAroundTrailingLambda:
active: false
UnnecessaryFilter:
active: true
UnnecessaryInheritance:
active: true
UnnecessaryInnerClass:
active: false
UnnecessaryLet:
active: false
UnnecessaryParentheses:
active: false
allowForUnclearPrecedence: false
UntilInsteadOfRangeTo:
active: false
UnusedImports:
active: false
UnusedParameter:
active: true
allowedNames: "ignored|expected"
UnusedPrivateClass:
active: true
UnusedPrivateMember:
active: true
allowedNames: ""
ignoreAnnotated: ['Preview', 'DevicePreviews']
UnusedPrivateProperty:
active: true
allowedNames: "_|ignored|expected|serialVersionUID"
UseAnyOrNoneInsteadOfFind:
active: true
UseArrayLiteralsInAnnotations:
active: true
UseCheckNotNull:
active: true
UseCheckOrError:
active: true
UseDataClass:
active: false
allowVars: false
UseEmptyCounterpart:
active: false
UseIfEmptyOrIfBlank:
active: false
UseIfInsteadOfWhen:
active: false
ignoreWhenContainingVariableDeclaration: false
UseIsNullOrEmpty:
active: true
UseLet:
active: false
UseOrEmpty:
active: true
UseRequire:
active: true
UseRequireNotNull:
active: true
UseSumOfInsteadOfFlatMapSize:
active: false
UselessCallOnNotNull:
active: true
UtilityClassWithPublicConstructor:
active: true
VarCouldBeVal:
active: true
ignoreLateinitVar: false
WildcardImport:
active: true
excludeImports:
- "java.util.*"
TwitterCompose:
CompositionLocalAllowlist:
active: false
# You can optionally define a list of CompositionLocals that are allowed here
# allowedCompositionLocals: LocalSomething,LocalSomethingElse
CompositionLocalNaming:
active: true
ContentEmitterReturningValues:
active: true
# You can optionally add your own composables here
# contentEmitters: MyComposable,MyOtherComposable
ModifierComposable:
active: true
ModifierMissing:
active: true
ModifierReused:
active: true
ModifierWithoutDefault:
active: true
MultipleEmitters:
active: true
# You can optionally add your own composables here
# contentEmitters: MyComposable,MyOtherComposable
MutableParams:
active: true
ComposableNaming:
active: true
# You can optionally disable the checks in this rule for regex matches against the composable name (e.g. molecule presenters)
# allowedComposableFunctionNames: .*Presenter,.*MoleculePresenter
ComposableParamOrder:
active: true
PreviewNaming:
active: true
PreviewPublic:
active: true
# You can optionally disable that only previews with @PreviewParameter are flagged
# previewPublicOnlyIfParams: false
RememberMissing:
active: true
UnstableCollections:
active: false
ViewModelForwarding:
active: true
ViewModelInjection:
active: true

View File

@ -1,22 +1,21 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
plugins {
alias(libs.plugins.mifos.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.mifos.android.hilt)
}
apply(from = "${project.rootDir}/config/quality/quality.gradle")
android {
namespace = "org.mifos.mobile.core.common"
}
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)
}

View File

@ -1,24 +0,0 @@
package org.mifos.mobile.core.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.mobile.core.common.test", appContext.packageName)
}
}

View File

@ -1,4 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!--
Copyright 2024 Mifos Initiative
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file,
You can obtain one at https://mozilla.org/MPL/2.0/.
See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
-->
<manifest>
</manifest>

View File

@ -1,9 +1,14 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common
/**
* @author Vishwajeet
* @since 11/06/16
*/
object ApiEndPoints {
// This class contains all the Constants for API End Points
const val AUTHENTICATION = "authentication"

View File

@ -1,6 +1,14 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common
object Constants {
const val CLIENT_NAME = "clientName"
const val CLIENT_ID = "clientId"

View File

@ -1,13 +1,20 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common
import android.annotation.SuppressLint
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.telephony.TelephonyManager
/**
* Created by rishabhkhanna on 07/03/17.
*/
object Network {
/**
* Get the network info
@ -15,6 +22,7 @@ object Network {
* @param context
* @return
*/
@SuppressLint("MissingPermission")
private fun getNetworkInfo(context: Context): NetworkInfo? {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return cm.activeNetworkInfo
@ -86,6 +94,7 @@ object Network {
* @param subType
* @return
*/
@Suppress("CyclomaticComplexMethod")
private fun isConnectionFast(type: Int, subType: Int): Boolean {
return when (type) {
ConnectivityManager.TYPE_WIFI -> {

View File

@ -0,0 +1,22 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common.network
import javax.inject.Qualifier
import kotlin.annotation.AnnotationRetention.RUNTIME
@Qualifier
@Retention(RUNTIME)
annotation class Dispatcher(val dispatcher: MifosDispatchers)
enum class MifosDispatchers {
Default,
IO,
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common.network.di
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import org.mifos.mobile.core.common.network.Dispatcher
import org.mifos.mobile.core.common.network.MifosDispatchers
import javax.inject.Qualifier
import javax.inject.Singleton
@Retention(AnnotationRetention.RUNTIME)
@Qualifier
annotation class ApplicationScope
@Module
@InstallIn(SingletonComponent::class)
object CoroutineScopesModule {
@Provides
@Singleton
@ApplicationScope
fun providesCoroutineScope(
@Dispatcher(MifosDispatchers.Default) dispatcher: CoroutineDispatcher,
): CoroutineScope = CoroutineScope(SupervisorJob() + dispatcher)
}
object ApplicationModule

View File

@ -0,0 +1,31 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common.network.di
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import org.mifos.mobile.core.common.network.Dispatcher
import org.mifos.mobile.core.common.network.MifosDispatchers
@Module
@InstallIn(SingletonComponent::class)
object DispatchersModule {
@Provides
@Dispatcher(MifosDispatchers.IO)
fun providesIODispatcher(): CoroutineDispatcher = Dispatchers.IO
@Provides
@Dispatcher(MifosDispatchers.Default)
fun providesDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default
}

View File

@ -1,3 +1,12 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common.utils
import android.content.Context
@ -5,9 +14,6 @@ import android.telephony.TelephonyManager
import java.text.DecimalFormat
import java.util.Locale
/**
* Created by dilpreet on 21/8/17.
*/
object CurrencyUtil {
private val defaultLocale = Locale.US

View File

@ -1,6 +1,11 @@
/*
* This project is licensed under the open source MPL V2.
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common.utils
@ -11,17 +16,11 @@ import java.util.Calendar
import java.util.Date
import java.util.Locale
/**
* Created by ishankhanna on 30/05/14.
*
* This is a helper class that will be used to convert List<Interger> Type Dates
* from MifosX into Simple Strings or Date Formats</Interger>
*/
object DateHelper {
val LOG_TAG: String? = DateHelper::class.java.simpleName
const val FORMAT_dd_MMMM_yyyy = "dd MMMM yyyy"
const val FORMAT_dd_MM_yyyy = "dd-MM-yyyy"
private val LOG_TAG: String? = DateHelper::class.java.simpleName
const val FORMAT_MMMM = "dd MMMM yyyy"
const val FORMAT_MM = "dd-MM-yyyy"
fun getCurrentDate(dateFormat: String?, separator: String): List<Int> {
val date: MutableList<Int> = ArrayList()
val s = SimpleDateFormat(dateFormat, Locale.getDefault()).format(Date())
@ -164,3 +163,6 @@ object DateHelper {
return sdf.format(timeInMillis?.let { Date(it) })
}
}
fun getTodayFormatted(): String =
SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(Calendar.getInstance().time)

View File

@ -1,23 +1,32 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common.utils
import android.annotation.TargetApi
import android.content.Context
import android.os.Build
import android.preference.PreferenceManager
import org.mifos.mobile.core.common.R
import java.util.*
import java.util.Locale
/**
* Created by dilpreet on 02/10/17.
*/
object LanguageHelper {
// https://gunhansancar.com/change-language-programmatically-in-android/
fun onAttach(context: Context): Context? {
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
return if (preferences.getBoolean(context.getString(R.string.default_system_language), true)) {
if(!context.resources.getStringArray(R.array.languages_value).contains(Locale.getDefault().language)){
return if (preferences.getBoolean(
context.getString(R.string.core_common_default_system_language),
true,
)
) {
if (!context.resources.getStringArray(R.array.core_common_languages_value)
.contains(Locale.getDefault().language)
) {
setLocale(context, "en")
}else{
} else {
setLocale(context, Locale.getDefault().language)
}
} else {
@ -32,20 +41,18 @@ object LanguageHelper {
return lang?.let { setLocale(context, it) }
}
fun setLocale(context: Context?, language: String): Context? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResources(context!!, language)
} else {
updateResourcesLegacy(context, language)
}
fun setLocale(context: Context?, language: String): Context {
return updateResources(context!!, language)
}
private fun getPersistedData(context: Context, defaultLanguage: String): String? {
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
return preferences.getString(context.getString(R.string.language_type), defaultLanguage)
return preferences.getString(
context.getString(R.string.core_common_language_type),
defaultLanguage,
)
}
@TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, language: String): Context {
val locale = Locale(language)
Locale.setDefault(locale)
@ -54,15 +61,4 @@ object LanguageHelper {
configuration.setLayoutDirection(locale)
return context.createConfigurationContext(configuration)
}
private fun updateResourcesLegacy(context: Context?, language: String): Context? {
val locale = Locale(language)
Locale.setDefault(locale)
val resources = context?.resources
val configuration = resources?.configuration
configuration?.locale = locale
configuration?.setLayoutDirection(locale)
resources?.updateConfiguration(configuration, resources.displayMetrics)
return context
}
}

View File

@ -1,44 +0,0 @@
/*
* This project is licensed under the open source MPL V2.
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common.utils
import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.DateValidatorPointBackward
import com.google.android.material.datepicker.DateValidatorPointForward
import com.google.android.material.datepicker.MaterialDatePicker
import java.text.SimpleDateFormat
import java.time.Instant
import java.util.Calendar
import java.util.Locale
enum class DatePickerConstrainType {
ONLY_FUTURE_DAYS, ONLY_PAST_DAYS, NONE
}
fun getDatePickerDialog(
selectedInstant: Instant = Instant.now(),
constrainType: DatePickerConstrainType = DatePickerConstrainType.NONE,
onDatePick: (dateLong: Long) -> Unit = {},
): MaterialDatePicker<Long> {
val constrainsBuilder = CalendarConstraints.Builder().apply {
when (constrainType) {
DatePickerConstrainType.ONLY_FUTURE_DAYS -> setValidator(DateValidatorPointForward.now())
DatePickerConstrainType.ONLY_PAST_DAYS -> setValidator(DateValidatorPointBackward.now())
DatePickerConstrainType.NONE -> {}
}
}
val dialog = MaterialDatePicker.Builder.datePicker()
.setSelection(selectedInstant.toEpochMilli())
.setCalendarConstraints(constrainsBuilder.build())
.build()
dialog.addOnPositiveButtonClickListener {
onDatePick(it)
}
return dialog
}
fun getTodayFormatted(): String =
SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(Calendar.getInstance().time)

View File

@ -1,3 +1,12 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common.utils
import android.os.Build
@ -29,4 +38,4 @@ object ParcelableAndSerializableUtils {
this.getSerializable(key)
}
}
}
}

View File

@ -1,40 +0,0 @@
package org.mifos.mobile.core.common.utils
import android.R.attr
import android.R.id
import android.app.Activity
import android.content.Context
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.ProgressBar
import android.widget.RelativeLayout
/**
* @author Rajan Maurya
*/
class ProgressBarHandler(mContext: Context) {
private val mProgressBar: ProgressBar
fun show() {
mProgressBar.visibility = View.VISIBLE
}
fun hide() {
mProgressBar.visibility = View.INVISIBLE
}
init {
val layout = (mContext as Activity).findViewById<View>(id.content).rootView as ViewGroup
mProgressBar = ProgressBar(mContext, null, attr.progressBarStyleInverse)
mProgressBar.isIndeterminate = true
val params = RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT,
)
val rl = RelativeLayout(mContext)
rl.gravity = Gravity.CENTER
rl.addView(mProgressBar)
layout.addView(rl, params)
hide()
}
}

View File

@ -1,8 +1,14 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common.utils
/**
* Created by Rajan Maurya on 05/03/17.
*/
object SymbolsUtils {
const val PERCENT = "%"
}

View File

@ -1,3 +1,12 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.core.common.utils
import android.content.Context
@ -18,9 +27,6 @@ import java.io.IOException
import java.text.DateFormatSymbols
import java.util.Locale
/**
* Created by michaelsosnick on 12/12/16.
*/
object Utils {
fun getMonth(month: Int): String {
return DateFormatSymbols().months[month - 1]
@ -41,7 +47,7 @@ object Utils {
fun setCircularBackground(colorId: Int, context: Context?): LayerDrawable {
val color: Drawable = ColorDrawable(ContextCompat.getColor(context!!, colorId))
val image = ContextCompat.getDrawable(context, R.drawable.circular_background)
val image = ContextCompat.getDrawable(context, R.drawable.core_common_circular_background)
return LayerDrawable(arrayOf(image, color))
}
@ -85,7 +91,8 @@ object Utils {
) + " ",
)
}
} catch (_: Exception) {}
} catch (_: Exception) {
}
return builder.toString()
}
}

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
android:width="25dp"
android:height="25dp" />
</shape>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2024 Mifos Initiative
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file,
You can obtain one at https://mozilla.org/MPL/2.0/.
See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
android:width="25dp"
android:height="25dp" />
</shape>

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

@ -1,6 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2024 Mifos Initiative
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file,
You can obtain one at https://mozilla.org/MPL/2.0/.
See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
-->
<resources>
<dimen name="account_status_width">25dp</dimen>
<dimen name="account_status_height">25dp</dimen>
<dimen name="core_common_account_status_width">25dp</dimen>
<dimen name="core_common_account_status_height">25dp</dimen>
</resources>

View File

@ -1,9 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2024 Mifos Initiative
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file,
You can obtain one at https://mozilla.org/MPL/2.0/.
See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
-->
<resources>
<string name="working">Working</string>
<string name="default_system_language" translatable="false">default_system_language</string>
<string name="language_type" translatable="false">language_type</string>
<string-array name="languages_value" translatable="false">
<string name="core_common_working">Working</string>
<string name="core_common_default_system_language" translatable="false">default_system_language</string>
<string name="core_common_language_type" translatable="false">language_type</string>
<string-array name="core_common_languages_value" translatable="false">
<item>System_Language</item>
<item>en</item>
<item>hi</item>

View File

@ -1,17 +0,0 @@
package org.mifos.mobile.core.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)
}
}

View File

@ -1,4 +1,4 @@
package org.mifos.mobile.api
package org.mifos.mobile.core.datastore
/**
* @author Vishwajeet
@ -7,7 +7,7 @@ package org.mifos.mobile.api
class BaseURL {
val url: String? = null
get() = field
?: PROTOCOL_HTTPS + API_ENDPOINT + API_PATH
?: (PROTOCOL_HTTPS + API_ENDPOINT + API_PATH)
val defaultBaseUrl: String
get() = PROTOCOL_HTTPS + API_ENDPOINT

View File

@ -2,16 +2,13 @@
* This project is licensed under the open source MPL V2.
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package org.mifos.mobile.api
package org.mifos.mobile.core.datastore
import android.text.TextUtils
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Request.Builder
import okhttp3.Response
import java.io.IOException
import kotlin.jvm.Throws
import org.mifos.mobile.api.local.PreferencesHelper
/**
* @author Vishwajeet
@ -23,10 +20,16 @@ class SelfServiceInterceptor(private val preferencesHelper: PreferencesHelper) :
override fun intercept(chain: Interceptor.Chain): Response {
val chainRequest: Request = chain.request()
val builder: Builder = chainRequest.newBuilder()
.header(HEADER_TENANT, preferencesHelper.tenant)
if (!TextUtils.isEmpty(preferencesHelper.token)) {
builder.header(HEADER_AUTH, preferencesHelper.token)
preferencesHelper.tenant?.let {
builder.header(HEADER_TENANT, it)
}
preferencesHelper.token?.let {
if (it.isNotEmpty()) {
builder.header(HEADER_AUTH, it)
}
}
val request: Request = builder.build()
return chain.proceed(request)
}

View File

@ -22,7 +22,7 @@ import org.mifos.mobile.feature.about.R
fun AboutUsHeader() {
Column {
Image(
painter = painterResource(id = R.mipmap.mifos_icon),
painter = painterResource(id = R.mipmap.core_common_mifos_icon),
contentDescription = null,
modifier = Modifier
.size(100.dp)

View File

@ -1,6 +1,5 @@
package org.mifos.mobile.feature.loan.loan_account_application
import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
@ -8,7 +7,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.DatePicker
@ -16,16 +14,15 @@ import androidx.compose.material3.DatePickerDefaults
import androidx.compose.material3.DatePickerDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
@ -35,7 +32,7 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.mifos.mobile.core.common.utils.DateHelper
import org.mifos.mobile.core.common.utils.DateHelper.FORMAT_dd_MM_yyyy
import org.mifos.mobile.core.common.utils.DateHelper.FORMAT_MM
import org.mifos.mobile.core.ui.component.MifosDropDownTextField
import org.mifos.mobile.core.ui.component.MifosOutlinedTextField
import org.mifos.mobile.core.ui.component.MifosTextTitleDescDrawableSingleLine
@ -43,8 +40,6 @@ import org.mifos.mobile.core.ui.component.MifosTextTitleDescSingleLine
import org.mifos.mobile.core.ui.theme.MifosMobileTheme
import org.mifos.mobile.core.ui.utils.PresentOrFutureSelectableDates
import org.mifos.mobile.feature.loan.R
import java.text.SimpleDateFormat
import java.util.Locale
@OptIn(ExperimentalMaterial3Api::class)
@ -216,7 +211,7 @@ fun LoanApplicationContent(
TextButton(
onClick = {
val formattedDate = DateHelper.getSpecificFormat(
format = FORMAT_dd_MM_yyyy,
format = FORMAT_MM,
dateLong = datePickerState.selectedDateMillis
)
formattedDate?.let {

View File

@ -1,7 +1,6 @@
package org.mifos.mobile.feature.loan.loan_account_application
import android.content.Context
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
@ -21,16 +20,15 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.gson.Gson
import org.mifos.mobile.core.ui.component.MifosErrorComponent
import org.mifos.mobile.core.ui.component.MifosProgressIndicatorOverlay
import org.mifos.mobile.core.ui.component.MifosTopBar
import org.mifos.mobile.core.ui.theme.MifosMobileTheme
import org.mifos.mobile.core.common.Network
import org.mifos.mobile.core.common.utils.DateHelper
import org.mifos.mobile.core.model.entity.payload.LoansPayload
import org.mifos.mobile.core.model.enums.LoanState
import org.mifos.mobile.core.ui.component.MifosErrorComponent
import org.mifos.mobile.core.ui.component.MifosProgressIndicatorOverlay
import org.mifos.mobile.core.ui.component.MifosTopBar
import org.mifos.mobile.core.ui.theme.MifosMobileTheme
import org.mifos.mobile.feature.loan.R
import org.mifos.mobile.feature.loan.navigation.LoanRoute
@Composable
@ -183,8 +181,8 @@ private fun getLoanPayload(
repaymentEvery = viewModel.loanTemplate.repaymentEvery
repaymentFrequencyType = viewModel.loanTemplate.interestRateFrequencyType?.id
interestRatePerPeriod = viewModel.loanTemplate.interestRatePerPeriod
expectedDisbursementDate = DateHelper.getSpecificFormat(DateHelper.FORMAT_dd_MMMM_yyyy, viewModel.loanApplicationScreenData.value.disbursementDate)
submittedOnDate = DateHelper.getSpecificFormat(DateHelper.FORMAT_dd_MMMM_yyyy, viewModel.loanApplicationScreenData.value.submittedDate).takeIf { loanState == LoanState.CREATE }
expectedDisbursementDate = DateHelper.getSpecificFormat(DateHelper.FORMAT_MMMM, viewModel.loanApplicationScreenData.value.disbursementDate)
submittedOnDate = DateHelper.getSpecificFormat(DateHelper.FORMAT_MMMM, viewModel.loanApplicationScreenData.value.submittedDate).takeIf { loanState == LoanState.CREATE }
transactionProcessingStrategyId = viewModel.loanTemplate.transactionProcessingStrategyId
amortizationType = viewModel.loanTemplate.amortizationType?.id
interestCalculationPeriodType = viewModel.loanTemplate.interestCalculationPeriodType?.id

View File

@ -1,7 +1,5 @@
package org.mifos.mobile.feature.savings.savings_account_application
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@ -14,6 +12,8 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.mifos.mobile.core.common.Constants
import org.mifos.mobile.core.common.utils.DateHelper
import org.mifos.mobile.core.common.utils.getTodayFormatted
import org.mifos.mobile.core.data.repositories.SavingsAccountRepository
import org.mifos.mobile.core.datastore.PreferencesHelper
import org.mifos.mobile.core.model.entity.accounts.savings.SavingsAccountApplicationPayload
@ -21,10 +21,6 @@ import org.mifos.mobile.core.model.entity.accounts.savings.SavingsAccountUpdateP
import org.mifos.mobile.core.model.entity.accounts.savings.SavingsWithAssociations
import org.mifos.mobile.core.model.entity.templates.savings.SavingsAccountTemplate
import org.mifos.mobile.core.model.enums.SavingsAccountState
import org.mifos.mobile.core.common.utils.DateHelper
import org.mifos.mobile.core.common.utils.getTodayFormatted
import org.mifos.mobile.core.model.entity.accounts.loan.LoanWithAssociations
import org.mifos.mobile.core.model.enums.LoanState
import org.mifos.mobile.feature.savings.R
import javax.inject.Inject
@ -132,7 +128,7 @@ class SavingsAccountApplicationViewModel @Inject constructor(
return
}
payload.submittedOnDate =
DateHelper.getSpecificFormat(DateHelper.FORMAT_dd_MMMM_yyyy, getTodayFormatted())
DateHelper.getSpecificFormat(DateHelper.FORMAT_MMMM, getTodayFormatted())
submitSavingsAccountApplication(payload)
}
}

View File

@ -19,8 +19,8 @@
<string name="cancel">Cancel</string>
<string name="dialog_action_ok">OK</string>
<string name="default_system_language" translatable="false">default_system_language</string>
<string name="language_type" translatable="false">language_type</string>
<string name="core_common_default_system_language" translatable="false">default_system_language</string>
<string name="core_common_language_type" translatable="false">language_type</string>
<string-array name="languages" translatable="false">
<item>System Language</item>
<item>English</item>

View File

@ -66,7 +66,7 @@ fun ReviewTransferPayload.convertToTransferPayloadString(): String {
toAccountId = payload.payToAccount?.accountId
toClientId = payload.payToAccount?.clientId
toAccountType = payload.payToAccount?.accountType?.id
transferDate = DateHelper.getSpecificFormat(DateHelper.FORMAT_dd_MMMM_yyyy, getTodayFormatted())
transferDate = DateHelper.getSpecificFormat(DateHelper.FORMAT_MMMM, getTodayFormatted())
transferAmount = payload.amount.toDoubleOrNull()
transferDescription = payload.review
fromAccountNumber = payload.payFromAccount?.accountNo