Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ import com.mifos.feature.loan.navigation.loanNavGraph
import com.mifos.feature.loan.navigation.navigateToGroupLoanScreen
import com.mifos.feature.loan.navigation.navigateToLoanAccountScreen
import com.mifos.feature.loan.navigation.navigateToLoanAccountSummaryScreen
import com.mifos.feature.note.navigation.navigateToNoteScreen
import com.mifos.feature.note.navigation.noteNavGraph
import com.mifos.feature.note.notes.navigateToNoteScreen
import com.mifos.feature.offline.navigation.offlineNavGraph
import com.mifos.feature.path.tracking.navigation.pathTrackingNavGraph
import com.mifos.feature.report.navigation.reportNavGraph
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,4 +409,24 @@ object DateHelper {
require(month in 1..12) { "Month should be between 1 and 12" }
return Month.entries[month - 1].name.lowercase().replaceFirstChar { it.uppercase() }
}

/**
* This method is used to Convert IOS string date into dd MM yyyy formate
* @param isoString take IOS date as a String
* Example : ISO string 2025-08-28T16:02:32.242705+05:30 and return 28 08 2025
*/
fun formatIsoDateToDdMmYyyy(isoString: String): String {
// Parse the string into an Instant
val instant = Instant.parse(isoString)

// Convert to LocalDateTime in system timezone
val localDate = instant.toLocalDateTime(TimeZone.currentSystemDefault()).date

val day = localDate.dayOfMonth.toString().padStart(2, '0')
val monthName = localDate.month.name.lowercase()
.replaceFirstChar { it.uppercase() } // "January", "February", etc.
val year = localDate.year

return "$day $monthName $year"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.mifos.core.domain.useCases.ActivateGroupUseCase
import com.mifos.core.domain.useCases.ActivateSavingsUseCase
import com.mifos.core.domain.useCases.AddClientPinpointLocationUseCase
import com.mifos.core.domain.useCases.AddDataTableEntryUseCase
import com.mifos.core.domain.useCases.AddNoteUseCase
import com.mifos.core.domain.useCases.ApproveCheckerUseCase
import com.mifos.core.domain.useCases.ApproveSavingsApplicationUseCase
import com.mifos.core.domain.useCases.CreateChargesUseCase
Expand All @@ -28,6 +29,7 @@ import com.mifos.core.domain.useCases.DeleteCheckerUseCase
import com.mifos.core.domain.useCases.DeleteClientAddressPinpointUseCase
import com.mifos.core.domain.useCases.DeleteDataTableEntryUseCase
import com.mifos.core.domain.useCases.DeleteIdentifierUseCase
import com.mifos.core.domain.useCases.DeleteNoteUseCase
import com.mifos.core.domain.useCases.DownloadDocumentUseCase
import com.mifos.core.domain.useCases.FetchCenterDetailsUseCase
import com.mifos.core.domain.useCases.FetchCollectionSheetUseCase
Expand Down Expand Up @@ -75,6 +77,7 @@ import com.mifos.core.domain.useCases.ServerConfigValidatorUseCase
import com.mifos.core.domain.useCases.SubmitCollectionSheetUseCase
import com.mifos.core.domain.useCases.SubmitProductiveSheetUseCase
import com.mifos.core.domain.useCases.UpdateClientPinpointUseCase
import com.mifos.core.domain.useCases.UpdateNoteUseCase
import com.mifos.core.domain.useCases.UploadClientImageUseCase
import com.mifos.core.domain.useCases.UsernameValidationUseCase
import com.mifos.core.domain.useCases.ValidateServerApiPathUseCase
Expand Down Expand Up @@ -159,4 +162,7 @@ val UseCaseModule = module {
factoryOf(::GetGroupDetailsUseCase)
factoryOf(::GetLoanAndLoanRepaymentUseCase)
factoryOf(::GetSavingsAccountAndTemplateUseCase)
factoryOf(::AddNoteUseCase)
factoryOf(::UpdateNoteUseCase)
factoryOf(::DeleteNoteUseCase)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2025 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/android-client/blob/master/LICENSE.md
*/
package com.mifos.core.domain.useCases

import com.mifos.core.common.utils.DataState
import com.mifos.core.common.utils.asDataStateFlow
import com.mifos.core.data.repository.NoteRepository
import com.mifos.core.model.objects.payloads.NotesPayload
import com.mifos.core.network.GenericResponse
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow

class AddNoteUseCase(
val repository: NoteRepository,
) {
operator fun invoke(
resourceType: String,
resourceId: Long,
notesPayload: NotesPayload,
): Flow<DataState<GenericResponse>> = flow {
emit(repository.addNewNote(resourceType, resourceId, notesPayload))
}.asDataStateFlow()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2025 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/android-client/blob/master/LICENSE.md
*/
package com.mifos.core.domain.useCases

import com.mifos.core.common.utils.DataState
import com.mifos.core.common.utils.asDataStateFlow
import com.mifos.core.data.repository.NoteRepository
import com.mifos.core.network.GenericResponse
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow

class DeleteNoteUseCase(
val repository: NoteRepository,
) {
operator fun invoke(
resourceType: String,
resourceId: Long,
noteId: Long,
): Flow<DataState<GenericResponse>> = flow {
emit(repository.deleteNote(resourceType, resourceId, noteId))
}.asDataStateFlow()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2025 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/android-client/blob/master/LICENSE.md
*/
package com.mifos.core.domain.useCases

import com.mifos.core.common.utils.DataState
import com.mifos.core.common.utils.asDataStateFlow
import com.mifos.core.data.repository.NoteRepository
import com.mifos.core.model.objects.payloads.NotesPayload
import com.mifos.core.network.GenericResponse
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow

class UpdateNoteUseCase(
val repository: NoteRepository,
) {
operator fun invoke(
resourceType: String,
resourceId: Long,
noteId: Long,
notesPayload: NotesPayload,
): Flow<DataState<GenericResponse>> = flow {
emit(repository.updateNote(resourceType, resourceId, noteId, notesPayload))
}.asDataStateFlow()
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ data class Note(

val createdByUsername: String? = null,

val createdOn: Long? = null,
val createdOn: String? = null,

val id: Long? = null,

Expand All @@ -44,6 +44,6 @@ data class Note(

val updatedByUsername: String? = null,

val updatedOn: Long? = null,
val updatedOn: String? = null,

)
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
*/
package com.mifos.core.network

/**
* Created by ishankhanna on 24/06/14.
*/
class GenericResponse {
var responseFields = HashMap<String, Any>()
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement

@Serializable
data class GenericResponse(
val responseFields: Map<String, JsonElement> = emptyMap(),
) {
override fun toString(): String {
return "GenericResponse{" +
"responseFields=" + responseFields +
'}'
return "GenericResponse{responseFields=$responseFields}"
}
}
1 change: 1 addition & 0 deletions feature/note/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ kotlin {
implementation(compose.ui)
implementation(projects.core.common)
implementation(projects.core.model)
implementation(projects.core.domain)
implementation(libs.kotlinx.serialization.json)
}
}
Expand Down
13 changes: 13 additions & 0 deletions feature/note/src/commonMain/composeResources/values/res.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,17 @@
<string name="feature_note_item">Item</string>
<string name="feature_note_Unexpected_error">"Unexpected error"</string>
<string name="feature_note_delete_note_confirmation">Once deleted, this note cannot be recovered. Do you want to continue?</string>

<string name="feature_note_write_note_label">Write a Note</string>
<string name="feature_note_edit_note_label">Edit a Note</string>
<string name="feature_note_add_note">Add Note</string>
<string name="feature_note_update_note">Update Note</string>
<string name="feature_note_button_add">Add</string>
<string name="feature_note_button_update">Update</string>
<string name="feature_note_button_back">Back</string>
<string name="feature_note_edit_success">Note Updated Successfully</string>
<string name="feature_note_add_success">Note Added Successfully</string>
<string name="feature_note_button_confirm">Confirm</string>
<string name="feature_note_dialog_warning">Warning</string>
<string name="feature_note_dialog_warning_message">Discard changes? Unsaved data will be lost.</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2025 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/android-client/blob/master/LICENSE.md
*/
package com.mifos.feature.note.addEditNotes

import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import kotlinx.serialization.Serializable

@Serializable
data class AddEditNoteRoute(
val resourceId: Int,
val resourceType: String?,
val noteId: Long?,
)

fun NavGraphBuilder.addEditNoteRoute(
onBackPressed: () -> Unit,
onNavigateWithUpdatedList: (Int, String?) -> Unit,
) {
composable<AddEditNoteRoute> {
AddEditNoteScreen(
onBackPressed = onBackPressed,
onNavigateWithUpdatedList = onNavigateWithUpdatedList,
)
}
}

fun NavController.navigateToAddEditNoteScreen(resourceId: Int, resourceType: String?, noteId: Long?) {
this.navigate(AddEditNoteRoute(resourceId, resourceType, noteId))
}
Loading