mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-16 18:25:00 -06:00
Expand AC
This commit is contained in:
parent
c3b99c322d
commit
9939ed0aaf
@ -42,12 +42,19 @@
|
||||
:has-submission-error="hasSubmissionErrors.description"
|
||||
:disabled-input="disabledInput"
|
||||
:description="transaction.description"
|
||||
@update:description="updateDescription"/>
|
||||
@update:description="updateDescription"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4 q-mb-xs q-pr-xs">
|
||||
<SourceAccount name="Test" :disabled-input="false" submission-error="" :has-submission-error="false" />
|
||||
<SourceAccount
|
||||
:name="''"
|
||||
@update:source="updateSource"
|
||||
:disabled-input="false"
|
||||
submission-error=""
|
||||
:transaction-type="transactionType"
|
||||
:has-submission-error="false"/>
|
||||
</div>
|
||||
<div class="col-4 q-px-xs">
|
||||
<q-input
|
||||
@ -60,14 +67,13 @@
|
||||
outlined reverse-fill-mask/>
|
||||
</div>
|
||||
<div class="col-4 q-pl-xs">
|
||||
<q-input dense
|
||||
v-model="transaction.destination"
|
||||
:disable="disabledInput"
|
||||
:error="hasSubmissionErrors.destination"
|
||||
:error-message="submissionErrors.destination" :label="$t('firefly.destination_account')"
|
||||
bottom-slots
|
||||
clearable
|
||||
outlined/>
|
||||
<DestinationAccount
|
||||
:name="''"
|
||||
@update:destination="updateDestination"
|
||||
:disabled-input="false"
|
||||
submission-error=""
|
||||
:transaction-type="transactionType"
|
||||
:has-submission-error="false"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
@ -268,15 +274,21 @@
|
||||
<script>
|
||||
import TransactionDescription from "components/transactions/form/TransactionDescription.vue";
|
||||
import SourceAccount from "components/transactions/form/SourceAccount.vue";
|
||||
import DestinationAccount from "components/transactions/form/DestinationAccount.vue";
|
||||
|
||||
export default {
|
||||
name: "Split",
|
||||
components: {SourceAccount, TransactionDescription},
|
||||
components: {DestinationAccount, SourceAccount, TransactionDescription},
|
||||
props: {
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
transactionType: {
|
||||
type: String,
|
||||
default: 'unknown',
|
||||
required: true
|
||||
},
|
||||
disabledInput: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
@ -297,6 +309,17 @@ export default {
|
||||
methods: {
|
||||
updateDescription(newVal) {
|
||||
this.transaction.description = newVal;
|
||||
console.log('Description is now "' + newVal + '"');
|
||||
},
|
||||
updateSource(newVal) {
|
||||
this.transaction.source = newVal;
|
||||
console.log('Source is now:');
|
||||
console.log(newVal);
|
||||
},
|
||||
updateDestination(newVal) {
|
||||
this.transaction.destination = newVal;
|
||||
console.log('Destination is now:');
|
||||
console.log(newVal);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
156
frontend/src/components/transactions/form/DestinationAccount.vue
Normal file
156
frontend/src/components/transactions/form/DestinationAccount.vue
Normal file
@ -0,0 +1,156 @@
|
||||
<!--
|
||||
- SourceAccount.vue
|
||||
- Copyright (c) 2023 james@firefly-iii.org
|
||||
-
|
||||
- This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<q-select
|
||||
v-model="model"
|
||||
use-input
|
||||
:options="options"
|
||||
@filter="filterFn"
|
||||
dense
|
||||
:loading="loading"
|
||||
outlined
|
||||
new-value-mode="add-unique"
|
||||
:disable="disabledInput"
|
||||
:error="hasSubmissionError"
|
||||
:label="$t('firefly.destination_account')"
|
||||
:error-message="submissionError"
|
||||
bottom-slots
|
||||
clearable
|
||||
>
|
||||
<!--
|
||||
|
||||
input-debounce="0"
|
||||
|
||||
label="Lazy filter"
|
||||
-->
|
||||
<template v-slot:option="scope">
|
||||
<q-item v-bind="scope.itemProps">
|
||||
<q-item-section>
|
||||
<q-item-label>{{ scope.opt.label }}</q-item-label>
|
||||
<q-item-label caption>{{ scope.opt.type }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No results
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
|
||||
</template>
|
||||
|
||||
<!--
|
||||
source account is basic dropdown from API
|
||||
with optional filters on account type. This depends
|
||||
on transaction type which is null or invalid or withdrawal or whatever
|
||||
if the index is not null the field shall be disabled and empty.
|
||||
-->
|
||||
|
||||
<script>
|
||||
import Accounts from '../../../api/v2/autocomplete/accounts'
|
||||
|
||||
export default {
|
||||
name: "DestinationAccount",
|
||||
data() {
|
||||
return {
|
||||
model: null,
|
||||
transactionTypeString: '',
|
||||
options: [],
|
||||
loading: true,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
transactionType: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'unknown'
|
||||
},
|
||||
disabledInput: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: true
|
||||
},
|
||||
hasSubmissionError: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: true
|
||||
},
|
||||
submissionError: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getAccounts('');
|
||||
this.model = this.name;
|
||||
|
||||
},
|
||||
methods: {
|
||||
getAccounts: function (query) {
|
||||
this.loading = true;
|
||||
// default set of account types, will later be set by the transaction type.
|
||||
let types = 'Expense account, Loan, Debt, Mortgage';
|
||||
if('deposit' === this.transactionType) {
|
||||
let types = 'Asset account, Loan, Debt, Mortgage';
|
||||
}
|
||||
(new Accounts).get(types, query).then(response => {
|
||||
this.stringOptions = [];
|
||||
for (let i in response.data) {
|
||||
let entry = response.data[i];
|
||||
let current = {
|
||||
label: entry.name,
|
||||
value: entry.id,
|
||||
type: entry.type
|
||||
}
|
||||
|
||||
this.stringOptions.push(current);
|
||||
}
|
||||
//this.stringOptions = response.data.data;
|
||||
this.options = this.stringOptions;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
filterFn(val, update, abort) {
|
||||
update(() => {
|
||||
this.getAccounts(val);
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
model: {
|
||||
handler: function (newVal) {
|
||||
if(newVal !== undefined) {
|
||||
this.$emit('update:destination', newVal);
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -27,6 +27,7 @@
|
||||
dense
|
||||
:loading="loading"
|
||||
outlined
|
||||
new-value-mode="add-unique"
|
||||
:disable="disabledInput"
|
||||
:error="hasSubmissionError"
|
||||
:label="$t('firefly.source_account')"
|
||||
@ -44,7 +45,7 @@
|
||||
<q-item v-bind="scope.itemProps">
|
||||
<q-item-section>
|
||||
<q-item-label>{{ scope.opt.label }}</q-item-label>
|
||||
<q-item-label caption>{{ scope.opt.description }}</q-item-label>
|
||||
<q-item-label caption>{{ scope.opt.type }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
@ -87,7 +88,8 @@ export default {
|
||||
},
|
||||
transactionType: {
|
||||
type: String,
|
||||
required: false
|
||||
required: false,
|
||||
default: 'unknown'
|
||||
},
|
||||
disabledInput: {
|
||||
type: Boolean,
|
||||
@ -105,16 +107,18 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log('Mounted');
|
||||
//this.options.value = this.stringOptions
|
||||
this.getAccounts('');
|
||||
this.model = this.name;
|
||||
|
||||
},
|
||||
methods: {
|
||||
getAccounts: function (query) {
|
||||
this.loading = true;
|
||||
console.log('getAccounts("'+query+'")');
|
||||
// default set of account types, will later be set by the transaction type.
|
||||
let types = 'Asset account,Revenue account,Loan,Debt,Mortgage';
|
||||
if('deposit' === this.transactionType) {
|
||||
console.log('NOW DEPOSIT');
|
||||
}
|
||||
(new Accounts).get(types, query).then(response => {
|
||||
this.stringOptions = [];
|
||||
for (let i in response.data) {
|
||||
@ -122,46 +126,31 @@ export default {
|
||||
let current = {
|
||||
label: entry.name,
|
||||
value: entry.id,
|
||||
description: entry.type
|
||||
type: entry.type
|
||||
}
|
||||
|
||||
this.stringOptions.push(current);
|
||||
}
|
||||
//this.stringOptions = response.data.data;
|
||||
this.options = this.stringOptions;
|
||||
this.options = this.stringOptions;
|
||||
this.loading = false;
|
||||
console.log('getAccounts done!');
|
||||
});
|
||||
},
|
||||
filterFn(val, update, abort) {
|
||||
console.log('filterFn(' + val + ')');
|
||||
if (val === '') {
|
||||
update(() => {
|
||||
this.getAccounts('');
|
||||
//this.options = stringOptions
|
||||
|
||||
// here you have access to "ref" which
|
||||
// is the Vue reference of the QSelect
|
||||
})
|
||||
return
|
||||
}
|
||||
update(() => {
|
||||
this.getAccounts(val);
|
||||
//const needle = val.toLowerCase()
|
||||
//this.options = this.options.filter(v => v.label.toLowerCase().indexOf(needle) > -1)
|
||||
})
|
||||
// console.log('filterFn(' + val + ')');
|
||||
// if (this.loading) {
|
||||
// console.log('return');
|
||||
// return
|
||||
// }
|
||||
// const needle = val.toLowerCase()
|
||||
// this.options = this.stringOptions.filter(v => v.label.toLowerCase().indexOf(needle) > -1);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
model: {
|
||||
handler: function (newVal) {
|
||||
if(newVal !== undefined) {
|
||||
this.$emit('update:source', newVal);
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
@ -59,6 +59,7 @@
|
||||
<Split
|
||||
:transaction="transaction"
|
||||
:index="index"
|
||||
:transaction-type="transactionType"
|
||||
:disabled-input="disabledInput"
|
||||
:has-submission-errors="hasSubmissionErrors[index]"
|
||||
:submission-errors="submissionErrors[index]"
|
||||
@ -112,6 +113,7 @@ import format from 'date-fns/format';
|
||||
import formatISO from 'date-fns/formatISO';
|
||||
import Post from "../../api/transactions/post";
|
||||
import Split from "components/transactions/Split.vue";
|
||||
import CalculateType from "src/support/transactions/calculate-type";
|
||||
|
||||
export default {
|
||||
name: 'Create',
|
||||
@ -119,6 +121,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
tab: 'split-0',
|
||||
transactionType: 'unknown',
|
||||
transactions: [],
|
||||
submissionErrors: [],
|
||||
hasSubmissionErrors: [],
|
||||
@ -165,7 +168,7 @@ export default {
|
||||
this.tab = 'split-' + index;
|
||||
},
|
||||
getSplitLabel: function (index) {
|
||||
console.log('Get split label (' + index + ')');
|
||||
//console.log('Get split label (' + index + ')');
|
||||
if (this.transactions.hasOwnProperty(index) &&
|
||||
null !== this.transactions[index].description &&
|
||||
this.transactions[index].description.length > 0) {
|
||||
@ -196,10 +199,9 @@ export default {
|
||||
},
|
||||
updateTransaction: function (obj) {
|
||||
const index = obj.index;
|
||||
const transaction = obj.transaction;
|
||||
console.log('Update transaction ' + index);
|
||||
console.log(transaction);
|
||||
this.transactions[index] = transaction;
|
||||
this.transactions[index] = obj.transaction;
|
||||
// TODO needs to update all splits if necessary and warn user about it.
|
||||
this.transactionType = (new CalculateType()).calculateType(this.transactions[0].source, this.transactions[0].destination);
|
||||
},
|
||||
processSuccess: function (response) {
|
||||
console.log('process success');
|
||||
|
69
frontend/src/support/transactions/calculate-type.js
vendored
Normal file
69
frontend/src/support/transactions/calculate-type.js
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* calculate-type.js
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export default class CalculateType {
|
||||
calculateType(source, destination) {
|
||||
const srcEmpty = this.empty(source);
|
||||
const dstEmpty = this.empty(destination);
|
||||
// both are null or ''
|
||||
if (srcEmpty && dstEmpty) {
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
// source has data, dest has not
|
||||
if (typeof source === 'object' && null !== source && dstEmpty) {
|
||||
if (source.type === 'Asset account' || source.type === 'Loan' || source.type === 'Debt' || source.type === 'Mortgage') {
|
||||
return 'withdrawal';
|
||||
}
|
||||
if (source.type === 'Revenue account') {
|
||||
return 'deposit';
|
||||
}
|
||||
}
|
||||
// dst has data, source has not
|
||||
if (typeof destination === 'object' && null !== destination && srcEmpty) {
|
||||
if (destination.type === 'Asset account') {
|
||||
return 'deposit';
|
||||
}
|
||||
}
|
||||
// both have data:
|
||||
if (!srcEmpty && !dstEmpty) {
|
||||
if (source.type === 'Asset account' && destination.type === 'Expense account') {
|
||||
return 'withdrawal';
|
||||
}
|
||||
if (source.type === destination.type) {
|
||||
return 'transfer';
|
||||
}
|
||||
}
|
||||
|
||||
console.error('Cannot handle');
|
||||
console.log(source);
|
||||
console.log(destination);
|
||||
}
|
||||
|
||||
empty(value) {
|
||||
if (null === value || '' === value) {
|
||||
return true;
|
||||
}
|
||||
if (null !== value && typeof value === 'object') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user