Skip to content
This repository has been archived by the owner on Nov 5, 2024. It is now read-only.

Fix issue 2740 #2928

Merged
merged 15 commits into from
Feb 8, 2024
37 changes: 24 additions & 13 deletions screen/loans/src/main/java/com/ivy/loans/loan/LoanViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.viewModelScope
import com.ivy.base.legacy.SharedPrefs
import com.ivy.base.model.LoanRecordType
import com.ivy.data.db.dao.read.LoanRecordDao
import com.ivy.data.db.dao.read.SettingsDao
import com.ivy.data.db.dao.write.WriteLoanDao
Expand Down Expand Up @@ -164,22 +165,22 @@ class LoanViewModel @Inject constructor(
allLoans = ioThread {
loansAct(Unit)
.map { loan ->
val amountPaid = calculateAmountPaid(loan)
val loanAmount = loan.amount
val percentPaid = amountPaid / loanAmount
val (amountPaid, loanTotalAmount) = calculateAmountPaidAndTotalAmount(loan)
val percentPaid = amountPaid / loanTotalAmount
ILIYANGERMANOV marked this conversation as resolved.
Show resolved Hide resolved
var currCode = findCurrencyCode(accounts.value, loan.accountId)

when (loan.type) {
LoanType.BORROW -> totalOweAmount += (loanAmount - amountPaid)
LoanType.LEND -> totalOwedAmount += (loanAmount - amountPaid)
LoanType.BORROW -> totalOweAmount += (loanTotalAmount - amountPaid)
LoanType.LEND -> totalOwedAmount += (loanTotalAmount - amountPaid)
}

DisplayLoan(
loan = loan,
loanTotalAmount = loanTotalAmount,
amountPaid = amountPaid,
currencyCode = currCode,
formattedDisplayText = "${amountPaid.format(currCode)} $currCode / ${
loanAmount.format(
loanTotalAmount.format(
currCode
)
} $currCode (${
Expand Down Expand Up @@ -300,18 +301,28 @@ class LoanViewModel @Inject constructor(
} ?: defaultCurrencyCode
}

private suspend fun calculateAmountPaid(loan: Loan): Double {
/**
* Calculates the total amount paid and the total loan amount including any changes made to the loan.
* @return A Pair containing the total amount paid and the total loan amount.
*/
private suspend fun calculateAmountPaidAndTotalAmount(loan: Loan): Pair<Double, Double> {
ILIYANGERMANOV marked this conversation as resolved.
Show resolved Hide resolved
val loanRecords = ioThread { loanRecordDao.findAllByLoanId(loanId = loan.id) }
var amount = 0.0
var amountPaid = 0.0
var loanTotalAmount = loan.amount
ILIYANGERMANOV marked this conversation as resolved.
Show resolved Hide resolved

loanRecords.forEach { loanRecord ->
if (!loanRecord.interest) {
val convertedAmount = loanRecord.convertedAmount ?: loanRecord.amount
amount += convertedAmount
if (loanRecord.interest) return@forEach
val convertedAmount = loanRecord.convertedAmount ?: loanRecord.amount
when (loanRecord.loanRecordType) {
ILIYANGERMANOV marked this conversation as resolved.
Show resolved Hide resolved
LoanRecordType.DECREASE -> {
amountPaid += convertedAmount
}
LoanRecordType.INCREASE -> {
loanTotalAmount += convertedAmount
}
}
}

return amount
return amountPaid to loanTotalAmount
ILIYANGERMANOV marked this conversation as resolved.
Show resolved Hide resolved
}

private fun updatePaidOffLoanVisibility() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ private fun LoanHeader(

Spacer(Modifier.height(4.dp))

val leftToPay = loan.amount - displayLoan.amountPaid
val leftToPay = displayLoan.loanTotalAmount - displayLoan.amountPaid
BalanceRow(
modifier = Modifier
.align(Alignment.CenterHorizontally),
Expand Down Expand Up @@ -413,6 +413,7 @@ private fun Preview() {
type = LoanType.BORROW,
dateTime = LocalDateTime.now()
),
loanTotalAmount = 5500.0,
amountPaid = 0.0,
percentPaid = 0.4
),
Expand All @@ -425,6 +426,7 @@ private fun Preview() {
type = LoanType.BORROW,
dateTime = LocalDateTime.now()
),
loanTotalAmount = 252.36,
amountPaid = 124.23,
percentPaid = 0.2
),
Expand All @@ -437,6 +439,7 @@ private fun Preview() {
type = LoanType.LEND,
dateTime = LocalDateTime.now()
),
loanTotalAmount = 7000.0,
amountPaid = 8000.0,
percentPaid = 0.8
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.ivy.wallet.domain.data.Reorderable

data class DisplayLoan(
val loan: Loan,
val loanTotalAmount: Double,
val amountPaid: Double,
val currencyCode: String? = getDefaultFIATCurrency().currencyCode,
val formattedDisplayText: String = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.ivy.base.model.LoanRecordType
import com.ivy.base.model.TransactionType
import com.ivy.data.model.LoanType
import com.ivy.design.l0_system.UI
Expand Down Expand Up @@ -125,6 +126,7 @@ private fun BoxWithConstraintsScope.UI(
Header(
loan = state.loan,
baseCurrency = state.baseCurrency,
loanTotalAmount = state.loanTotalAmount,
amountPaid = state.amountPaid,
loanAmountPaid = state.loanAmountPaid,
itemColor = itemColor,
Expand Down Expand Up @@ -172,6 +174,13 @@ private fun BoxWithConstraintsScope.UI(
)
}
)
item {
InitialRecordItem(
loan = state.loan,
amount = state.loan.amount,
baseCurrency = state.baseCurrency,
)
}
}

if (state.displayLoanRecords.isEmpty()) {
Expand Down Expand Up @@ -234,14 +243,14 @@ private fun BoxWithConstraintsScope.UI(
private fun Header(
loan: Loan,
baseCurrency: String,
loanTotalAmount: Double,
amountPaid: Double,
loanAmountPaid: Double = 0.0,
itemColor: Color,
selectedLoanAccount: Account? = null,

onAmountClick: () -> Unit,
onEditLoan: () -> Unit,
onDeleteLoan: () -> Unit,
loanAmountPaid: Double = 0.0,
selectedLoanAccount: Account? = null,
onAddRecord: () -> Unit
) {
val contrastColor = findContrastTextColor(itemColor)
Expand Down Expand Up @@ -278,7 +287,7 @@ private fun Header(
},
textColor = contrastColor,
currency = baseCurrency,
balance = loan.amount,
balance = loanTotalAmount,
)

Spacer(Modifier.height(20.dp))
Expand All @@ -288,6 +297,7 @@ private fun Header(
baseCurrency = baseCurrency,
amountPaid = amountPaid,
loanAmountPaid = loanAmountPaid,
loanTotalAmount = loanTotalAmount,
selectedLoanAccount = selectedLoanAccount,
onAddRecord = onAddRecord
)
Expand Down Expand Up @@ -356,10 +366,12 @@ private fun LoanItem(
}
}

@Suppress("LongMethod")
@Composable
private fun LoanInfoCard(
loan: Loan,
baseCurrency: String,
loanTotalAmount: Double,
amountPaid: Double,
loanAmountPaid: Double = 0.0,
selectedLoanAccount: Account? = null,
Expand All @@ -373,8 +385,8 @@ private fun LoanInfoCard(
}

val contrastColor = findContrastTextColor(backgroundColor)
val percentPaid = amountPaid / loan.amount
val loanPercentPaid = loanAmountPaid / loan.amount
val percentPaid = amountPaid / loanTotalAmount
val loanPercentPaid = loanAmountPaid / loanTotalAmount
val nav = navigation()

Column(
Expand Down Expand Up @@ -437,7 +449,7 @@ private fun LoanInfoCard(
modifier = Modifier
.padding(horizontal = 24.dp)
.testTag("amount_paid"),
text = "${amountPaid.format(baseCurrency)} / ${loan.amount.format(baseCurrency)}",
text = "${amountPaid.format(baseCurrency)} / ${loanTotalAmount.format(baseCurrency)}",
style = UI.typo.nB1.style(
color = contrastColor,
fontWeight = FontWeight.ExtraBold
Expand Down Expand Up @@ -707,9 +719,25 @@ private fun LoanRecordItem(
if (loanRecord.note.isNullOrEmpty()) {
Spacer(Modifier.height(16.dp))
}
val transactionType = when (loan.type) {
LoanType.LEND -> {
if (loanRecord.loanRecordType == LoanRecordType.INCREASE) {
TransactionType.EXPENSE
} else {
TransactionType.INCOME
}
}

LoanType.BORROW -> {
if (loanRecord.loanRecordType == LoanRecordType.INCREASE) {
TransactionType.INCOME
} else {
TransactionType.EXPENSE
}
}
}
TypeAmountCurrency(
transactionType = if (loan.type == LoanType.LEND) TransactionType.INCOME else TransactionType.EXPENSE,
transactionType = transactionType,
dueDate = null,
currency = baseCurrency,
amount = loanRecord.amount
Expand All @@ -730,6 +758,61 @@ private fun LoanRecordItem(
}
}

@Composable
private fun InitialRecordItem(
loan: Loan,
amount: Double,
baseCurrency: String,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
.clip(UI.shapes.r4)
.background(UI.colors.medium, UI.shapes.r4)
.testTag("loan_record_item")
) {
IvyButton(
modifier = Modifier.padding(16.dp),
backgroundGradient = Gradient.solid(UI.colors.pure),
text = stringResource(id = R.string.initial_loan_record),
iconTint = UI.colors.pureInverse,
iconStart = getCustomIconIdS(
iconName = loan.icon,
defaultIcon = R.drawable.ic_custom_loan_s
),
textStyle = UI.typo.c.style(
color = UI.colors.pureInverse,
fontWeight = FontWeight.ExtraBold
),
padding = 8.dp,
) {}

loan.dateTime?.formatNicelyWithTime(
noWeekDay = false
)?.let { nicelyFormattedDate ->
Text(
modifier = Modifier.padding(horizontal = 24.dp),
text = nicelyFormattedDate.uppercase(),
style = UI.typo.nC.style(
color = Gray,
fontWeight = FontWeight.Bold
)
)
}

Spacer(modifier = Modifier.height(16.dp))

TypeAmountCurrency(
transactionType = if (loan.type == LoanType.LEND) TransactionType.EXPENSE else TransactionType.INCOME,
dueDate = null,
currency = baseCurrency,
amount = amount
)
Spacer(Modifier.height(16.dp))
}
}

@Composable
private fun NoLoanRecordsEmptyState() {
Column(
Expand Down Expand Up @@ -783,6 +866,7 @@ private fun Preview_Empty() {
),
displayLoanRecords = persistentListOf(),
amountPaid = 3821.00,
loanTotalAmount = 4023.54,
loanAmountPaid = 100.0,
accounts = persistentListOf(),
selectedLoanAccount = null,
Expand Down Expand Up @@ -816,25 +900,29 @@ private fun Preview_Records() {
amount = 123.45,
dateTime = timeNowUTC().minusDays(1),
note = "Cash",
loanId = UUID.randomUUID()
loanId = UUID.randomUUID(),
loanRecordType = LoanRecordType.INCREASE
)
),
DisplayLoanRecord(
LoanRecord(
amount = 0.50,
dateTime = timeNowUTC().minusYears(1),
loanId = UUID.randomUUID()
loanId = UUID.randomUUID(),
loanRecordType = LoanRecordType.DECREASE
)
),
DisplayLoanRecord(
LoanRecord(
amount = 1000.00,
dateTime = timeNowUTC().minusMonths(1),
note = "Revolut",
loanId = UUID.randomUUID()
loanId = UUID.randomUUID(),
loanRecordType = LoanRecordType.INCREASE
)
),
),
loanTotalAmount = 4023.54,
amountPaid = 3821.00,
loanAmountPaid = 100.0,
accounts = persistentListOf(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ data class LoanDetailsScreenState(
val baseCurrency: String,
val loan: Loan?,
val displayLoanRecords: ImmutableList<DisplayLoanRecord>,
val loanTotalAmount: Double,
val amountPaid: Double,
val loanAmountPaid: Double,
val accounts: ImmutableList<Account>,
Expand Down
Loading