Refactor transfer amount calculation to handle account changes
- Refactor `setTransactionSuitableDestinationAmount` in transactions store to handle account ID changes and avoid logic duplication. - Recalculate transfer-in amount when changing accounts, while preserving manual edits by verifying previous exchange rate relationships. - Clean up redundant calculation logic in `TransactionEditPageBase.ts`.
This commit is contained in:
+27
-13
@@ -556,34 +556,48 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
clearUserTransactionDraft();
|
||||
}
|
||||
|
||||
function setTransactionSuitableDestinationAmount(transaction: Transaction, oldValue: number, newValue: number): void {
|
||||
function setTransactionSuitableDestinationAmount(transaction: Transaction, oldSourceAmount: number, newSourceAmount: number, oldSourceAccountId?: string, oldDestinationAccountId?: string): void {
|
||||
if (transaction.type === TransactionType.Expense || transaction.type === TransactionType.Income) {
|
||||
transaction.destinationAmount = newValue;
|
||||
transaction.destinationAmount = newSourceAmount;
|
||||
} else if (transaction.type === TransactionType.Transfer) {
|
||||
const sourceAccount = accountsStore.allAccountsMap[transaction.sourceAccountId];
|
||||
const destinationAccount = accountsStore.allAccountsMap[transaction.destinationAccountId];
|
||||
|
||||
if (sourceAccount && destinationAccount && sourceAccount.currency !== destinationAccount.currency) {
|
||||
const decimalNumberCount = getCurrencyFraction(destinationAccount.currency);
|
||||
const exchangedOldValue = exchangeRatesStore.getExchangedAmount(oldValue, sourceAccount.currency, destinationAccount.currency);
|
||||
const exchangedNewValue = exchangeRatesStore.getExchangedAmount(newValue, sourceAccount.currency, destinationAccount.currency);
|
||||
if (!sourceAccount || !destinationAccount) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldSourceAccount = oldSourceAccountId ? accountsStore.allAccountsMap[oldSourceAccountId] : sourceAccount;
|
||||
const oldDestinationAccount = oldDestinationAccountId ? accountsStore.allAccountsMap[oldDestinationAccountId] : destinationAccount;
|
||||
|
||||
let oldValueToCompare = oldSourceAmount;
|
||||
let newValueToSet = newSourceAmount;
|
||||
|
||||
if (oldSourceAccount && oldDestinationAccount && oldSourceAccount.currency !== oldDestinationAccount.currency) {
|
||||
const decimalNumberCount = getCurrencyFraction(oldDestinationAccount.currency);
|
||||
const exchangedOldValue = exchangeRatesStore.getExchangedAmount(oldSourceAmount, oldSourceAccount.currency, oldDestinationAccount.currency);
|
||||
|
||||
if (isNumber(decimalNumberCount) && isNumber(exchangedOldValue)) {
|
||||
oldValue = Math.trunc(exchangedOldValue);
|
||||
oldValue = getAmountWithDecimalNumberCount(oldValue, decimalNumberCount);
|
||||
oldValueToCompare = Math.trunc(exchangedOldValue);
|
||||
oldValueToCompare = getAmountWithDecimalNumberCount(oldValueToCompare, decimalNumberCount);
|
||||
}
|
||||
}
|
||||
|
||||
if (sourceAccount.currency !== destinationAccount.currency) {
|
||||
const decimalNumberCount = getCurrencyFraction(destinationAccount.currency);
|
||||
const exchangedNewValue = exchangeRatesStore.getExchangedAmount(newSourceAmount, sourceAccount.currency, destinationAccount.currency);
|
||||
|
||||
if (isNumber(decimalNumberCount) && isNumber(exchangedNewValue)) {
|
||||
newValue = Math.trunc(exchangedNewValue);
|
||||
newValue = getAmountWithDecimalNumberCount(newValue, decimalNumberCount);
|
||||
newValueToSet = Math.trunc(exchangedNewValue);
|
||||
newValueToSet = getAmountWithDecimalNumberCount(newValueToSet, decimalNumberCount);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!sourceAccount || !destinationAccount || transaction.destinationAmount === oldValue || transaction.destinationAmount === 0) &&
|
||||
(TRANSACTION_MIN_AMOUNT <= newValue && newValue <= TRANSACTION_MAX_AMOUNT)) {
|
||||
transaction.destinationAmount = newValue;
|
||||
if ((transaction.destinationAmount === oldValueToCompare || transaction.destinationAmount === 0) &&
|
||||
(TRANSACTION_MIN_AMOUNT <= newValueToSet && newValueToSet <= TRANSACTION_MAX_AMOUNT)) {
|
||||
transaction.destinationAmount = newValueToSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import type { LocalizedTimezoneInfo } from '@/core/timezone.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
import { TemplateType } from '@/core/template.ts';
|
||||
import { DISPLAY_HIDDEN_AMOUNT } from '@/consts/numeral.ts';
|
||||
import { TRANSACTION_MAX_PICTURE_COUNT, TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
||||
import { TRANSACTION_MAX_PICTURE_COUNT } from '@/consts/transaction.ts';
|
||||
|
||||
import { Account, type CategorizedAccountWithDisplayBalance } from '@/models/account.ts';
|
||||
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
||||
@@ -26,19 +26,13 @@ import { Transaction } from '@/models/transaction.ts';
|
||||
import { TransactionTemplate } from '@/models/transaction_template.ts';
|
||||
|
||||
import {
|
||||
isArray,
|
||||
isNumber
|
||||
isArray
|
||||
} from '@/lib/common.ts';
|
||||
|
||||
import {
|
||||
getExchangedAmountByRate,
|
||||
getAmountWithDecimalNumberCount
|
||||
getExchangedAmountByRate
|
||||
} from '@/lib/numeral.ts';
|
||||
|
||||
import {
|
||||
getCurrencyFraction
|
||||
} from '@/lib/currency.ts';
|
||||
|
||||
import {
|
||||
getUtcOffsetByUtcOffsetMinutes,
|
||||
getTimezoneOffsetMinutes,
|
||||
@@ -437,11 +431,6 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
return;
|
||||
}
|
||||
|
||||
// Only recalculate if accounts actually changed
|
||||
if (newSourceAccountId === oldSourceAccountId && newDestinationAccountId === oldDestinationAccountId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only recalculate if accounts actually changed (skip initial watch call)
|
||||
if (oldSourceAccountId !== undefined && oldDestinationAccountId !== undefined) {
|
||||
if (newSourceAccountId === oldSourceAccountId && newDestinationAccountId === oldDestinationAccountId) {
|
||||
@@ -449,33 +438,7 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
}
|
||||
}
|
||||
|
||||
const sourceAccount = allAccountsMap.value[transaction.value.sourceAccountId];
|
||||
const destinationAccount = allAccountsMap.value[transaction.value.destinationAccountId];
|
||||
|
||||
if (!sourceAccount || !destinationAccount) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Recalculate destination amount based on source amount and exchange rate
|
||||
if (sourceAccount.currency !== destinationAccount.currency) {
|
||||
const exchangedAmount = exchangeRatesStore.getExchangedAmount(transaction.value.sourceAmount, sourceAccount.currency, destinationAccount.currency);
|
||||
|
||||
if (isNumber(exchangedAmount)) {
|
||||
const decimalNumberCount = getCurrencyFraction(destinationAccount.currency);
|
||||
let newDestinationAmount = Math.trunc(exchangedAmount);
|
||||
|
||||
if (isNumber(decimalNumberCount)) {
|
||||
newDestinationAmount = getAmountWithDecimalNumberCount(newDestinationAmount, decimalNumberCount);
|
||||
}
|
||||
|
||||
if (TRANSACTION_MIN_AMOUNT <= newDestinationAmount && newDestinationAmount <= TRANSACTION_MAX_AMOUNT) {
|
||||
transaction.value.destinationAmount = newDestinationAmount;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Same currency, just copy the source amount
|
||||
transaction.value.destinationAmount = transaction.value.sourceAmount;
|
||||
}
|
||||
transactionsStore.setTransactionSuitableDestinationAmount(transaction.value, transaction.value.sourceAmount, transaction.value.sourceAmount, oldSourceAccountId as string, oldDestinationAccountId as string);
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user