Coverage Summary for Class: DeleteTransactionUseCase (com.georgeci.moneysurfer.domain.usecase)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| DeleteTransactionUseCase |
100%
(2/2)
|
87.5%
(7/8)
|
100%
(9/9)
|
100%
(141/141)
|
| DeleteTransactionUseCase$invoke$1 |
|
| Total |
100%
(2/2)
|
87.5%
(7/8)
|
100%
(9/9)
|
100%
(141/141)
|
package com.georgeci.moneysurfer.domain.usecase
import com.georgeci.moneysurfer.domain.model.Transaction
import com.georgeci.moneysurfer.domain.primitives.TransactionId
import com.georgeci.moneysurfer.domain.repositories.TransactionRepository
import org.koin.core.annotation.Single
@Single
class DeleteTransactionUseCase(
private val transactionRepository: TransactionRepository,
private val applyTransactionChange: ApplyTransactionChangeUseCase,
) {
/**
* Deletes the transaction and returns every row removed, so callers can offer an Undo by
* handing the list straight back to [RestoreTransactionsUseCase].
*
* A transfer is deleted whole. Its two legs are one movement of money split across two rows,
* and removing only the one the user swiped would leave the other account credited out of
* nowhere — a corrupt balance rather than a partly-finished delete.
*
* A split is deleted whole for the same reason read as the user sees it: the group is one
* receipt shown as one row, so deleting that row deletes the payment — not the two thirds of it
* that happened to be filed under Groceries. The remaining legs would otherwise stay behind
* with no collapsed row left to reveal them.
*
* Returns an empty list when [id] names nothing, which is also how a caller knows there is
* nothing to offer an Undo for.
*/
suspend operator fun invoke(id: TransactionId): List<Transaction> {
val target = transactionRepository.getById(id) ?: return emptyList()
// A row always matches its own transferId / splitId, so either lookup returns the target
// plus its siblings — no fallback needed for the grouped cases. The two groupings are
// mutually exclusive in practice (a transfer leg carries the system Transfer category and
// is never split), and transfers win if a foreign writer ever sets both.
val rows = target.transferId?.let { transactionRepository.getByTransferId(it) }
?: target.splitId?.let { transactionRepository.getBySplitId(it) }
?: listOf(target)
rows.forEach { applyTransactionChange(old = it, new = null) }
return rows
}
}