mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2026-10-26 07:00:10 -05:00
Expand create transaction
This commit is contained in:
1 parent
3ab98c4c76
commit
ff889714d7
15 files changed
+46
-1109
No files matched your search
@@ -32,6 +32,7 @@ use FireflyIII\Http\Requests\PreferencesRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Facades\AppConfiguration;
|
||||
use FireflyIII\Support\Facades\Navigation;
|
||||
use FireflyIII\Support\Facades\Preferences;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
@@ -193,9 +194,12 @@ final class PreferencesController extends Controller
|
||||
$ntfyPass = '';
|
||||
}
|
||||
|
||||
$mapEnabled = true === AppConfiguration::get('enable_external_map', config('firefly.enable_external_map', false))->data;
|
||||
|
||||
return view('preferences.index', [
|
||||
'anonymous' => $anonymous,
|
||||
'language' => $language,
|
||||
'mapEnabled' => $mapEnabled,
|
||||
'pushoverAppToken' => $pushoverAppToken,
|
||||
'pushoverUserToken' => $pushoverUserToken,
|
||||
'ntfyServer' => $ntfyServer,
|
||||
|
||||
@@ -138,7 +138,7 @@ final class CreateController extends Controller
|
||||
$optionalFields['external_url'] ??= false;
|
||||
$optionalFields['location'] ??= false;
|
||||
$optionalFields['location'] = $optionalFields['location']
|
||||
&& true === AppConfiguration::get('enable_external_map', config('firefly.enable_external_map'))->data;
|
||||
&& true === AppConfiguration::get('enable_external_map', config('firefly.enable_external_map', false))->data;
|
||||
|
||||
// map info:
|
||||
$longitude = config('firefly.default_location.longitude');
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
<!--
|
||||
- Budget.vue
|
||||
- Copyright (c) 2019 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>
|
||||
<div v-if="typeof this.transactionType === 'undefined' || this.transactionType === 'withdrawal' || this.transactionType === 'Withdrawal' || this.transactionType === '' || null === this.transactionType"
|
||||
class="form-group"
|
||||
v-bind:class="{ 'has-error': hasError()}">
|
||||
<div class="col-sm-12 text-sm">
|
||||
{{ $t('firefly.budget') }}
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<select
|
||||
v-if="this.budgets.length > 0"
|
||||
ref="budget"
|
||||
v-model="selected"
|
||||
:title="$t('firefly.budget')"
|
||||
class="form-control"
|
||||
name="budget[]"
|
||||
@input="handleInput"
|
||||
v-on:change="signalChange">
|
||||
<option v-for="cBudget in this.budgets"
|
||||
:label="cBudget.name"
|
||||
:value="cBudget.id">{{ cBudget.name }}
|
||||
</option>
|
||||
</select>
|
||||
<p v-if="this.budgets.length === 1" class="help-block" v-html="$t('firefly.no_budget_pointer')"></p>
|
||||
<ul v-for="error in this.error" class="list-unstyled">
|
||||
<li class="text-danger">{{ error }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Budget",
|
||||
props: {
|
||||
transactionType: String,
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
error: Array,
|
||||
no_budget: String,
|
||||
},
|
||||
mounted() {
|
||||
this.loadBudgets();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selected: this.value ?? 0,
|
||||
budgets: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: function () {
|
||||
// console.log('budget: value changed to ' + this.value);
|
||||
this.selected = this.value;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// Fixes edit change budget not updating on every browser
|
||||
signalChange: function (e) {
|
||||
this.$emit('input', this.$refs.budget.value);
|
||||
},
|
||||
handleInput(e) {
|
||||
this.$emit('input', this.$refs.budget.value);
|
||||
},
|
||||
hasError: function () {
|
||||
return this.error.length > 0;
|
||||
},
|
||||
loadBudgets: function () {
|
||||
let URI = document.getElementsByTagName('base')[0].href + 'api/v1/autocomplete/budgets?limit=1337';
|
||||
axios.get(URI, {}).then((res) => {
|
||||
this.budgets = [
|
||||
{
|
||||
name: this.no_budget,
|
||||
id: 0,
|
||||
}
|
||||
];
|
||||
for (const key in res.data) {
|
||||
if (res.data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
||||
this.budgets.push(res.data[key]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,177 +0,0 @@
|
||||
<!--
|
||||
- Category.vue
|
||||
- Copyright (c) 2019 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>
|
||||
<div class="form-group" v-bind:class="{ 'has-error': hasError()}">
|
||||
<div class="col-sm-12 text-sm">
|
||||
{{ $t('firefly.category') }}
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="input-group">
|
||||
<input
|
||||
spellcheck="false"
|
||||
ref="input"
|
||||
:value="value"
|
||||
autocomplete="off"
|
||||
class="form-control"
|
||||
data-role="input"
|
||||
name="category[]"
|
||||
type="text"
|
||||
v-bind:placeholder="$t('firefly.category')"
|
||||
v-bind:title="$t('firefly.category')"
|
||||
@input="handleInput"
|
||||
v-on:keypress="handleEnter"
|
||||
v-on:submit.prevent>
|
||||
<span class="input-group-btn">
|
||||
<button
|
||||
class="btn btn-default"
|
||||
type="button"
|
||||
v-on:click="clearCategory"><i class="fa fa-trash-o"></i></button>
|
||||
</span>
|
||||
</div>
|
||||
<typeahead
|
||||
v-model="name"
|
||||
:async-function="aSyncFunction"
|
||||
:open-on-empty=true
|
||||
:open-on-focus=true
|
||||
ref="typea"
|
||||
:target="target"
|
||||
item-key="name"
|
||||
v-on:input="selectedItem"
|
||||
>
|
||||
<template slot="item" slot-scope="props">
|
||||
<li v-for="(item, index) in props.items" :class="{active:props.activeIndex===index}">
|
||||
<a role="button" @click="props.select(item)">
|
||||
<span v-html="betterHighlight(item)"></span>
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
</typeahead>
|
||||
<ul v-for="error in this.error" class="list-unstyled">
|
||||
<li class="text-danger">{{ error }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Category",
|
||||
props: {
|
||||
value: String,
|
||||
inputName: String,
|
||||
error: Array,
|
||||
accountName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
categoryAutoCompleteURI: null,
|
||||
name: null,
|
||||
target: null,
|
||||
acKey: null,
|
||||
}
|
||||
},
|
||||
ready() {
|
||||
this.name = this.accountName;
|
||||
this.acKey = 'name';
|
||||
},
|
||||
mounted() {
|
||||
this.target = this.$refs.input;
|
||||
this.categoryAutoCompleteURI = document.getElementsByTagName('base')[0].href + "api/v1/autocomplete/categories?query=";
|
||||
},
|
||||
methods: {
|
||||
hasError: function () {
|
||||
return this.error.length > 0;
|
||||
},
|
||||
betterHighlight: function (item) {
|
||||
var inputValue = this.$refs.input.value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
||||
var escapedName = this.escapeHtml(item.name);
|
||||
return escapedName.replace(new RegExp(("" + inputValue), 'i'), '<b>$&</b>');
|
||||
},
|
||||
aSyncFunction: function (query, done) {
|
||||
axios.get(this.categoryAutoCompleteURI + query)
|
||||
.then(res => {
|
||||
done(res.data);
|
||||
})
|
||||
.catch(err => {
|
||||
// any error handler
|
||||
})
|
||||
},
|
||||
escapeHtml: function (string) {
|
||||
|
||||
let entityMap = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
'/': '/',
|
||||
'`': '`',
|
||||
'=': '='
|
||||
};
|
||||
|
||||
return String(string).replace(/[&<>"'`=\/]/g, function fromEntityMap(s) {
|
||||
return entityMap[s];
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
handleInput(e) {
|
||||
if (typeof this.$refs.input.value === 'string') {
|
||||
this.$emit('input', this.$refs.input.value);
|
||||
return;
|
||||
}
|
||||
this.$emit('input', this.$refs.input.value.name);
|
||||
|
||||
},
|
||||
clearCategory: function () {
|
||||
//props.value = '';
|
||||
this.name = '';
|
||||
this.$refs.input.value = '';
|
||||
this.$emit('input', this.$refs.input.value);
|
||||
// some event?
|
||||
this.$emit('clear:category')
|
||||
},
|
||||
selectedItem: function (e) {
|
||||
if (typeof this.name === 'undefined') {
|
||||
return;
|
||||
}
|
||||
// emit the fact that the user selected a type of account
|
||||
// (influencing the destination)
|
||||
this.$emit('select:category', this.name);
|
||||
|
||||
if (typeof this.name === 'string') {
|
||||
this.$emit('input', this.name);
|
||||
return;
|
||||
}
|
||||
this.$emit('input', this.name.name);
|
||||
},
|
||||
handleEnter: function (e) {
|
||||
// TODO feels sloppy
|
||||
if (e.keyCode === 13) {
|
||||
//e.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -17,454 +17,11 @@
|
||||
- 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>
|
||||
<form accept-charset="UTF-8" class="form-horizontal" enctype="multipart/form-data">
|
||||
<div>
|
||||
<div v-for="(transaction, index) in transactions" class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="box">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div id="amount-info" class="col-lg-4">
|
||||
<amount
|
||||
v-model="transaction.amount"
|
||||
:destination="transaction.destination_account"
|
||||
:error="transaction.errors.amount"
|
||||
:source="transaction.source_account"
|
||||
:transactionType="transactionType"
|
||||
></amount>
|
||||
<foreign-amount
|
||||
v-model="transaction.foreign_amount"
|
||||
:destination="transaction.destination_account"
|
||||
:error="transaction.errors.foreign_amount"
|
||||
:source="transaction.source_account"
|
||||
:transactionType="transactionType"
|
||||
v-bind:title="$t('form.foreign_amount')"
|
||||
></foreign-amount>
|
||||
</div>
|
||||
<div id="optional-info" class="col-lg-4">
|
||||
<budget
|
||||
v-model="transaction.budget"
|
||||
:error="transaction.errors.budget_id"
|
||||
:no_budget="$t('firefly.none_in_select_list')"
|
||||
:transactionType="transactionType"
|
||||
></budget>
|
||||
<category
|
||||
v-model="transaction.category"
|
||||
:error="transaction.errors.category"
|
||||
:transactionType="transactionType"
|
||||
></category>
|
||||
<piggy-bank
|
||||
v-model="transaction.piggy_bank"
|
||||
:error="transaction.errors.piggy_bank"
|
||||
:no_piggy_bank="$t('firefly.no_piggy_bank')"
|
||||
:transactionType="transactionType"
|
||||
></piggy-bank>
|
||||
<tags
|
||||
v-model="transaction.tags"
|
||||
:error="transaction.errors.tags"
|
||||
></tags>
|
||||
<bill
|
||||
v-model="transaction.bill"
|
||||
:error="transaction.errors.bill_id"
|
||||
:no_bill="$t('firefly.none_in_select_list')"
|
||||
:transactionType="transactionType"
|
||||
></bill>
|
||||
<custom-transaction-fields
|
||||
v-model="transaction.custom_fields"
|
||||
:error="transaction.errors.custom_errors"
|
||||
></custom-transaction-fields>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="transactions.length-1 === index" class="box-footer">
|
||||
<button class="split_add_btn btn btn-default" type="button" @click="addTransactionToArray">
|
||||
{{ $t('firefly.add_another_split') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="transactions.length > 1" class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
{{ $t('firefly.split_transaction_title') }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<group-description
|
||||
v-model="group_title"
|
||||
:error="group_title_errors"
|
||||
></group-description>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
{{ $t('firefly.submission') }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input v-model="createAnother" name="create_another" type="checkbox">
|
||||
{{ $t('firefly.create_another') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label v-bind:class="{ 'text-muted': this.createAnother === false}">
|
||||
<input v-model="resetFormAfter" :disabled="this.createAnother === false"
|
||||
name="reset_form" type="checkbox">
|
||||
{{ $t('firefly.reset_after') }}
|
||||
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="btn-group">
|
||||
<button id="submitButton" class="btn btn-success" @click="submit">{{
|
||||
$t('firefly.submit')
|
||||
}}
|
||||
</button>
|
||||
</div>
|
||||
<p class="text-success" v-html="success_message"></p>
|
||||
<p class="text-danger" v-html="error_message"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
{{ $t('firefly.submission_options') }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input v-model="applyRules" name="apply_rules" type="checkbox">
|
||||
{{ $t('firefly.apply_rules_checkbox') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input v-model="fireWebhooks" name="fire_webhooks" type="checkbox">
|
||||
{{ $t('firefly.fire_webhooks_checkbox') }}
|
||||
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "CreateTransaction",
|
||||
components: {},
|
||||
created() {
|
||||
this.addTransactionToArray();
|
||||
document.onreadystatechange = () => {
|
||||
if (document.readyState === "complete") {
|
||||
this.prefillSourceAccount();
|
||||
this.prefillDestinationAccount();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
prefillSourceAccount() {
|
||||
if (0 === window.sourceId) {
|
||||
return;
|
||||
}
|
||||
this.getAccount(window.sourceId, 'source_account');
|
||||
},
|
||||
prefillDestinationAccount() {
|
||||
if (0 === destinationId) {
|
||||
return;
|
||||
}
|
||||
this.getAccount(window.destinationId, 'destination_account');
|
||||
},
|
||||
getAccount(accountId, slot) {
|
||||
const uri = './api/v1/accounts/' + accountId + '?_token=' + document.head.querySelector('meta[name="csrf-token"]').content;
|
||||
axios.get(uri).then(response => {
|
||||
let model = response.data.data.attributes;
|
||||
model.type = this.fullAccountType(model.type, model.liability_type);
|
||||
model.id = parseInt(response.data.data.id);
|
||||
if ('source_account' === slot) {
|
||||
this.selectedSourceAccount(0, model);
|
||||
}
|
||||
if ('destination_account' === slot) {
|
||||
this.selectedDestinationAccount(0, model);
|
||||
}
|
||||
}).catch(error => {
|
||||
console.warn('Could not auto fill account');
|
||||
console.warn(error);
|
||||
});
|
||||
|
||||
},
|
||||
fullAccountType: function (shortType, liabilityType) {
|
||||
let searchType = shortType;
|
||||
if ('liabilities' === shortType) {
|
||||
searchType = liabilityType;
|
||||
}
|
||||
let arr = {
|
||||
'asset': 'Asset account',
|
||||
'loan': 'Loan',
|
||||
'debt': 'Debt',
|
||||
'mortgage': 'Mortgage'
|
||||
};
|
||||
return arr[searchType] ?? searchType;
|
||||
},
|
||||
convertData: function () {
|
||||
// console.log('Now in convertData()');
|
||||
let data = {
|
||||
'apply_rules': this.applyRules,
|
||||
'fire_webhooks': this.fireWebhooks,
|
||||
'transactions': [],
|
||||
};
|
||||
let transactionType;
|
||||
let firstSource;
|
||||
let firstDestination;
|
||||
|
||||
if (this.transactions.length > 1) {
|
||||
data.group_title = this.group_title;
|
||||
}
|
||||
|
||||
// get transaction type from first transaction
|
||||
transactionType = this.transactionType ? this.transactionType.toLowerCase() : 'invalid';
|
||||
|
||||
// if the transaction type is invalid, might just be that we can deduce it from
|
||||
// the presence of a source or destination account
|
||||
firstSource = this.transactions[0].source_account.type;
|
||||
firstDestination = this.transactions[0].destination_account.type;
|
||||
// console.log('Type of first source is ' + firstSource);
|
||||
|
||||
if ('invalid' === transactionType && ['asset', 'Asset account', 'Loan', 'Debt', 'Mortgage'].includes(firstSource)) {
|
||||
transactionType = 'withdrawal';
|
||||
}
|
||||
|
||||
if ('invalid' === transactionType && ['asset', 'Asset account', 'Loan', 'Debt', 'Mortgage'].includes(firstDestination)) {
|
||||
transactionType = 'deposit';
|
||||
}
|
||||
|
||||
for (let key in this.transactions) {
|
||||
if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
||||
data.transactions.push(this.convertDataRow(this.transactions[key], key, transactionType));
|
||||
}
|
||||
}
|
||||
|
||||
// overrule group title in case its empty:
|
||||
if ('' === data.group_title && data.transactions.length > 1) {
|
||||
data.group_title = data.transactions[0].description;
|
||||
}
|
||||
|
||||
return data;
|
||||
},
|
||||
convertDataRow(row, index, transactionType) {
|
||||
// console.log('Now in convertDataRow()');
|
||||
let tagList = [];
|
||||
let foreignAmount = null;
|
||||
let foreignCurrency = null;
|
||||
let currentArray;
|
||||
let sourceId;
|
||||
let sourceName;
|
||||
let destId;
|
||||
let destName;
|
||||
let date;
|
||||
|
||||
sourceId = row.source_account.id;
|
||||
sourceName = row.source_account.name;
|
||||
destId = row.destination_account.id;
|
||||
destName = row.destination_account.name;
|
||||
|
||||
date = row.date;
|
||||
if (index > 0) {
|
||||
date = this.transactions[0].date;
|
||||
}
|
||||
|
||||
// if type is 'withdrawal' and destination is empty, cash withdrawal.
|
||||
if (transactionType === 'withdrawal' && '' === destName) {
|
||||
destId = window.cashAccountId;
|
||||
}
|
||||
|
||||
// if type is 'deposit' and source is empty, cash deposit.
|
||||
if (transactionType === 'deposit' && '' === sourceName) {
|
||||
sourceId = window.cashAccountId;
|
||||
}
|
||||
|
||||
// if index is over 0 and type is withdrawal or transfer, take source from index 0.
|
||||
if (index > 0 && (transactionType.toLowerCase() === 'withdrawal' || transactionType.toLowerCase() === 'transfer')) {
|
||||
sourceId = this.transactions[0].source_account.id;
|
||||
sourceName = this.transactions[0].source_account.name;
|
||||
}
|
||||
|
||||
// if index is over 0 and type is deposit or transfer, take destination from index 0.
|
||||
if (index > 0 && (transactionType.toLowerCase() === 'deposit' || transactionType.toLowerCase() === 'transfer')) {
|
||||
destId = this.transactions[0].destination_account.id;
|
||||
destName = this.transactions[0].destination_account.name;
|
||||
}
|
||||
|
||||
tagList = [];
|
||||
// loop tags
|
||||
for (let tagKey in row.tags) {
|
||||
if (row.tags.hasOwnProperty(tagKey) && /^0$|^[1-9]\d*$/.test(tagKey) && tagKey <= 4294967294) {
|
||||
tagList.push(row.tags[tagKey].text);
|
||||
}
|
||||
}
|
||||
|
||||
// set foreign currency info:
|
||||
if (row.foreign_amount.amount !== '' && parseFloat(row.foreign_amount.amount) !== .00) {
|
||||
foreignAmount = row.foreign_amount.amount;
|
||||
foreignCurrency = row.foreign_amount.currency_id;
|
||||
}
|
||||
if (foreignCurrency === row.currency_id) {
|
||||
foreignAmount = null;
|
||||
foreignCurrency = null;
|
||||
}
|
||||
|
||||
// correct some id's
|
||||
if (0 === destId) {
|
||||
destId = null;
|
||||
}
|
||||
if (0 === sourceId) {
|
||||
sourceId = null;
|
||||
}
|
||||
// parse amount if has exactly one comma:
|
||||
// solves issues with some locales.
|
||||
if (1 === (row.amount.match(/\,/g) || []).length) {
|
||||
row.amount = row.amount.replace(',', '.');
|
||||
}
|
||||
|
||||
currentArray =
|
||||
{
|
||||
type: transactionType,
|
||||
date: date,
|
||||
|
||||
amount: row.amount,
|
||||
currency_id: row.currency_id,
|
||||
|
||||
description: row.description,
|
||||
|
||||
source_id: sourceId,
|
||||
source_name: sourceName,
|
||||
|
||||
destination_id: destId,
|
||||
destination_name: destName,
|
||||
|
||||
|
||||
category_name: row.category,
|
||||
|
||||
interest_date: row.custom_fields.interest_date,
|
||||
book_date: row.custom_fields.book_date,
|
||||
process_date: row.custom_fields.process_date,
|
||||
due_date: row.custom_fields.due_date,
|
||||
payment_date: row.custom_fields.payment_date,
|
||||
invoice_date: row.custom_fields.invoice_date,
|
||||
internal_reference: row.custom_fields.internal_reference,
|
||||
notes: row.custom_fields.notes,
|
||||
external_url: row.custom_fields.external_url
|
||||
};
|
||||
|
||||
if (tagList.length > 0) {
|
||||
currentArray.tags = tagList;
|
||||
}
|
||||
if (null !== foreignAmount) {
|
||||
currentArray.foreign_amount = foreignAmount;
|
||||
currentArray.foreign_currency_id = foreignCurrency;
|
||||
}
|
||||
// set budget id and piggy ID.
|
||||
if (parseInt(row.budget) > 0) {
|
||||
currentArray.budget_id = parseInt(row.budget);
|
||||
}
|
||||
if (parseInt(row.bill) > 0) {
|
||||
currentArray.bill_id = parseInt(row.bill);
|
||||
}
|
||||
if (parseInt(row.piggy_bank) > 0) {
|
||||
currentArray.piggy_bank_id = parseInt(row.piggy_bank);
|
||||
}
|
||||
return currentArray;
|
||||
},
|
||||
// submit transaction
|
||||
submit(e) {
|
||||
// console.log('Now in submit()');
|
||||
const uri = './api/v1/transactions?_token=' + document.head.querySelector('meta[name="csrf-token"]').content;
|
||||
const data = this.convertData();
|
||||
|
||||
let button = $('#submitButton');
|
||||
button.prop("disabled", true);
|
||||
|
||||
axios.post(uri, data).then(response => {
|
||||
// console.log('Did a successful POST');
|
||||
// this method will ultimately send the user on (or not).
|
||||
if (0 === this.collectAttachmentData(response)) {
|
||||
// console.log('Will now go to redirectUser()');
|
||||
this.redirectUser(response.data.data.id, response.data.data);
|
||||
}
|
||||
}).catch(error => {
|
||||
// give user errors things back.
|
||||
// something something render errors.
|
||||
|
||||
console.error('Error in transaction submission.');
|
||||
console.error(error);
|
||||
this.parseErrors(error.response.data);
|
||||
|
||||
// something.
|
||||
// console.log('enable button again.')
|
||||
button.removeAttr('disabled');
|
||||
});
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
escapeHTML(unsafeText) {
|
||||
let div = document.createElement('div');
|
||||
div.innerText = unsafeText;
|
||||
return div.innerHTML;
|
||||
},
|
||||
redirectUser(groupId, transactionData) {
|
||||
// console.log('In redirectUser()');
|
||||
// console.log(transactionData);
|
||||
let title = null === transactionData.attributes.group_title ? transactionData.attributes.transactions[0].description : transactionData.attributes.group_title;
|
||||
// console.log('Title is "' + title + '"');
|
||||
// if count is 0, send user onwards.
|
||||
if (this.createAnother) {
|
||||
// do message:
|
||||
this.success_message = this.$t('firefly.transaction_stored_link', {
|
||||
ID: groupId,
|
||||
title: this.escapeHTML(title)
|
||||
});
|
||||
this.error_message = '';
|
||||
if (this.resetFormAfter) {
|
||||
// also clear form.
|
||||
this.resetTransactions();
|
||||
// do a short time out?
|
||||
setTimeout(() => this.addTransactionToArray(), 50);
|
||||
//this.addTransactionToArray();
|
||||
}
|
||||
|
||||
// clear errors:
|
||||
this.setDefaultErrors();
|
||||
|
||||
// console.log('enable button again.')
|
||||
let button = $('#submitButton');
|
||||
button.removeAttr('disabled');
|
||||
} else {
|
||||
//console.log('Will redirect to previous URL. (' + previousUrl + ')');
|
||||
window.location.href = window.previousUrl + '?transaction_group_id=' + groupId + '&message=created';
|
||||
}
|
||||
},
|
||||
|
||||
collectAttachmentData(response) {
|
||||
// console.log('Now incollectAttachmentData()');
|
||||
let groupId = response.data.data.id;
|
||||
@@ -584,355 +141,6 @@ export default {
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
setDefaultErrors: function () {
|
||||
for (const key in this.transactions) {
|
||||
if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
||||
// console.log('Set default errors for key ' + key);
|
||||
//this.transactions[key].description
|
||||
this.transactions[key].errors = {
|
||||
source_account: [],
|
||||
destination_account: [],
|
||||
description: [],
|
||||
amount: [],
|
||||
date: [],
|
||||
budget_id: [],
|
||||
bill_id: [],
|
||||
foreign_amount: [],
|
||||
category: [],
|
||||
piggy_bank: [],
|
||||
tags: [],
|
||||
// custom fields:
|
||||
custom_errors: {
|
||||
interest_date: [],
|
||||
book_date: [],
|
||||
process_date: [],
|
||||
due_date: [],
|
||||
payment_date: [],
|
||||
invoice_date: [],
|
||||
internal_reference: [],
|
||||
notes: [],
|
||||
attachments: [],
|
||||
external_url: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
parseErrors: function (errors) {
|
||||
this.setDefaultErrors();
|
||||
this.error_message = "";
|
||||
if (typeof errors.errors === 'undefined') {
|
||||
this.success_message = '';
|
||||
this.error_message = errors.message;
|
||||
} else {
|
||||
this.success_message = '';
|
||||
this.error_message = this.$t('firefly.errors_submission');
|
||||
}
|
||||
let transactionIndex;
|
||||
let fieldName;
|
||||
|
||||
for (const key in errors.errors) {
|
||||
if (errors.errors.hasOwnProperty(key)) {
|
||||
if (key === 'group_title') {
|
||||
this.group_title_errors = errors.errors[key];
|
||||
}
|
||||
if (key !== 'group_title') {
|
||||
// lol dumbest way to explode "transactions.0.something" ever.
|
||||
transactionIndex = parseInt(key.split('.')[1]);
|
||||
fieldName = key.split('.')[2];
|
||||
// set error in this object thing.
|
||||
switch (fieldName) {
|
||||
case 'amount':
|
||||
case 'date':
|
||||
case 'budget_id':
|
||||
case 'bill_id':
|
||||
case 'description':
|
||||
case 'tags':
|
||||
this.transactions[transactionIndex].errors[fieldName] = errors.errors[key];
|
||||
break;
|
||||
case 'type':
|
||||
if(errors.errors[key].length > 0) {
|
||||
this.transactions[transactionIndex].errors.source_account = [this.$t('firefly.select_source_account')];
|
||||
this.transactions[transactionIndex].errors.destination_account = [this.$t('firefly.select_dest_account')];
|
||||
}
|
||||
break;
|
||||
case 'source_name':
|
||||
case 'source_id':
|
||||
this.transactions[transactionIndex].errors.source_account =
|
||||
this.transactions[transactionIndex].errors.source_account.concat(errors.errors[key]);
|
||||
break;
|
||||
case 'destination_name':
|
||||
case 'destination_id':
|
||||
this.transactions[transactionIndex].errors.destination_account =
|
||||
this.transactions[transactionIndex].errors.destination_account.concat(errors.errors[key]);
|
||||
break;
|
||||
case 'foreign_amount':
|
||||
case 'foreign_currency_id':
|
||||
this.transactions[transactionIndex].errors.foreign_amount =
|
||||
this.transactions[transactionIndex].errors.foreign_amount.concat(errors.errors[key]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// unique some things
|
||||
if (typeof this.transactions[transactionIndex] !== 'undefined') {
|
||||
this.transactions[transactionIndex].errors.source_account =
|
||||
Array.from(new Set(this.transactions[transactionIndex].errors.source_account));
|
||||
this.transactions[transactionIndex].errors.destination_account =
|
||||
Array.from(new Set(this.transactions[transactionIndex].errors.destination_account));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
resetTransactions: function () {
|
||||
// console.log('Now in resetTransactions()');
|
||||
this.transactions = [];
|
||||
this.group_title = '';
|
||||
|
||||
},
|
||||
addTransactionToArray: function (e) {
|
||||
// console.log('Now in addTransactionToArray()');
|
||||
this.transactions.push({
|
||||
description: "",
|
||||
date: "",
|
||||
amount: "",
|
||||
category: "",
|
||||
piggy_bank: 0,
|
||||
errors: {
|
||||
source_account: [],
|
||||
destination_account: [],
|
||||
description: [],
|
||||
amount: [],
|
||||
date: [],
|
||||
budget_id: [],
|
||||
bill_id: [],
|
||||
foreign_amount: [],
|
||||
category: [],
|
||||
piggy_bank: [],
|
||||
tags: [],
|
||||
// custom fields:
|
||||
custom_errors: {
|
||||
interest_date: [],
|
||||
book_date: [],
|
||||
process_date: [],
|
||||
due_date: [],
|
||||
payment_date: [],
|
||||
invoice_date: [],
|
||||
internal_reference: [],
|
||||
notes: [],
|
||||
attachments: [],
|
||||
external_url: [],
|
||||
},
|
||||
},
|
||||
budget: 0,
|
||||
bill: 0,
|
||||
tags: [],
|
||||
custom_fields: {
|
||||
"interest_date": "",
|
||||
"book_date": "",
|
||||
"process_date": "",
|
||||
"due_date": "",
|
||||
"payment_date": "",
|
||||
"invoice_date": "",
|
||||
"internal_reference": "",
|
||||
"notes": "",
|
||||
"attachments": [],
|
||||
"external_url": "",
|
||||
},
|
||||
foreign_amount: {
|
||||
amount: "",
|
||||
currency_id: 0
|
||||
},
|
||||
source_account: {
|
||||
id: 0,
|
||||
name: "",
|
||||
type: "",
|
||||
currency_id: 0,
|
||||
currency_name: '',
|
||||
currency_code: '',
|
||||
currency_decimal_places: 2,
|
||||
allowed_types: ['Asset account', 'Revenue account', 'Loan', 'Debt', 'Mortgage'],
|
||||
default_allowed_types: ['Asset account', 'Revenue account', 'Loan', 'Debt', 'Mortgage']
|
||||
},
|
||||
destination_account: {
|
||||
id: 0,
|
||||
name: "",
|
||||
type: "",
|
||||
currency_id: 0,
|
||||
currency_name: '',
|
||||
currency_code: '',
|
||||
currency_decimal_places: 2,
|
||||
allowed_types: ['Asset account', 'Expense account', 'Loan', 'Debt', 'Mortgage'],
|
||||
default_allowed_types: ['Asset account', 'Expense account', 'Loan', 'Debt', 'Mortgage']
|
||||
}
|
||||
});
|
||||
if (this.transactions.length === 1) {
|
||||
// console.log('Length == 1, set date to today.');
|
||||
// set first date.
|
||||
let today = new Date();
|
||||
this.transactions[0].date = today.getFullYear() + '-' + ("0" + (today.getMonth() + 1)).slice(-2) + '-' + ("0" + today.getDate()).slice(-2)
|
||||
+ 'T'+ ("0" + today.getHours()).slice(-2) +':' + ("0" + today.getMinutes()).slice(-2);
|
||||
//console.log(this.transactions[0].date);
|
||||
|
||||
// call for extra clear thing:
|
||||
// this.clearSource(0);
|
||||
//this.clearDestination(0);
|
||||
}
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
setTransactionType: function (type) {
|
||||
this.transactionType = type;
|
||||
},
|
||||
|
||||
deleteTransaction: function (index, event) {
|
||||
event.preventDefault();
|
||||
// console.log('Remove transaction.');
|
||||
this.transactions.splice(index, 1);
|
||||
},
|
||||
limitSourceType: function (type) {
|
||||
let i;
|
||||
for (i = 0; i < this.transactions.length; i++) {
|
||||
this.transactions[i].source_account.allowed_types = [type];
|
||||
}
|
||||
},
|
||||
limitDestinationType: function (type) {
|
||||
let i;
|
||||
for (i = 0; i < this.transactions.length; i++) {
|
||||
this.transactions[i].destination_account.allowed_types = [type];
|
||||
}
|
||||
},
|
||||
|
||||
selectedSourceAccount: function (index, model) {
|
||||
// console.log('Now in selectedSourceAccount()');
|
||||
if (typeof model === 'string') {
|
||||
//console.log('model is string.')
|
||||
// cant change types, only name.
|
||||
this.transactions[index].source_account.name = model;
|
||||
} else {
|
||||
//console.log('model is NOT string.')
|
||||
this.transactions[index].source_account = {
|
||||
id: model.id,
|
||||
name: model.name,
|
||||
type: model.type,
|
||||
currency_id: model.currency_id,
|
||||
currency_name: model.currency_name,
|
||||
currency_code: model.currency_code,
|
||||
currency_decimal_places: model.currency_decimal_places,
|
||||
allowed_types: this.transactions[index].source_account.allowed_types,
|
||||
default_allowed_types: ['Asset account', 'Revenue account', 'Loan', 'Debt', 'Mortgage']
|
||||
};
|
||||
if(model.hasOwnProperty('account_currency_id') && null !== model.account_currency_id) {
|
||||
this.transactions[index].source_account.currency_id = model.account_currency_id;
|
||||
this.transactions[index].source_account.currency_name = model.account_currency_name;
|
||||
this.transactions[index].source_account.currency_code = model.account_currency_code;
|
||||
this.transactions[index].source_account.currency_decimal_places = model.account_currency_decimal_places;
|
||||
}
|
||||
|
||||
// force types on destination selector.
|
||||
this.transactions[index].destination_account.allowed_types = window.allowedOpposingTypes.source[model.type];
|
||||
}
|
||||
//console.log('Transactions:');
|
||||
//console.log(this.transactions);
|
||||
},
|
||||
selectedDestinationAccount: function (index, model) {
|
||||
// console.log('Now in selectedDestinationAccount()');
|
||||
if (typeof model === 'string') {
|
||||
// cant change types, only name.
|
||||
this.transactions[index].destination_account.name = model;
|
||||
} else {
|
||||
this.transactions[index].destination_account = {
|
||||
id: model.id,
|
||||
name: model.name,
|
||||
type: model.type,
|
||||
currency_id: model.currency_id,
|
||||
currency_name: model.currency_name,
|
||||
currency_code: model.currency_code,
|
||||
currency_decimal_places: model.currency_decimal_places,
|
||||
allowed_types: this.transactions[index].destination_account.allowed_types,
|
||||
default_allowed_types: ['Asset account', 'Expense account', 'Loan', 'Debt', 'Mortgage']
|
||||
};
|
||||
if(model.hasOwnProperty('account_currency_id') && null !== model.account_currency_id) {
|
||||
this.transactions[index].destination_account.currency_id = model.account_currency_id;
|
||||
this.transactions[index].destination_account.currency_name = model.account_currency_name;
|
||||
this.transactions[index].destination_account.currency_code = model.account_currency_code;
|
||||
this.transactions[index].destination_account.currency_decimal_places = model.account_currency_decimal_places;
|
||||
}
|
||||
|
||||
// force types on destination selector.
|
||||
this.transactions[index].source_account.allowed_types = window.allowedOpposingTypes.destination[model.type];
|
||||
}
|
||||
},
|
||||
clearSource: function (index) {
|
||||
// console.log('clearSource(' + index + ')');
|
||||
// reset source account:
|
||||
this.transactions[index].source_account = {
|
||||
id: 0,
|
||||
name: '',
|
||||
type: '',
|
||||
currency_id: 0,
|
||||
currency_name: '',
|
||||
currency_code: '',
|
||||
currency_decimal_places: 2,
|
||||
allowed_types: this.transactions[index].source_account.allowed_types,
|
||||
default_allowed_types: ['Asset account', 'Revenue account', 'Loan', 'Debt', 'Mortgage']
|
||||
};
|
||||
// reset destination allowed account types.
|
||||
this.transactions[index].destination_account.allowed_types = [];
|
||||
|
||||
// if there is a destination model, reset the types of the source
|
||||
// by pretending we selected it again.
|
||||
if (this.transactions[index].destination_account) {
|
||||
this.selectedDestinationAccount(index, this.transactions[index].destination_account);
|
||||
}
|
||||
},
|
||||
clearDestination: function (index) {
|
||||
// console.log('clearDestination(' + index + ')');
|
||||
// reset destination account:
|
||||
this.transactions[index].destination_account = {
|
||||
id: 0,
|
||||
name: '',
|
||||
type: '',
|
||||
currency_id: 0,
|
||||
currency_name: '',
|
||||
currency_code: '',
|
||||
currency_decimal_places: 2,
|
||||
allowed_types: this.transactions[index].destination_account.allowed_types,
|
||||
default_allowed_types: ['Asset account', 'Expense account', 'Loan', 'Debt', 'Mortgage']
|
||||
};
|
||||
// reset destination allowed account types.
|
||||
this.transactions[index].source_account.allowed_types = [];
|
||||
|
||||
// if there is a source model, reset the types of the destination
|
||||
// by pretending we selected it again.
|
||||
if (this.transactions[index].source_account) {
|
||||
this.selectedSourceAccount(index, this.transactions[index].source_account);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* The component's data.
|
||||
*/
|
||||
data() {
|
||||
return {
|
||||
transactionType: null,
|
||||
group_title: "",
|
||||
transactions: [],
|
||||
group_title_errors: [],
|
||||
error_message: "",
|
||||
success_message: "",
|
||||
cash_account_id: 0,
|
||||
createAnother: false,
|
||||
resetFormAfter: false,
|
||||
fireWebhooks: true,
|
||||
applyRules: true,
|
||||
resetButtonDisabled: true,
|
||||
attachmentCount: 0,
|
||||
};
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -49,10 +49,7 @@ import {addSplit} from "./shared/add-split.js";
|
||||
import {clearSourceAccount, clearDestinationAccount} from './shared/clear-fields.js';
|
||||
import {detectTransactionType} from './shared/detect-transaction-type.js';
|
||||
import {determineAmountCurrency} from './shared/determine-amount-currency.js';
|
||||
// TODO fix tags
|
||||
// TODO upload attachments to other file
|
||||
// TODO fix two maps, perhaps disconnect from entries entirely.
|
||||
// TODO group title
|
||||
// TODO map location from preferences
|
||||
// TODO field preferences
|
||||
|
||||
@@ -213,6 +210,8 @@ let create = function () {
|
||||
this.i18next = i18next;
|
||||
this.addSplit();
|
||||
|
||||
// load custom field preference and enable/disable those fields.
|
||||
|
||||
// load currencies and save in form data.
|
||||
loadCurrencies().then(data => {
|
||||
this.formStates.loadingCurrencies = false;
|
||||
@@ -230,7 +229,7 @@ let create = function () {
|
||||
this.formData.piggyBanks = data;
|
||||
this.formStates.loadingPiggyBanks = false;
|
||||
});
|
||||
loadSubscriptions().then(data => {
|
||||
loadSubscriptions(false).then(data => {
|
||||
this.formData.subscriptions = data;
|
||||
this.formStates.loadingSubscriptions = false;
|
||||
});
|
||||
@@ -293,7 +292,6 @@ let create = function () {
|
||||
};
|
||||
|
||||
// catch for group title:
|
||||
// TODO later this must be handled with more care (ie use the group title input)
|
||||
if (transactions.length > 1 && ('' === submission.group_title || null === submission.group_title)) {
|
||||
submission.group_title = transactions[0].description;
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ let transactions = function () {
|
||||
this.formData.piggyBanks = data;
|
||||
this.formStates.loadingPiggyBanks = false;
|
||||
});
|
||||
loadSubscriptions().then(data => {
|
||||
loadSubscriptions(true).then(data => {
|
||||
this.formData.subscriptions = data;
|
||||
this.formStates.loadingSubscriptions = false;
|
||||
});
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
*/
|
||||
|
||||
import SubscriptionGet from "../../../api/model/subscription/get.js";
|
||||
import i18next from "i18next";
|
||||
|
||||
export function loadSubscriptions() {
|
||||
export function loadSubscriptions(includeInactive) {
|
||||
let params = {
|
||||
page: 1, limit: 1337
|
||||
};
|
||||
@@ -38,9 +39,15 @@ export function loadSubscriptions() {
|
||||
let current = response.data.data[i];
|
||||
let objectGroupId = current.attributes.object_group_id ?? '0';
|
||||
let objectGroupTitle = current.attributes.object_group_title ?? '(no group)';
|
||||
let piggyBank = {
|
||||
id: current.id, name: current.attributes.name, order: current.attributes.order,
|
||||
let subscription = {
|
||||
id: current.id,
|
||||
name: current.attributes.active ? current.attributes.name : current.attributes.name + ' ('+i18next.t('firefly.inactive').toLowerCase()+')',
|
||||
order: current.attributes.order,
|
||||
};
|
||||
if(!includeInactive && false === current.attributes.active) {
|
||||
// skip over inactive items.
|
||||
continue;
|
||||
}
|
||||
if (!subscriptions.hasOwnProperty(objectGroupId)) {
|
||||
subscriptions[objectGroupId] = {
|
||||
id: objectGroupId,
|
||||
@@ -49,7 +56,7 @@ export function loadSubscriptions() {
|
||||
subscriptions: []
|
||||
};
|
||||
}
|
||||
subscriptions[objectGroupId].subscriptions.push(piggyBank);
|
||||
subscriptions[objectGroupId].subscriptions.push(subscription);
|
||||
subscriptions[objectGroupId].subscriptions.sort((a, b) => a.order - b.order);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ export function parseErrors(data) {
|
||||
this.notifications.success.show = false;
|
||||
this.notifications.wait.show = false;
|
||||
this.formStates.isSubmitting = false;
|
||||
this.notifications.error.text = i18next.t('firefly.errors_submission_v2', {errorMessage: data.message});
|
||||
this.notifications.error.text = this.i18next.t('firefly.errors_submission_v2', {errorMessage: data.message});
|
||||
|
||||
if (data.hasOwnProperty('errors')) {
|
||||
this.entries = spliceErrorsIntoTransactions(data.errors, this.entries);
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import i18next from "i18next";
|
||||
import Delete from "../../../api/model/transaction/delete.js";
|
||||
|
||||
export function processUploadError(event){
|
||||
@@ -26,10 +25,10 @@ export function processUploadError(event){
|
||||
this.notifications.wait.show = false;
|
||||
this.notifications.error.show = true;
|
||||
this.formStates.isSubmitting = false;
|
||||
this.notifications.error.text = i18next.t('firefly.errors_upload');
|
||||
this.notifications.error.text = this.i18next.t('firefly.errors_upload');
|
||||
console.log(event.detail.error.response.status);
|
||||
if(413 === event.detail.error.response.status) {
|
||||
this.notifications.error.text = i18next.t('firefly.upload_too_large');
|
||||
this.notifications.error.text = this.i18next.t('firefly.upload_too_large');
|
||||
}
|
||||
if('create' === this.formBehaviour.formType) {
|
||||
// delete transaction and let user try again.
|
||||
|
||||
@@ -2599,6 +2599,7 @@ return [
|
||||
'config_features' => 'Enabled features',
|
||||
'config_tech' => 'Tech related features',
|
||||
'config_external_connections' => 'Privacy-sensitive settings (connects to the internet)',
|
||||
'no_external_map_disabled' => 'This option is disabled because Firefly III is not allowed to download external maps.',
|
||||
|
||||
'setting_enable_exchange_rates' => 'Enable exchange rates',
|
||||
'setting_enable_exchange_rates_explain' => 'Firefly III has the capability of calculating exchange rates for you.',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div :class="{'tab-pane fade pt-2':true, 'show active': index ===0}" :id="'split-'+index+'-pane'" role="tabpanel" :aria-labelledby="'split-'+index+'-tab'" tabindex="0" x-init="addedSplit()">
|
||||
<div :class="{'tab-pane fade pt-2':true, 'show active': index ===0 }" :id="'split-'+index+'-pane'" role="tabpanel" :aria-labelledby="'split-'+index+'-tab'" tabindex="0" x-init="addedSplit()">
|
||||
<div class="row mb-2">
|
||||
<div class="col-xl-6 col-lg-6 col-md-12 col-xs-12 mb-2">
|
||||
<!-- BASIC TRANSACTION INFORMATION -->
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="row mb-3" id="{{ $name }}_holder">
|
||||
<div class="col-sm-9 offset-sm-3">
|
||||
<div class="form-check has-validation">
|
||||
{{ Html::checkbox($name, $options['checked'], $value)->class($inputClasses)->id($options['id']) }}
|
||||
{{ Html::checkbox($name, $options['checked'], $value)->disabled($options['disabled'] ?? false)->class($inputClasses)->id($options['id']) }}
|
||||
<label class="form-check-label" for="{{ $options['id'] }}">
|
||||
{{ $label }}
|
||||
</label>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
data-latitude="{{ $latitude ?? '' }}"
|
||||
data-longitude="{{ $longitude ?? '' }}"
|
||||
data-zoom-level="{{ $zoomLevel ?? '' }}"
|
||||
id="location_map" class="map-size" :data-index="index"></div>
|
||||
:id="'location_map_' + index" class="map-size" :data-index="index"></div>
|
||||
<span class="muted small">
|
||||
<template x-if="!transaction.hasLocation">
|
||||
<span>{{ __('firefly.click_tap_location') }}</span>
|
||||
|
||||
@@ -124,8 +124,8 @@
|
||||
@php
|
||||
$isCustomFiscalYear = $customFiscalYear === 1;
|
||||
@endphp
|
||||
{!! ExpandedForm::checkbox('customFiscalYear','1',1 === $customFiscalYear,['label' => 'pref_custom_fiscal_year_label' ]) !!}
|
||||
{!! ExpandedForm::date('fiscalYearStart',1 === $customFiscalYear,['label' => 'pref_fiscal_year_start_label' ]) !!}
|
||||
{!! ExpandedForm::checkbox('customFiscalYear','1',1 === $customFiscalYear,['label' => __('firefly.pref_custom_fiscal_year_label') ]) !!}
|
||||
{!! ExpandedForm::date('fiscalYearStart',1 === $customFiscalYear,['label' => __('firefly.pref_fiscal_year_start_label') ]) !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
<p>
|
||||
{{ __('firefly.pref_convert_to_primary_help') }}
|
||||
</p>
|
||||
{!! ExpandedForm::checkbox('convertToPrimary','1', $convertToPrimary,['label' => 'pref_convert_primary_help']) !!}
|
||||
{!! ExpandedForm::checkbox('convertToPrimary','1', $convertToPrimary,['label' => __('firefly.pref_convert_primary_help')]) !!}
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@@ -170,22 +170,26 @@
|
||||
{{ __('firefly.pref_optional_fields_transaction_help') }}
|
||||
</p>
|
||||
<h4>{{ __('firefly.optional_tj_date_fields') }}</h4>
|
||||
{!! ExpandedForm::checkbox('tj[interest_date]','1', $tjOptionalFields['interest_date'],['label' => 'pref_optional_tj_interest_date']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[book_date]','1', $tjOptionalFields['book_date'],['label' => 'pref_optional_tj_book_date']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[process_date]','1', $tjOptionalFields['process_date'],['label' => 'pref_optional_tj_process_date']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[due_date]','1', $tjOptionalFields['due_date'],['label' => 'pref_optional_tj_due_date']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[payment_date]','1', $tjOptionalFields['payment_date'],['label' => 'pref_optional_tj_payment_date']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[invoice_date]','1', $tjOptionalFields['invoice_date'],['label' => 'pref_optional_tj_invoice_date']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[interest_date]','1', $tjOptionalFields['interest_date'],['label' => __('firefly.pref_optional_tj_interest_date')]) !!}
|
||||
{!! ExpandedForm::checkbox('tj[book_date]','1', $tjOptionalFields['book_date'],['label' => __('firefly.pref_optional_tj_book_date')]) !!}
|
||||
{!! ExpandedForm::checkbox('tj[process_date]','1', $tjOptionalFields['process_date'],['label' => __('firefly.pref_optional_tj_process_date')]) !!}
|
||||
{!! ExpandedForm::checkbox('tj[due_date]','1', $tjOptionalFields['due_date'],['label' => __('firefly.pref_optional_tj_due_date')]) !!}
|
||||
{!! ExpandedForm::checkbox('tj[payment_date]','1', $tjOptionalFields['payment_date'],['label' => __('firefly.pref_optional_tj_payment_date')]) !!}
|
||||
{!! ExpandedForm::checkbox('tj[invoice_date]','1', $tjOptionalFields['invoice_date'],['label' => __('firefly.pref_optional_tj_invoice_date')]) !!}
|
||||
|
||||
<h4>{{ __('firefly.optional_tj_other_fields') }}</h4>
|
||||
{!! ExpandedForm::checkbox('tj[internal_reference]','1', $tjOptionalFields['internal_reference'],['label' => 'pref_optional_tj_internal_reference']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[external_url]','1', $tjOptionalFields['external_url'],['label' => 'pref_optional_tj_external_url']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[notes]','1', $tjOptionalFields['notes'],['label' => 'pref_optional_tj_notes']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[location]','1', $tjOptionalFields['location'],['label' => 'pref_optional_tj_location']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[links]','1', $tjOptionalFields['links'],['label' => 'pref_optional_tj_links']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[internal_reference]','1', $tjOptionalFields['internal_reference'],['label' => __('firefly.pref_optional_tj_internal_reference')]) !!}
|
||||
{!! ExpandedForm::checkbox('tj[external_url]','1', $tjOptionalFields['external_url'],['label' => __('firefly.pref_optional_tj_external_url')]) !!}
|
||||
{!! ExpandedForm::checkbox('tj[notes]','1', $tjOptionalFields['notes'],['label' => __('firefly.pref_optional_tj_notes')]) !!}
|
||||
@if($mapEnabled)
|
||||
{!! ExpandedForm::checkbox('tj[location]','1', $tjOptionalFields['location'],['label' => __('firefly.pref_optional_tj_location')]) !!}
|
||||
@else
|
||||
{!! ExpandedForm::checkbox('__DISABLED__','1', false, ['disabled' => true, 'helpText'=> __('firefly.no_external_map_disabled'),'label' => __('firefly.pref_optional_tj_location')]) !!}
|
||||
@endif
|
||||
{!! ExpandedForm::checkbox('tj[links]','1', $tjOptionalFields['links'],['label' => __('firefly.pref_optional_tj_links')]) !!}
|
||||
|
||||
<h4>{{ __('firefly.optional_tj_attachment_fields') }}</h4>
|
||||
{!! ExpandedForm::checkbox('tj[attachments]','1', $tjOptionalFields['attachments'], ['label' => 'pref_optional_tj_attachments']) !!}
|
||||
{!! ExpandedForm::checkbox('tj[attachments]','1', $tjOptionalFields['attachments'], ['label' => __('firefly.pref_optional_tj_attachments')]) !!}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user