diff --git a/ci-actions/compose-stability/ivy-compose-stability-baseline.txt b/ci-actions/compose-stability/ivy-compose-stability-baseline.txt index 1e6ac0c4a2..bcc0026ea8 100644 --- a/ci-actions/compose-stability/ivy-compose-stability-baseline.txt +++ b/ci-actions/compose-stability/ivy-compose-stability-baseline.txt @@ -14,6 +14,7 @@ com.ivy.design.utils.keyboardVisibleState com.ivy.legacy.ivyWalletCtx com.ivy.legacy.rootView com.ivy.legacy.rootActivity +com.ivy.legacy.ui.component.transaction.getTransactionDescription com.ivy.legacy.rootScreen com.ivy.frp.view.FRP com.ivy.wallet.ui.theme.pureBlur diff --git a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt index 11505c271c..b7db3dda8d 100644 --- a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt +++ b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt @@ -113,6 +113,7 @@ class EditTransactionViewModel @Inject constructor( private val description = mutableStateOf(null) private val dateTime = mutableStateOf(null) private val dueDate = mutableStateOf(null) + private val paidHistory = mutableStateOf(null) private val date = MutableStateFlow(null) private val time = MutableStateFlow(null) private val accounts = mutableStateOf>(persistentListOf()) @@ -373,6 +374,7 @@ class EditTransactionViewModel @Inject constructor( dateTime.value = transaction.dateTime description.value = transaction.description dueDate.value = transaction.dueDate + paidHistory.value = transaction.paidFor val selectedAccount = accountByIdAct(transaction.accountId)!! account.value = selectedAccount toAccount.value = transaction.toAccountId?.let { @@ -578,6 +580,7 @@ class EditTransactionViewModel @Inject constructor( syncTransaction = false ) { paidTransaction -> loadedTransaction = paidTransaction + paidHistory.value = paidTransaction.paidFor dueDate.value = paidTransaction.dueDate dateTime.value = paidTransaction.dateTime @@ -674,6 +677,7 @@ class EditTransactionViewModel @Inject constructor( amount = amount, type = transactionType.value, dueDate = dueDate.value, + paidFor = paidHistory.value, dateTime = when { loadedTransaction().dateTime == null && dueDate.value == null -> { diff --git a/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Dark].png b/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Dark].png index 634cfe08f0..42ea518c91 100644 Binary files a/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Dark].png and b/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Dark].png differ diff --git a/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Light].png b/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Light].png index e4944156c6..64b9aa7737 100644 Binary files a/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Light].png and b/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Light].png differ diff --git a/shared/base/src/main/java/com/ivy/base/legacy/Transaction.kt b/shared/base/src/main/java/com/ivy/base/legacy/Transaction.kt index 7f74d86890..4aaf60aea3 100644 --- a/shared/base/src/main/java/com/ivy/base/legacy/Transaction.kt +++ b/shared/base/src/main/java/com/ivy/base/legacy/Transaction.kt @@ -30,6 +30,10 @@ data class Transaction( val time: LocalTime? = null, val recurringRuleId: UUID? = null, + /** to store the date for which the payment was made. */ + @Suppress("DataClassDefaultValues") + val paidFor: LocalDateTime? = null, + val attachmentUrl: String? = null, // This refers to the loan id that is linked with a transaction diff --git a/shared/data/core/src/main/java/com/ivy/data/db/IvyRoomDatabase.kt b/shared/data/core/src/main/java/com/ivy/data/db/IvyRoomDatabase.kt index 3e821e51b7..bec15293ff 100644 --- a/shared/data/core/src/main/java/com/ivy/data/db/IvyRoomDatabase.kt +++ b/shared/data/core/src/main/java/com/ivy/data/db/IvyRoomDatabase.kt @@ -41,6 +41,7 @@ import com.ivy.data.db.entity.UserEntity import com.ivy.data.db.migration.Migration123to124_LoanIncludeDateTime import com.ivy.data.db.migration.Migration124to125_LoanEditDateTime import com.ivy.data.db.migration.Migration126to127_LoanRecordType +import com.ivy.data.db.migration.Migration127to128_PaidForDateRecord import com.ivy.domain.db.RoomTypeConverters import com.ivy.domain.db.migration.Migration105to106_TrnRecurringRules import com.ivy.domain.db.migration.Migration106to107_Wishlist @@ -75,7 +76,7 @@ import com.ivy.domain.db.migration.Migration125to126_Tags spec = IvyRoomDatabase.DeleteSEMigration::class ) ], - version = 127, + version = 128, exportSchema = true ) @TypeConverters(RoomTypeConverters::class) @@ -129,7 +130,8 @@ abstract class IvyRoomDatabase : RoomDatabase() { Migration123to124_LoanIncludeDateTime(), Migration124to125_LoanEditDateTime(), Migration125to126_Tags(), - Migration126to127_LoanRecordType() + Migration126to127_LoanRecordType(), + Migration127to128_PaidForDateRecord() ) @Suppress("SpreadOperator") diff --git a/shared/data/core/src/main/java/com/ivy/data/db/entity/TransactionEntity.kt b/shared/data/core/src/main/java/com/ivy/data/db/entity/TransactionEntity.kt index 2004329820..473d96f93b 100644 --- a/shared/data/core/src/main/java/com/ivy/data/db/entity/TransactionEntity.kt +++ b/shared/data/core/src/main/java/com/ivy/data/db/entity/TransactionEntity.kt @@ -11,6 +11,7 @@ import kotlinx.serialization.Serializable import java.time.LocalDateTime import java.util.* +@Suppress("DataClassDefaultValues") @Keep @Serializable @Entity(tableName = "transactions") @@ -43,6 +44,9 @@ data class TransactionEntity( @SerialName("recurringRuleId") @Serializable(with = KSerializerUUID::class) val recurringRuleId: UUID? = null, + @SerialName("paidForDateTime") + @Serializable(with = KSerializerLocalDateTime::class) + val paidForDateTime: LocalDateTime? = null, @SerialName("attachmentUrl") val attachmentUrl: String? = null, // This refers to the loan id that is linked with a transaction diff --git a/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration127to128_PaidForDateRecord.kt b/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration127to128_PaidForDateRecord.kt new file mode 100644 index 0000000000..3755382cbd --- /dev/null +++ b/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration127to128_PaidForDateRecord.kt @@ -0,0 +1,11 @@ +package com.ivy.data.db.migration + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +@Suppress("MagicNumber", "ClassNaming") +class Migration127to128_PaidForDateRecord : Migration(127, 128) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE transactions ADD COLUMN paidForDateTime INTEGER") + } +} \ No newline at end of file diff --git a/shared/data/core/src/main/java/com/ivy/data/repository/mapper/TransactionMapper.kt b/shared/data/core/src/main/java/com/ivy/data/repository/mapper/TransactionMapper.kt index 2b3f6cd850..70a1c574ee 100644 --- a/shared/data/core/src/main/java/com/ivy/data/repository/mapper/TransactionMapper.kt +++ b/shared/data/core/src/main/java/com/ivy/data/repository/mapper/TransactionMapper.kt @@ -35,6 +35,7 @@ class TransactionMapper @Inject constructor( ): Either = either { val metadata = TransactionMetadata( recurringRuleId = recurringRuleId, + paidForDateTime = paidForDateTime?.atZone(timeProvider.getZoneId())?.toInstant(), loanId = loanId, loanRecordId = loanRecordId ) @@ -68,7 +69,7 @@ class TransactionMapper @Inject constructor( metadata = metadata, lastUpdated = Instant.EPOCH, removed = isDeleted, - tags = tags + tags = tags, ) } @@ -85,7 +86,7 @@ class TransactionMapper @Inject constructor( metadata = metadata, lastUpdated = Instant.EPOCH, removed = isDeleted, - tags = tags + tags = tags, ) } @@ -124,7 +125,7 @@ class TransactionMapper @Inject constructor( fromValue = fromValue, toAccount = toAccountId, toValue = toValue, - tags = tags + tags = tags, ) } } @@ -161,6 +162,7 @@ class TransactionMapper @Inject constructor( dateTime = dateTime.takeIf { settled }, categoryId = category?.value, dueDate = dateTime.takeIf { !settled }, + paidForDateTime = metadata.paidForDateTime?.atZone(timeProvider.getZoneId())?.toLocalDateTime(), recurringRuleId = metadata.recurringRuleId, attachmentUrl = null, loanId = metadata.loanId, diff --git a/shared/data/core/src/test/java/com/ivy/data/ArbTransactionEntity.kt b/shared/data/core/src/test/java/com/ivy/data/ArbTransactionEntity.kt index b5afb1d165..2010b5cd92 100644 --- a/shared/data/core/src/test/java/com/ivy/data/ArbTransactionEntity.kt +++ b/shared/data/core/src/test/java/com/ivy/data/ArbTransactionEntity.kt @@ -74,6 +74,9 @@ fun Arb.Companion.validTransfer(): Arb = arbitrary { dueDate = Arb.localDateTime().bind().takeIf { isPlannedPayment || Arb.boolean().bind() }, + paidForDateTime = Arb.localDateTime().bind().takeIf { + !isPlannedPayment || Arb.boolean().bind() + }, categoryId = Arb.maybe(Arb.uuid()).bind(), recurringRuleId = Arb.maybe(Arb.uuid()).bind(), attachmentUrl = Arb.maybe(Arb.string()).bind(), @@ -128,6 +131,9 @@ fun Arb.Companion.validIncomeOrExpense(): Arb = arbitrary { dueDate = Arb.localDateTime().bind().takeIf { isPlannedPayment || Arb.boolean().bind() }, + paidForDateTime = Arb.localDateTime().bind().takeIf { + !isPlannedPayment || Arb.boolean().bind() + }, categoryId = Arb.maybe(Arb.uuid()).bind(), recurringRuleId = Arb.maybe(Arb.uuid()).bind(), attachmentUrl = Arb.maybe(Arb.string()).bind(), diff --git a/shared/data/core/src/test/java/com/ivy/data/repository/mapper/TransactionMapperTest.kt b/shared/data/core/src/test/java/com/ivy/data/repository/mapper/TransactionMapperTest.kt index 562608b612..5feaa7fc3c 100644 --- a/shared/data/core/src/test/java/com/ivy/data/repository/mapper/TransactionMapperTest.kt +++ b/shared/data/core/src/test/java/com/ivy/data/repository/mapper/TransactionMapperTest.kt @@ -74,6 +74,7 @@ class TransactionMapperTest { metadata = TransactionMetadata( recurringRuleId = RecurringRuleId, loanId = LoanId, + paidForDateTime = PaidForDateTime, loanRecordId = LoanRecordId ), lastUpdated = InstantNow, @@ -102,6 +103,7 @@ class TransactionMapperTest { dateTime = dateTime.takeIf { settled }, categoryId = CategoryId.value, dueDate = dateTime.takeIf { !settled }, + paidForDateTime = PaidForDateTime.atZone(timeProvider.getZoneId()).toLocalDateTime(), recurringRuleId = RecurringRuleId, attachmentUrl = null, loanId = LoanId, @@ -128,6 +130,7 @@ class TransactionMapperTest { metadata = TransactionMetadata( recurringRuleId = RecurringRuleId, loanId = LoanId, + paidForDateTime = PaidForDateTime, loanRecordId = LoanRecordId ), lastUpdated = Instant.EPOCH, @@ -156,6 +159,7 @@ class TransactionMapperTest { dateTime = dateTime.takeIf { settled }, categoryId = CategoryId.value, dueDate = dateTime.takeIf { !settled }, + paidForDateTime = PaidForDateTime.atZone(timeProvider.getZoneId()).toLocalDateTime(), recurringRuleId = RecurringRuleId, attachmentUrl = null, loanId = LoanId, @@ -182,6 +186,7 @@ class TransactionMapperTest { metadata = TransactionMetadata( recurringRuleId = RecurringRuleId, loanId = LoanId, + paidForDateTime = PaidForDateTime, loanRecordId = LoanRecordId ), lastUpdated = Instant.EPOCH, @@ -215,6 +220,7 @@ class TransactionMapperTest { dateTime = dateTime.takeIf { settled }, categoryId = CategoryId.value, dueDate = dateTime.takeIf { !settled }, + paidForDateTime = PaidForDateTime.atZone(timeProvider.getZoneId()).toLocalDateTime(), recurringRuleId = RecurringRuleId, attachmentUrl = null, loanId = LoanId, @@ -254,6 +260,7 @@ class TransactionMapperTest { metadata = TransactionMetadata( recurringRuleId = RecurringRuleId, loanId = LoanId, + paidForDateTime = PaidForDateTime, loanRecordId = LoanRecordId ), lastUpdated = Instant.EPOCH, @@ -380,6 +387,7 @@ class TransactionMapperTest { metadata = TransactionMetadata( recurringRuleId = RecurringRuleId, loanId = LoanId, + paidForDateTime = PaidForDateTime, loanRecordId = LoanRecordId ), lastUpdated = Instant.EPOCH, @@ -511,6 +519,7 @@ class TransactionMapperTest { metadata = TransactionMetadata( recurringRuleId = RecurringRuleId, loanId = LoanId, + paidForDateTime = PaidForDateTime, loanRecordId = LoanRecordId ), lastUpdated = Instant.EPOCH, @@ -691,6 +700,7 @@ class TransactionMapperTest { val ToAccountId = AccountId(UUID.randomUUID()) val CategoryId = CategoryId(UUID.randomUUID()) val RecurringRuleId = UUID.randomUUID() + val PaidForDateTime: Instant = Instant.now() val LoanId = UUID.randomUUID() val LoanRecordId = UUID.randomUUID() val TransactionId = TransactionId(UUID.randomUUID()) @@ -707,6 +717,7 @@ class TransactionMapperTest { dateTime = DateTime, categoryId = CategoryId.value, dueDate = null, + paidForDateTime = PaidForDateTime.atZone(ZoneId.of("UTC")).toLocalDateTime(), recurringRuleId = RecurringRuleId, attachmentUrl = null, loanId = LoanId, @@ -727,6 +738,7 @@ class TransactionMapperTest { dateTime = DateTime, categoryId = CategoryId.value, dueDate = null, + paidForDateTime = PaidForDateTime.atZone(ZoneId.of("UTC")).toLocalDateTime(), recurringRuleId = RecurringRuleId, attachmentUrl = null, loanId = LoanId, @@ -747,6 +759,7 @@ class TransactionMapperTest { dateTime = DateTime, categoryId = CategoryId.value, dueDate = null, + paidForDateTime = PaidForDateTime.atZone(ZoneId.of("UTC")).toLocalDateTime(), recurringRuleId = RecurringRuleId, attachmentUrl = null, loanId = LoanId, diff --git a/shared/data/model-testing/src/main/java/com/ivy/data/model/testing/ArbTransaction.kt b/shared/data/model-testing/src/main/java/com/ivy/data/model/testing/ArbTransaction.kt index 9ea9f811c0..6f8c1380c1 100644 --- a/shared/data/model-testing/src/main/java/com/ivy/data/model/testing/ArbTransaction.kt +++ b/shared/data/model-testing/src/main/java/com/ivy/data/model/testing/ArbTransaction.kt @@ -47,6 +47,7 @@ fun Arb.Companion.income( metadata = TransactionMetadata( recurringRuleId = null, loanId = null, + paidForDateTime = null, loanRecordId = null ), lastUpdated = Instant.EPOCH, @@ -77,6 +78,7 @@ fun Arb.Companion.expense( metadata = TransactionMetadata( recurringRuleId = null, loanId = null, + paidForDateTime = null, loanRecordId = null ), lastUpdated = Instant.EPOCH, @@ -111,6 +113,7 @@ fun Arb.Companion.transfer( metadata = TransactionMetadata( recurringRuleId = null, loanId = null, + paidForDateTime = null, loanRecordId = null ), lastUpdated = Instant.EPOCH, diff --git a/shared/data/model/src/main/kotlin/com/ivy/data/model/Transaction.kt b/shared/data/model/src/main/kotlin/com/ivy/data/model/Transaction.kt index 0422008427..b6464968e4 100644 --- a/shared/data/model/src/main/kotlin/com/ivy/data/model/Transaction.kt +++ b/shared/data/model/src/main/kotlin/com/ivy/data/model/Transaction.kt @@ -72,6 +72,7 @@ data class Transfer( @Suppress("DataClassTypedIDs") data class TransactionMetadata( val recurringRuleId: UUID?, + val paidForDateTime: Instant?, // This refers to the loan id that is linked with a transaction val loanId: UUID? = null, // This refers to the loan record id that is linked with a transaction diff --git a/shared/data/model/src/test/java/com/ivy/data/model/primitive/TransactionTest.kt b/shared/data/model/src/test/java/com/ivy/data/model/primitive/TransactionTest.kt index a174ed703d..ded621141b 100644 --- a/shared/data/model/src/test/java/com/ivy/data/model/primitive/TransactionTest.kt +++ b/shared/data/model/src/test/java/com/ivy/data/model/primitive/TransactionTest.kt @@ -139,6 +139,7 @@ class TransactionTest { metadata = TransactionMetadata( recurringRuleId = null, loanId = null, + paidForDateTime = null, loanRecordId = null ), lastUpdated = Instant.EPOCH, @@ -161,6 +162,7 @@ class TransactionTest { metadata = TransactionMetadata( recurringRuleId = null, loanId = null, + paidForDateTime = null, loanRecordId = null ), lastUpdated = Instant.EPOCH, @@ -183,6 +185,7 @@ class TransactionTest { metadata = TransactionMetadata( recurringRuleId = null, loanId = null, + paidForDateTime = null, loanRecordId = null ), lastUpdated = Instant.EPOCH, diff --git a/shared/ui/core/src/main/res/values/strings.xml b/shared/ui/core/src/main/res/values/strings.xml index da05666a8c..2ee5a264d6 100644 --- a/shared/ui/core/src/main/res/values/strings.xml +++ b/shared/ui/core/src/main/res/values/strings.xml @@ -487,4 +487,5 @@ Continue "\n!!!⚠️WARNING: Importing may duplicate transactions!!!\nDuplicate transactions can NOT be easily deleted and you'll need to remove manually each one of them! \nReason: We can't parse transaction ids because Ivy Wallet works only with UUID and other apps don't.\nIf you're starting fresh, no worries - kindly ignore this message." Select Tags + Your bill for %1$s %2$d has been paid diff --git a/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/TransactionExt.kt b/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/TransactionExt.kt index ba394263ef..221c6d6e48 100644 --- a/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/TransactionExt.kt +++ b/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/TransactionExt.kt @@ -15,6 +15,7 @@ fun Transaction.toEntity(): TransactionEntity = TransactionEntity( categoryId = categoryId, dueDate = dueDate, recurringRuleId = recurringRuleId, + paidForDateTime = paidFor, attachmentUrl = attachmentUrl, loanId = loanId, loanRecordId = loanRecordId, diff --git a/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/temp/TransactionExt.kt b/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/temp/TransactionExt.kt index 7c0a544e02..edc3743549 100644 --- a/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/temp/TransactionExt.kt +++ b/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/temp/TransactionExt.kt @@ -28,6 +28,7 @@ fun TransactionEntity.toLegacyDomain( categoryId = categoryId, dueDate = dueDate, recurringRuleId = recurringRuleId, + paidFor = paidForDateTime, attachmentUrl = attachmentUrl, loanId = loanId, loanRecordId = loanRecordId, diff --git a/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/PlannedPaymentsGenerator.kt b/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/PlannedPaymentsGenerator.kt index 103f6c0298..c565ce7cde 100644 --- a/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/PlannedPaymentsGenerator.kt +++ b/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/PlannedPaymentsGenerator.kt @@ -86,7 +86,6 @@ class PlannedPaymentsGenerator @Inject constructor( dueDate = dueDate, dateTime = null, toAccountId = null, - isSynced = false ).toEntity() ) diff --git a/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/PlannedPaymentsLogic.kt b/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/PlannedPaymentsLogic.kt index e52aefaa83..fc8d928d5e 100644 --- a/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/PlannedPaymentsLogic.kt +++ b/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/PlannedPaymentsLogic.kt @@ -165,6 +165,7 @@ class PlannedPaymentsLogic @Inject constructor( if (transaction.dueDate == null || transaction.dateTime != null) return val paidTransaction = transaction.copy( + paidFor = transaction.dueDate, dueDate = null, dateTime = timeNowUTC(), isSynced = false, diff --git a/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/transaction/TransactionCard.kt b/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/transaction/TransactionCard.kt index 4ffd8b49dc..597b5a67c4 100644 --- a/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/transaction/TransactionCard.kt +++ b/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/transaction/TransactionCard.kt @@ -45,6 +45,7 @@ import com.ivy.design.l1_buildingBlocks.SpacerHor import com.ivy.legacy.IvyWalletPreview import com.ivy.legacy.data.AppBaseData import com.ivy.legacy.datamodel.Account +import com.ivy.legacy.utils.capitalizeLocal import com.ivy.legacy.utils.dateNowUTC import com.ivy.legacy.utils.format import com.ivy.legacy.utils.formatNicely @@ -117,6 +118,8 @@ fun TransactionCard( baseData.accounts.find { it.id == transaction.toAccountId }?.currency ?: baseData.baseCurrency + val transactionDescription = getTransactionDescription(transaction) + Spacer(Modifier.height(20.dp)) TransactionHeaderRow( @@ -162,7 +165,7 @@ fun TransactionCard( ) } - if (transaction.description.isNotNullOrBlank()) { + if (transactionDescription.isNotNullOrBlank()) { Spacer( Modifier.height( if (transaction.title.isNotNullOrBlank()) 4.dp else 8.dp @@ -170,7 +173,7 @@ fun TransactionCard( ) Text( - text = transaction.description!!, + text = transactionDescription!!, modifier = Modifier.padding(horizontal = 24.dp), style = UI.typo.nC.style( color = UI.colors.gray, @@ -367,6 +370,19 @@ fun CategoryBadgeDisplay( } } +@Composable +private fun getTransactionDescription(transaction: Transaction): String? { + return when { + transaction.description.isNotNullOrBlank() -> transaction.description!! + transaction.recurringRuleId != null && transaction.dueDate == null -> stringResource( + R.string.bill_paid, + transaction.paidFor?.month?.name?.lowercase()?.capitalizeLocal() ?: "", + transaction.paidFor?.year ?: "" + ) + else -> null + } +} + @Composable private fun TransactionBadge( text: String,