4 Commits
8 changed files with 61 additions and 12 deletions

No files matched your search

+2 -2
View File
@@ -30,8 +30,8 @@ android {
applicationId = "com.oqba26.monthlypaymentapp"
minSdk = 25
targetSdk = 34
versionCode = 14
versionName = "1.1.3"
versionCode = 16
versionName = "1.1.5"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { useSupportLibrary = true }
}
@@ -113,6 +113,7 @@ fun PaidListScreen(
PersonListItem(
person = person,
index = index + 1,
listType = PersonListType.PAID,
onPersonClick = { navController.navigate("person_detail/${person.id}") },
onQuickPayClick = { },
onArchiveClick = { personToArchive.value = it },
@@ -1332,6 +1332,7 @@ fun PersonListItem(
person: PersonUiModel,
index: Int,
modifier: Modifier = Modifier,
listType: PersonListType = PersonListType.UNPAID,
isSelectionMode: Boolean = false,
isSelected: Boolean = false,
reorderableState: org.burnoutcrew.reorderable.ReorderableLazyListState? = null,
@@ -1368,6 +1369,15 @@ fun PersonListItem(
)
}
if (listType == PersonListType.PAID && person.hasPaidThisMonth) {
Icon(
imageVector = Icons.Filled.Check,
contentDescription = "Paid",
tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(20.dp).padding(end = 2.dp)
)
}
val dragModifier = if (reorderableState != null && !isSelectionMode) {
Modifier.detectReorderAfterLongPress(reorderableState)
} else Modifier
@@ -1377,14 +1387,33 @@ fun PersonListItem(
style = MaterialTheme.typography.bodyLarge,
modifier = dragModifier.padding(end = 4.dp)
)
Column(modifier = Modifier.weight(1f)) {
Text(
person.name,
modifier = Modifier.weight(1f),
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Bold,
maxLines = 2,
overflow = TextOverflow.Visible
)
if (listType == PersonListType.PAID) {
person.lastPaymentTime?.let { time ->
Text(
text = formatTimestampToPersianDateTime(time),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
person.lastPaymentAmount?.let { amount ->
Text(
text = "مبلغ: ${formatNumberAsPersian(amount)} تومان",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.primary,
fontWeight = FontWeight.Medium
)
}
}
}
if (person.debtCount > 0) {
Surface(
@@ -1420,6 +1449,7 @@ fun PersonListItem(
)
}
if (listType != PersonListType.PAID) {
Spacer(Modifier.width(4.dp))
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
@@ -1449,4 +1479,5 @@ fun PersonListItem(
}
}
}
}
@@ -31,7 +31,11 @@ fun formatTimestampToPersianDateTime(timestamp: Long): String {
return "$date، ساعت $time"
}
fun isTimestampInCurrentCycle(timestamp: Long): Boolean {
fun isTimestampInCurrentCycle(rawTimestamp: Long): Boolean {
if (rawTimestamp <= 0L) return false
val timestamp = if (rawTimestamp < 100000000000L) rawTimestamp * 1000L else rawTimestamp
val now = PersianDate()
val curYear = now.shYear
val curMonth = now.shMonth
@@ -198,6 +198,8 @@ class PersonViewModel @Inject constructor(
it.shamsiMonth == targetMonth && it.shamsiYear == targetYear && it.category == category
}
val categoryPayments = allPayments.filter { it.category == category }
val activePersons = persons
.filter { !it.isArchived && it.category == category }
.sortedWith(compareBy({ it.displayOrder }, { it.createdAt }))
@@ -205,6 +207,13 @@ class PersonViewModel @Inject constructor(
val uiModels = activePersons.map { person ->
val hasPaid = relevantPayments.any { it.personId == person.id }
val personCyclePayments = categoryPayments.filter {
it.personId == person.id && isTimestampInCurrentCycle(if ((it.createdAt ?: 0L) > 0L) it.createdAt!! else it.timestamp)
}
val latestPayment = personCyclePayments.maxByOrNull { if ((it.createdAt ?: 0L) > 0L) it.createdAt!! else it.timestamp }
val lastPaymentTime = latestPayment?.let { if ((it.createdAt ?: 0L) > 0L) it.createdAt!! else it.timestamp }
val lastPaymentAmount = if (personCyclePayments.isNotEmpty()) personCyclePayments.sumOf { it.amount } else null
val unpaidResult = if (category == "mosque" || person.isAnonymous) {
Triple(0, 0.0, emptyList<String>() to emptyList())
} else {
@@ -242,14 +251,16 @@ class PersonViewModel @Inject constructor(
monthlyCommitment = person.monthlyCommitment,
unpaidMonthsNames = unpaidMonthsNames,
unpaidMonths = unpaidMonths,
needsSync = person.needsSync
needsSync = person.needsSync,
lastPaymentTime = lastPaymentTime,
lastPaymentAmount = lastPaymentAmount
)
}
val categoryPayments = allPayments.filter { it.category == category }
updateDashboard(uiModels.size, relevantPayments, categoryPayments)
val (paidModels, unpaidModels) = uiModels.partition { it.hasPaidThisMonth }
val (rawPaidModels, unpaidModels) = uiModels.partition { it.hasPaidThisMonth }
val paidModels = rawPaidModels.sortedByDescending { it.lastPaymentTime ?: 0L }
// محاسبه گزارشات مالی جامع
val personsMap = persons.associateBy { it.id }
@@ -596,7 +607,7 @@ class PersonViewModel @Inject constructor(
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
val time = if ((payment.createdAt ?: 0L) > 0L) payment.createdAt!! else payment.timestamp
isTimestampInCurrentCycle(time)
}
val totalCycleIncome = cyclePayments.sumOf { it.amount }
@@ -17,6 +17,8 @@ data class PersonUiModel(
val unpaidMonthsNames: List<String> = emptyList(),
val unpaidMonths: List<Int> = emptyList(),
val needsSync: Boolean = false,
val lastPaymentTime: Long? = null,
val lastPaymentAmount: Double? = null
)
data class PersonListUiState(
+1 -1
View File
@@ -3,7 +3,7 @@
org.gradle.jvmargs=-Xmx2560m -XX:+UseParallelGC -Dfile.encoding=UTF-8
android.useAndroidX=true
android.enableJetifier=true
android.enableJetifier=false
kotlin.code.style=official
android.nonTransitiveRClass=true
android.suppressUnsupportedCompileSdk=34
+3 -3
View File
@@ -1,7 +1,7 @@
{
"versionCode": 13,
"versionName": "1.1.2",
"url": "https://github.com/oqba26/MonthlyPaymentApp/releases/download/v1.1.2/MonthlyPaymentApp-v1.1.2.apk",
"versionCode": 15,
"versionName": "1.1.4",
"url": "https://github.com/oqba26/MonthlyPaymentApp/releases/download/v1.1.4/MonthlyPaymentApp-v1.1.4.apk",
"releaseNotes": "بهبودهای پایداری و عملکرد همگام‌سازی",
"isForceUpdate": false
}