mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-16 16:07:33 +08:00
add transaction template
This commit is contained in:
@@ -5,6 +5,7 @@ import { useUserStore } from './user.js';
|
||||
import { useAccountsStore } from './account.js';
|
||||
import { useTransactionCategoriesStore } from './transactionCategory.js';
|
||||
import { useTransactionTagsStore } from './transactionTag.js';
|
||||
import { useTransactionTemplatesStore } from './transactionTemplate.js';
|
||||
import { useTransactionsStore } from './transaction.js';
|
||||
import { useOverviewStore } from './overview.js';
|
||||
import { useStatisticsStore } from './statistics.js';
|
||||
@@ -38,6 +39,9 @@ export const useRootStore = defineStore('root', {
|
||||
const transactionCategoriesStore = useTransactionCategoriesStore();
|
||||
transactionCategoriesStore.resetTransactionCategories();
|
||||
|
||||
const transactionTemplatesStore = useTransactionTemplatesStore();
|
||||
transactionTemplatesStore.resetTransactionTemplates();
|
||||
|
||||
const accountsStore = useAccountsStore();
|
||||
accountsStore.resetAccounts();
|
||||
|
||||
|
||||
@@ -0,0 +1,477 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
import transactionConstants from '@/consts/transaction.js';
|
||||
import { isDefined, isObject, isArray, isEquals } from '@/lib/common.js';
|
||||
import services from '@/lib/services.js';
|
||||
import logger from '@/lib/logger.js';
|
||||
|
||||
function loadTransactionTemplateList(state, templateType, templates) {
|
||||
state.allTransactionTemplates[templateType] = templates;
|
||||
state.allTransactionTemplatesMap[templateType] = {};
|
||||
|
||||
for (let i = 0; i < templates.length; i++) {
|
||||
const template = templates[i];
|
||||
state.allTransactionTemplatesMap[templateType][template.id] = template;
|
||||
}
|
||||
}
|
||||
|
||||
function addTemplateToTransactionTemplateList(state, templateType, template) {
|
||||
if (isArray(state.allTransactionTemplates[templateType])) {
|
||||
state.allTransactionTemplates[templateType].push(template);
|
||||
}
|
||||
|
||||
if (isObject(state.allTransactionTemplatesMap[templateType])) {
|
||||
state.allTransactionTemplatesMap[templateType][template.id] = template;
|
||||
}
|
||||
}
|
||||
|
||||
function updateTemplateInTransactionTemplateList(state, templateType, template) {
|
||||
if (isArray(state.allTransactionTemplates[templateType])) {
|
||||
for (let i = 0; i < state.allTransactionTemplates[templateType].length; i++) {
|
||||
if (state.allTransactionTemplates[templateType][i].id === template.id) {
|
||||
state.allTransactionTemplates[templateType].splice(i, 1, template);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isObject(state.allTransactionTemplatesMap[templateType])) {
|
||||
state.allTransactionTemplatesMap[templateType][template.id] = template;
|
||||
}
|
||||
}
|
||||
|
||||
function updateTemplateDisplayOrderInTransactionTemplateList(state, templateType, { from, to }) {
|
||||
if (isArray(state.allTransactionTemplates[templateType])) {
|
||||
state.allTransactionTemplates[templateType].splice(to, 0, state.allTransactionTemplates[templateType].splice(from, 1)[0]);
|
||||
}
|
||||
}
|
||||
|
||||
function updateTemplateVisibilityInTransactionTemplateList(state, templateType, { template, hidden }) {
|
||||
if (isObject(state.allTransactionTemplatesMap[templateType])) {
|
||||
if (state.allTransactionTemplatesMap[templateType][template.id]) {
|
||||
state.allTransactionTemplatesMap[templateType][template.id].hidden = hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeTemplateFromTransactionTemplateList(state, templateType, template) {
|
||||
if (isArray(state.allTransactionTemplates[templateType])) {
|
||||
for (let i = 0; i < state.allTransactionTemplates[templateType].length; i++) {
|
||||
if (state.allTransactionTemplates[templateType][i].id === template.id) {
|
||||
state.allTransactionTemplates[templateType].splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isObject(state.allTransactionTemplatesMap[templateType])) {
|
||||
if (state.allTransactionTemplatesMap[templateType][template.id]) {
|
||||
delete state.allTransactionTemplatesMap[templateType][template.id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const useTransactionTemplatesStore = defineStore('transactionTemplates', {
|
||||
state: () => ({
|
||||
allTransactionTemplates: {},
|
||||
allTransactionTemplatesMap: {},
|
||||
transactionTemplateListStatesInvalid: {},
|
||||
}),
|
||||
getters: {
|
||||
allVisibleTemplates(state) {
|
||||
const allVisibleTemplates = {};
|
||||
|
||||
for (const templateType in state.allTransactionTemplates) {
|
||||
if (!Object.prototype.hasOwnProperty.call(state.allTransactionTemplates, templateType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const visibleTemplates = [];
|
||||
|
||||
for (let i = 0; i < state.allTransactionTemplates[templateType].length; i++) {
|
||||
const template = state.allTransactionTemplates[templateType][i];
|
||||
|
||||
if (!template.hidden) {
|
||||
visibleTemplates.push(template);
|
||||
}
|
||||
}
|
||||
|
||||
allVisibleTemplates[templateType] = visibleTemplates;
|
||||
}
|
||||
|
||||
return allVisibleTemplates;
|
||||
},
|
||||
allAvailableTemplatesCount(state) {
|
||||
const allAvailableTemplateCounts = {};
|
||||
|
||||
for (const templateType in state.allTransactionTemplates) {
|
||||
if (!Object.prototype.hasOwnProperty.call(state.allTransactionTemplates, templateType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
allAvailableTemplateCounts[templateType] = state.allTransactionTemplates[templateType].length;
|
||||
}
|
||||
|
||||
return allAvailableTemplateCounts;
|
||||
},
|
||||
allVisibleTemplatesCount(state) {
|
||||
const allVisibleTemplateCounts = {};
|
||||
|
||||
for (const templateType in state.allVisibleTemplates) {
|
||||
if (!Object.prototype.hasOwnProperty.call(state.allVisibleTemplates, templateType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
allVisibleTemplateCounts[templateType] = state.allVisibleTemplates[templateType].length;
|
||||
}
|
||||
|
||||
return allVisibleTemplateCounts;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
generateNewTransactionTemplateModel(templateType) {
|
||||
return {
|
||||
id: '',
|
||||
templateType: templateType,
|
||||
name: ''
|
||||
};
|
||||
},
|
||||
updateTransactionTemplateListInvalidState(templateType, invalidState) {
|
||||
this.transactionTemplateListStatesInvalid[templateType] = invalidState;
|
||||
},
|
||||
resetTransactionTemplates() {
|
||||
this.allTransactionTemplates = {};
|
||||
this.allTransactionTemplatesMap = {};
|
||||
this.transactionTemplateListStatesInvalid = {};
|
||||
},
|
||||
loadAllTemplates({ templateType, force }) {
|
||||
const self = this;
|
||||
|
||||
if (!force && isDefined(self.transactionTemplateListStatesInvalid[templateType]) && !self.transactionTemplateListStatesInvalid[templateType]) {
|
||||
return new Promise((resolve) => {
|
||||
resolve(self.allTransactionTemplates[templateType] || []);
|
||||
});
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
services.getAllTransactionTemplates({ templateType }).then(response => {
|
||||
const data = response.data;
|
||||
|
||||
if (!data || !data.success || !data.result) {
|
||||
reject({ message: 'Unable to retrieve template list' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDefined(self.transactionTemplateListStatesInvalid[templateType]) || self.transactionTemplateListStatesInvalid[templateType]) {
|
||||
self.updateTransactionTemplateListInvalidState(templateType, false);
|
||||
}
|
||||
|
||||
if (force && data.result && isEquals(self.allTransactionTemplates[templateType], data.result)) {
|
||||
reject({ message: 'Template list is up to date' });
|
||||
return;
|
||||
}
|
||||
|
||||
loadTransactionTemplateList(self, templateType, data.result);
|
||||
|
||||
resolve(data.result);
|
||||
}).catch(error => {
|
||||
if (force) {
|
||||
logger.error('failed to force load template list', error);
|
||||
} else {
|
||||
logger.error('failed to load template list', 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 template list' });
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
getTemplate({ templateId }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
services.getTransactionTemplate({
|
||||
id: templateId
|
||||
}).then(response => {
|
||||
const data = response.data;
|
||||
|
||||
if (!data || !data.success || !data.result) {
|
||||
reject({ message: 'Unable to retrieve template' });
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(data.result);
|
||||
}).catch(error => {
|
||||
logger.error('failed to load template 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 template' });
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
saveTemplateName({ template }) {
|
||||
const self = this;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let promise = null;
|
||||
|
||||
if (!template.id) {
|
||||
promise = services.addTransactionTemplate(template);
|
||||
} else {
|
||||
promise = services.modifyTransactionNameTemplate(template);
|
||||
}
|
||||
|
||||
promise.then(response => {
|
||||
const data = response.data;
|
||||
|
||||
if (!data || !data.success || !data.result) {
|
||||
if (!template.id) {
|
||||
reject({ message: 'Unable to add template' });
|
||||
} else {
|
||||
reject({ message: 'Unable to save template' });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!template.id) {
|
||||
addTemplateToTransactionTemplateList(self, template.templateType, data.result);
|
||||
} else {
|
||||
updateTemplateInTransactionTemplateList(self, template.templateType, data.result);
|
||||
}
|
||||
|
||||
resolve(data.result);
|
||||
}).catch(error => {
|
||||
logger.error('failed to save template', error);
|
||||
|
||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||
reject({ error: error.response.data });
|
||||
} else if (!error.processed) {
|
||||
if (!template.id) {
|
||||
reject({ message: 'Unable to add template' });
|
||||
} else {
|
||||
reject({ message: 'Unable to save template' });
|
||||
}
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
modifyTemplateContent({ template }) {
|
||||
const self = this;
|
||||
|
||||
const submitTemplate = {
|
||||
id: template.id,
|
||||
type: template.type,
|
||||
sourceAccountId: template.sourceAccountId,
|
||||
sourceAmount: template.sourceAmount,
|
||||
destinationAccountId: '0',
|
||||
destinationAmount: 0,
|
||||
tagIds: template.tagIds,
|
||||
comment: template.comment
|
||||
};
|
||||
|
||||
if (template.type === transactionConstants.allTransactionTypes.Expense) {
|
||||
submitTemplate.categoryId = template.expenseCategory;
|
||||
} else if (template.type === transactionConstants.allTransactionTypes.Income) {
|
||||
submitTemplate.categoryId = template.incomeCategory;
|
||||
} else if (template.type === transactionConstants.allTransactionTypes.Transfer) {
|
||||
submitTemplate.categoryId = template.transferCategory;
|
||||
submitTemplate.destinationAccountId = template.destinationAccountId;
|
||||
submitTemplate.destinationAmount = template.destinationAmount;
|
||||
} else {
|
||||
return Promise.reject('An error occurred');
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
services.modifyTransactionTemplate(submitTemplate).then(response => {
|
||||
const data = response.data;
|
||||
|
||||
if (!data || !data.success || !data.result) {
|
||||
reject({ message: 'Unable to save template' });
|
||||
return;
|
||||
}
|
||||
|
||||
updateTemplateInTransactionTemplateList(self, template.templateType, data.result);
|
||||
|
||||
resolve(data.result);
|
||||
}).catch(error => {
|
||||
logger.error('failed to save template', error);
|
||||
|
||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||
reject({ error: error.response.data });
|
||||
} else if (!error.processed) {
|
||||
reject({ message: 'Unable to save template' });
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
changeTemplateDisplayOrder({ templateType, templateId, from, to }) {
|
||||
const self = this;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let template = null;
|
||||
|
||||
if (!isArray(self.allTransactionTemplates[templateType])) {
|
||||
reject({ message: 'Unable to move template' });
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < self.allTransactionTemplates[templateType].length; i++) {
|
||||
if (self.allTransactionTemplates[templateType][i].id === templateId) {
|
||||
template = self.allTransactionTemplates[templateType][i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!template || !self.allTransactionTemplates[templateType][to]) {
|
||||
reject({ message: 'Unable to move template' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDefined(self.transactionTemplateListStatesInvalid[templateType]) && !self.transactionTemplateListStatesInvalid[templateType]) {
|
||||
self.updateTransactionTemplateListInvalidState(templateType, true);
|
||||
}
|
||||
|
||||
updateTemplateDisplayOrderInTransactionTemplateList(self, templateType, {
|
||||
template: template,
|
||||
from: from,
|
||||
to: to
|
||||
});
|
||||
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
updateTemplateDisplayOrders({ templateType }) {
|
||||
const self = this;
|
||||
const newDisplayOrders = [];
|
||||
|
||||
if (isArray(self.allTransactionTemplates[templateType])) {
|
||||
for (let i = 0; i < self.allTransactionTemplates[templateType].length; i++) {
|
||||
newDisplayOrders.push({
|
||||
id: self.allTransactionTemplates[templateType][i].id,
|
||||
displayOrder: i + 1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
services.moveTransactionTemplate({
|
||||
newDisplayOrders: newDisplayOrders
|
||||
}).then(response => {
|
||||
const data = response.data;
|
||||
|
||||
if (!data || !data.success || !data.result) {
|
||||
reject({ message: 'Unable to move template' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDefined(self.transactionTemplateListStatesInvalid[templateType]) || self.transactionTemplateListStatesInvalid[templateType]) {
|
||||
self.updateTransactionTemplateListInvalidState(templateType, false);
|
||||
}
|
||||
|
||||
resolve(data.result);
|
||||
}).catch(error => {
|
||||
logger.error('failed to save templates display order', error);
|
||||
|
||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||
reject({ error: error.response.data });
|
||||
} else if (!error.processed) {
|
||||
reject({ message: 'Unable to move template' });
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
hideTemplate({ template, hidden }) {
|
||||
const self = this;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
services.hideTransactionTemplate({
|
||||
id: template.id,
|
||||
hidden: hidden
|
||||
}).then(response => {
|
||||
const data = response.data;
|
||||
|
||||
if (!data || !data.success || !data.result) {
|
||||
if (hidden) {
|
||||
reject({ message: 'Unable to hide this template' });
|
||||
} else {
|
||||
reject({ message: 'Unable to unhide this template' });
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
updateTemplateVisibilityInTransactionTemplateList(self, template.templateType, {
|
||||
template: template,
|
||||
hidden: hidden
|
||||
});
|
||||
|
||||
resolve(data.result);
|
||||
}).catch(error => {
|
||||
logger.error('failed to change template visibility', error);
|
||||
|
||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||
reject({ error: error.response.data });
|
||||
} else if (!error.processed) {
|
||||
if (hidden) {
|
||||
reject({ message: 'Unable to hide this template' });
|
||||
} else {
|
||||
reject({ message: 'Unable to unhide this template' });
|
||||
}
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
deleteTemplate({ template, beforeResolve }) {
|
||||
const self = this;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
services.deleteTransactionTemplate({
|
||||
id: template.id
|
||||
}).then(response => {
|
||||
const data = response.data;
|
||||
|
||||
if (!data || !data.success || !data.result) {
|
||||
reject({ message: 'Unable to delete this template' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (beforeResolve) {
|
||||
beforeResolve(() => {
|
||||
removeTemplateFromTransactionTemplateList(self, template.templateType, template);
|
||||
});
|
||||
} else {
|
||||
removeTemplateFromTransactionTemplateList(self, template.templateType, template);
|
||||
}
|
||||
|
||||
resolve(data.result);
|
||||
}).catch(error => {
|
||||
logger.error('failed to delete template', 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 template' });
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user