11package com.ritesh.cashiro.data.repository
22
33import com.ritesh.cashiro.data.database.dao.TransactionDao
4+ import com.ritesh.cashiro.data.database.entity.AccountBalanceEntity
45import com.ritesh.cashiro.data.database.entity.TransactionEntity
56import com.ritesh.cashiro.data.database.entity.TransactionType
67import java.math.BigDecimal
@@ -13,7 +14,10 @@ import kotlinx.coroutines.flow.Flow
1314import kotlinx.coroutines.flow.map
1415
1516@Singleton
16- class TransactionRepository @Inject constructor(private val transactionDao : TransactionDao ) {
17+ class TransactionRepository @Inject constructor(
18+ private val transactionDao : TransactionDao ,
19+ private val accountBalanceRepository : AccountBalanceRepository
20+ ) {
1721 fun getAllTransactions (): Flow <List <TransactionEntity >> = transactionDao.getAllTransactions()
1822
1923 fun getTransactionCount (): Flow <Int > = transactionDao.getTransactionCount()
@@ -124,14 +128,17 @@ class TransactionRepository @Inject constructor(private val transactionDao: Tran
124128 } else {
125129 transactionDao.softDeleteTransaction(transaction.id)
126130 }
131+ reverseBalanceForDeletion(transaction)
127132 }
128133
129134 suspend fun deleteTransactionById (id : Long , hardDelete : Boolean = false) {
135+ val transaction = transactionDao.getTransactionById(id) ? : return
130136 if (hardDelete) {
131137 transactionDao.deleteTransactionById(id)
132138 } else {
133139 transactionDao.softDeleteTransaction(id)
134140 }
141+ reverseBalanceForDeletion(transaction)
135142 }
136143
137144 suspend fun deleteAllTransactions () = transactionDao.deleteAllTransactions()
@@ -144,6 +151,7 @@ class TransactionRepository @Inject constructor(private val transactionDao: Tran
144151
145152 suspend fun undoDeleteTransaction (transaction : TransactionEntity ) {
146153 transactionDao.updateTransaction(transaction.copy(isDeleted = false ))
154+ applyBalanceForTransaction(transaction)
147155 }
148156
149157 suspend fun deleteTransactions (transactions : List <TransactionEntity >, hardDelete : Boolean = false) {
@@ -153,14 +161,100 @@ class TransactionRepository @Inject constructor(private val transactionDao: Tran
153161 } else {
154162 transactionDao.softDeleteTransactions(transactionIds)
155163 }
164+ transactions.forEach { reverseBalanceForDeletion(it) }
156165 }
157166
158167 suspend fun undoDeleteTransactions (transactions : List <TransactionEntity >) {
159168 transactions.forEach { transaction ->
160169 transactionDao.updateTransaction(transaction.copy(isDeleted = false ))
170+ applyBalanceForTransaction(transaction)
161171 }
162172 }
163173
174+ private suspend fun reverseBalanceForDeletion (transaction : TransactionEntity ) {
175+ val bankName = transaction.bankName ? : return
176+ val accountLast4 = transaction.accountNumber ? : return
177+ val latestBalance = accountBalanceRepository.getLatestBalance(bankName, accountLast4) ? : return
178+ val currentBalance = latestBalance.balance
179+ val isCreditCard = latestBalance.isCreditCard
180+
181+ val reversedBalance = when {
182+ isCreditCard -> {
183+ when (transaction.transactionType) {
184+ TransactionType .EXPENSE , TransactionType .INVESTMENT -> currentBalance - transaction.amount
185+ TransactionType .INCOME -> currentBalance + transaction.amount
186+ else -> currentBalance
187+ }
188+ }
189+ else -> {
190+ when (transaction.transactionType) {
191+ TransactionType .EXPENSE , TransactionType .INVESTMENT -> currentBalance + transaction.amount
192+ TransactionType .INCOME -> currentBalance - transaction.amount
193+ else -> currentBalance
194+ }
195+ }
196+ }.max(BigDecimal .ZERO )
197+
198+ val balanceEntity = AccountBalanceEntity (
199+ bankName = bankName,
200+ accountLast4 = accountLast4,
201+ balance = reversedBalance,
202+ timestamp = LocalDateTime .now(),
203+ transactionId = null ,
204+ creditLimit = latestBalance.creditLimit,
205+ isCreditCard = isCreditCard,
206+ iconResId = latestBalance.iconResId,
207+ iconName = latestBalance.iconName,
208+ isWallet = latestBalance.isWallet,
209+ color = latestBalance.color,
210+ currency = transaction.currency,
211+ sourceType = " DELETE_REVERSAL"
212+ )
213+ accountBalanceRepository.insertBalance(balanceEntity)
214+ }
215+
216+ private suspend fun applyBalanceForTransaction (transaction : TransactionEntity ) {
217+ val bankName = transaction.bankName ? : return
218+ val accountLast4 = transaction.accountNumber ? : return
219+ val latestBalance = accountBalanceRepository.getLatestBalance(bankName, accountLast4) ? : return
220+ val currentBalance = latestBalance.balance
221+ val isCreditCard = latestBalance.isCreditCard
222+
223+ val newBalance = when {
224+ isCreditCard -> {
225+ when (transaction.transactionType) {
226+ TransactionType .EXPENSE , TransactionType .INVESTMENT -> currentBalance + transaction.amount
227+ TransactionType .INCOME -> (currentBalance - transaction.amount).max(BigDecimal .ZERO )
228+ else -> currentBalance
229+ }
230+ }
231+ else -> {
232+ when (transaction.transactionType) {
233+ TransactionType .EXPENSE , TransactionType .INVESTMENT -> (currentBalance - transaction.amount).max(BigDecimal .ZERO )
234+ TransactionType .INCOME -> currentBalance + transaction.amount
235+ else -> currentBalance
236+ }
237+ }
238+ }
239+
240+ val balanceEntity = AccountBalanceEntity (
241+ bankName = bankName,
242+ accountLast4 = accountLast4,
243+ balance = newBalance,
244+ timestamp = LocalDateTime .now(),
245+ transactionId = null ,
246+ creditLimit = latestBalance.creditLimit,
247+ isCreditCard = isCreditCard,
248+ iconResId = latestBalance.iconResId,
249+ iconName = latestBalance.iconName,
250+ isWallet = latestBalance.isWallet,
251+ color = latestBalance.color,
252+ currency = transaction.currency,
253+ sourceType = " UNDO_REVERSAL"
254+ )
255+ accountBalanceRepository.insertBalance(balanceEntity)
256+ }
257+
164258 suspend fun updateCategoryForMerchant (merchantName : String , newCategory : String ) {
165259 transactionDao.updateCategoryForMerchant(merchantName, newCategory)
166260 }
0 commit comments