1 Commits
Author SHA1 Message Date
Oqba 7d865a3d6d ارتقا به نسخه 1.1.3 و بهینه‌سازی محاسبات ماه جاری و تاریخ شمسی
Android Release / build (push) Canceled after 0s
2026-10-28 08:51:47 +03:30
5 changed files with 59 additions and 9 deletions

No files matched your search

+2 -2
View File
@@ -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 }
}
@@ -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))
@@ -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
}
@@ -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<String>()
val infoMessage = _infoMessage.asSharedFlow()
val isOperatorMode: StateFlow<Boolean> = settingsRepository.isOperatorModeFlow
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000L), false)
private val _uiState = MutableStateFlow(PersonListUiState())
val uiState: StateFlow<PersonListUiState> = _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<PaymentRecord>) {
private fun updateDashboard(
totalPersonCount: Int,
paymentsThisMonth: List<PaymentRecord>,
categoryPayments: List<PaymentRecord>
) {
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 {
@@ -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
)