Coverage Summary for Class: TransactionGroupUi (com.georgeci.moneysurfer.feature.transaction.list)
| Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| TransactionGroupUi |
100%
(1/1)
|
100%
(1/1)
|
|
100%
(6/6)
|
100%
(27/27)
|
package com.georgeci.moneysurfer.feature.transaction.list
import com.georgeci.moneysurfer.domain.primitives.TransactionId
import com.georgeci.moneysurfer.feature.transaction.filter.TransactionDateRange
import com.georgeci.moneysurfer.feature.transaction.filter.TransactionSort
import com.georgeci.moneysurfer.feature.transaction.filter.TransactionTypeFilter
import kotlinx.datetime.LocalDate
data class TransactionGroupUi(
val date: LocalDate,
val dateLabel: TransactionDateUi,
val netFormatted: String,
val netPositive: Boolean,
val transactions: List<TransactionRowUi>,
)
/** Day-header label, resolved to text by the screen. */
sealed interface TransactionDateUi {
data object Today : TransactionDateUi
data object Yesterday : TransactionDateUi
data class Exact(val date: LocalDate) : TransactionDateUi
}
/** Pager label, resolved to text by the screen — see the `PeriodPager` design component. */
sealed interface TransactionPeriodUi {
data class Month(val monthNumber: Int, val year: Int) : TransactionPeriodUi
data class Week(
val from: LocalDate,
val to: LocalDate,
val weekNumber: Int,
val weekYear: Int,
) : TransactionPeriodUi
data object AllTime : TransactionPeriodUi
}
/**
* The filter chip rail's contents. Every chip is a shortcut into the filter screen, so these carry
* only what the chip label shows — a name when exactly one thing is picked, a count otherwise.
*/
data class TransactionFilterChipsUi(
val dateRange: TransactionDateRange,
val type: TransactionTypeFilter,
val accountCount: Int,
val accountName: String?,
val categoryCount: Int,
val categoryName: String?,
val sort: TransactionSort,
)
data class TransactionRowUi(
val id: TransactionId,
val title: String,
val subtitle: String,
val formattedAmount: String,
val isExpense: Boolean,
val categoryHueSeed: String,
/** Name of the owning account, rendered only where the list mixes several — may be blank. */
val accountName: String = "",
/** One leg of a transfer: money moved sideways, drawn neutral with a swap glyph. */
val isTransfer: Boolean = false,
/**
* How many categories a collapsed split row covers, or `0` when the row is an ordinary
* transaction. Non-zero replaces [subtitle] with the "N categories" badge: a receipt split
* across several categories has no single category name to show, and [formattedAmount] is the
* whole receipt rather than any one leg. [id] is the leg the row opens — its details screen
* carries the breakdown.
*/
val splitCategoryCount: Int = 0,
/**
* Whether the row belongs to a receipt split across categories — true for a collapsed row and
* for a lone leg alike.
*
* Deliberately separate from [splitCategoryCount], which is only non-zero once a group is
* collapsed: a page that holds part of a group renders its legs individually, and deleting one
* of those still takes the whole receipt. The delete confirmation keys off this, so what the
* dialog promises matches what the delete does at every window size.
*/
val isSplitLeg: Boolean = false,
)
data class TransactionSummaryUi(
val incomeFormatted: String,
val expenseFormatted: String,
val netFormatted: String,
val netPositive: Boolean,
)