diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 34c9165..0318805 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -30,8 +30,8 @@ android { applicationId = "com.oqba26.monthlypaymentapp" minSdk = 25 targetSdk = 34 - versionCode = 13 - versionName = "1.1.2" + versionCode = 14 + versionName = "1.1.3" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true } } diff --git a/app/src/main/java/com/oqba26/monthlypaymentapp/ui/screens/PersonScreen.kt b/app/src/main/java/com/oqba26/monthlypaymentapp/ui/screens/PersonScreen.kt index 05eb1ad..484bfd1 100644 --- a/app/src/main/java/com/oqba26/monthlypaymentapp/ui/screens/PersonScreen.kt +++ b/app/src/main/java/com/oqba26/monthlypaymentapp/ui/screens/PersonScreen.kt @@ -1114,6 +1114,19 @@ fun DashboardCard( Text("${formatNumberAsPersian(data.totalIncome)} تومان", style = MaterialTheme.typography.bodyMedium, fontWeight = FontWeight.Bold) } + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = if (isMosqueCategory) "مجموع کمک‌های جمع‌آوری شده دوره جاری" else "مجموع حقوق جمع‌آوری شده دوره جاری", + style = MaterialTheme.typography.titleSmall, + fontWeight = FontWeight.Bold + ) + Text("${formatNumberAsPersian(data.totalCycleIncome)} تومان", style = MaterialTheme.typography.bodyMedium, fontWeight = FontWeight.Bold) + } + if (financialReportData.totalOverdueDebt > 0 || financialReportData.debtors.isNotEmpty()) { HorizontalDivider(modifier = Modifier.padding(vertical = 2.dp)) diff --git a/app/src/main/java/com/oqba26/monthlypaymentapp/utils/ShamsiUtils.kt b/app/src/main/java/com/oqba26/monthlypaymentapp/utils/ShamsiUtils.kt index 676d946..7a8996e 100644 --- a/app/src/main/java/com/oqba26/monthlypaymentapp/utils/ShamsiUtils.kt +++ b/app/src/main/java/com/oqba26/monthlypaymentapp/utils/ShamsiUtils.kt @@ -30,3 +30,32 @@ fun formatTimestampToPersianDateTime(timestamp: Long): String { val time = formatTimestampToPersianTime(timestamp) return "$date، ساعت $time" } + +fun isTimestampInCurrentCycle(timestamp: Long): Boolean { + val now = PersianDate() + val curYear = now.shYear + val curMonth = now.shMonth + val curDay = now.shDay + + val (startYear, startMonth) = if (curDay >= 20) { + curYear to curMonth + } else { + if (curMonth == 1) (curYear - 1) to 12 else curYear to (curMonth - 1) + } + + val (endYear, endMonth) = if (startMonth == 12) { + (startYear + 1) to 1 + } else { + startYear to (startMonth + 1) + } + + val recordDate = PersianDate(Date(timestamp)) + val rYear = recordDate.shYear + val rMonth = recordDate.shMonth + val rDay = recordDate.shDay + + val isFirstHalf = (rYear == startYear && rMonth == startMonth && rDay >= 20) + val isSecondHalf = (rYear == endYear && rMonth == endMonth && rDay < 20) + + return isFirstHalf || isSecondHalf +} diff --git a/app/src/main/java/com/oqba26/monthlypaymentapp/viewmodel/PersonViewModel.kt b/app/src/main/java/com/oqba26/monthlypaymentapp/viewmodel/PersonViewModel.kt index 9a04706..a59804b 100644 --- a/app/src/main/java/com/oqba26/monthlypaymentapp/viewmodel/PersonViewModel.kt +++ b/app/src/main/java/com/oqba26/monthlypaymentapp/viewmodel/PersonViewModel.kt @@ -14,6 +14,7 @@ import com.oqba26.monthlypaymentapp.utils.getCurrentShamsiDay import com.oqba26.monthlypaymentapp.utils.getCurrentShamsiMonth import com.oqba26.monthlypaymentapp.utils.getCurrentShamsiYear import com.oqba26.monthlypaymentapp.utils.getPersianMonthName +import com.oqba26.monthlypaymentapp.utils.isTimestampInCurrentCycle import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope @@ -69,9 +70,6 @@ class PersonViewModel @Inject constructor( private val _infoMessage = MutableSharedFlow() val infoMessage = _infoMessage.asSharedFlow() - val isOperatorMode: StateFlow = settingsRepository.isOperatorModeFlow - .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000L), false) - private val _uiState = MutableStateFlow(PersonListUiState()) val uiState: StateFlow = _uiState.asStateFlow() @@ -248,13 +246,13 @@ class PersonViewModel @Inject constructor( ) } - updateDashboard(uiModels.size, relevantPayments) + val categoryPayments = allPayments.filter { it.category == category } + updateDashboard(uiModels.size, relevantPayments, categoryPayments) val (paidModels, unpaidModels) = uiModels.partition { it.hasPaidThisMonth } // محاسبه گزارشات مالی جامع val personsMap = persons.associateBy { it.id } - val categoryPayments = allPayments.filter { it.category == category } val totalAllTimeIncome = categoryPayments.sumOf { it.amount } val debtorsList = unpaidModels.filter { it.debtCount > 0 }.map { personModel -> @@ -590,11 +588,20 @@ class PersonViewModel @Inject constructor( exportManager.shareReceipt(payment, personName) } - private fun updateDashboard(totalPersonCount: Int, paymentsThisMonth: List) { + private fun updateDashboard( + totalPersonCount: Int, + paymentsThisMonth: List, + categoryPayments: List + ) { val paidCount = paymentsThisMonth.map { it.personId }.distinct().size val totalIncome = paymentsThisMonth.sumOf { it.amount } + val cyclePayments = categoryPayments.filter { payment -> + val time = payment.createdAt ?: payment.timestamp + isTimestampInCurrentCycle(time) + } + val totalCycleIncome = cyclePayments.sumOf { it.amount } val progress = if (totalPersonCount > 0) paidCount.toFloat() / totalPersonCount.toFloat() else 0f - _dashboardData.value = DashboardUiModel(paidCount, totalPersonCount, totalIncome, progress) + _dashboardData.value = DashboardUiModel(paidCount, totalPersonCount, totalIncome, totalCycleIncome, progress) } private fun createPaymentRecord(personId: String, month: Int, year: Int, amount: Double, description: String): PaymentRecord { diff --git a/app/src/main/java/com/oqba26/monthlypaymentapp/viewmodel/UiModels.kt b/app/src/main/java/com/oqba26/monthlypaymentapp/viewmodel/UiModels.kt index 857404b..a27d0b2 100644 --- a/app/src/main/java/com/oqba26/monthlypaymentapp/viewmodel/UiModels.kt +++ b/app/src/main/java/com/oqba26/monthlypaymentapp/viewmodel/UiModels.kt @@ -143,6 +143,7 @@ data class DashboardUiModel( val paidCount: Int = 0, val totalCount: Int = 0, val totalIncome: Double = 0.0, + val totalCycleIncome: Double = 0.0, val progress: Float = 0f )