1331 lines
54 KiB
JavaScript
1331 lines
54 KiB
JavaScript
import { defineStore } from 'pinia';
|
|
|
|
import { useSettingsStore } from './setting.ts';
|
|
import { useUserStore } from './user.ts';
|
|
import { useAccountsStore } from './account.js';
|
|
import { useTransactionCategoriesStore } from './transactionCategory.js';
|
|
import { useOverviewStore } from './overview.js';
|
|
import { useStatisticsStore } from './statistics.js';
|
|
import { useExchangeRatesStore } from './exchangeRates.ts';
|
|
|
|
import { DateRange } from '@/core/datetime.ts';
|
|
import { CategoryType } from '@/core/category.ts';
|
|
import { TransactionType, TransactionTagFilterType } from '@/core/transaction.ts';
|
|
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
|
import {
|
|
getUserTransactionDraft,
|
|
updateUserTransactionDraft,
|
|
clearUserTransactionDraft
|
|
} from '@/lib/userstate.ts';
|
|
import services from '@/lib/services.ts';
|
|
import logger from '@/lib/logger.ts';
|
|
import {
|
|
isDefined,
|
|
isNumber,
|
|
isString
|
|
} from '@/lib/common.ts';
|
|
import {
|
|
getCurrentUnixTime,
|
|
getTimezoneOffsetMinutes,
|
|
getBrowserTimezoneOffsetMinutes,
|
|
getActualUnixTimeForStore,
|
|
parseDateFromUnixTime,
|
|
getShortDate,
|
|
getYear,
|
|
getMonth,
|
|
getYearAndMonth,
|
|
getDay,
|
|
getDayOfWeekName
|
|
} from '@/lib/datetime.ts';
|
|
import { getAmountWithDecimalNumberCount } from '@/lib/numeral.ts';
|
|
import { getCurrencyFraction } from '@/lib/currency.ts';
|
|
import { getFirstAvailableCategoryId } from '@/lib/category.js';
|
|
|
|
const emptyTransactionResult = {
|
|
items: [],
|
|
transactionsNextTimeId: 0
|
|
};
|
|
|
|
function loadTransactionList(state, settingsStore, exchangeRatesStore, { transactions, reload, autoExpand, defaultCurrency }) {
|
|
if (reload) {
|
|
state.transactions = [];
|
|
}
|
|
|
|
if (transactions.items && transactions.items.length) {
|
|
const currentUtcOffset = getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone);
|
|
let currentMonthListIndex = -1;
|
|
let currentMonthList = null;
|
|
|
|
for (let i = 0; i < transactions.items.length; i++) {
|
|
const item = transactions.items[i];
|
|
fillTransactionObject(state, item, currentUtcOffset);
|
|
|
|
const transactionTime = parseDateFromUnixTime(item.time, item.utcOffset, currentUtcOffset);
|
|
const transactionYear = getYear(transactionTime);
|
|
const transactionMonth = getMonth(transactionTime);
|
|
const transactionYearMonth = getYearAndMonth(transactionTime);
|
|
|
|
if (i === 0 && state.transactions.length > 0) {
|
|
const lastMonthList = state.transactions[state.transactions.length - 1];
|
|
|
|
if (lastMonthList.totalAmount.incompleteExpense || lastMonthList.totalAmount.incompleteIncome) {
|
|
// calculate the total amount of last month which has incomplete total amount before starting to process a new request
|
|
calculateMonthTotalAmount(exchangeRatesStore, lastMonthList, defaultCurrency, state.transactionsFilter.accountIds, false);
|
|
}
|
|
}
|
|
|
|
if (currentMonthList && currentMonthList.year === transactionYear && currentMonthList.month === transactionMonth) {
|
|
currentMonthList.items.push(Object.freeze(item));
|
|
|
|
if (i === transactions.items.length - 1) {
|
|
// calculate the total amount of current month when processing the last transaction item of this request
|
|
calculateMonthTotalAmount(exchangeRatesStore, currentMonthList, defaultCurrency, state.transactionsFilter.accountIds, true);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
for (let j = currentMonthListIndex + 1; j < state.transactions.length; j++) {
|
|
if (state.transactions[j].year === transactionYear && state.transactions[j].month === transactionMonth) {
|
|
currentMonthListIndex = j;
|
|
currentMonthList = state.transactions[j];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!currentMonthList || currentMonthList.year !== transactionYear || currentMonthList.month !== transactionMonth) {
|
|
// calculate the total amount of current month when processing the first transaction item of the next month
|
|
calculateMonthTotalAmount(exchangeRatesStore, currentMonthList, defaultCurrency, state.transactionsFilter.accountIds, false);
|
|
|
|
state.transactions.push({
|
|
year: transactionYear,
|
|
month: transactionMonth,
|
|
yearMonth: transactionYearMonth,
|
|
opened: autoExpand,
|
|
items: []
|
|
});
|
|
|
|
currentMonthListIndex = state.transactions.length - 1;
|
|
currentMonthList = state.transactions[state.transactions.length - 1];
|
|
}
|
|
|
|
currentMonthList.items.push(Object.freeze(item));
|
|
// init the total amount struct of current month when processing the first transaction item of current month
|
|
calculateMonthTotalAmount(exchangeRatesStore, currentMonthList, defaultCurrency, state.transactionsFilter.accountIds, true);
|
|
}
|
|
}
|
|
|
|
if (transactions.nextTimeSequenceId) {
|
|
state.transactionsNextTimeId = transactions.nextTimeSequenceId;
|
|
} else {
|
|
calculateMonthTotalAmount(exchangeRatesStore, state.transactions[state.transactions.length - 1], defaultCurrency, state.transactionsFilter.accountIds, false);
|
|
state.transactionsNextTimeId = -1;
|
|
}
|
|
}
|
|
|
|
function updateTransactionInTransactionList(state, settingsStore, exchangeRatesStore, { transaction, defaultCurrency }) {
|
|
const currentUtcOffset = getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone);
|
|
const transactionTime = parseDateFromUnixTime(transaction.time, transaction.utcOffset, currentUtcOffset);
|
|
const transactionYear = getYear(transactionTime);
|
|
const transactionMonth = getMonth(transactionTime);
|
|
|
|
for (let i = 0; i < state.transactions.length; i++) {
|
|
const transactionMonthList = state.transactions[i];
|
|
|
|
if (!transactionMonthList.items) {
|
|
continue;
|
|
}
|
|
|
|
for (let j = 0; j < transactionMonthList.items.length; j++) {
|
|
if (transactionMonthList.items[j].id === transaction.id) {
|
|
fillTransactionObject(state, transaction, currentUtcOffset);
|
|
|
|
if (transactionYear !== transactionMonthList.year ||
|
|
transactionMonth !== transactionMonthList.month ||
|
|
transaction.day !== transactionMonthList.items[j].day) {
|
|
state.transactionListStateInvalid = true;
|
|
return;
|
|
}
|
|
|
|
if ((state.transactionsFilter.categoryIds && !state.allFilterCategoryIds[transaction.categoryId]) ||
|
|
(state.transactionsFilter.accountIds && !state.allFilterAccountIds[transaction.sourceAccountId] && !state.allFilterAccountIds[transaction.destinationAccountId] &&
|
|
(!transaction.sourceAccount || !state.allFilterAccountIds[transaction.sourceAccount.parentId]) &&
|
|
(!transaction.destinationAccount || !state.allFilterAccountIds[transaction.destinationAccount.parentId])
|
|
)
|
|
) {
|
|
transactionMonthList.items.splice(j, 1);
|
|
} else {
|
|
transactionMonthList.items.splice(j, 1, transaction);
|
|
}
|
|
|
|
if (transactionMonthList.items.length < 1) {
|
|
state.transactions.splice(i, 1);
|
|
} else {
|
|
calculateMonthTotalAmount(exchangeRatesStore, transactionMonthList, defaultCurrency, state.transactionsFilter.accountIds, i >= state.transactions.length - 1 && state.transactionsNextTimeId > 0);
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function removeTransactionFromTransactionList(state, exchangeRatesStore, { transaction, defaultCurrency }) {
|
|
for (let i = 0; i < state.transactions.length; i++) {
|
|
const transactionMonthList = state.transactions[i];
|
|
|
|
if (!transactionMonthList.items ||
|
|
transactionMonthList.items[0].time < transaction.time ||
|
|
transactionMonthList.items[transactionMonthList.items.length - 1].time > transaction.time) {
|
|
continue;
|
|
}
|
|
|
|
for (let j = 0; j < transactionMonthList.items.length; j++) {
|
|
if (transactionMonthList.items[j].id === transaction.id) {
|
|
transactionMonthList.items.splice(j, 1);
|
|
}
|
|
}
|
|
|
|
if (transactionMonthList.items.length < 1) {
|
|
state.transactions.splice(i, 1);
|
|
} else {
|
|
calculateMonthTotalAmount(exchangeRatesStore, transactionMonthList, defaultCurrency, state.transactionsFilter.accountIds, i >= state.transactions.length - 1 && state.transactionsNextTimeId > 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
function calculateMonthTotalAmount(exchangeRatesStore, transactionMonthList, defaultCurrency, accountIds, incomplete) {
|
|
if (!transactionMonthList) {
|
|
return;
|
|
}
|
|
|
|
let totalExpense = 0;
|
|
let totalIncome = 0;
|
|
let hasUnCalculatedTotalExpense = false;
|
|
let hasUnCalculatedTotalIncome = false;
|
|
|
|
const allAccountIdsMap = {};
|
|
let totalAccountIdsCount = 0;
|
|
|
|
if (accountIds && accountIds !== '0') {
|
|
const allAccountIdsArray = accountIds.split(',');
|
|
|
|
for (let i = 0; i < allAccountIdsArray.length; i++) {
|
|
if (allAccountIdsArray[i]) {
|
|
allAccountIdsMap[allAccountIdsArray[i]] = true;
|
|
totalAccountIdsCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < transactionMonthList.items.length; i++) {
|
|
const transaction = transactionMonthList.items[i];
|
|
|
|
let amount = transaction.sourceAmount;
|
|
let account = transaction.sourceAccount;
|
|
|
|
if (totalAccountIdsCount > 0 && transaction.destinationAccount
|
|
&& (!allAccountIdsMap[transaction.sourceAccount.id] && !allAccountIdsMap[transaction.sourceAccount.parentId])
|
|
&& (allAccountIdsMap[transaction.destinationAccount.id] || allAccountIdsMap[transaction.destinationAccount.parentId])) {
|
|
amount = transaction.destinationAmount;
|
|
account = transaction.destinationAccount;
|
|
}
|
|
|
|
if (!account) {
|
|
continue;
|
|
}
|
|
|
|
if (account.currency !== defaultCurrency) {
|
|
const balance = exchangeRatesStore.getExchangedAmount(amount, account.currency, defaultCurrency);
|
|
|
|
if (!isNumber(balance)) {
|
|
if (transaction.type === TransactionType.Expense) {
|
|
hasUnCalculatedTotalExpense = true;
|
|
} else if (transaction.type === TransactionType.Income) {
|
|
hasUnCalculatedTotalIncome = true;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
amount = balance;
|
|
}
|
|
|
|
if (transaction.type === TransactionType.Expense) {
|
|
totalExpense += amount;
|
|
} else if (transaction.type === TransactionType.Income) {
|
|
totalIncome += amount;
|
|
} else if (transaction.type === TransactionType.Transfer && totalAccountIdsCount > 0) {
|
|
if (allAccountIdsMap[transaction.sourceAccountId] && allAccountIdsMap[transaction.destinationAccountId]) {
|
|
// Do Nothing
|
|
} else if (transaction.sourceAccount && transaction.destinationAccount && allAccountIdsMap[transaction.sourceAccount.parentId] && allAccountIdsMap[transaction.destinationAccount.parentId]) {
|
|
// Do Nothing
|
|
} else if (transaction.sourceAccount && allAccountIdsMap[transaction.sourceAccount.parentId] && allAccountIdsMap[transaction.destinationAccountId]) {
|
|
// Do Nothing
|
|
} else if (transaction.destinationAccount && allAccountIdsMap[transaction.sourceAccountId] && allAccountIdsMap[transaction.destinationAccount.parentId]) {
|
|
// Do Nothing
|
|
} else if (allAccountIdsMap[transaction.sourceAccountId] || (transaction.sourceAccount && allAccountIdsMap[transaction.sourceAccount.parentId])) {
|
|
totalExpense += amount;
|
|
} else if (allAccountIdsMap[transaction.destinationAccountId] || (transaction.destinationAccount && allAccountIdsMap[transaction.destinationAccount.parentId])) {
|
|
totalIncome += amount;
|
|
}
|
|
}
|
|
}
|
|
|
|
transactionMonthList.totalAmount = {
|
|
expense: Math.floor(totalExpense),
|
|
incompleteExpense: incomplete || hasUnCalculatedTotalExpense,
|
|
income: Math.floor(totalIncome),
|
|
incompleteIncome: incomplete || hasUnCalculatedTotalIncome
|
|
};
|
|
}
|
|
|
|
function fillTransactionObject(state, transaction, currentUtcOffset) {
|
|
if (!transaction) {
|
|
return;
|
|
}
|
|
|
|
const accountsStore = useAccountsStore();
|
|
const transactionCategoriesStore = useTransactionCategoriesStore();
|
|
const transactionTime = parseDateFromUnixTime(transaction.time, transaction.utcOffset, currentUtcOffset);
|
|
|
|
transaction.date = getShortDate(transactionTime);
|
|
transaction.day = getDay(transactionTime);
|
|
transaction.dayOfWeek = getDayOfWeekName(transactionTime);
|
|
|
|
if (transaction.sourceAccountId) {
|
|
transaction.sourceAccount = accountsStore.allAccountsMap[transaction.sourceAccountId];
|
|
}
|
|
|
|
if (transaction.destinationAccountId) {
|
|
transaction.destinationAccount = accountsStore.allAccountsMap[transaction.destinationAccountId];
|
|
}
|
|
|
|
if (transaction.categoryId) {
|
|
transaction.category = transactionCategoriesStore.allTransactionCategoriesMap[transaction.categoryId];
|
|
}
|
|
|
|
return transaction;
|
|
}
|
|
|
|
function buildBasicSubmitTransaction(transaction, dummyTime) {
|
|
const submitTransaction = {
|
|
type: transaction.type,
|
|
time: dummyTime ? getActualUnixTimeForStore(transaction.time, transaction.utcOffset, getBrowserTimezoneOffsetMinutes()) : transaction.time,
|
|
sourceAccountId: transaction.sourceAccountId,
|
|
sourceAmount: transaction.sourceAmount,
|
|
destinationAccountId: '0',
|
|
destinationAmount: 0,
|
|
hideAmount: transaction.hideAmount,
|
|
tagIds: transaction.tagIds,
|
|
comment: transaction.comment,
|
|
geoLocation: transaction.geoLocation,
|
|
utcOffset: transaction.utcOffset
|
|
};
|
|
|
|
if (transaction.type === TransactionType.Transfer) {
|
|
submitTransaction.destinationAccountId = transaction.destinationAccountId;
|
|
submitTransaction.destinationAmount = transaction.destinationAmount;
|
|
}
|
|
|
|
return submitTransaction;
|
|
}
|
|
|
|
function buildTransactionDraft(transaction) {
|
|
if (!transaction) {
|
|
return null;
|
|
}
|
|
|
|
let categoryId = '';
|
|
|
|
if (transaction.type === TransactionType.Expense) {
|
|
categoryId = transaction.expenseCategory;
|
|
} else if (transaction.type === TransactionType.Income) {
|
|
categoryId = transaction.incomeCategory;
|
|
} else if (transaction.type === TransactionType.Transfer) {
|
|
categoryId = transaction.transferCategory;
|
|
} else {
|
|
return null;
|
|
}
|
|
|
|
const transactionDraft = {
|
|
type: transaction.type,
|
|
categoryId: categoryId,
|
|
sourceAccountId: transaction.sourceAccountId,
|
|
sourceAmount: transaction.sourceAmount,
|
|
destinationAccountId: '0',
|
|
destinationAmount: 0,
|
|
hideAmount: transaction.hideAmount,
|
|
tagIds: transaction.tagIds,
|
|
pictures: transaction.pictures,
|
|
comment: transaction.comment,
|
|
};
|
|
|
|
if (transaction.type === TransactionType.Transfer) {
|
|
transactionDraft.destinationAccountId = transaction.destinationAccountId;
|
|
transactionDraft.destinationAmount = transaction.destinationAmount;
|
|
}
|
|
|
|
return transactionDraft;
|
|
}
|
|
|
|
export const useTransactionsStore = defineStore('transactions', {
|
|
state: () => ({
|
|
transactionDraft: getUserTransactionDraft(),
|
|
transactionsFilter: {
|
|
dateType: DateRange.All.type,
|
|
maxTime: 0,
|
|
minTime: 0,
|
|
type: 0,
|
|
categoryIds: '',
|
|
accountIds: '',
|
|
tagIds: '',
|
|
tagFilterType: TransactionTagFilterType.Default.type,
|
|
amountFilter: '',
|
|
keyword: ''
|
|
},
|
|
transactions: [],
|
|
transactionsNextTimeId: 0,
|
|
transactionListStateInvalid: true,
|
|
}),
|
|
getters: {
|
|
allFilterCategoryIds(state) {
|
|
if (!state.transactionsFilter.categoryIds) {
|
|
return {};
|
|
}
|
|
|
|
const allCategoryIds = state.transactionsFilter.categoryIds.split(',');
|
|
const ret = {};
|
|
|
|
for (let i = 0; i < allCategoryIds.length; i++) {
|
|
if (allCategoryIds[i]) {
|
|
ret[allCategoryIds[i]] = true;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
},
|
|
allFilterAccountIds(state) {
|
|
if (!state.transactionsFilter.accountIds) {
|
|
return {};
|
|
}
|
|
|
|
const allAccountIds = state.transactionsFilter.accountIds.split(',');
|
|
const ret = {};
|
|
|
|
for (let i = 0; i < allAccountIds.length; i++) {
|
|
if (allAccountIds[i]) {
|
|
ret[allAccountIds[i]] = true;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
},
|
|
allFilterTagIds(state) {
|
|
if (!state.transactionsFilter.tagIds) {
|
|
return {};
|
|
}
|
|
|
|
const allTagIds = state.transactionsFilter.tagIds.split(',');
|
|
const ret = {};
|
|
|
|
for (let i = 0; i < allTagIds.length; i++) {
|
|
if (allTagIds[i]) {
|
|
ret[allTagIds[i]] = true;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
},
|
|
allFilterCategoryIdsCount(state) {
|
|
if (!state.transactionsFilter.categoryIds) {
|
|
return 0;
|
|
}
|
|
|
|
const allCategoryIds = state.transactionsFilter.categoryIds.split(',');
|
|
let count = 0;
|
|
|
|
for (let i = 0; i < allCategoryIds.length; i++) {
|
|
if (allCategoryIds[i]) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
},
|
|
allFilterAccountIdsCount(state) {
|
|
if (!state.transactionsFilter.accountIds) {
|
|
return 0;
|
|
}
|
|
|
|
const allAccountIds = state.transactionsFilter.accountIds.split(',');
|
|
let count = 0;
|
|
|
|
for (let i = 0; i < allAccountIds.length; i++) {
|
|
if (allAccountIds[i]) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
},
|
|
allFilterTagIdsCount(state) {
|
|
if (!state.transactionsFilter.tagIds) {
|
|
return 0;
|
|
}
|
|
|
|
const allTagIds = state.transactionsFilter.tagIds.split(',');
|
|
let count = 0;
|
|
|
|
for (let i = 0; i < allTagIds.length; i++) {
|
|
if (allTagIds[i]) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
},
|
|
noTransaction(state) {
|
|
for (let i = 0; i < state.transactions.length; i++) {
|
|
const transactionMonthList = state.transactions[i];
|
|
|
|
for (let j = 0; j < transactionMonthList.items.length; j++) {
|
|
if (transactionMonthList.items[j]) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
},
|
|
hasMoreTransaction(state) {
|
|
return state.transactionsNextTimeId > 0;
|
|
}
|
|
},
|
|
actions: {
|
|
initTransactionDraft() {
|
|
const settingsStore = useSettingsStore();
|
|
|
|
if (settingsStore.appSettings.autoSaveTransactionDraft === 'enabled' || settingsStore.appSettings.autoSaveTransactionDraft === 'confirmation') {
|
|
this.transactionDraft = getUserTransactionDraft();
|
|
} else {
|
|
this.transactionDraft = null;
|
|
}
|
|
},
|
|
isTransactionDraftModified(transaction) {
|
|
if (!transaction) {
|
|
return false;
|
|
}
|
|
|
|
const userStore = useUserStore();
|
|
const transactionCategoriesStore = useTransactionCategoriesStore();
|
|
|
|
if (transaction.sourceAmount !== 0) {
|
|
return true;
|
|
}
|
|
|
|
if (transaction.type === TransactionType.Transfer && transaction.destinationAmount !== 0) {
|
|
return true;
|
|
}
|
|
|
|
if (transaction.sourceAccountId && transaction.sourceAccountId !== '0' && transaction.sourceAccountId !== userStore.currentUserDefaultAccountId) {
|
|
return true;
|
|
}
|
|
|
|
if (transaction.type === TransactionType.Transfer && transaction.destinationAccountId && transaction.destinationAccountId !== '0' && transaction.destinationAccountId !== userStore.currentUserDefaultAccountId) {
|
|
return true;
|
|
}
|
|
|
|
const allCategories = transactionCategoriesStore.allTransactionCategories;
|
|
|
|
if (allCategories) {
|
|
if (transaction.type === TransactionType.Expense) {
|
|
const defaultCategoryId = getFirstAvailableCategoryId(allCategories[CategoryType.Expense]);
|
|
|
|
if (transaction.expenseCategory && transaction.expenseCategory !== '0' && transaction.expenseCategory !== defaultCategoryId) {
|
|
return true;
|
|
}
|
|
} else if (transaction.type === TransactionType.Income) {
|
|
const defaultCategoryId = getFirstAvailableCategoryId(allCategories[CategoryType.Income]);
|
|
|
|
if (transaction.incomeCategory && transaction.incomeCategory !== '0' && transaction.incomeCategory !== defaultCategoryId) {
|
|
return true;
|
|
}
|
|
} else if (transaction.type === TransactionType.Transfer) {
|
|
const defaultCategoryId = getFirstAvailableCategoryId(allCategories[CategoryType.Transfer]);
|
|
|
|
if (transaction.transferCategory && transaction.transferCategory !== '0' && transaction.transferCategory !== defaultCategoryId) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (transaction.hideAmount) {
|
|
return true;
|
|
}
|
|
|
|
if (transaction.tagIds && transaction.tagIds.length > 0) {
|
|
return true;
|
|
}
|
|
|
|
if (transaction.pictures && transaction.pictures.length > 0) {
|
|
return true;
|
|
}
|
|
|
|
if (transaction.comment && transaction.comment.trim()) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
saveTransactionDraft(transaction) {
|
|
const settingsStore = useSettingsStore();
|
|
|
|
if (settingsStore.appSettings.autoSaveTransactionDraft !== 'enabled' && settingsStore.appSettings.autoSaveTransactionDraft !== 'confirmation') {
|
|
this.clearTransactionDraft();
|
|
return;
|
|
}
|
|
|
|
if (transaction) {
|
|
if (!this.isTransactionDraftModified(transaction)) {
|
|
this.clearTransactionDraft();
|
|
return;
|
|
}
|
|
|
|
this.transactionDraft = buildTransactionDraft(transaction);
|
|
}
|
|
|
|
updateUserTransactionDraft(this.transactionDraft);
|
|
},
|
|
clearTransactionDraft() {
|
|
this.transactionDraft = null;
|
|
clearUserTransactionDraft();
|
|
},
|
|
generateNewTransactionModel(type) {
|
|
const settingsStore = useSettingsStore();
|
|
const now = getCurrentUnixTime();
|
|
const currentTimezone = settingsStore.appSettings.timeZone;
|
|
|
|
let defaultType = TransactionType.Expense;
|
|
|
|
if (type === TransactionType.Income.toString()) {
|
|
defaultType = TransactionType.Income;
|
|
} else if (type === TransactionType.Transfer.toString()) {
|
|
defaultType = TransactionType.Transfer;
|
|
}
|
|
|
|
return {
|
|
type: defaultType,
|
|
time: now,
|
|
timeZone: currentTimezone,
|
|
utcOffset: getTimezoneOffsetMinutes(currentTimezone),
|
|
expenseCategory: '',
|
|
incomeCategory: '',
|
|
transferCategory: '',
|
|
sourceAccountId: '',
|
|
destinationAccountId: '',
|
|
sourceAmount: 0,
|
|
destinationAmount: 0,
|
|
hideAmount: false,
|
|
tagIds: [],
|
|
pictures: [],
|
|
comment: '',
|
|
geoLocation: null
|
|
};
|
|
},
|
|
setTransactionSuitableDestinationAmount(transaction, oldValue, newValue) {
|
|
const accountsStore = useAccountsStore();
|
|
const exchangeRatesStore = useExchangeRatesStore();
|
|
|
|
if (transaction.type === TransactionType.Expense || transaction.type === TransactionType.Income) {
|
|
transaction.destinationAmount = newValue;
|
|
} 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 (isNumber(exchangedOldValue)) {
|
|
oldValue = Math.floor(exchangedOldValue);
|
|
oldValue = getAmountWithDecimalNumberCount(oldValue, decimalNumberCount);
|
|
}
|
|
|
|
if (isNumber(exchangedNewValue)) {
|
|
newValue = Math.floor(exchangedNewValue);
|
|
newValue = getAmountWithDecimalNumberCount(newValue, decimalNumberCount);
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ((!sourceAccount || !destinationAccount || transaction.destinationAmount === oldValue || transaction.destinationAmount === 0) &&
|
|
(TRANSACTION_MIN_AMOUNT <= newValue && newValue <= TRANSACTION_MAX_AMOUNT)) {
|
|
transaction.destinationAmount = newValue;
|
|
}
|
|
}
|
|
},
|
|
updateTransactionListInvalidState(invalidState) {
|
|
this.transactionListStateInvalid = invalidState;
|
|
},
|
|
resetTransactions() {
|
|
this.transactionsFilter.dateType = DateRange.All.type;
|
|
this.transactionsFilter.maxTime = 0;
|
|
this.transactionsFilter.minTime = 0;
|
|
this.transactionsFilter.type = 0;
|
|
this.transactionsFilter.categoryIds = '';
|
|
this.transactionsFilter.accountIds = '';
|
|
this.transactionsFilter.tagIds = '';
|
|
this.transactionsFilter.tagFilterType = TransactionTagFilterType.Default.type;
|
|
this.transactionsFilter.amountFilter = '';
|
|
this.transactionsFilter.keyword = '';
|
|
this.transactions = [];
|
|
this.transactionsNextTimeId = 0;
|
|
this.transactionListStateInvalid = true;
|
|
},
|
|
clearTransactions() {
|
|
this.transactions = [];
|
|
this.transactionsNextTimeId = 0;
|
|
this.transactionListStateInvalid = true;
|
|
},
|
|
initTransactionListFilter(filter) {
|
|
if (filter && isNumber(filter.dateType)) {
|
|
this.transactionsFilter.dateType = filter.dateType;
|
|
} else {
|
|
this.transactionsFilter.dateType = DateRange.All.type;
|
|
}
|
|
|
|
if (filter && isNumber(filter.maxTime)) {
|
|
this.transactionsFilter.maxTime = filter.maxTime;
|
|
} else {
|
|
this.transactionsFilter.maxTime = 0;
|
|
}
|
|
|
|
if (filter && isNumber(filter.minTime)) {
|
|
this.transactionsFilter.minTime = filter.minTime;
|
|
} else {
|
|
this.transactionsFilter.minTime = 0;
|
|
}
|
|
|
|
if (filter && isNumber(filter.type)) {
|
|
this.transactionsFilter.type = filter.type;
|
|
} else {
|
|
this.transactionsFilter.type = 0;
|
|
}
|
|
|
|
if (filter && isString(filter.categoryIds)) {
|
|
this.transactionsFilter.categoryIds = filter.categoryIds;
|
|
} else {
|
|
this.transactionsFilter.categoryIds = '';
|
|
}
|
|
|
|
if (filter && isString(filter.accountIds)) {
|
|
this.transactionsFilter.accountIds = filter.accountIds;
|
|
} else {
|
|
this.transactionsFilter.accountIds = '';
|
|
}
|
|
|
|
if (filter && isString(filter.tagIds)) {
|
|
this.transactionsFilter.tagIds = filter.tagIds;
|
|
} else {
|
|
this.transactionsFilter.tagIds = '';
|
|
}
|
|
|
|
if (filter && isNumber(filter.tagFilterType)) {
|
|
this.transactionsFilter.tagFilterType = filter.tagFilterType;
|
|
} else {
|
|
this.transactionsFilter.tagFilterType = TransactionTagFilterType.Default.type;
|
|
}
|
|
|
|
if (filter && isString(filter.amountFilter)) {
|
|
this.transactionsFilter.amountFilter = filter.amountFilter;
|
|
} else {
|
|
this.transactionsFilter.amountFilter = '';
|
|
}
|
|
|
|
if (filter && isString(filter.keyword)) {
|
|
this.transactionsFilter.keyword = filter.keyword;
|
|
} else {
|
|
this.transactionsFilter.keyword = '';
|
|
}
|
|
},
|
|
updateTransactionListFilter(filter) {
|
|
const accountsStore = useAccountsStore();
|
|
let changed = false;
|
|
|
|
if (filter && isNumber(filter.dateType) && this.transactionsFilter.dateType !== filter.dateType) {
|
|
this.transactionsFilter.dateType = filter.dateType;
|
|
changed = true;
|
|
}
|
|
|
|
if (filter && isNumber(filter.maxTime) && this.transactionsFilter.maxTime !== filter.maxTime) {
|
|
this.transactionsFilter.maxTime = filter.maxTime;
|
|
changed = true;
|
|
}
|
|
|
|
if (filter && isNumber(filter.minTime) && this.transactionsFilter.minTime !== filter.minTime) {
|
|
this.transactionsFilter.minTime = filter.minTime;
|
|
changed = true;
|
|
}
|
|
|
|
if (filter && isNumber(filter.type) && this.transactionsFilter.type !== filter.type) {
|
|
this.transactionsFilter.type = filter.type;
|
|
changed = true;
|
|
}
|
|
|
|
if (filter && isString(filter.categoryIds) && this.transactionsFilter.categoryIds !== filter.categoryIds) {
|
|
this.transactionsFilter.categoryIds = filter.categoryIds;
|
|
changed = true;
|
|
}
|
|
|
|
if (filter && isString(filter.accountIds) && this.transactionsFilter.accountIds !== filter.accountIds) {
|
|
if (DateRange.isBillingCycle(this.transactionsFilter.dateType) &&
|
|
(!accountsStore.getAccountStatementDate(filter.accountIds) || accountsStore.getAccountStatementDate(filter.accountIds) !== accountsStore.getAccountStatementDate(this.transactionsFilter.accountIds))) {
|
|
this.transactionsFilter.dateType = DateRange.Custom.type;
|
|
}
|
|
|
|
this.transactionsFilter.accountIds = filter.accountIds;
|
|
|
|
changed = true;
|
|
}
|
|
|
|
if (filter && isString(filter.tagIds) && this.transactionsFilter.tagIds !== filter.tagIds) {
|
|
this.transactionsFilter.tagIds = filter.tagIds;
|
|
changed = true;
|
|
}
|
|
|
|
if (filter && isNumber(filter.tagFilterType) && this.transactionsFilter.tagFilterType !== filter.tagFilterType) {
|
|
this.transactionsFilter.tagFilterType = filter.tagFilterType;
|
|
changed = true;
|
|
}
|
|
|
|
if (filter && isString(filter.amountFilter) && this.transactionsFilter.amountFilter !== filter.amountFilter) {
|
|
this.transactionsFilter.amountFilter = filter.amountFilter;
|
|
changed = true;
|
|
}
|
|
|
|
if (filter && isString(filter.keyword) && this.transactionsFilter.keyword !== filter.keyword) {
|
|
this.transactionsFilter.keyword = filter.keyword;
|
|
changed = true;
|
|
}
|
|
|
|
return changed;
|
|
},
|
|
getTransactionListPageParams() {
|
|
const querys = [];
|
|
|
|
if (this.transactionsFilter.type) {
|
|
querys.push('type=' + this.transactionsFilter.type);
|
|
}
|
|
|
|
if (this.transactionsFilter.accountIds) {
|
|
querys.push('accountIds=' + this.transactionsFilter.accountIds);
|
|
}
|
|
|
|
if (this.transactionsFilter.categoryIds) {
|
|
querys.push('categoryIds=' + this.transactionsFilter.categoryIds);
|
|
}
|
|
|
|
if (this.transactionsFilter.tagIds) {
|
|
querys.push('tagIds=' + this.transactionsFilter.tagIds);
|
|
}
|
|
|
|
if (this.transactionsFilter.tagFilterType) {
|
|
querys.push('tagFilterType=' + this.transactionsFilter.tagFilterType);
|
|
}
|
|
|
|
querys.push('dateType=' + this.transactionsFilter.dateType);
|
|
|
|
if (DateRange.isBillingCycle(this.transactionsFilter.dateType) || this.transactionsFilter.dateType === DateRange.Custom.type) {
|
|
querys.push('maxTime=' + this.transactionsFilter.maxTime);
|
|
querys.push('minTime=' + this.transactionsFilter.minTime);
|
|
}
|
|
|
|
if (this.transactionsFilter.amountFilter) {
|
|
querys.push('amountFilter=' + encodeURIComponent(this.transactionsFilter.amountFilter));
|
|
}
|
|
|
|
if (this.transactionsFilter.keyword) {
|
|
querys.push('keyword=' + encodeURIComponent(this.transactionsFilter.keyword));
|
|
}
|
|
|
|
return querys.join('&');
|
|
},
|
|
loadTransactions({ reload, count, page, withCount, autoExpand, defaultCurrency }) {
|
|
const self = this;
|
|
const settingsStore = useSettingsStore();
|
|
const exchangeRatesStore = useExchangeRatesStore();
|
|
let actualMaxTime = self.transactionsNextTimeId;
|
|
|
|
if (reload && self.transactionsFilter.maxTime > 0) {
|
|
actualMaxTime = self.transactionsFilter.maxTime * 1000 + 999;
|
|
} else if (reload && self.transactionsFilter.maxTime <= 0) {
|
|
actualMaxTime = 0;
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
services.getTransactions({
|
|
maxTime: actualMaxTime,
|
|
minTime: self.transactionsFilter.minTime * 1000,
|
|
count: count || 50,
|
|
page: page || 1,
|
|
withCount: (!!withCount) || false,
|
|
type: self.transactionsFilter.type,
|
|
categoryIds: self.transactionsFilter.categoryIds,
|
|
accountIds: self.transactionsFilter.accountIds,
|
|
tagIds: self.transactionsFilter.tagIds,
|
|
tagFilterType: self.transactionsFilter.tagFilterType,
|
|
amountFilter: self.transactionsFilter.amountFilter,
|
|
keyword: self.transactionsFilter.keyword
|
|
}).then(response => {
|
|
const data = response.data;
|
|
|
|
if (!data || !data.success || !data.result) {
|
|
if (reload) {
|
|
loadTransactionList(self, settingsStore, exchangeRatesStore, {
|
|
transactions: emptyTransactionResult,
|
|
reload: reload,
|
|
autoExpand: autoExpand,
|
|
defaultCurrency: defaultCurrency
|
|
});
|
|
|
|
if (!self.transactionListStateInvalid) {
|
|
self.updateTransactionListInvalidState(true);
|
|
}
|
|
}
|
|
|
|
reject({ message: 'Unable to retrieve transaction list' });
|
|
return;
|
|
}
|
|
|
|
loadTransactionList(self, settingsStore, exchangeRatesStore, {
|
|
transactions: data.result,
|
|
reload: reload,
|
|
autoExpand: autoExpand,
|
|
defaultCurrency: defaultCurrency
|
|
});
|
|
|
|
if (reload) {
|
|
if (self.transactionListStateInvalid) {
|
|
self.updateTransactionListInvalidState(false);
|
|
}
|
|
}
|
|
|
|
resolve(data.result);
|
|
}).catch(error => {
|
|
logger.error('failed to load transaction list', error);
|
|
|
|
if (reload) {
|
|
loadTransactionList(self, settingsStore, exchangeRatesStore, {
|
|
transactions: emptyTransactionResult,
|
|
reload: reload,
|
|
autoExpand: autoExpand,
|
|
defaultCurrency: defaultCurrency
|
|
});
|
|
|
|
if (!self.transactionListStateInvalid) {
|
|
self.updateTransactionListInvalidState(true);
|
|
}
|
|
}
|
|
|
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
reject({ error: error.response.data });
|
|
} else if (!error.processed) {
|
|
reject({ message: 'Unable to retrieve transaction list' });
|
|
} else {
|
|
reject(error);
|
|
}
|
|
});
|
|
});
|
|
},
|
|
loadMonthlyAllTransactions({ year, month, autoExpand, defaultCurrency }) {
|
|
const self = this;
|
|
const settingsStore = useSettingsStore();
|
|
const exchangeRatesStore = useExchangeRatesStore();
|
|
|
|
return new Promise((resolve, reject) => {
|
|
services.getAllTransactionsByMonth({
|
|
year: year,
|
|
month: month,
|
|
type: self.transactionsFilter.type,
|
|
categoryIds: self.transactionsFilter.categoryIds,
|
|
accountIds: self.transactionsFilter.accountIds,
|
|
tagIds: self.transactionsFilter.tagIds,
|
|
tagFilterType: self.transactionsFilter.tagFilterType,
|
|
amountFilter: self.transactionsFilter.amountFilter,
|
|
keyword: self.transactionsFilter.keyword
|
|
}).then(response => {
|
|
const data = response.data;
|
|
|
|
if (!data || !data.success || !data.result) {
|
|
loadTransactionList(self, settingsStore, exchangeRatesStore, {
|
|
transactions: emptyTransactionResult,
|
|
reload: true,
|
|
autoExpand: autoExpand,
|
|
defaultCurrency: defaultCurrency
|
|
});
|
|
|
|
if (!self.transactionListStateInvalid) {
|
|
self.updateTransactionListInvalidState(true);
|
|
}
|
|
|
|
reject({ message: 'Unable to retrieve transaction list' });
|
|
return;
|
|
}
|
|
|
|
loadTransactionList(self, settingsStore, exchangeRatesStore, {
|
|
transactions: data.result,
|
|
reload: true,
|
|
autoExpand: autoExpand,
|
|
defaultCurrency: defaultCurrency
|
|
});
|
|
|
|
if (self.transactionListStateInvalid) {
|
|
self.updateTransactionListInvalidState(false);
|
|
}
|
|
|
|
resolve(data.result);
|
|
}).catch(error => {
|
|
logger.error('failed to load monthly all transaction list', error);
|
|
|
|
loadTransactionList(self, settingsStore, exchangeRatesStore, {
|
|
transactions: emptyTransactionResult,
|
|
reload: true,
|
|
autoExpand: autoExpand,
|
|
defaultCurrency: defaultCurrency
|
|
});
|
|
|
|
if (!self.transactionListStateInvalid) {
|
|
self.updateTransactionListInvalidState(true);
|
|
}
|
|
|
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
reject({ error: error.response.data });
|
|
} else if (!error.processed) {
|
|
reject({ message: 'Unable to retrieve transaction list' });
|
|
} else {
|
|
reject(error);
|
|
}
|
|
});
|
|
});
|
|
},
|
|
getTransaction({ transactionId, withPictures }) {
|
|
return new Promise((resolve, reject) => {
|
|
if (!isDefined(withPictures)) {
|
|
withPictures = true;
|
|
}
|
|
|
|
services.getTransaction({
|
|
id: transactionId,
|
|
withPictures: withPictures
|
|
}).then(response => {
|
|
const data = response.data;
|
|
|
|
if (!data || !data.success || !data.result) {
|
|
reject({ message: 'Unable to retrieve transaction' });
|
|
return;
|
|
}
|
|
|
|
resolve(data.result);
|
|
}).catch(error => {
|
|
logger.error('failed to load transaction info', error);
|
|
|
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
reject({ error: error.response.data });
|
|
} else if (!error.processed) {
|
|
reject({ message: 'Unable to retrieve transaction' });
|
|
} else {
|
|
reject(error);
|
|
}
|
|
});
|
|
});
|
|
},
|
|
saveTransaction({ transaction, defaultCurrency, isEdit, clientSessionId }) {
|
|
const self = this;
|
|
const settingsStore = useSettingsStore();
|
|
const exchangeRatesStore = useExchangeRatesStore();
|
|
|
|
const submitTransaction = buildBasicSubmitTransaction(transaction, true);
|
|
|
|
if (transaction.type === TransactionType.Expense) {
|
|
submitTransaction.categoryId = transaction.expenseCategory;
|
|
} else if (transaction.type === TransactionType.Income) {
|
|
submitTransaction.categoryId = transaction.incomeCategory;
|
|
} else if (transaction.type === TransactionType.Transfer) {
|
|
submitTransaction.categoryId = transaction.transferCategory;
|
|
} else {
|
|
return Promise.reject('An error occurred');
|
|
}
|
|
|
|
if (clientSessionId) {
|
|
submitTransaction.clientSessionId = clientSessionId;
|
|
}
|
|
|
|
if (transaction.pictures && transaction.pictures.length > 0) {
|
|
const pictureIds = [];
|
|
|
|
for (let i = 0; i < transaction.pictures.length; i++) {
|
|
if (transaction.pictures[i].pictureId) {
|
|
pictureIds.push(transaction.pictures[i].pictureId);
|
|
}
|
|
}
|
|
|
|
submitTransaction.pictureIds = pictureIds;
|
|
}
|
|
|
|
if (isEdit) {
|
|
submitTransaction.id = transaction.id;
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
let promise = null;
|
|
|
|
if (!submitTransaction.id) {
|
|
promise = services.addTransaction(submitTransaction);
|
|
} else {
|
|
promise = services.modifyTransaction(submitTransaction);
|
|
}
|
|
|
|
promise.then(response => {
|
|
const data = response.data;
|
|
|
|
if (!data || !data.success || !data.result) {
|
|
if (!submitTransaction.id) {
|
|
reject({ message: 'Unable to add transaction' });
|
|
} else {
|
|
reject({ message: 'Unable to save transaction' });
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!submitTransaction.id) {
|
|
if (!self.transactionListStateInvalid) {
|
|
self.updateTransactionListInvalidState(true);
|
|
}
|
|
} else {
|
|
updateTransactionInTransactionList(self, settingsStore, exchangeRatesStore, {
|
|
transaction: data.result,
|
|
defaultCurrency: defaultCurrency
|
|
});
|
|
}
|
|
|
|
const accountsStore = useAccountsStore();
|
|
if (!accountsStore.accountListStateInvalid) {
|
|
accountsStore.updateAccountListInvalidState(true);
|
|
}
|
|
|
|
const overviewStore = useOverviewStore();
|
|
if (!overviewStore.transactionOverviewStateInvalid) {
|
|
overviewStore.updateTransactionOverviewInvalidState(true);
|
|
}
|
|
|
|
const statisticsStore = useStatisticsStore();
|
|
if (!statisticsStore.transactionStatisticsStateInvalid) {
|
|
statisticsStore.updateTransactionStatisticsInvalidState(true);
|
|
}
|
|
|
|
resolve(data.result);
|
|
}).catch(error => {
|
|
logger.error('failed to save transaction', error);
|
|
|
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
reject({ error: error.response.data });
|
|
} else if (!error.processed) {
|
|
if (!submitTransaction.id) {
|
|
reject({ message: 'Unable to add transaction' });
|
|
} else {
|
|
reject({ message: 'Unable to save transaction' });
|
|
}
|
|
} else {
|
|
reject(error);
|
|
}
|
|
});
|
|
});
|
|
},
|
|
deleteTransaction({ transaction, defaultCurrency, beforeResolve }) {
|
|
const self = this;
|
|
const exchangeRatesStore = useExchangeRatesStore();
|
|
|
|
return new Promise((resolve, reject) => {
|
|
services.deleteTransaction({
|
|
id: transaction.id
|
|
}).then(response => {
|
|
const data = response.data;
|
|
|
|
if (!data || !data.success || !data.result) {
|
|
reject({ message: 'Unable to delete this transaction' });
|
|
return;
|
|
}
|
|
|
|
if (beforeResolve) {
|
|
beforeResolve(() => {
|
|
removeTransactionFromTransactionList(self, exchangeRatesStore, {
|
|
transaction: transaction,
|
|
defaultCurrency: defaultCurrency
|
|
});
|
|
});
|
|
} else {
|
|
removeTransactionFromTransactionList(self, exchangeRatesStore, {
|
|
transaction: transaction,
|
|
defaultCurrency: defaultCurrency
|
|
});
|
|
}
|
|
|
|
const accountsStore = useAccountsStore();
|
|
if (!accountsStore.accountListStateInvalid) {
|
|
accountsStore.updateAccountListInvalidState(true);
|
|
}
|
|
|
|
const overviewStore = useOverviewStore();
|
|
if (!overviewStore.transactionOverviewStateInvalid) {
|
|
overviewStore.updateTransactionOverviewInvalidState(true);
|
|
}
|
|
|
|
const statisticsStore = useStatisticsStore();
|
|
if (!statisticsStore.transactionStatisticsStateInvalid) {
|
|
statisticsStore.updateTransactionStatisticsInvalidState(true);
|
|
}
|
|
|
|
resolve(data.result);
|
|
}).catch(error => {
|
|
logger.error('failed to delete transaction', error);
|
|
|
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
reject({ error: error.response.data });
|
|
} else if (!error.processed) {
|
|
reject({ message: 'Unable to delete this transaction' });
|
|
} else {
|
|
reject(error);
|
|
}
|
|
});
|
|
});
|
|
},
|
|
parseImportTransaction({ fileType, importFile }) {
|
|
return new Promise((resolve, reject) => {
|
|
services.parseImportTransaction({ fileType, importFile }).then(response => {
|
|
const data = response.data;
|
|
|
|
if (!data || !data.success || !data.result) {
|
|
reject({ message: 'Unable to parse import file' });
|
|
return;
|
|
}
|
|
|
|
resolve(data.result);
|
|
}).catch(error => {
|
|
logger.error('Unable to parse import file', error);
|
|
|
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
reject({ error: error.response.data });
|
|
} else if (!error.processed) {
|
|
reject({ message: 'Unable to parse import file' });
|
|
} else {
|
|
reject(error);
|
|
}
|
|
});
|
|
});
|
|
},
|
|
importTransactions({ transactions, clientSessionId }) {
|
|
const submitTransactions = [];
|
|
|
|
if (transactions) {
|
|
for (let i = 0; i < transactions.length; i++) {
|
|
const transaction = transactions[i];
|
|
const submitTransaction = buildBasicSubmitTransaction(transaction, false);
|
|
|
|
submitTransaction.categoryId = transaction.categoryId;
|
|
submitTransactions.push(submitTransaction);
|
|
}
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
services.importTransactions({
|
|
transactions: submitTransactions,
|
|
clientSessionId: clientSessionId
|
|
}).then(response => {
|
|
const data = response.data;
|
|
|
|
if (!data || !data.success || !data.result) {
|
|
reject({ message: 'Unable to import transactions' });
|
|
return;
|
|
}
|
|
|
|
resolve(data.result);
|
|
}).catch(error => {
|
|
logger.error('Unable to import transactions', error);
|
|
|
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
reject({ error: error.response.data });
|
|
} else if (!error.processed) {
|
|
reject({ message: 'Unable to import transactions' });
|
|
} else {
|
|
reject(error);
|
|
}
|
|
});
|
|
});
|
|
},
|
|
uploadTransactionPicture({ pictureFile, clientSessionId }) {
|
|
return new Promise((resolve, reject) => {
|
|
services.uploadTransactionPicture({ pictureFile, clientSessionId }).then(response => {
|
|
const data = response.data;
|
|
|
|
if (!data || !data.success || !data.result) {
|
|
reject({ message: 'Unable to upload transaction picture' });
|
|
return;
|
|
}
|
|
|
|
resolve(data.result);
|
|
}).catch(error => {
|
|
logger.error('Unable to upload transaction picture', error);
|
|
|
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
reject({ error: error.response.data });
|
|
} else if (!error.processed) {
|
|
reject({ message: 'Unable to upload transaction picture' });
|
|
} else {
|
|
reject(error);
|
|
}
|
|
});
|
|
});
|
|
},
|
|
removeUnusedTransactionPicture({ pictureInfo }) {
|
|
return new Promise((resolve, reject) => {
|
|
services.removeUnusedTransactionPicture({
|
|
id: pictureInfo.pictureId
|
|
}).then(response => {
|
|
const data = response.data;
|
|
|
|
if (!data || !data.success || !data.result) {
|
|
reject({ message: 'Unable to remove transaction picture' });
|
|
return;
|
|
}
|
|
|
|
resolve(data.result);
|
|
}).catch(error => {
|
|
logger.error('failed to remove transaction picture', error);
|
|
|
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
reject({ error: error.response.data });
|
|
} else if (!error.processed) {
|
|
reject({ message: 'Unable to remove transaction picture' });
|
|
} else {
|
|
reject(error);
|
|
}
|
|
});
|
|
});
|
|
},
|
|
getTransactionPictureUrl(pictureInfo, disableBrowserCache) {
|
|
if (!pictureInfo || !pictureInfo.originalUrl) {
|
|
return null;
|
|
}
|
|
|
|
return services.getTransactionPictureUrlWithToken(pictureInfo.originalUrl, disableBrowserCache);
|
|
},
|
|
collapseMonthInTransactionList({ month, collapse }) {
|
|
if (month) {
|
|
month.opened = !collapse;
|
|
}
|
|
}
|
|
}
|
|
});
|