mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-12-12 18:02:34 +00:00
Remove frontend source from repository.
This commit is contained in:
@@ -1,53 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
#
|
|
||||||
# build.sh
|
|
||||||
# Copyright (c) 2021 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/>.
|
|
||||||
#
|
|
||||||
|
|
||||||
[ -d "~/Sites" ] && exit 1;
|
|
||||||
|
|
||||||
# build translations.
|
|
||||||
php /sites/FF3/dev/tools/cli.php ff3:json-translations v2
|
|
||||||
|
|
||||||
# remove old stuff
|
|
||||||
rm -rf public/
|
|
||||||
rm -rf ../public/fonts
|
|
||||||
rm -rf ../public/images
|
|
||||||
rm -rf ../public/v2/js
|
|
||||||
rm -rf ../public/v2/css
|
|
||||||
mkdir -p public/js
|
|
||||||
mkdir -p public/css
|
|
||||||
|
|
||||||
# build new stuff
|
|
||||||
yarn install
|
|
||||||
yarn audit fix
|
|
||||||
yarn upgrade
|
|
||||||
yarn prod
|
|
||||||
|
|
||||||
# yarn watch
|
|
||||||
|
|
||||||
# move to right directory
|
|
||||||
# mv public/js ../public/v2
|
|
||||||
# mv public/css ../public/v2
|
|
||||||
|
|
||||||
# also copy fonts
|
|
||||||
#cp -r fonts ../public/v2/css
|
|
||||||
|
|
||||||
# remove built stuff
|
|
||||||
rm -rf public/
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"/public/js/dashboard.js": "/public/js/dashboard.js",
|
|
||||||
"/public/js/accounts/index.js": "/public/js/accounts/index.js",
|
|
||||||
"/public/js/accounts/delete.js": "/public/js/accounts/delete.js",
|
|
||||||
"/public/js/accounts/show.js": "/public/js/accounts/show.js",
|
|
||||||
"/public/js/accounts/create.js": "/public/js/accounts/create.js",
|
|
||||||
"/public/js/accounts/edit.js": "/public/js/accounts/edit.js",
|
|
||||||
"/public/js/bills/index.js": "/public/js/bills/index.js",
|
|
||||||
"/public/js/bills/create.js": "/public/js/bills/create.js",
|
|
||||||
"/public/js/budgets/index.js": "/public/js/budgets/index.js",
|
|
||||||
"/public/js/transactions/create.js": "/public/js/transactions/create.js",
|
|
||||||
"/public/js/transactions/edit.js": "/public/js/transactions/edit.js",
|
|
||||||
"/public/js/transactions/index.js": "/public/js/transactions/index.js",
|
|
||||||
"/public/js/empty.js": "/public/js/empty.js",
|
|
||||||
"/public/js/register.js": "/public/js/register.js",
|
|
||||||
"/public/js/manifest.js": "/public/js/manifest.js",
|
|
||||||
"/public/css/app.css": "/public/css/app.css",
|
|
||||||
"/public/js/vendor.js": "/public/js/vendor.js",
|
|
||||||
"/public/v2/js/dashboard.js": "/public/v2/js/dashboard.js",
|
|
||||||
"/public/v2/js/dashboard.js.map": "/public/v2/js/dashboard.js.map",
|
|
||||||
"/public/v2/js/empty.js": "/public/v2/js/empty.js",
|
|
||||||
"/public/v2/js/empty.js.map": "/public/v2/js/empty.js.map",
|
|
||||||
"/public/v2/js/manifest.js": "/public/v2/js/manifest.js",
|
|
||||||
"/public/v2/js/manifest.js.map": "/public/v2/js/manifest.js.map",
|
|
||||||
"/public/v2/js/register.js": "/public/v2/js/register.js",
|
|
||||||
"/public/v2/js/register.js.map": "/public/v2/js/register.js.map",
|
|
||||||
"/public/v2/js/vendor.js": "/public/v2/js/vendor.js",
|
|
||||||
"/public/v2/js/vendor.js.LICENSE.txt": "/public/v2/js/vendor.js.LICENSE.txt",
|
|
||||||
"/public/v2/js/vendor.js.map": "/public/v2/js/vendor.js.map",
|
|
||||||
"/public/v2/css/app.css": "/public/v2/css/app.css",
|
|
||||||
"/public/v2/css/app.css.map": "/public/v2/css/app.css.map"
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
{
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"dev": "npm run development",
|
|
||||||
"development": "mix",
|
|
||||||
"watch": "mix watch",
|
|
||||||
"watch-poll": "mix watch -- --watch-options-poll=1000",
|
|
||||||
"hot": "mix watch --hot",
|
|
||||||
"prod": "npm run production",
|
|
||||||
"production": "mix --production"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"axios": "^0.21",
|
|
||||||
"date-fns": "^2.27.0",
|
|
||||||
"laravel-mix": "^6",
|
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"lodash.clonedeep": "^4.5.0",
|
|
||||||
"postcss": "^8.4.5",
|
|
||||||
"resolve-url-loader": "^4.0.0",
|
|
||||||
"sass": "^1.49.0",
|
|
||||||
"sass-loader": "^12.2.0",
|
|
||||||
"vue-i18n": "^8.27.0",
|
|
||||||
"vue-loader": "^15",
|
|
||||||
"vue-template-compiler": "^2.6.12",
|
|
||||||
"vuex": "^3.6.2",
|
|
||||||
"webpack": "^5.67.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@fortawesome/fontawesome-free": "^5.15.3",
|
|
||||||
"@johmun/vue-tags-input": "^2.1.0",
|
|
||||||
"admin-lte": "^3.1.0",
|
|
||||||
"axios-cache-adapter": "^2.7.3",
|
|
||||||
"bootstrap": "^4.6.0",
|
|
||||||
"bootstrap-vue": "^2.21.2",
|
|
||||||
"chart.js": "^3.7.0",
|
|
||||||
"icheck-bootstrap": "^3.0.1",
|
|
||||||
"jquery-ui": "^1.13.1",
|
|
||||||
"leaflet": "^1.7.1",
|
|
||||||
"localforage": "^1.9.0",
|
|
||||||
"localforage-memoryStorageDriver": "^0.9.2",
|
|
||||||
"overlayscrollbars": "^1.13.1",
|
|
||||||
"sortablejs": "^1.14.0",
|
|
||||||
"uiv": "^1.4.1",
|
|
||||||
"v-calendar": "^2.3.2",
|
|
||||||
"vue-typeahead-bootstrap": "^2.8.0",
|
|
||||||
"vue2-leaflet": "^2.7.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
#
|
|
||||||
# render.sh
|
|
||||||
# Copyright (c) 2021 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/>.
|
|
||||||
#
|
|
||||||
|
|
||||||
[ -d "~/Sites" ] && exit 1;
|
|
||||||
|
|
||||||
# build translations.
|
|
||||||
php /sites/FF3/dev/tools/cli.php ff3:json-translations v2
|
|
||||||
90
frontend/src/app.scss
vendored
90
frontend/src/app.scss
vendored
@@ -1,90 +0,0 @@
|
|||||||
/*!
|
|
||||||
* app.scss
|
|
||||||
* Copyright (c) 2021 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/>.
|
|
||||||
*/
|
|
||||||
$blue: #1E6581;
|
|
||||||
$green: #64B624;
|
|
||||||
$red: #CD5029;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Fonts
|
|
||||||
@import '~@fortawesome/fontawesome-free/css/all.css';
|
|
||||||
// OverlayScrollbars
|
|
||||||
@import '~overlayscrollbars/css/OverlayScrollbars.css';
|
|
||||||
// iCheck
|
|
||||||
@import '~icheck-bootstrap/icheck-bootstrap.css';
|
|
||||||
// AdminLTE
|
|
||||||
//@import 'dist/css/adminlte.css';
|
|
||||||
|
|
||||||
//@import 'adminlte/scss/adminlte.css'
|
|
||||||
|
|
||||||
//@import '~admin-lte/build/scss/AdminLTE';
|
|
||||||
|
|
||||||
// ADMIN LTE
|
|
||||||
@import '~bootstrap/scss/functions';
|
|
||||||
@import '~admin-lte/build/scss/bootstrap-variables';
|
|
||||||
@import '~bootstrap/scss/bootstrap';
|
|
||||||
|
|
||||||
@import '~bootstrap-vue/src/index';
|
|
||||||
|
|
||||||
// Variables and Mixins
|
|
||||||
// ---------------------------------------------------
|
|
||||||
@import '~admin-lte/build/scss/variables';
|
|
||||||
@import '~admin-lte/build/scss/variables-alt';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@import '~admin-lte/build/scss/mixins';
|
|
||||||
@import '~admin-lte/build/scss/parts/core';
|
|
||||||
|
|
||||||
// admin LTE components
|
|
||||||
@import '~admin-lte/build/scss/forms';
|
|
||||||
@import '~admin-lte/build/scss/progress-bars';
|
|
||||||
@import '~admin-lte/build/scss/cards';
|
|
||||||
@import '~admin-lte/build/scss/modals';
|
|
||||||
//@import '../toasts';
|
|
||||||
@import '~admin-lte/build/scss/buttons';
|
|
||||||
@import '~admin-lte/build/scss/callout';
|
|
||||||
@import '~admin-lte/build/scss/alerts';
|
|
||||||
@import '~admin-lte/build/scss/table';
|
|
||||||
//@import '../carousel';
|
|
||||||
|
|
||||||
// admin LTE extra components
|
|
||||||
//@import '../small-box';
|
|
||||||
@import '~admin-lte/build/scss/info-box';
|
|
||||||
//@import '../timeline';
|
|
||||||
//@import '../products';
|
|
||||||
//@import '../direct-chat';
|
|
||||||
//@import '../users-list';
|
|
||||||
//@import '../social-widgets';
|
|
||||||
|
|
||||||
// admin LTE pages (unused)
|
|
||||||
@import '~admin-lte/build/scss/parts/pages';
|
|
||||||
|
|
||||||
// admin LTE plugins (unused)
|
|
||||||
// @import 'parts/plugins';
|
|
||||||
|
|
||||||
// admin LTE misc
|
|
||||||
@import '~admin-lte/build/scss/miscellaneous';
|
|
||||||
@import '~admin-lte/build/scss/print';
|
|
||||||
@import '~admin-lte/build/scss/text';
|
|
||||||
@import '~admin-lte/build/scss/elevation';
|
|
||||||
@import '~admin-lte/build/scss/colors';
|
|
||||||
|
|
||||||
|
|
||||||
26
frontend/src/bootstrap-basic.js
vendored
26
frontend/src/bootstrap-basic.js
vendored
@@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
/*
|
|
||||||
* bootstrap-basic.js
|
|
||||||
* Copyright (c) 2020 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 jquery for others scripts to use
|
|
||||||
window.$ = window.jQuery = require('jquery');
|
|
||||||
|
|
||||||
// admin stuff
|
|
||||||
require('bootstrap');
|
|
||||||
64
frontend/src/bootstrap.js
vendored
64
frontend/src/bootstrap.js
vendored
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* bootstrap.js
|
|
||||||
* Copyright (c) 2021 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// // imports
|
|
||||||
import Vue from 'vue';
|
|
||||||
import VueI18n from 'vue-i18n'
|
|
||||||
import * as uiv from 'uiv';
|
|
||||||
|
|
||||||
// export jquery for others scripts to use
|
|
||||||
window.$ = window.jQuery = require('jquery');
|
|
||||||
|
|
||||||
// axios
|
|
||||||
window.axios = require('axios');
|
|
||||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
|
||||||
|
|
||||||
// CSRF
|
|
||||||
let token = document.head.querySelector('meta[name="csrf-token"]');
|
|
||||||
|
|
||||||
if (token) {
|
|
||||||
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
|
|
||||||
} else {
|
|
||||||
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
|
|
||||||
}
|
|
||||||
|
|
||||||
// locale
|
|
||||||
let localeToken = document.head.querySelector('meta[name="locale"]');
|
|
||||||
|
|
||||||
if (localeToken) {
|
|
||||||
localStorage.locale = localeToken.content;
|
|
||||||
} else {
|
|
||||||
localStorage.locale = 'en_US';
|
|
||||||
}
|
|
||||||
|
|
||||||
// admin stuff
|
|
||||||
require('jquery-ui');
|
|
||||||
require('bootstrap'); // bootstrap CSS?
|
|
||||||
|
|
||||||
require('admin-lte/dist/js/adminlte');
|
|
||||||
require('overlayscrollbars');
|
|
||||||
|
|
||||||
|
|
||||||
// vue
|
|
||||||
window.vuei18n = VueI18n;
|
|
||||||
window.uiv = uiv;
|
|
||||||
Vue.use(vuei18n);
|
|
||||||
Vue.use(uiv);
|
|
||||||
window.Vue = Vue;
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
<!--
|
|
||||||
- AssetAccountRole.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('form.account_role') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="loading">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="!loading">
|
|
||||||
<select
|
|
||||||
ref="account_role"
|
|
||||||
v-model="account_role"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:title="$t('form.account_role')"
|
|
||||||
autocomplete="off"
|
|
||||||
name="account_role"
|
|
||||||
:disabled=disabled
|
|
||||||
>
|
|
||||||
<option v-for="role in this.roleList" :label="role.title" :value="role.slug">{{ role.title }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "AssetAccountRole",
|
|
||||||
props: {
|
|
||||||
value: {},
|
|
||||||
errors: {},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
roleList: [],
|
|
||||||
account_role: this.value,
|
|
||||||
loading: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadRoles: function () {
|
|
||||||
//
|
|
||||||
axios.get('./api/v1/configuration/firefly.accountRoles')
|
|
||||||
.then(response => {
|
|
||||||
let content = response.data.data.value;
|
|
||||||
for (let i in content) {
|
|
||||||
if (content.hasOwnProperty(i)) {
|
|
||||||
let current = content[i];
|
|
||||||
this.roleList.push({slug: current, title: this.$t('firefly.account_role_' + current)})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
account_role: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'account_role', value: value});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.loadRoles()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,397 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Create.vue
|
|
||||||
- Copyright (c) 2021 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>
|
|
||||||
<Alert :message="errorMessage" type="danger"/>
|
|
||||||
<Alert :message="successMessage" type="success"/>
|
|
||||||
<form @submit="submitForm" autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div class="card card-primary">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
{{ $t('firefly.mandatoryFields') }}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<GenericTextInput :disabled="submitting" v-model="name" field-name="name" :errors="errors.name" :title="$t('form.name')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericCurrency :disabled="submitting" v-model="currency_id" :errors="errors.currency_id" v-on:set-field="storeField($event)"/>
|
|
||||||
<AssetAccountRole :disabled="submitting" v-if="'asset' === type" v-model="account_role" :errors="errors.account_role"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<!-- some CC fields -->
|
|
||||||
<CreditCardType :disabled="submitting" v-if="'ccAsset' === account_role" v-model="credit_card_type" :errors="errors.credit_card_type"
|
|
||||||
v-on:set-field="storeField($event)" />
|
|
||||||
<GenericTextInput :disabled="submitting" v-if="'ccAsset' === account_role" field-type="date" v-model="monthly_payment_date" field-name="monthly_payment_date"
|
|
||||||
:errors="errors.monthly_payment_date" :title="$t('form.cc_monthly_payment_date')" v-on:set-field="storeField($event)" />
|
|
||||||
|
|
||||||
<!-- liability fields -->
|
|
||||||
<LiabilityType :disabled="submitting" v-if="'liabilities' === type" v-model="liability_type" :errors="errors.liability_type"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<LiabilityDirection :disabled="submitting" v-if="'liabilities' === type" v-model="liability_direction" :errors="errors.liability_direction"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericTextInput :disabled="submitting" v-if="'liabilities' === type" field-type="number" field-step="any" v-model="liability_amount"
|
|
||||||
field-name="liability_amount" :errors="errors.liability_amount" :title="$t('form.amount')" v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericTextInput :disabled="submitting" v-if="'liabilities' === type" field-type="date" v-model="liability_date" field-name="liability_date"
|
|
||||||
:errors="errors.liability_date" :title="$t('form.date')" v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<Interest :disabled="submitting" v-if="'liabilities' === type" v-model="interest" :errors="errors.interest" v-on:set-field="storeField($event)"/>
|
|
||||||
<InterestPeriod :disabled="submitting" v-if="'liabilities' === type" v-model="interest_period" :errors="errors.interest_period"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
{{ $t('firefly.optionalFields') }}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<GenericTextInput :disabled="submitting" v-model="iban" field-name="iban" :errors="errors.iban" :title="$t('form.iban')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextInput :disabled="submitting" v-model="bic" field-name="bic" :errors="errors.bic" :title="$t('form.BIC')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextInput :disabled="submitting" v-model="account_number" field-name="account_number" :errors="errors.account_number"
|
|
||||||
:title="$t('form.account_number')" v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericTextInput :disabled="submitting" v-if="'asset' === type" field-type="amount" v-model="virtual_balance" field-name="virtual_balance"
|
|
||||||
:errors="errors.virtual_balance" :title="$t('form.virtual_balance')" v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextInput :disabled="submitting" v-if="'asset' === type" field-type="amount" v-model="opening_balance" field-name="opening_balance"
|
|
||||||
:errors="errors.opening_balance" :title="$t('form.opening_balance')" v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextInput :disabled="submitting" v-if="'asset' === type" field-type="date" v-model="opening_balance_date"
|
|
||||||
field-name="opening_balance_date" :errors="errors.opening_balance_date" :title="$t('form.opening_balance_date')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericCheckbox :disabled="submitting" v-if="'asset' === type" :title="$t('form.include_net_worth')" field-name="include_net_worth"
|
|
||||||
v-model="include_net_worth" :errors="errors.include_net_worth" :description="$t('form.include_net_worth')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericCheckbox :disabled="submitting" :title="$t('form.active')" field-name="active"
|
|
||||||
v-model="active" :errors="errors.active" :description="$t('form.active')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextarea :disabled="submitting" field-name="notes" :title="$t('form.notes')" v-model="notes" :errors="errors.notes"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericLocation :disabled="submitting" v-model="location" :title="$t('form.location')" :errors="errors.location"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<!-- attachments -->
|
|
||||||
<GenericAttachments :disabled="submitting" :title="$t('form.attachments')" field-name="attachments" :errors="errors.attachments"
|
|
||||||
v-on:selected-attachments="selectedAttachments($event)"
|
|
||||||
v-on:selected-no-attachments="selectedNoAttachments($event)"
|
|
||||||
v-on:uploaded-attachments="uploadedAttachments($event)"
|
|
||||||
:upload-trigger="uploadTrigger"
|
|
||||||
:upload-object-type="uploadObjectType"
|
|
||||||
:upload-object-id="uploadObjectId"
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12 offset-xl-6 offset-lg-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-6 offset-lg-6">
|
|
||||||
<button :disabled=submitting type="button" @click="submitForm" class="btn btn-success btn-block">{{
|
|
||||||
$t('firefly.store_new_' + type + '_account')
|
|
||||||
}}
|
|
||||||
</button>
|
|
||||||
<div class="form-check">
|
|
||||||
<input id="createAnother" v-model="createAnother" class="form-check-input" type="checkbox">
|
|
||||||
<label class="form-check-label" for="createAnother">
|
|
||||||
<span class="small">{{ $t('firefly.create_another') }}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check">
|
|
||||||
<input id="resetFormAfter" v-model="resetFormAfter" :disabled="!createAnother" class="form-check-input" type="checkbox">
|
|
||||||
<label class="form-check-label" for="resetFormAfter">
|
|
||||||
<span class="small">{{ $t('firefly.reset_after') }}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import format from "date-fns/format";
|
|
||||||
|
|
||||||
const lodashClonedeep = require('lodash.clonedeep');
|
|
||||||
import GenericCurrency from "../form/GenericCurrency";
|
|
||||||
import AssetAccountRole from "./AssetAccountRole"
|
|
||||||
import LiabilityType from "./LiabilityType";
|
|
||||||
import CreditCardType from "./CreditCardType";
|
|
||||||
import LiabilityDirection from "./LiabilityDirection";
|
|
||||||
import Interest from "./Interest";
|
|
||||||
import InterestPeriod from "./InterestPeriod";
|
|
||||||
import GenericTextInput from "../form/GenericTextInput";
|
|
||||||
import GenericTextarea from "../form/GenericTextarea";
|
|
||||||
import GenericLocation from "../form/GenericLocation";
|
|
||||||
import GenericAttachments from "../form/GenericAttachments";
|
|
||||||
import GenericCheckbox from "../form/GenericCheckbox";
|
|
||||||
import Alert from '../partials/Alert';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Create",
|
|
||||||
components: {
|
|
||||||
GenericCurrency, AssetAccountRole, LiabilityType, LiabilityDirection, Interest, InterestPeriod,
|
|
||||||
GenericTextInput, GenericTextarea, GenericLocation, GenericAttachments, GenericCheckbox, Alert,
|
|
||||||
CreditCardType
|
|
||||||
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.errors = lodashClonedeep(this.defaultErrors);
|
|
||||||
let pathName = window.location.pathname;
|
|
||||||
let parts = pathName.split('/');
|
|
||||||
this.type = parts[parts.length - 1];
|
|
||||||
|
|
||||||
this.date = format(new Date, 'yyyy-MM-dd');
|
|
||||||
this.monthly_payment_date = format(new Date, 'yyyy-MM-dd');
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
submitting: false,
|
|
||||||
successMessage: '',
|
|
||||||
errorMessage: '',
|
|
||||||
createAnother: false,
|
|
||||||
resetFormAfter: false,
|
|
||||||
returnedId: 0,
|
|
||||||
returnedTitle: '',
|
|
||||||
|
|
||||||
// info
|
|
||||||
name: '',
|
|
||||||
type: 'any',
|
|
||||||
currency_id: null,
|
|
||||||
|
|
||||||
// liabilities
|
|
||||||
liability_type: 'Loan',
|
|
||||||
liability_direction: 'debit',
|
|
||||||
liability_amount: null,
|
|
||||||
liability_date: null,
|
|
||||||
interest: null,
|
|
||||||
interest_period: 'monthly',
|
|
||||||
|
|
||||||
|
|
||||||
// optional fields
|
|
||||||
iban: null,
|
|
||||||
bic: null,
|
|
||||||
account_number: null,
|
|
||||||
virtual_balance: null,
|
|
||||||
opening_balance: null,
|
|
||||||
opening_balance_date: null,
|
|
||||||
include_net_worth: true,
|
|
||||||
active: true,
|
|
||||||
notes: null,
|
|
||||||
location: {},
|
|
||||||
|
|
||||||
// credit card fields
|
|
||||||
monthly_payment_date: null,
|
|
||||||
credit_card_type: 'monthlyFull',
|
|
||||||
|
|
||||||
// has attachments to upload?
|
|
||||||
hasAttachments: false,
|
|
||||||
uploadTrigger: false,
|
|
||||||
uploadObjectId: 0,
|
|
||||||
uploadObjectType: 'Account',
|
|
||||||
|
|
||||||
|
|
||||||
account_role: 'defaultAsset',
|
|
||||||
errors: {
|
|
||||||
currency_id: [],
|
|
||||||
credit_card_type: [],
|
|
||||||
},
|
|
||||||
defaultErrors: {
|
|
||||||
name: [],
|
|
||||||
monthly_payment_date: [],
|
|
||||||
currency_id: [],
|
|
||||||
account_role: [],
|
|
||||||
liability_type: [],
|
|
||||||
liability_direction: [],
|
|
||||||
liability_amount: [],
|
|
||||||
credit_card_type: [],
|
|
||||||
liability_date: [],
|
|
||||||
interest: [],
|
|
||||||
interest_period: [],
|
|
||||||
iban: [],
|
|
||||||
bic: [],
|
|
||||||
account_number: [],
|
|
||||||
virtual_balance: [],
|
|
||||||
opening_balance: [],
|
|
||||||
opening_balance_date: [],
|
|
||||||
include_net_worth: [],
|
|
||||||
notes: [],
|
|
||||||
location: [],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
storeField: function (payload) {
|
|
||||||
// console.log(payload);
|
|
||||||
if ('location' === payload.field) {
|
|
||||||
if (true === payload.value.hasMarker) {
|
|
||||||
this.location = payload.value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.location = {};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this[payload.field] = payload.value;
|
|
||||||
},
|
|
||||||
selectedAttachments: function (e) {
|
|
||||||
this.hasAttachments = true;
|
|
||||||
},
|
|
||||||
selectedNoAttachments: function (e) {
|
|
||||||
this.hasAttachments = false;
|
|
||||||
},
|
|
||||||
uploadedAttachments: function (e) {
|
|
||||||
// console.log('Response to event uploaded-attachments');
|
|
||||||
// console.log(e);
|
|
||||||
this.finishSubmission();
|
|
||||||
},
|
|
||||||
submitForm: function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.submitting = true;
|
|
||||||
let submission = this.getSubmission();
|
|
||||||
// console.log('Will submit:');
|
|
||||||
// console.log(submission);
|
|
||||||
let url = './api/v1/accounts';
|
|
||||||
|
|
||||||
axios.post(url, submission)
|
|
||||||
.then(response => {
|
|
||||||
this.errors = lodashClonedeep(this.defaultErrors);
|
|
||||||
this.returnedId = parseInt(response.data.data.id);
|
|
||||||
this.returnedTitle = response.data.data.attributes.name;
|
|
||||||
|
|
||||||
if (this.hasAttachments) {
|
|
||||||
// upload attachments. Do a callback to a finish up method.
|
|
||||||
this.uploadObjectId = this.returnedId;
|
|
||||||
this.uploadTrigger = true;
|
|
||||||
}
|
|
||||||
if (!this.hasAttachments) {
|
|
||||||
this.finishSubmission();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
this.submitting = false;
|
|
||||||
this.parseErrors(error.response.data);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
finishSubmission: function () {
|
|
||||||
this.successMessage = this.$t('firefly.stored_new_account_js', {ID: this.returnedId, name: this.returnedTitle});
|
|
||||||
// stay here is false?
|
|
||||||
if (false === this.createAnother) {
|
|
||||||
window.location.href = (window.previousURL ?? '/') + '?account_id=' + this.returnedId + '&message=created';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.submitting = false;
|
|
||||||
if (this.resetFormAfter) {
|
|
||||||
// console.log('reset!');
|
|
||||||
this.name = '';
|
|
||||||
this.liability_type = 'Loan';
|
|
||||||
this.liability_direction = 'debit';
|
|
||||||
this.liability_amount = null;
|
|
||||||
this.liability_date = null;
|
|
||||||
this.interest = null;
|
|
||||||
this.interest_period = 'monthly';
|
|
||||||
this.iban = null;
|
|
||||||
this.bic = null;
|
|
||||||
this.account_number = null;
|
|
||||||
this.virtual_balance = null;
|
|
||||||
this.opening_balance = null;
|
|
||||||
this.opening_balance_date = null;
|
|
||||||
this.include_net_worth = true;
|
|
||||||
this.active = true;
|
|
||||||
this.notes = null;
|
|
||||||
this.location = {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
parseErrors: function (errors) {
|
|
||||||
this.errors = lodashClonedeep(this.defaultErrors);
|
|
||||||
// console.log(errors);
|
|
||||||
for (let i in errors.errors) {
|
|
||||||
if (errors.errors.hasOwnProperty(i)) {
|
|
||||||
this.errors[i] = errors.errors[i];
|
|
||||||
}
|
|
||||||
if ('liability_start_date' === i) {
|
|
||||||
this.errors.opening_balance_date = errors.errors[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getSubmission: function () {
|
|
||||||
let submission = {
|
|
||||||
"name": this.name,
|
|
||||||
"type": this.type,
|
|
||||||
"iban": this.iban,
|
|
||||||
"bic": this.bic,
|
|
||||||
"account_number": this.account_number,
|
|
||||||
"currency_id": this.currency_id,
|
|
||||||
"virtual_balance": this.virtual_balance,
|
|
||||||
"active": this.active,
|
|
||||||
"order": 31337,
|
|
||||||
"include_net_worth": this.include_net_worth,
|
|
||||||
"account_role": this.account_role,
|
|
||||||
"notes": this.notes,
|
|
||||||
};
|
|
||||||
if ('liabilities' === this.type) {
|
|
||||||
submission.liability_type = this.liability_type.toLowerCase();
|
|
||||||
submission.interest = this.interest;
|
|
||||||
submission.interest_period = this.interest_period;
|
|
||||||
submission.liability_amount = this.liability_amount;
|
|
||||||
submission.liability_start_date = this.liability_date;
|
|
||||||
submission.liability_direction = this.liability_direction;
|
|
||||||
}
|
|
||||||
if ((null !== this.opening_balance || null !== this.opening_balance_date) && 'asset' === this.type) {
|
|
||||||
submission.opening_balance = this.opening_balance;
|
|
||||||
submission.opening_balance_date = this.opening_balance_date;
|
|
||||||
}
|
|
||||||
if ('' === submission.opening_balance) {
|
|
||||||
delete submission.opening_balance;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('asset' === this.type && 'ccAsset' === this.account_role) {
|
|
||||||
submission.credit_card_type = this.credit_card_type;
|
|
||||||
submission.monthly_payment_date = this.monthly_payment_date;
|
|
||||||
}
|
|
||||||
if (Object.keys(this.location).length >= 3) {
|
|
||||||
submission.longitude = this.location.lng;
|
|
||||||
submission.latitude = this.location.lat;
|
|
||||||
submission.zoom_level = this.location.zoomLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
return submission;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
<!--
|
|
||||||
- LiabilityType.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('form.cc_type') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="loading">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="!loading">
|
|
||||||
<select
|
|
||||||
ref="credit_card_type"
|
|
||||||
v-model="credit_card_type"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:title="$t('form.cc_type')"
|
|
||||||
autocomplete="off"
|
|
||||||
name="credit_card_type"
|
|
||||||
:disabled=disabled
|
|
||||||
>
|
|
||||||
<option v-for="type in this.typeList" :label="type.title" :value="type.slug">{{ type.title }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "CreditCardType",
|
|
||||||
props: {
|
|
||||||
value: {},
|
|
||||||
errors: {},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
typeList: [],
|
|
||||||
credit_card_type: this.value,
|
|
||||||
loading: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadRoles: function () {
|
|
||||||
//
|
|
||||||
axios.get('./api/v1/configuration/firefly.credit_card_types')
|
|
||||||
.then(response => {
|
|
||||||
let content = response.data.data.value;
|
|
||||||
for (let i in content) {
|
|
||||||
if (content.hasOwnProperty(i)) {
|
|
||||||
let current = content[i];
|
|
||||||
this.typeList.push({slug: current, title: this.$t('firefly.credit_card_type_' + current)})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
credit_card_type: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'credit_card_type', value: value});
|
|
||||||
},
|
|
||||||
value: function(value) {
|
|
||||||
this.credit_card_type = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.loadRoles()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Delete.vue
|
|
||||||
- Copyright (c) 2021 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>
|
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div class="card card-default card-danger">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
<span class="fas fa-exclamation-triangle"></span>
|
|
||||||
{{ $t('firefly.delete_account') }}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<!-- /.card-header -->
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="callout callout-danger" v-if="!deleting && !deleted">
|
|
||||||
<p>
|
|
||||||
<span class="far fa-dizzy"></span> {{ $t('form.permDeleteWarning') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<p v-if="!loading && !deleting && !deleted">
|
|
||||||
{{ $t('form.account_areYouSure_js', {'name': this.accountName}) }}
|
|
||||||
</p>
|
|
||||||
<p v-if="!loading && !deleting && !deleted">
|
|
||||||
<span v-if="piggyBankCount > 0">
|
|
||||||
{{ $tc('form.also_delete_piggyBanks_js', piggyBankCount, {count: piggyBankCount}) }}
|
|
||||||
</span>
|
|
||||||
<span v-if="transactionCount > 0">
|
|
||||||
{{ $tc('form.also_delete_transactions_js', transactionCount, {count: transactionCount}) }}
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
<p v-if="transactionCount > 0 && !deleting && !deleted">
|
|
||||||
{{ $tc('firefly.save_transactions_by_moving_js', transactionCount) }}
|
|
||||||
</p>
|
|
||||||
<p v-if="transactionCount > 0 && !deleting && !deleted">
|
|
||||||
<select name="account" v-model="moveToAccount" class="form-control">
|
|
||||||
<option :label="$t('firefly.none_in_select_list')" :value="0">{{ $t('firefly.none_in_select_list') }}</option>
|
|
||||||
<option v-for="account in accounts" :label="account.name" :value="account.id">{{ account.name }}</option>
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p v-if="loading || deleting || deleted" class="text-center">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<button @click="deleteAccount" class="btn btn-danger float-right" v-if="!loading && !deleting && !deleted"> {{
|
|
||||||
$t('form.deletePermanently')
|
|
||||||
}}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "Delete",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
deleting: false,
|
|
||||||
deleted: false,
|
|
||||||
accountId: 0,
|
|
||||||
accountName: '',
|
|
||||||
piggyBankCount: 0,
|
|
||||||
transactionCount: 0,
|
|
||||||
moveToAccount: 0,
|
|
||||||
accounts: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
let pathName = window.location.pathname;
|
|
||||||
let parts = pathName.split('/');
|
|
||||||
this.accountId = parseInt(parts[parts.length - 1]);
|
|
||||||
this.getAccount();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
deleteAccount: function () {
|
|
||||||
this.deleting = true;
|
|
||||||
if (0 === this.moveToAccount) {
|
|
||||||
this.execDeleteAccount();
|
|
||||||
}
|
|
||||||
if (0 !== this.moveToAccount) {
|
|
||||||
// move to another account:
|
|
||||||
this.moveTransactions();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
moveTransactions: function () {
|
|
||||||
|
|
||||||
let query =
|
|
||||||
{
|
|
||||||
where: {account_id: this.accountId},
|
|
||||||
update: {account_id: this.moveToAccount}
|
|
||||||
};
|
|
||||||
|
|
||||||
axios.post('./api/v1/data/bulk/transactions', {query: JSON.stringify(query)}).then(response => {
|
|
||||||
this.execDeleteAccount();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
execDeleteAccount: function () {
|
|
||||||
axios.delete('./api/v1/accounts/' + this.accountId)
|
|
||||||
.then(response => {
|
|
||||||
this.deleted = true;
|
|
||||||
this.deleting = false;
|
|
||||||
window.location.href = (window.previousURL ?? '/') + '?account_id=' + this.accountId + '&message=deleted';
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getAccount: function () {
|
|
||||||
axios.get('./api/v1/accounts/' + this.accountId)
|
|
||||||
.then(response => {
|
|
||||||
let account = response.data.data;
|
|
||||||
this.accountName = account.attributes.name;
|
|
||||||
// now get piggy and transaction count
|
|
||||||
this.getPiggyBankCount(account.attributes.type, account.attributes.currency_code);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
getAccounts: function (type, currencyCode) {
|
|
||||||
axios.get('./api/v1/accounts?type=' + type)
|
|
||||||
.then(response => {
|
|
||||||
let accounts = response.data.data;
|
|
||||||
for (let i in accounts) {
|
|
||||||
if (accounts.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = accounts[i];
|
|
||||||
if (false === current.attributes.active) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (currencyCode !== current.attributes.currency_code) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (this.accountId === parseInt(current.id)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.accounts.push({id: current.id, name: current.attributes.name});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// get accounts of the same type.
|
|
||||||
// console.log('Go for "' + type + '"');
|
|
||||||
},
|
|
||||||
getPiggyBankCount: function (type, currencyCode) {
|
|
||||||
axios.get('./api/v1/accounts/' + this.accountId + '/piggy_banks')
|
|
||||||
.then(response => {
|
|
||||||
this.piggyBankCount = response.data.meta.pagination.total ? parseInt(response.data.meta.pagination.total) : 0;
|
|
||||||
this.getTransactionCount(type, currencyCode);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
getTransactionCount: function (type, currencyCode) {
|
|
||||||
axios.get('./api/v1/accounts/' + this.accountId + '/transactions')
|
|
||||||
.then(response => {
|
|
||||||
this.transactionCount = response.data.meta.pagination.total ? parseInt(response.data.meta.pagination.total) : 0;
|
|
||||||
if (this.transactionCount > 0) {
|
|
||||||
this.getAccounts(type, currencyCode);
|
|
||||||
}
|
|
||||||
if (0 === this.transactionCount) {
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,388 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Edit.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<Alert :message="errorMessage" type="danger"/>
|
|
||||||
<Alert :message="successMessage" type="success"/>
|
|
||||||
<form @submit="submitForm" autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div class="card card-primary">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
{{ $t('firefly.mandatoryFields') }}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<GenericTextInput :disabled="submitting" v-model="account.name" field-name="name" :errors="errors.name" :title="$t('form.name')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericCurrency :disabled="submitting" v-model="account.currency_id" :errors="errors.currency_id" v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<AssetAccountRole :disabled="submitting" v-if="'asset' === account.type" v-model="account.account_role" :errors="errors.account_role"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<LiabilityType :disabled="submitting" v-if="'liabilities' === account.type" v-model="account.liability_type" :errors="errors.liability_type"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<LiabilityDirection :disabled="submitting" v-if="'liabilities' === account.type" v-model="account.liability_direction"
|
|
||||||
:errors="errors.liability_direction"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericTextInput :disabled="submitting" v-if="'liabilities' === account.type" field-type="number" field-step="any"
|
|
||||||
v-model="account.liability_amount"
|
|
||||||
field-name="liability_amount" :errors="errors.liability_amount" :title="$t('form.amount')" v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextInput :disabled="submitting" v-if="'liabilities' === account.type" field-type="date" v-model="account.liability_date"
|
|
||||||
field-name="liability_date"
|
|
||||||
:errors="errors.liability_date" :title="$t('form.date')" v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<Interest :disabled="submitting" v-if="'liabilities' === account.type" v-model="account.interest" :errors="errors.interest"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<InterestPeriod :disabled="submitting" v-if="'liabilities' === account.type" v-model="account.interest_period" :errors="errors.interest_period"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
{{ $t('firefly.optionalFields') }}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<GenericTextInput :disabled="submitting" v-model="account.iban" field-name="iban" :errors="errors.iban" :title="$t('form.iban')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextInput :disabled="submitting" v-model="account.bic" field-name="bic" :errors="errors.bic" :title="$t('form.BIC')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextInput :disabled="submitting" v-model="account.account_number" field-name="account_number" :errors="errors.account_number"
|
|
||||||
:title="$t('form.account_number')" v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericTextInput :disabled="submitting" v-if="'asset' === account.type" field-type="amount" v-model="account.virtual_balance"
|
|
||||||
field-name="virtual_balance"
|
|
||||||
:errors="errors.virtual_balance" :title="$t('form.virtual_balance')" v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextInput :disabled="submitting" v-if="'asset' === account.type" field-type="amount" v-model="account.opening_balance"
|
|
||||||
field-name="opening_balance"
|
|
||||||
:errors="errors.opening_balance" :title="$t('form.opening_balance')" v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextInput :disabled="submitting" v-if="'asset' === account.type" field-type="date" v-model="account.opening_balance_date"
|
|
||||||
field-name="opening_balance_date" :errors="errors.opening_balance_date" :title="$t('form.opening_balance_date')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericCheckbox :disabled="submitting" v-if="'asset' === account.type" :title="$t('form.include_net_worth')" field-name="include_net_worth"
|
|
||||||
v-model="account.include_net_worth" :errors="errors.include_net_worth" :description="$t('form.include_net_worth')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericCheckbox :disabled="submitting" :title="$t('form.active')" field-name="active"
|
|
||||||
v-model="account.active" :errors="errors.active" :description="$t('form.active')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextarea :disabled="submitting" field-name="notes" :title="$t('form.notes')" v-model="account.notes" :errors="errors.notes"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericLocation :disabled="submitting" v-model="account.location" :title="$t('form.location')" :errors="errors.location"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericAttachments :disabled="submitting" :title="$t('form.attachments')" field-name="attachments" :errors="errors.attachments"
|
|
||||||
v-on:selected-attachments="selectedAttachments($event)"
|
|
||||||
v-on:selected-no-attachments="selectedNoAttachments($event)"
|
|
||||||
v-on:uploaded-attachments="uploadedAttachments($event)"
|
|
||||||
:upload-trigger="uploadTrigger"
|
|
||||||
:upload-object-type="uploadObjectType"
|
|
||||||
:upload-object-id="uploadObjectId"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12 offset-xl-6 offset-lg-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-6 offset-lg-6">
|
|
||||||
<button :disabled=submitting type="button" @click="submitForm" class="btn btn-success btn-block">{{
|
|
||||||
$t('firefly.update_' + account.type + '_account')
|
|
||||||
}}
|
|
||||||
</button>
|
|
||||||
<div class="form-check">
|
|
||||||
<input id="stayHere" v-model="stayHere" class="form-check-input" type="checkbox">
|
|
||||||
<label class="form-check-label" for="stayHere">
|
|
||||||
<span class="small">{{ $t('firefly.after_update_create_another') }}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import Alert from '../partials/Alert';
|
|
||||||
import lodashClonedeep from "lodash.clonedeep";
|
|
||||||
import GenericTextInput from '../form/GenericTextInput';
|
|
||||||
import GenericCurrency from "../form/GenericCurrency";
|
|
||||||
import AssetAccountRole from "./AssetAccountRole";
|
|
||||||
import LiabilityType from "./LiabilityType";
|
|
||||||
import LiabilityDirection from "./LiabilityDirection";
|
|
||||||
import Interest from "./Interest";
|
|
||||||
import InterestPeriod from "./InterestPeriod";
|
|
||||||
import GenericTextarea from "../form/GenericTextarea";
|
|
||||||
import GenericCheckbox from "../form/GenericCheckbox";
|
|
||||||
import GenericAttachments from "../form/GenericAttachments";
|
|
||||||
import GenericLocation from "../form/GenericLocation";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Edit",
|
|
||||||
created() {
|
|
||||||
// console.log('Created');
|
|
||||||
let parts = window.location.pathname.split('/');
|
|
||||||
this.accountId = parseInt(parts[parts.length - 1]);
|
|
||||||
this.uploadObjectId = parseInt(parts[parts.length - 1]);
|
|
||||||
this.getAccount();
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
Alert,
|
|
||||||
GenericTextInput,
|
|
||||||
GenericCurrency,
|
|
||||||
AssetAccountRole,
|
|
||||||
LiabilityDirection,
|
|
||||||
LiabilityType,
|
|
||||||
Interest,
|
|
||||||
InterestPeriod,
|
|
||||||
GenericTextarea,
|
|
||||||
GenericCheckbox,
|
|
||||||
GenericAttachments,
|
|
||||||
GenericLocation
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
successMessage: '',
|
|
||||||
errorMessage: '',
|
|
||||||
stayHere: false,
|
|
||||||
inError: false,
|
|
||||||
accountId: 0,
|
|
||||||
submitting: false,
|
|
||||||
|
|
||||||
// account + original account
|
|
||||||
account: {},
|
|
||||||
originalAccount: {},
|
|
||||||
|
|
||||||
// has attachments to upload?
|
|
||||||
hasAttachments: false,
|
|
||||||
uploadTrigger: false,
|
|
||||||
uploadObjectId: 0,
|
|
||||||
uploadObjectType: 'Account',
|
|
||||||
|
|
||||||
// errors
|
|
||||||
errors: {
|
|
||||||
currency_id: [],
|
|
||||||
account_role: [],
|
|
||||||
liability_type: [],
|
|
||||||
location: []
|
|
||||||
},
|
|
||||||
defaultErrors: {
|
|
||||||
name: [],
|
|
||||||
currency_id: [],
|
|
||||||
account_role: [],
|
|
||||||
liability_type: [],
|
|
||||||
liability_direction: [],
|
|
||||||
liability_amount: [],
|
|
||||||
liability_date: [],
|
|
||||||
interest: [],
|
|
||||||
interest_period: [],
|
|
||||||
iban: [],
|
|
||||||
bic: [],
|
|
||||||
account_number: [],
|
|
||||||
virtual_balance: [],
|
|
||||||
opening_balance: [],
|
|
||||||
opening_balance_date: [],
|
|
||||||
include_net_worth: [],
|
|
||||||
active: [],
|
|
||||||
notes: [],
|
|
||||||
location: [],
|
|
||||||
attachments: [],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
selectedAttachments: function (e) {
|
|
||||||
this.hasAttachments = true;
|
|
||||||
},
|
|
||||||
selectedNoAttachments: function (e) {
|
|
||||||
this.hasAttachments = false;
|
|
||||||
},
|
|
||||||
uploadedAttachments: function (e) {
|
|
||||||
this.finaliseSubmission();
|
|
||||||
},
|
|
||||||
submitForm: function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.submitting = true;
|
|
||||||
let submission = this.getSubmission();
|
|
||||||
if (0 === Object.keys(submission).length) {
|
|
||||||
// console.log('Nothing to submit. Just finish up.');
|
|
||||||
this.finaliseSubmission();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// console.log('Will submit:');
|
|
||||||
// console.log(submission);
|
|
||||||
const url = './api/v1/accounts/' + this.accountId;
|
|
||||||
axios.put(url, submission)
|
|
||||||
.then(this.processSubmission)
|
|
||||||
.catch(err => {
|
|
||||||
this.handleSubmissionError(err.response.data)
|
|
||||||
});
|
|
||||||
},
|
|
||||||
processSubmission: function() {
|
|
||||||
if (this.hasAttachments) {
|
|
||||||
// upload attachments. Do a callback to a finish up method.
|
|
||||||
this.uploadTrigger = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.finaliseSubmission();
|
|
||||||
},
|
|
||||||
finaliseSubmission: function () {
|
|
||||||
// console.log('finaliseSubmission');
|
|
||||||
// stay here, display message
|
|
||||||
if (true === this.stayHere && false === this.inError) {
|
|
||||||
this.errorMessage = '';
|
|
||||||
this.successMessage = this.$t('firefly.updated_account_js', {ID: this.accountId, title: this.account.name});
|
|
||||||
this.submitting = false;
|
|
||||||
}
|
|
||||||
// return to previous (bad hack), display message:
|
|
||||||
if (false === this.stayHere && false === this.inError) {
|
|
||||||
//console.log('no error + changes + redirect');
|
|
||||||
window.location.href = (window.previousURL ?? '/') + '?account_id=' + this.accountId + '&message=updated';
|
|
||||||
this.submitting = false;
|
|
||||||
}
|
|
||||||
// error or warning? here.
|
|
||||||
// console.log('end of finaliseSubmission');
|
|
||||||
},
|
|
||||||
handleSubmissionError: function (errors) {
|
|
||||||
console.error('Bad');
|
|
||||||
console.error(errors);
|
|
||||||
this.inError = true;
|
|
||||||
this.submitting = false;
|
|
||||||
this.errors = lodashClonedeep(this.defaultErrors);
|
|
||||||
for (let i in errors.errors) {
|
|
||||||
if (errors.errors.hasOwnProperty(i)) {
|
|
||||||
this.errors[i] = errors.errors[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getSubmission: function () {
|
|
||||||
let submission = {};
|
|
||||||
// console.log('getSubmission');
|
|
||||||
// console.log(this.account);
|
|
||||||
for (let i in this.account) {
|
|
||||||
// console.log(i);
|
|
||||||
if (this.account.hasOwnProperty(i) && this.originalAccount.hasOwnProperty(i) && JSON.stringify(this.account[i]) !== JSON.stringify(this.originalAccount[i])) {
|
|
||||||
// console.log('Field "' + i + '" has changed.');
|
|
||||||
// console.log('Original:')
|
|
||||||
// console.log(this.account[i]);
|
|
||||||
// console.log('Backup : ');
|
|
||||||
// console.log(this.originalAccount[i]);
|
|
||||||
submission[i] = this.account[i];
|
|
||||||
}
|
|
||||||
// else {
|
|
||||||
// console.log('Field "' + i + '" has not changed.');
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
return submission;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Grab account from URL and submit GET.
|
|
||||||
*/
|
|
||||||
getAccount: function () {
|
|
||||||
// console.log('getTransactionGroup');
|
|
||||||
axios.get('./api/v1/accounts/' + this.accountId)
|
|
||||||
.then(response => {
|
|
||||||
this.parseAccount(response.data);
|
|
||||||
}
|
|
||||||
).catch(error => {
|
|
||||||
console.error('I failed :(');
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
storeField: function (payload) {
|
|
||||||
//console.log(payload);
|
|
||||||
if ('location' === payload.field) {
|
|
||||||
if (true === payload.value.hasMarker) {
|
|
||||||
this.account.location = payload.value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.account.location = {};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.account[payload.field] = payload.value;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Parse transaction group. Title is easy, transactions have their own method.
|
|
||||||
* @param response
|
|
||||||
*/
|
|
||||||
parseAccount: function (response) {
|
|
||||||
// console.log('Will now parse');
|
|
||||||
// console.log(response);
|
|
||||||
let attributes = response.data.attributes;
|
|
||||||
let account = {};
|
|
||||||
|
|
||||||
// parse account:
|
|
||||||
account.account_number = attributes.account_number;
|
|
||||||
account.account_role = attributes.account_role;
|
|
||||||
account.active = attributes.active;
|
|
||||||
account.bic = attributes.bic;
|
|
||||||
account.credit_card_type = attributes.credit_card_type;
|
|
||||||
account.currency_code = attributes.currency_code;
|
|
||||||
account.currency_decimal_places = parseInt(attributes.currency_decimal_places);
|
|
||||||
account.currency_id = parseInt(attributes.currency_id);
|
|
||||||
account.currency_symbol = attributes.currency_symbol;
|
|
||||||
account.iban = attributes.iban;
|
|
||||||
account.include_net_worth = attributes.include_net_worth;
|
|
||||||
account.interest = attributes.interest;
|
|
||||||
account.interest_period = attributes.interest_period;
|
|
||||||
account.liability_direction = attributes.liability_direction;
|
|
||||||
account.liability_type = attributes.liability_type;
|
|
||||||
account.monthly_payment_date = attributes.monthly_payment_date;
|
|
||||||
account.name = attributes.name;
|
|
||||||
account.notes = attributes.notes;
|
|
||||||
account.opening_balance = attributes.opening_balance;
|
|
||||||
account.opening_balance_date = attributes.opening_balance_date;
|
|
||||||
account.type = attributes.type;
|
|
||||||
account.virtual_balance = attributes.virtual_balance;
|
|
||||||
account.location = {};
|
|
||||||
if (null !== attributes.latitude && null !== attributes.longitude && null !== attributes.zoom_level) {
|
|
||||||
account.location = {
|
|
||||||
latitude: attributes.latitude,
|
|
||||||
longitude: attributes.longitude,
|
|
||||||
zoom_level: attributes.zoom_level
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.account = account;
|
|
||||||
this.originalAccount = lodashClonedeep(this.account);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,611 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Index.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-8 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
<b-pagination
|
|
||||||
v-model="currentPage"
|
|
||||||
:total-rows="total"
|
|
||||||
:per-page="perPage"
|
|
||||||
aria-controls="my-table"
|
|
||||||
></b-pagination>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
<a :href="'./accounts/create/' + type" class="btn btn-sm mb-2 float-right btn-success" :title="$t('firefly.create_new_' + type)"><span class="fas fa-plus"></span> {{ $t('firefly.create_new_' + type) }}</a>
|
|
||||||
<button @click="newCacheKey" class="btn btn-sm mb-2 mr-2 float-right btn-info"><span class="fas fa-sync"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body p-0">
|
|
||||||
<b-table id="my-table" striped hover responsive="md" primary-key="id" :no-local-sorting="false"
|
|
||||||
:items="accounts" :fields="fields"
|
|
||||||
:per-page="perPage"
|
|
||||||
sort-icon-left
|
|
||||||
ref="table"
|
|
||||||
:current-page="currentPage"
|
|
||||||
:busy.sync="loading"
|
|
||||||
:sort-by.sync="sortBy"
|
|
||||||
:sort-desc.sync="sortDesc"
|
|
||||||
>
|
|
||||||
<template #table-busy>
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</template>
|
|
||||||
<template #cell(name)="data">
|
|
||||||
<a :class="false === data.item.active ? 'text-muted' : ''" :href="'./accounts/show/' + data.item.id" :title="data.value">{{ data.value }}</a>
|
|
||||||
</template>
|
|
||||||
<template #cell(acct_number)="data">
|
|
||||||
{{ data.item.acct_number }}
|
|
||||||
</template>
|
|
||||||
<template #cell(last_activity)="data">
|
|
||||||
<span v-if="'asset' === type && 'loading' === data.item.last_activity">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</span>
|
|
||||||
<span v-if="'asset' === type && 'none' === data.item.last_activity" class="text-muted">
|
|
||||||
{{ $t('firefly.never') }}
|
|
||||||
</span>
|
|
||||||
<span v-if="'asset' === type && 'loading' !== data.item.last_activity && 'none' !== data.item.last_activity">
|
|
||||||
{{ data.item.last_activity }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #cell(amount_due)="data">
|
|
||||||
<span class="text-success" v-if="parseFloat(data.item.amount_due) > 0">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: data.item.currency_code}).format(data.item.amount_due) }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="text-danger" v-if="parseFloat(data.item.amount_due) < 0">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: data.item.currency_code}).format(data.item.amount_due) }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="text-muted" v-if="parseFloat(data.item.amount_due) === 0.0">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: data.item.currency_code}).format(data.item.amount_due) }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
<template #cell(current_balance)="data">
|
|
||||||
<span class="text-success" v-if="parseFloat(data.item.current_balance) > 0">
|
|
||||||
{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency', currency:
|
|
||||||
data.item.currency_code
|
|
||||||
}).format(data.item.current_balance)
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
<span class="text-danger" v-if="parseFloat(data.item.current_balance) < 0">
|
|
||||||
{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency', currency:
|
|
||||||
data.item.currency_code
|
|
||||||
}).format(data.item.current_balance)
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="text-muted" v-if="0 === parseFloat(data.item.current_balance)">
|
|
||||||
{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency', currency:
|
|
||||||
data.item.currency_code
|
|
||||||
}).format(data.item.current_balance)
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
<span v-if="'asset' === type && 'loading' === data.item.balance_diff">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</span>
|
|
||||||
<span v-if="'asset' === type && 'loading' !== data.item.balance_diff">
|
|
||||||
(<span class="text-success" v-if="parseFloat(data.item.balance_diff) > 0">{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency', currency:
|
|
||||||
data.item.currency_code
|
|
||||||
}).format(data.item.balance_diff)
|
|
||||||
}}</span><span class="text-muted" v-if="0===parseFloat(data.item.balance_diff)">{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency', currency:
|
|
||||||
data.item.currency_code
|
|
||||||
}).format(data.item.balance_diff)
|
|
||||||
}}</span><span class="text-danger" v-if="parseFloat(data.item.balance_diff) < 0">{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency', currency:
|
|
||||||
data.item.currency_code
|
|
||||||
}).format(data.item.balance_diff)
|
|
||||||
}}</span>)
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #cell(interest)="data">
|
|
||||||
{{ parseFloat(data.item.interest) }}% ({{ data.item.interest_period }})
|
|
||||||
</template>
|
|
||||||
<template #cell(menu)="data">
|
|
||||||
<div class="btn-group btn-group-sm">
|
|
||||||
<div class="dropdown">
|
|
||||||
<button class="btn btn-light btn-sm dropdown-toggle" type="button" :id="'dropdownMenuButton' + data.item.id" data-toggle="dropdown"
|
|
||||||
aria-haspopup="true" aria-expanded="false">
|
|
||||||
{{ $t('firefly.actions') }}
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" :aria-labelledby="'dropdownMenuButton' + data.item.id">
|
|
||||||
<a class="dropdown-item" :href="'./accounts/edit/' + data.item.id"><span class="fa fas fa-pencil-alt"></span> {{ $t('firefly.edit') }}</a>
|
|
||||||
<a class="dropdown-item" :href="'./accounts/delete/' + data.item.id"><span class="fa far fa-trash"></span> {{ $t('firefly.delete') }}</a>
|
|
||||||
<a v-if="'asset' === type" class="dropdown-item" :href="'./accounts/reconcile/' + data.item.id + '/index'"><span
|
|
||||||
class="fas fa-check"></span>
|
|
||||||
{{ $t('firefly.reconcile_this_account') }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</b-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-8 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
<b-pagination
|
|
||||||
v-model="currentPage"
|
|
||||||
:total-rows="total"
|
|
||||||
:per-page="perPage"
|
|
||||||
aria-controls="my-table"
|
|
||||||
></b-pagination>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
<a :href="'./accounts/create/' + type" class="btn btn-sm mt-2 float-right btn-success" :title="$t('firefly.create_new_' + type)"><span class="fas fa-plus"></span> {{ $t('firefly.create_new_' + type) }}</a>
|
|
||||||
<button @click="newCacheKey" class="btn btn-sm mt-2 mr-2 float-right btn-info"><span class="fas fa-sync"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import {mapGetters, mapMutations} from "vuex";
|
|
||||||
import Sortable from "sortablejs";
|
|
||||||
import format from "date-fns/format";
|
|
||||||
import {configureAxios} from "../../shared/forageStore";
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Index",
|
|
||||||
props: {
|
|
||||||
accountTypes: String
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
accounts: [],
|
|
||||||
allAccounts: [],
|
|
||||||
type: 'all',
|
|
||||||
downloaded: false,
|
|
||||||
loading: false,
|
|
||||||
ready: false,
|
|
||||||
fields: [],
|
|
||||||
currentPage: 1,
|
|
||||||
perPage: 5,
|
|
||||||
total: 1,
|
|
||||||
sortBy: 'order',
|
|
||||||
sortDesc: false,
|
|
||||||
api: null,
|
|
||||||
sortableOptions: {
|
|
||||||
disabled: false,
|
|
||||||
chosenClass: 'is-selected',
|
|
||||||
onEnd: null
|
|
||||||
},
|
|
||||||
sortable: null,
|
|
||||||
locale: 'en-US'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
start: function () {
|
|
||||||
this.getAccountList();
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
this.getAccountList();
|
|
||||||
},
|
|
||||||
orderMode: function (value) {
|
|
||||||
// update the table headers
|
|
||||||
this.updateFieldList();
|
|
||||||
|
|
||||||
// reorder the accounts:
|
|
||||||
this.reorderAccountList(value);
|
|
||||||
|
|
||||||
// make table sortable:
|
|
||||||
this.makeTableSortable(value);
|
|
||||||
},
|
|
||||||
activeFilter: function (value) {
|
|
||||||
this.filterAccountList();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('root', ['listPageSize', 'cacheKey']),
|
|
||||||
...mapGetters('accounts/index', ['orderMode', 'activeFilter']),
|
|
||||||
...mapGetters('dashboard/index', ['start', 'end',]),
|
|
||||||
'indexReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && null !== this.listPageSize && this.ready;
|
|
||||||
},
|
|
||||||
cardTitle: function () {
|
|
||||||
return this.$t('firefly.' + this.type + '_accounts');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
let pathName = window.location.pathname;
|
|
||||||
let parts = pathName.split('/');
|
|
||||||
this.type = parts[parts.length - 1];
|
|
||||||
this.perPage = this.listPageSize ?? 51;
|
|
||||||
// console.log('Per page: ' + this.perPage);
|
|
||||||
|
|
||||||
let params = new URLSearchParams(window.location.search);
|
|
||||||
this.currentPage = params.get('page') ? parseInt(params.get('page')) : 1;
|
|
||||||
this.updateFieldList();
|
|
||||||
this.ready = true;
|
|
||||||
|
|
||||||
// make object thing:
|
|
||||||
// let token = document.head.querySelector('meta[name="csrf-token"]');
|
|
||||||
// this.api = setup(
|
|
||||||
// {
|
|
||||||
// // `axios` options
|
|
||||||
// //baseURL: './',
|
|
||||||
// headers: {'X-CSRF-TOKEN': token.content, 'X-James': 'yes'},
|
|
||||||
//
|
|
||||||
// // `axios-cache-adapter` options
|
|
||||||
// cache: {
|
|
||||||
// maxAge: 15 * 60 * 1000,
|
|
||||||
// readHeaders: false,
|
|
||||||
// exclude: {
|
|
||||||
// query: false,
|
|
||||||
// },
|
|
||||||
// debug: true
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
...mapMutations('root', ['refreshCacheKey',]),
|
|
||||||
// itemsProvider: function (ctx, callback) {
|
|
||||||
// console.log('itemsProvider()');
|
|
||||||
// console.log('ctx.currentPage = ' + ctx.currentPage);
|
|
||||||
// console.log('this.currentPage = ' + this.currentPage);
|
|
||||||
// if (ctx.currentPage === this.currentPage) {
|
|
||||||
// let direction = this.sortDesc ? '-' : '+';
|
|
||||||
// let url = 'api/v1/accounts?type=' + this.type + '&page=' + ctx.currentPage + '&sort=' + direction + this.sortBy;
|
|
||||||
// this.api.get(url)
|
|
||||||
// .then(async (response) => {
|
|
||||||
// this.total = parseInt(response.data.meta.pagination.total);
|
|
||||||
// let items = this.parseAccountsAndReturn(response.data.data);
|
|
||||||
// items = this.filterAccountListAndReturn(items);
|
|
||||||
// callback(items);
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// return [];
|
|
||||||
// },
|
|
||||||
|
|
||||||
saveAccountSort: function (event) {
|
|
||||||
let oldIndex = parseInt(event.oldIndex);
|
|
||||||
let newIndex = parseInt(event.newIndex);
|
|
||||||
let identifier = parseInt(event.item.attributes.getNamedItem('data-pk').value);
|
|
||||||
for (let i in this.accounts) {
|
|
||||||
if (this.accounts.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = this.accounts[i];
|
|
||||||
|
|
||||||
// the actual account
|
|
||||||
if (current.id === identifier) {
|
|
||||||
let newOrder = parseInt(current.order) + (newIndex - oldIndex);
|
|
||||||
this.accounts[i].order = newOrder;
|
|
||||||
let url = './api/v1/accounts/' + current.id;
|
|
||||||
axios.put(url, {order: newOrder}).then(response => {
|
|
||||||
// See reference nr. 8
|
|
||||||
this.getAccountList();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
reorderAccountList: function (orderMode) {
|
|
||||||
if (orderMode) {
|
|
||||||
this.sortBy = 'order';
|
|
||||||
this.sortDesc = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
newCacheKey: function () {
|
|
||||||
this.refreshCacheKey();
|
|
||||||
this.downloaded = false;
|
|
||||||
this.accounts = [];
|
|
||||||
this.getAccountList();
|
|
||||||
},
|
|
||||||
makeTableSortable: function (orderMode) {
|
|
||||||
this.sortableOptions.disabled = !orderMode;
|
|
||||||
this.sortableOptions.onEnd = this.saveAccountSort;
|
|
||||||
|
|
||||||
// make sortable of table:
|
|
||||||
if (null === this.sortable) {
|
|
||||||
this.sortable = Sortable.create(this.$refs.table.$el.querySelector('tbody'), this.sortableOptions);
|
|
||||||
}
|
|
||||||
this.sortable.option('disabled', this.sortableOptions.disabled);
|
|
||||||
},
|
|
||||||
|
|
||||||
updateFieldList: function () {
|
|
||||||
this.fields = [];
|
|
||||||
this.fields = [{key: 'name', label: this.$t('list.name'), sortable: !this.orderMode}];
|
|
||||||
if ('asset' === this.type) {
|
|
||||||
this.fields.push({key: 'role', label: this.$t('list.role'), sortable: !this.orderMode});
|
|
||||||
}
|
|
||||||
if ('liabilities' === this.type) {
|
|
||||||
this.fields.push({key: 'liability_type', label: this.$t('list.liability_type'), sortable: !this.orderMode});
|
|
||||||
this.fields.push({key: 'liability_direction', label: this.$t('list.liability_direction'), sortable: !this.orderMode});
|
|
||||||
this.fields.push({key: 'interest', label: this.$t('list.interest') + ' (' + this.$t('list.interest_period') + ')', sortable: !this.orderMode});
|
|
||||||
}
|
|
||||||
// add the rest
|
|
||||||
this.fields.push({key: 'acct_number', label: this.$t('list.iban'), sortable: !this.orderMode});
|
|
||||||
this.fields.push({key: 'current_balance', label: this.$t('list.currentBalance'), sortable: !this.orderMode});
|
|
||||||
if ('liabilities' === this.type) {
|
|
||||||
this.fields.push({key: 'amount_due', label: this.$t('firefly.left_in_debt'), sortable: !this.orderMode});
|
|
||||||
}
|
|
||||||
if ('asset' === this.type || 'liabilities' === this.type) {
|
|
||||||
this.fields.push({key: 'last_activity', label: this.$t('list.lastActivity'), sortable: !this.orderMode});
|
|
||||||
}
|
|
||||||
this.fields.push({key: 'menu', label: ' ', sortable: false});
|
|
||||||
},
|
|
||||||
getAccountList: function () {
|
|
||||||
// console.log('getAccountList()');
|
|
||||||
if (this.indexReady && !this.loading && !this.downloaded) {
|
|
||||||
// console.log('Index ready, not loading and not already downloaded. Reset.');
|
|
||||||
this.loading = true;
|
|
||||||
this.perPage = this.listPageSize ?? 51;
|
|
||||||
this.accounts = [];
|
|
||||||
this.allAccounts = [];
|
|
||||||
this.downloadAccountList(1);
|
|
||||||
}
|
|
||||||
if (this.indexReady && !this.loading && this.downloaded) {
|
|
||||||
// console.log('Index ready, not loading and not downloaded.');
|
|
||||||
this.loading = true;
|
|
||||||
this.filterAccountList();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
downloadAccountList: function (page) {
|
|
||||||
// console.log('downloadAccountList(' + page + ')');
|
|
||||||
configureAxios().then(async (api) => {
|
|
||||||
api.get('./api/v1/accounts?type=' + this.type + '&page=' + page + '&key=' + this.cacheKey)
|
|
||||||
.then(response => {
|
|
||||||
let currentPage = parseInt(response.data.meta.pagination.current_page);
|
|
||||||
let totalPage = parseInt(response.data.meta.pagination.total_pages);
|
|
||||||
this.total = parseInt(response.data.meta.pagination.total);
|
|
||||||
this.parseAccounts(response.data.data);
|
|
||||||
if (currentPage < totalPage) {
|
|
||||||
let nextPage = currentPage + 1;
|
|
||||||
this.downloadAccountList(nextPage);
|
|
||||||
}
|
|
||||||
if (currentPage >= totalPage) {
|
|
||||||
// console.log('Looks like all downloaded.');
|
|
||||||
this.downloaded = true;
|
|
||||||
this.filterAccountList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
filterAccountListAndReturn: function (allAccounts) {
|
|
||||||
// console.log('filterAccountListAndReturn()');
|
|
||||||
let accounts = [];
|
|
||||||
for (let i in allAccounts) {
|
|
||||||
if (allAccounts.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
// 1 = active only
|
|
||||||
// 2 = inactive only
|
|
||||||
// 3 = both
|
|
||||||
if (1 === this.activeFilter && false === allAccounts[i].active) {
|
|
||||||
// console.log('Skip account #' + this.allAccounts[i].id + ' because not active.');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (2 === this.activeFilter && true === allAccounts[i].active) {
|
|
||||||
// console.log('Skip account #' + this.allAccounts[i].id + ' because active.');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// console.log('Include account #' + this.allAccounts[i].id + '.');
|
|
||||||
|
|
||||||
accounts.push(allAccounts[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return accounts;
|
|
||||||
},
|
|
||||||
filterAccountList: function () {
|
|
||||||
// console.log('filterAccountList()');
|
|
||||||
this.accounts = [];
|
|
||||||
for (let i in this.allAccounts) {
|
|
||||||
if (this.allAccounts.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
// 1 = active only
|
|
||||||
// 2 = inactive only
|
|
||||||
// 3 = both
|
|
||||||
if (1 === this.activeFilter && false === this.allAccounts[i].active) {
|
|
||||||
// console.log('Skip account #' + this.allAccounts[i].id + ' because not active.');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (2 === this.activeFilter && true === this.allAccounts[i].active) {
|
|
||||||
// console.log('Skip account #' + this.allAccounts[i].id + ' because active.');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// console.log('Include account #' + this.allAccounts[i].id + '.');
|
|
||||||
|
|
||||||
this.accounts.push(this.allAccounts[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.total = this.accounts.length;
|
|
||||||
this.loading = false;
|
|
||||||
},
|
|
||||||
roleTranslate: function (role) {
|
|
||||||
if (null === role) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return this.$t('firefly.account_role_' + role);
|
|
||||||
},
|
|
||||||
parsePages: function (data) {
|
|
||||||
this.total = parseInt(data.pagination.total);
|
|
||||||
// console.log('Total is now ' + this.total);
|
|
||||||
},
|
|
||||||
// parseAccountsAndReturn: function (data) {
|
|
||||||
// console.log('In parseAccountsAndReturn()');
|
|
||||||
// let allAccounts = [];
|
|
||||||
// for (let key in data) {
|
|
||||||
// if (data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
|
||||||
// let current = data[key];
|
|
||||||
// let acct = {};
|
|
||||||
// acct.id = parseInt(current.id);
|
|
||||||
// acct.order = current.attributes.order;
|
|
||||||
// acct.name = current.attributes.name;
|
|
||||||
// acct.active = current.attributes.active;
|
|
||||||
// acct.role = this.roleTranslate(current.attributes.account_role);
|
|
||||||
// acct.account_number = current.attributes.account_number;
|
|
||||||
// acct.current_balance = current.attributes.current_balance;
|
|
||||||
// acct.currency_code = current.attributes.currency_code;
|
|
||||||
//
|
|
||||||
// if ('liabilities' === this.type) {
|
|
||||||
// acct.liability_type = this.$t('firefly.account_type_' + current.attributes.liability_type);
|
|
||||||
// acct.liability_direction = this.$t('firefly.liability_direction_' + current.attributes.liability_direction + '_short');
|
|
||||||
// acct.interest = current.attributes.interest;
|
|
||||||
// acct.interest_period = this.$t('firefly.interest_calc_' + current.attributes.interest_period);
|
|
||||||
// acct.amount_due = current.attributes.current_debt;
|
|
||||||
// }
|
|
||||||
// acct.balance_diff = 'loading';
|
|
||||||
// acct.last_activity = 'loading';
|
|
||||||
//
|
|
||||||
// if (null !== current.attributes.iban) {
|
|
||||||
// acct.iban = current.attributes.iban.match(/.{1,4}/g).join(' ');
|
|
||||||
// }
|
|
||||||
// if (null === current.attributes.iban) {
|
|
||||||
// acct.iban = null;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// allAccounts.push(acct);
|
|
||||||
// if ('asset' === this.type) {
|
|
||||||
// See reference nr. 9
|
|
||||||
// //this.getAccountBalanceDifference(this.allAccounts.length - 1, current);
|
|
||||||
// //this.getAccountLastActivity(this.allAccounts.length - 1, current);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return allAccounts;
|
|
||||||
// },
|
|
||||||
parseAccounts: function (data) {
|
|
||||||
// console.log('In parseAccounts()');
|
|
||||||
for (let key in data) {
|
|
||||||
if (data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
|
||||||
let current = data[key];
|
|
||||||
let acct = {};
|
|
||||||
acct.id = parseInt(current.id);
|
|
||||||
acct.order = current.attributes.order;
|
|
||||||
acct.name = current.attributes.name;
|
|
||||||
acct.active = current.attributes.active;
|
|
||||||
acct.role = this.roleTranslate(current.attributes.account_role);
|
|
||||||
|
|
||||||
// account number in 'acct_number'
|
|
||||||
acct.acct_number = '';
|
|
||||||
let iban = null;
|
|
||||||
let acctNr = null;
|
|
||||||
acct.acct_number = '';
|
|
||||||
if (null !== current.attributes.iban) {
|
|
||||||
iban = current.attributes.iban.match(/.{1,4}/g).join(' ');
|
|
||||||
}
|
|
||||||
if (null !== current.attributes.account_number) {
|
|
||||||
acctNr = current.attributes.account_number;
|
|
||||||
}
|
|
||||||
// only account nr
|
|
||||||
if (null === iban && null !== acctNr) {
|
|
||||||
acct.acct_number = acctNr;
|
|
||||||
}
|
|
||||||
// only iban
|
|
||||||
if (null !== iban && null === acctNr) {
|
|
||||||
acct.acct_number = iban;
|
|
||||||
}
|
|
||||||
// both:
|
|
||||||
if (null !== iban && null !== acctNr) {
|
|
||||||
acct.acct_number = iban + ' (' + acctNr + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
acct.current_balance = current.attributes.current_balance;
|
|
||||||
acct.currency_code = current.attributes.currency_code;
|
|
||||||
|
|
||||||
if ('liabilities' === this.type) {
|
|
||||||
acct.liability_type = this.$t('firefly.account_type_' + current.attributes.liability_type);
|
|
||||||
acct.liability_direction = this.$t('firefly.liability_direction_' + current.attributes.liability_direction + '_short');
|
|
||||||
acct.interest = current.attributes.interest;
|
|
||||||
acct.interest_period = this.$t('firefly.interest_calc_' + current.attributes.interest_period);
|
|
||||||
acct.amount_due = current.attributes.current_debt;
|
|
||||||
}
|
|
||||||
acct.balance_diff = 'loading';
|
|
||||||
acct.last_activity = 'loading';
|
|
||||||
|
|
||||||
this.allAccounts.push(acct);
|
|
||||||
if ('asset' === this.type) {
|
|
||||||
this.getAccountBalanceDifference(this.allAccounts.length - 1, current);
|
|
||||||
this.getAccountLastActivity(this.allAccounts.length - 1, current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getAccountLastActivity: function (index, acct) {
|
|
||||||
// console.log('getAccountLastActivity(' + index + ')');
|
|
||||||
// get single transaction for account:
|
|
||||||
// /api/v1/accounts/1/transactions?limit=1
|
|
||||||
configureAxios().then(async (api) => {
|
|
||||||
api.get('./api/v1/accounts/' + acct.id + '/transactions?limit=1&key=' + this.cacheKey).then(response => {
|
|
||||||
if (0 === response.data.data.length) {
|
|
||||||
this.allAccounts[index].last_activity = 'none';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let date = new Date(response.data.data[0].attributes.transactions[0].date);
|
|
||||||
this.allAccounts[index].last_activity = format(date, this.$t('config.month_and_day_fns'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getAccountBalanceDifference: function (index, acct) {
|
|
||||||
// console.log('getAccountBalanceDifference(' + index + ')');
|
|
||||||
// get account on day 0
|
|
||||||
let promises = [];
|
|
||||||
|
|
||||||
// add meta data to promise context.
|
|
||||||
promises.push(Promise.resolve({
|
|
||||||
account: acct,
|
|
||||||
index: index,
|
|
||||||
}));
|
|
||||||
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
|
|
||||||
configureAxios().then(api => {
|
|
||||||
return api.get('./api/v1/accounts/' + acct.id + '?date=' + startStr + '&key=' + this.cacheKey);
|
|
||||||
});
|
|
||||||
|
|
||||||
//promises.push(axios.get('./api/v1/accounts/' + acct.id + '?date=' + startStr + '&key=' + this.cacheKey));
|
|
||||||
promises.push(configureAxios().then(api => {
|
|
||||||
return api.get('./api/v1/accounts/' + acct.id + '?date=' + startStr + '&key=' + this.cacheKey);
|
|
||||||
}));
|
|
||||||
promises.push(configureAxios().then(api => {
|
|
||||||
return api.get('./api/v1/accounts/' + acct.id + '?date=' + endStr + '&key=' + this.cacheKey);
|
|
||||||
}));
|
|
||||||
|
|
||||||
Promise.all(promises).then(responses => {
|
|
||||||
let index = responses[0].index;
|
|
||||||
let startBalance = parseFloat(responses[1].data.data.attributes.current_balance);
|
|
||||||
let endBalance = parseFloat(responses[2].data.data.attributes.current_balance);
|
|
||||||
this.allAccounts[index].balance_diff = endBalance - startBalance;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
<!--
|
|
||||||
- IndexOptions.vue
|
|
||||||
- Copyright (c) 2021 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>
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" name="order_mode" id="order_mode" v-model="orderMode">
|
|
||||||
<label class="form-check-label" for="order_mode">
|
|
||||||
Enable order mode
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" :disabled="orderMode" type="radio" value="1" v-model="activeFilter" id="active_filter_1">
|
|
||||||
<label class="form-check-label" for="active_filter_1">
|
|
||||||
Show active accounts
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" :disabled="orderMode" type="radio" value="2" v-model="activeFilter" id="active_filter_2">
|
|
||||||
<label class="form-check-label" for="active_filter_2">
|
|
||||||
Show inactive accounts
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" :disabled="orderMode" type="radio" value="3" v-model="activeFilter" id="active_filter_3">
|
|
||||||
<label class="form-check-label" for="active_filter_3">
|
|
||||||
Show both
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "IndexOptions",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
type: 'invalid'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// watch orderMode, if its false then go to active in filter.
|
|
||||||
computed: {
|
|
||||||
orderMode: {
|
|
||||||
get() {
|
|
||||||
return this.$store.getters["accounts/index/orderMode"];
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
this.$store.commit('accounts/index/setOrderMode', value);
|
|
||||||
if(true===value) {
|
|
||||||
this.$store.commit('accounts/index/setActiveFilter', 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
activeFilter: {
|
|
||||||
get() {
|
|
||||||
return this.$store.getters["accounts/index/activeFilter"];
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
this.$store.commit('accounts/index/setActiveFilter', parseInt(value));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
let pathName = window.location.pathname;
|
|
||||||
let parts = pathName.split('/');
|
|
||||||
this.type = parts[parts.length - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Interest.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('form.interest') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
v-model="interest"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="$t('form.interest')"
|
|
||||||
name="interest"
|
|
||||||
:disabled=disabled
|
|
||||||
type="number"
|
|
||||||
step="8"
|
|
||||||
/>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<div class="input-group-text">%</div>
|
|
||||||
<button class="btn btn-outline-secondary" tabindex="-1" type="button"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "Interest",
|
|
||||||
props: {
|
|
||||||
value: {},
|
|
||||||
errors: {},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
interest: this.value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
interest: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'interest', value: value});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
<!--
|
|
||||||
- InterestPeriod.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('form.interest_period') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="loading">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="!loading">
|
|
||||||
<select
|
|
||||||
ref="interest_period"
|
|
||||||
v-model="interest_period"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:title="$t('form.interest_period')"
|
|
||||||
autocomplete="off"
|
|
||||||
:disabled=disabled
|
|
||||||
name="interest_period"
|
|
||||||
>
|
|
||||||
<option v-for="period in this.periodList" :label="period.title" :value="period.slug">{{ period.title }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "InterestPeriod",
|
|
||||||
props: {
|
|
||||||
value: {},
|
|
||||||
errors: {},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
periodList: [],
|
|
||||||
interest_period: this.value,
|
|
||||||
loading: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadPeriods: function () {
|
|
||||||
//
|
|
||||||
axios.get('./api/v1/configuration/firefly.interest_periods')
|
|
||||||
.then(response => {
|
|
||||||
let content = response.data.data.value;
|
|
||||||
for (let i in content) {
|
|
||||||
if (content.hasOwnProperty(i)) {
|
|
||||||
let current = content[i];
|
|
||||||
this.periodList.push({slug: current, title: this.$t('firefly.interest_calc_' + current)})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
interest_period: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'interest_period', value: value});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.loadPeriods()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
<!--
|
|
||||||
- LiabilityAmount.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('form.amount') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
v-model="amount"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="$t('form.amount')"
|
|
||||||
name="liability_amount"
|
|
||||||
:disabled=disabled
|
|
||||||
type="number" step="any" min="0"
|
|
||||||
/>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" tabindex="-1" type="button"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "LiabilityAmount",
|
|
||||||
props: {
|
|
||||||
value: {},
|
|
||||||
errors: {},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
amount: this.value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
amount: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'liability_amount', value: value});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
<!--
|
|
||||||
- LiabilityDate.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('form.date') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
v-model="date"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="$t('form.date')"
|
|
||||||
name="liability_date"
|
|
||||||
:disabled=disabled
|
|
||||||
type="date"
|
|
||||||
/>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" tabindex="-1" type="button"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "LiabilityDate",
|
|
||||||
props: {
|
|
||||||
value: {},
|
|
||||||
errors: {},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
date: this.value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
date: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'liability_date', value: value});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
<!--
|
|
||||||
- LiabilityDirection.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('form.liability_direction') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<select
|
|
||||||
ref="liability_type"
|
|
||||||
v-model="liability_direction"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:title="$t('form.liability_direction')"
|
|
||||||
autocomplete="off"
|
|
||||||
name="liability_direction"
|
|
||||||
:disabled=disabled
|
|
||||||
>
|
|
||||||
<option :label="$t('firefly.liability_direction_credit')" value="credit">{{ $t('firefly.liability_direction_credit') }}</option>
|
|
||||||
<option :label="$t('firefly.liability_direction_debit')" value="debit">{{ $t('firefly.liability_direction_debit') }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "LiabilityDirection",
|
|
||||||
props: {
|
|
||||||
value: {},
|
|
||||||
errors: {},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
liability_direction: this.value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
liability_direction: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'liability_direction', value: value});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
<!--
|
|
||||||
- LiabilityType.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('form.liability_type') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="loading">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="!loading">
|
|
||||||
<select
|
|
||||||
ref="liability_type"
|
|
||||||
v-model="liability_type"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:title="$t('form.liability_type')"
|
|
||||||
autocomplete="off"
|
|
||||||
name="liability_type"
|
|
||||||
:disabled=disabled
|
|
||||||
>
|
|
||||||
<option v-for="type in this.typeList" :label="type.title" :value="type.slug">{{ type.title }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "LiabilityType",
|
|
||||||
props: {
|
|
||||||
value: {},
|
|
||||||
errors: {},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
typeList: [],
|
|
||||||
liability_type: this.value,
|
|
||||||
loading: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadRoles: function () {
|
|
||||||
//
|
|
||||||
axios.get('./api/v1/configuration/firefly.valid_liabilities')
|
|
||||||
.then(response => {
|
|
||||||
let content = response.data.data.value;
|
|
||||||
for (let i in content) {
|
|
||||||
if (content.hasOwnProperty(i)) {
|
|
||||||
let current = content[i];
|
|
||||||
this.typeList.push({slug: current, title: this.$t('firefly.account_type_' + current)})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
liability_type: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'liability_type', value: value});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.loadRoles()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Show.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
<!-- Custom Tabs will be put here (see file history). -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<TransactionListLarge
|
|
||||||
:entries="rawTransactions"
|
|
||||||
:isEmpty="isEmpty"
|
|
||||||
:page="currentPage"
|
|
||||||
ref="list"
|
|
||||||
:total="total"
|
|
||||||
:per-page="perPage"
|
|
||||||
:sort-desc="sortDesc"
|
|
||||||
v-on:jump-page="jumpToPage($event)"
|
|
||||||
v-on:refreshed-cache-key="refreshedKey"
|
|
||||||
/>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
Blocks
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
Blocks
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import TransactionListLarge from "../transactions/TransactionListLarge";
|
|
||||||
import {mapGetters} from "vuex";
|
|
||||||
import format from "date-fns/format";
|
|
||||||
import {configureAxios} from "../../shared/forageStore";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Show",
|
|
||||||
computed: {
|
|
||||||
...mapGetters('root', ['listPageSize', 'cacheKey']),
|
|
||||||
...mapGetters('dashboard/index', ['start', 'end',]),
|
|
||||||
'showReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && null !== this.listPageSize && this.ready;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
accountId: 0,
|
|
||||||
rawTransactions: [],
|
|
||||||
ready: false,
|
|
||||||
loading: false,
|
|
||||||
total: 0,
|
|
||||||
sortDesc: false,
|
|
||||||
currentPage: 1,
|
|
||||||
perPage: 51,
|
|
||||||
locale: 'en-US',
|
|
||||||
api: null,
|
|
||||||
nameLoading: false,
|
|
||||||
isEmpty: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.ready = true;
|
|
||||||
let parts = window.location.pathname.split('/');
|
|
||||||
this.accountId = parseInt(parts[parts.length - 1]);
|
|
||||||
this.perPage = this.listPageSize ?? 51;
|
|
||||||
|
|
||||||
let params = new URLSearchParams(window.location.search);
|
|
||||||
this.currentPage = params.get('page') ? parseInt(params.get('page')) : 1;
|
|
||||||
this.getTransactions();
|
|
||||||
this.updatePageTitle();
|
|
||||||
},
|
|
||||||
components: {TransactionListLarge},
|
|
||||||
methods: {
|
|
||||||
updatePageTitle: function () {
|
|
||||||
if (this.showReady && !this.nameLoading) {
|
|
||||||
// update page title.
|
|
||||||
this.nameLoading = true;
|
|
||||||
configureAxios().then(async (api) => {
|
|
||||||
let url = './api/v1/accounts/' + this.accountId;
|
|
||||||
api.get(url)
|
|
||||||
.then(response => {
|
|
||||||
let start = new Intl.DateTimeFormat(this.locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(this.start);
|
|
||||||
let end = new Intl.DateTimeFormat(this.locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(this.end);
|
|
||||||
document.getElementById('page-subTitle').innerText = this.$t('firefly.journals_in_period_for_account_js', {
|
|
||||||
start: start,
|
|
||||||
end: end,
|
|
||||||
title: response.data.data.attributes.name
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
refreshedKey: function () {
|
|
||||||
this.loading = false;
|
|
||||||
this.getTransactions();
|
|
||||||
this.updatePageTitle();
|
|
||||||
},
|
|
||||||
getTransactions: function () {
|
|
||||||
// console.log('getTransactions()');
|
|
||||||
if (this.showReady && !this.loading) {
|
|
||||||
// console.log('Show ready, not loading, go for download');
|
|
||||||
this.loading = true;
|
|
||||||
this.rawTransactions = [];
|
|
||||||
configureAxios().then(async (api) => {
|
|
||||||
// console.log('Now getTransactions() x Start');
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
let url = './api/v1/accounts/' + this.accountId + '/transactions?page=' + this.currentPage + '&limit=' + this.perPage + '&start=' + startStr + '&end=' + endStr + '&cache=' + this.cacheKey;
|
|
||||||
|
|
||||||
api.get(url)
|
|
||||||
.then(response => {
|
|
||||||
// console.log('Now getTransactions() DONE!');
|
|
||||||
this.total = parseInt(response.data.meta.pagination.total);
|
|
||||||
if (0 === this.total) {
|
|
||||||
this.isEmpty = true;
|
|
||||||
}
|
|
||||||
// let transactions = response.data.data;
|
|
||||||
// console.log('Have downloaded ' + transactions.length + ' transactions');
|
|
||||||
// console.log(response.data);
|
|
||||||
this.rawTransactions = response.data.data;
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
jumpToPage: function (event) {
|
|
||||||
// console.log('noticed a change in account/show!');
|
|
||||||
this.currentPage = event.page;
|
|
||||||
this.getTransactions();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
start: function () {
|
|
||||||
this.getTransactions();
|
|
||||||
this.updatePageTitle();
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
this.getTransactions();
|
|
||||||
this.updatePageTitle();
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,334 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Create.vue
|
|
||||||
- Copyright (c) 2021 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>
|
|
||||||
<Alert :message="errorMessage" type="danger"/>
|
|
||||||
<Alert :message="successMessage" type="success"/>
|
|
||||||
<form @submit="submitForm" autocomplete="off">
|
|
||||||
<div class="col">
|
|
||||||
<!-- tabs -->
|
|
||||||
<ul class="nav nav-tabs ml-auto p-2" id="subscriptionTabs">
|
|
||||||
<li>
|
|
||||||
<li class="nav-item"><a class="nav-link active" href="#subscription" data-toggle="pill">
|
|
||||||
Subscription
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="#rule" data-toggle="pill">
|
|
||||||
Rule
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="tab-content" id="subscriptionTabContent">
|
|
||||||
<div class="tab-pane show active" id="subscription" role="tabpanel" aria-labelledby="subscription-tab">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div class="card card-primary">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
{{ $t('firefly.mandatoryFields') }}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<GenericTextInput :disabled="submitting" v-model="name" field-name="name" :errors="errors.name" :title="$t('form.name')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericCurrency :disabled="submitting" v-model="currency_id" :errors="errors.currency_id" v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericTextInput :disabled="submitting" field-type="number" field-step="any" v-model="amount_min"
|
|
||||||
field-name="amount_min" :errors="errors.amount_min" :title="$t('form.amount_min')" v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericTextInput :disabled="submitting" field-type="number" field-step="any" v-model="amount_max"
|
|
||||||
field-name="amount_max" :errors="errors.amount_max" :title="$t('form.amount_max')" v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericTextInput :disabled="submitting" field-type="date" v-model="date" field-name="date"
|
|
||||||
:errors="errors.date" :title="$t('form.startdate')" v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextInput :disabled="submitting" field-type="date" v-model="end_date" field-name="end_date"
|
|
||||||
:errors="errors.end_date" :title="$t('form.end_date')" v-on:set-field="storeField($event)"/>
|
|
||||||
<GenericTextInput :disabled="submitting" field-type="date" v-model="extension_date" field-name="extension_date"
|
|
||||||
:errors="errors.extension_date" :title="$t('form.extension_date')" v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<RepeatFrequencyPeriod :disabled="submitting" v-model="repeat_freq" :errors="errors.repeat_freq"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
{{ $t('firefly.optionalFields') }}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<GenericTextarea :disabled="submitting" field-name="notes" :title="$t('form.notes')" v-model="notes" :errors="errors.notes"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericAttachments :disabled="submitting" :title="$t('form.attachments')" field-name="attachments" :errors="errors.attachments"
|
|
||||||
v-on:selected-attachments="selectedAttachments($event)"
|
|
||||||
v-on:selected-no-attachments="selectedNoAttachments($event)"
|
|
||||||
v-on:uploaded-attachments="uploadedAttachments($event)"
|
|
||||||
:upload-trigger="uploadTrigger"
|
|
||||||
:upload-object-type="uploadObjectType"
|
|
||||||
:upload-object-id="uploadObjectId"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<GenericTextInput :disabled="submitting" v-model="skip" field-name="skip" :errors="errors.skip" :title="$t('form.skip')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
|
|
||||||
<GenericGroup :disabled="submitting" v-model="group_title" field-name="group_title" :errors="errors.group_title"
|
|
||||||
:title="$t('form.object_group')"
|
|
||||||
v-on:set-field="storeField($event)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12 offset-xl-6 offset-lg-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-6 offset-lg-6">
|
|
||||||
<button :disabled=submitting type="button" @click="submitForm" class="btn btn-success btn-block">{{
|
|
||||||
$t('firefly.store_new_bill')
|
|
||||||
}}
|
|
||||||
</button>
|
|
||||||
<div class="form-check">
|
|
||||||
<input id="createAnother" v-model="createAnother" class="form-check-input" type="checkbox">
|
|
||||||
<label class="form-check-label" for="createAnother">
|
|
||||||
<span class="small">{{ $t('firefly.create_another') }}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check">
|
|
||||||
<input id="resetFormAfter" v-model="resetFormAfter" :disabled="!createAnother" class="form-check-input" type="checkbox">
|
|
||||||
<label class="form-check-label" for="resetFormAfter">
|
|
||||||
<span class="small">{{ $t('firefly.reset_after') }}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane show" id="rule" role="tabpanel" aria-labelledby="rule-tab">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div class="card card-primary">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
Title
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<p>
|
|
||||||
In the future here you can set rule info for the new subscription.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import RepeatFrequencyPeriod from "./RepeatFrequencyPeriod";
|
|
||||||
import Alert from '../partials/Alert';
|
|
||||||
import GenericTextInput from "../form/GenericTextInput";
|
|
||||||
import GenericCurrency from "../form/GenericCurrency";
|
|
||||||
import GenericTextarea from "../form/GenericTextarea";
|
|
||||||
import GenericAttachments from "../form/GenericAttachments";
|
|
||||||
import GenericGroup from "../form/GenericGroup";
|
|
||||||
import format from "date-fns/format";
|
|
||||||
|
|
||||||
const lodashClonedeep = require('lodash.clonedeep');
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Create",
|
|
||||||
components: {RepeatFrequencyPeriod, GenericAttachments, GenericGroup, GenericTextarea, Alert, GenericTextInput, GenericCurrency},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
submitting: false,
|
|
||||||
successMessage: '',
|
|
||||||
errorMessage: '',
|
|
||||||
createAnother: false,
|
|
||||||
resetFormAfter: false,
|
|
||||||
returnedId: 0,
|
|
||||||
returnedTitle: '',
|
|
||||||
|
|
||||||
// fields
|
|
||||||
name: '',
|
|
||||||
currency_id: null,
|
|
||||||
amount_min: '',
|
|
||||||
amount_max: '',
|
|
||||||
date: '',
|
|
||||||
end_date: '',
|
|
||||||
extension_date: '',
|
|
||||||
repeat_freq: 'monthly',
|
|
||||||
|
|
||||||
// optional fields
|
|
||||||
notes: '',
|
|
||||||
skip: '0',
|
|
||||||
group_title: '',
|
|
||||||
|
|
||||||
// has attachments to upload?
|
|
||||||
hasAttachments: false,
|
|
||||||
uploadTrigger: false,
|
|
||||||
uploadObjectId: 0,
|
|
||||||
uploadObjectType: 'Bill',
|
|
||||||
|
|
||||||
|
|
||||||
// optional fields:
|
|
||||||
location: {},
|
|
||||||
|
|
||||||
// errors
|
|
||||||
errors: {
|
|
||||||
currency_id: [],
|
|
||||||
repeat_freq: [],
|
|
||||||
group_title: [],
|
|
||||||
},
|
|
||||||
defaultErrors: {
|
|
||||||
name: [],
|
|
||||||
group_title: [],
|
|
||||||
currency_id: [],
|
|
||||||
amount_min: [],
|
|
||||||
amount_max: [],
|
|
||||||
date: [],
|
|
||||||
end_date: [],
|
|
||||||
extension_date: [],
|
|
||||||
repeat_freq: [],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.date = format(new Date, 'yyyy-MM-dd');
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
storeField: function (payload) {
|
|
||||||
// console.log(payload);
|
|
||||||
if ('location' === payload.field) {
|
|
||||||
if (true === payload.value.hasMarker) {
|
|
||||||
this.location = payload.value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.location = {};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this[payload.field] = payload.value;
|
|
||||||
},
|
|
||||||
selectedAttachments: function (e) {
|
|
||||||
this.hasAttachments = true;
|
|
||||||
},
|
|
||||||
selectedNoAttachments: function (e) {
|
|
||||||
this.hasAttachments = false;
|
|
||||||
},
|
|
||||||
submitForm: function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.submitting = true;
|
|
||||||
let submission = this.getSubmission();
|
|
||||||
// console.log('Will submit:');
|
|
||||||
// console.log(submission);
|
|
||||||
let url = './api/v1/bills';
|
|
||||||
|
|
||||||
axios.post(url, submission)
|
|
||||||
.then(response => {
|
|
||||||
this.errors = lodashClonedeep(this.defaultErrors);
|
|
||||||
this.returnedId = parseInt(response.data.data.id);
|
|
||||||
this.returnedTitle = response.data.data.attributes.name;
|
|
||||||
|
|
||||||
if (this.hasAttachments) {
|
|
||||||
// upload attachments. Do a callback to a finish up method.
|
|
||||||
//alert('must now upload!');
|
|
||||||
this.uploadObjectId = this.returnedId;
|
|
||||||
this.uploadTrigger = true;
|
|
||||||
}
|
|
||||||
if (!this.hasAttachments) {
|
|
||||||
this.finishSubmission();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
this.submitting = false;
|
|
||||||
this.parseErrors(error.response.data);
|
|
||||||
// display errors!
|
|
||||||
});
|
|
||||||
},
|
|
||||||
uploadedAttachments: function (e) {
|
|
||||||
this.finishSubmission();
|
|
||||||
},
|
|
||||||
finishSubmission: function () {
|
|
||||||
this.successMessage = this.$t('firefly.stored_new_bill_js', {ID: this.returnedId, name: this.returnedTitle});
|
|
||||||
// stay here is false?
|
|
||||||
if (false === this.createAnother) {
|
|
||||||
window.location.href = (window.previousURL ?? '/') + '?bill_id=' + this.returnedId + '&message=created';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.submitting = false;
|
|
||||||
if (this.resetFormAfter) {
|
|
||||||
// console.log('reset!');
|
|
||||||
this.name = '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
parseErrors: function (errors) {
|
|
||||||
this.errors = lodashClonedeep(this.defaultErrors);
|
|
||||||
// console.log(errors);
|
|
||||||
for (let i in errors.errors) {
|
|
||||||
if (errors.errors.hasOwnProperty(i)) {
|
|
||||||
this.errors[i] = errors.errors[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getSubmission: function () {
|
|
||||||
let submission = {
|
|
||||||
name: this.name,
|
|
||||||
currency_id: this.currency_id,
|
|
||||||
amount_min: this.amount_min,
|
|
||||||
amount_max: this.amount_max,
|
|
||||||
date: this.date,
|
|
||||||
repeat_freq: this.repeat_freq,
|
|
||||||
skip: this.skip,
|
|
||||||
active: true,
|
|
||||||
object_group_title: this.group_title
|
|
||||||
};
|
|
||||||
if (Object.keys(this.location).length >= 3) {
|
|
||||||
submission.longitude = this.location.lng;
|
|
||||||
submission.latitude = this.location.lat;
|
|
||||||
submission.zoom_level = this.location.zoomLevel;
|
|
||||||
}
|
|
||||||
if ('' !== this.end_date) {
|
|
||||||
submission.end_date = this.end_date;
|
|
||||||
}
|
|
||||||
if ('' !== this.extension_date) {
|
|
||||||
submission.extension_date = this.extension_date;
|
|
||||||
}
|
|
||||||
if ('' !== this.notes) {
|
|
||||||
submission.notes = this.notes;
|
|
||||||
}
|
|
||||||
|
|
||||||
return submission;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,360 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Index.vue
|
|
||||||
- Copyright (c) 2021 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>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<a href="./subscriptions/create" class="btn btn-sm mb-2 float-right btn-success"><span class="fas fa-plus"></span> {{
|
|
||||||
$t('firefly.create_new_bill')
|
|
||||||
}}</a>
|
|
||||||
<button @click="newCacheKey" class="btn btn-sm mb-2 mr-2 float-right btn-info"><span class="fas fa-sync"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row" v-for="group in sortedGroups">
|
|
||||||
<div v-if="group[1].bills.length > 0" class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
{{ group[1].title }}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body p-0">
|
|
||||||
<b-table id="my-table" striped hover responsive="md" primary-key="id" :no-local-sorting="false"
|
|
||||||
:items="group[1].bills"
|
|
||||||
sort-icon-left
|
|
||||||
:fields="fields"
|
|
||||||
:busy.sync="loading"
|
|
||||||
>
|
|
||||||
<template #cell(name)="data">
|
|
||||||
<a :href="'./bills/show/' + data.item.id">{{ data.item.name }}</a>
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
<small v-if="true === data.item.active && 0 === data.item.skip">{{ $t('firefly.bill_repeats_' + data.item.repeat_freq) }}</small>
|
|
||||||
<small v-if="true === data.item.active && 1 === data.item.skip">{{ $t('firefly.bill_repeats_' + data.item.repeat_freq + '_other') }}</small>
|
|
||||||
<small v-if="true === data.item.active && data.item.skip > 1">{{
|
|
||||||
$t('firefly.bill_repeats_' + data.item.repeat_freq + '_skip', {skip: data.item.skip + 1})
|
|
||||||
}}</small>
|
|
||||||
<small v-if="false === data.item.active">{{ $t('firefly.inactive') }}</small>
|
|
||||||
<!-- (rules, recurring) -->
|
|
||||||
</template>
|
|
||||||
<template #cell(expected_info)="data">
|
|
||||||
<span v-if="true === data.item.active && data.item.paid_dates.length > 0 && data.item.pay_dates.length > 0">
|
|
||||||
{{
|
|
||||||
new Intl.DateTimeFormat(locale, {
|
|
||||||
month: 'long',
|
|
||||||
year: 'numeric',
|
|
||||||
day: 'numeric'
|
|
||||||
}).format(new Date(data.item.next_expected_match.substring(0, 10)))
|
|
||||||
}}
|
|
||||||
<br>
|
|
||||||
</span>
|
|
||||||
<!--
|
|
||||||
not paid, not expected and active
|
|
||||||
-->
|
|
||||||
<span v-if="0 === data.item.paid_dates.length && 0 === data.item.pay_dates.length && true === data.item.active">
|
|
||||||
{{ $t('firefly.not_expected_period') }}
|
|
||||||
</span>
|
|
||||||
<!--
|
|
||||||
not paid but expected
|
|
||||||
-->
|
|
||||||
|
|
||||||
<span :title="new Intl.DateTimeFormat(locale, {
|
|
||||||
month: 'long',
|
|
||||||
year: 'numeric',
|
|
||||||
day: 'numeric'
|
|
||||||
}).format(new Date(data.item.pay_dates[0].substring(0,10)))"
|
|
||||||
class="text-danger" v-if="0 === data.item.paid_dates.length && data.item.pay_dates.length > 0 && true === data.item.active">
|
|
||||||
{{ $t('firefly.bill_expected_date_js', {date: data.item.next_expected_match_diff}) }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
bill is not active
|
|
||||||
-->
|
|
||||||
<span v-if="false === data.item.active">
|
|
||||||
~
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #cell(start_date)="data">
|
|
||||||
{{
|
|
||||||
new Intl.DateTimeFormat(locale, {
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'long',
|
|
||||||
day: 'numeric'
|
|
||||||
}).format(new Date(data.item.date.substring(0, 10)))
|
|
||||||
}}
|
|
||||||
</template>
|
|
||||||
<template #cell(end_date)="data">
|
|
||||||
<span v-if="null !== data.item.end_date">
|
|
||||||
{{
|
|
||||||
new Intl.DateTimeFormat(locale, {
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'long',
|
|
||||||
day: 'numeric'
|
|
||||||
}).format(new Date(data.item.end_date.substring(0, 10)))
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
<span v-if="null === data.item.end_date">{{ $t('firefly.forever') }}</span>
|
|
||||||
<span v-if="null !== data.item.extension_date"><br/>
|
|
||||||
<small>
|
|
||||||
{{
|
|
||||||
$t('firefly.extension_date_is', {
|
|
||||||
date: new Intl.DateTimeFormat(locale, {
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'long',
|
|
||||||
day: 'numeric'
|
|
||||||
}).format(new Date(data.item.extension_date.substring(0, 10)))
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
</small>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
<template #cell(amount)="data">
|
|
||||||
~ <span class="text-info">{{
|
|
||||||
Intl.NumberFormat(locale, {style: 'currency', currency: data.item.currency_code}).format((data.item.amount_min + data.item.amount_max) / 2)
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #cell(payment_info)="data">
|
|
||||||
<!--
|
|
||||||
paid_dates >= 0 (bill is paid X times).
|
|
||||||
Don't care about pay_dates.
|
|
||||||
-->
|
|
||||||
<span v-if="data.item.paid_dates.length > 0 && true === data.item.active">
|
|
||||||
<span v-for="currentPaid in data.item.paid_dates">
|
|
||||||
<a :href="'./transactions/show/' + currentPaid.transaction_group_id">
|
|
||||||
{{
|
|
||||||
new Intl.DateTimeFormat(locale, {
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'long',
|
|
||||||
day: 'numeric'
|
|
||||||
}).format(new Date(currentPaid.date.substring(0, 10)))
|
|
||||||
}}
|
|
||||||
</a>
|
|
||||||
<br/>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
bill is not active
|
|
||||||
-->
|
|
||||||
<span v-if="false === data.item.active">
|
|
||||||
~
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #cell(menu)="data">
|
|
||||||
<div class="btn-group btn-group-sm">
|
|
||||||
<div class="dropdown">
|
|
||||||
<button class="btn btn-light btn-sm dropdown-toggle" type="button" :id="'dropdownMenuButton' + data.item.id" data-toggle="dropdown"
|
|
||||||
aria-haspopup="true" aria-expanded="false">
|
|
||||||
{{ $t('firefly.actions') }}
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" :aria-labelledby="'dropdownMenuButton' + data.item.id">
|
|
||||||
<a class="dropdown-item" :href="'./subscriptions/edit/' + data.item.id"><span class="fa fas fa-pencil-alt"></span> {{
|
|
||||||
$t('firefly.edit')
|
|
||||||
}}</a>
|
|
||||||
<a class="dropdown-item" :href="'./subscriptions/delete/' + data.item.id"><span class="fa far fa-trash"></span> {{
|
|
||||||
$t('firefly.delete')
|
|
||||||
}}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</b-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<a href="./subscriptions/create" class="btn btn-sm mt-2 float-right btn-success"><span class="fas fa-plus"></span> {{
|
|
||||||
$t('firefly.create_new_bill')
|
|
||||||
}}</a>
|
|
||||||
<button @click="newCacheKey" class="btn btn-sm mt-2 mr-2 float-right btn-info"><span class="fas fa-sync"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {mapGetters, mapMutations} from "vuex";
|
|
||||||
import {configureAxios} from "../../shared/forageStore";
|
|
||||||
import format from "date-fns/format";
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Index",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
groups: {},
|
|
||||||
downloaded: false,
|
|
||||||
loading: false,
|
|
||||||
locale: 'en-US',
|
|
||||||
sortedGroups: [],
|
|
||||||
fields: [],
|
|
||||||
fnsLocale: null,
|
|
||||||
ready: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
start: function () {
|
|
||||||
this.downloadBills(1);
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
this.downloadBills(1);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('root', ['listPageSize', 'cacheKey']),
|
|
||||||
...mapGetters('dashboard/index', ['start', 'end',]),
|
|
||||||
'indexReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && null !== this.listPageSize && this.ready;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
this.updateFieldList();
|
|
||||||
this.ready = true;
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapMutations('root', ['refreshCacheKey',]),
|
|
||||||
formatDate: function (date, frm) {
|
|
||||||
return format(date, frm, {locale: {code: this.locale}});
|
|
||||||
},
|
|
||||||
updateFieldList: function () {
|
|
||||||
this.fields = [];
|
|
||||||
this.fields.push({key: 'name', label: this.$t('list.name')});
|
|
||||||
|
|
||||||
this.fields.push({key: 'expected_info', label: this.$t('list.expected_info')});
|
|
||||||
this.fields.push({key: 'start_date', label: this.$t('list.start_date')});
|
|
||||||
this.fields.push({key: 'end_date', label: this.$t('list.end_date')});
|
|
||||||
|
|
||||||
this.fields.push({key: 'amount', label: this.$t('list.amount')});
|
|
||||||
this.fields.push({key: 'payment_info', label: this.$t('list.payment_info')});
|
|
||||||
|
|
||||||
this.fields.push({key: 'menu', label: ' ', sortable: false});
|
|
||||||
},
|
|
||||||
newCacheKey: function () {
|
|
||||||
this.refreshCacheKey();
|
|
||||||
this.downloaded = false;
|
|
||||||
this.accounts = [];
|
|
||||||
this.downloadBills(1);
|
|
||||||
},
|
|
||||||
resetGroups: function () {
|
|
||||||
this.groups = {};
|
|
||||||
this.groups[0] =
|
|
||||||
{
|
|
||||||
id: 0,
|
|
||||||
title: this.$t('firefly.default_group_title_name'),
|
|
||||||
order: 1,
|
|
||||||
bills: []
|
|
||||||
};
|
|
||||||
},
|
|
||||||
downloadBills: function (page) {
|
|
||||||
// console.log('downloadBills');
|
|
||||||
// console.log(this.indexReady);
|
|
||||||
// console.log(this.loading);
|
|
||||||
// console.log(this.downloaded);
|
|
||||||
this.resetGroups();
|
|
||||||
// console.log('getAccountList()');
|
|
||||||
if (this.indexReady && !this.loading && !this.downloaded) {
|
|
||||||
this.loading = true;
|
|
||||||
configureAxios().then(async (api) => {
|
|
||||||
// get date from session.
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
|
|
||||||
api.get('./api/v1/bills?page=' + page + '&key=' + this.cacheKey + '&start='+startStr+'&end=' + endStr)
|
|
||||||
.then(response => {
|
|
||||||
// pages
|
|
||||||
let currentPage = parseInt(response.data.meta.pagination.current_page);
|
|
||||||
let totalPage = parseInt(response.data.meta.pagination.total_pages);
|
|
||||||
this.parseBills(response.data.data);
|
|
||||||
if (currentPage < totalPage) {
|
|
||||||
let nextPage = currentPage + 1;
|
|
||||||
this.downloadBills(nextPage);
|
|
||||||
}
|
|
||||||
if (currentPage >= totalPage) {
|
|
||||||
this.downloaded = true;
|
|
||||||
}
|
|
||||||
this.sortGroups();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
sortGroups: function () {
|
|
||||||
const sortable = Object.entries(this.groups);
|
|
||||||
//console.log('sortable');
|
|
||||||
//console.log(sortable);
|
|
||||||
sortable.sort(function (a, b) {
|
|
||||||
return a.order - b.order;
|
|
||||||
});
|
|
||||||
this.sortedGroups = sortable;
|
|
||||||
this.loading = false;
|
|
||||||
//console.log(this.sortedGroups);
|
|
||||||
},
|
|
||||||
parseBills: function (data) {
|
|
||||||
for (let key in data) {
|
|
||||||
if (data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
|
||||||
let current = data[key];
|
|
||||||
let bill = {};
|
|
||||||
|
|
||||||
// create group of necessary.
|
|
||||||
let groupId = null === current.attributes.object_group_id ? 0 : parseInt(current.attributes.object_group_id);
|
|
||||||
if (0 !== groupId && !(groupId in this.groups)) {
|
|
||||||
this.groups[groupId] = {
|
|
||||||
id: groupId,
|
|
||||||
title: current.attributes.object_group_title,
|
|
||||||
order: parseInt(current.attributes.object_group_order),
|
|
||||||
bills: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bill.id = parseInt(current.id);
|
|
||||||
bill.order = parseInt(current.attributes.order);
|
|
||||||
bill.name = current.attributes.name;
|
|
||||||
bill.repeat_freq = current.attributes.repeat_freq;
|
|
||||||
bill.skip = current.attributes.skip;
|
|
||||||
bill.active = current.attributes.active;
|
|
||||||
bill.date = current.attributes.date;
|
|
||||||
bill.end_date = current.attributes.end_date;
|
|
||||||
bill.extension_date = current.attributes.extension_date;
|
|
||||||
bill.amount_max = parseFloat(current.attributes.amount_max);
|
|
||||||
bill.amount_min = parseFloat(current.attributes.amount_min);
|
|
||||||
bill.currency_code = current.attributes.currency_code;
|
|
||||||
bill.currency_id = parseInt(current.attributes.currency_id);
|
|
||||||
bill.currency_decimal_places = parseInt(current.attributes.currency_decimal_places);
|
|
||||||
bill.currency_symbol = current.attributes.currency_symbol;
|
|
||||||
bill.next_expected_match = current.attributes.next_expected_match;
|
|
||||||
bill.next_expected_match_diff = current.attributes.next_expected_match_diff;
|
|
||||||
|
|
||||||
bill.notes = current.attributes.notes;
|
|
||||||
bill.paid_dates = current.attributes.paid_dates;
|
|
||||||
bill.pay_dates = current.attributes.pay_dates;
|
|
||||||
|
|
||||||
this.groups[groupId].bills.push(bill);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
<!--
|
|
||||||
- InterestPeriod.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('form.repeat_freq') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="loading">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="!loading">
|
|
||||||
<select
|
|
||||||
ref="repeat_freq"
|
|
||||||
v-model="repeat_freq"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:title="$t('form.repeat_freq')"
|
|
||||||
autocomplete="off"
|
|
||||||
:disabled=disabled
|
|
||||||
name="repeat_freq"
|
|
||||||
>
|
|
||||||
<option v-for="period in this.periodList" :label="period.title" :value="period.slug">{{ period.title }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {configureAxios} from "../../shared/forageStore";
|
|
||||||
import {mapGetters, mapMutations} from "vuex";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "RepeatFrequencyPeriod",
|
|
||||||
props: {
|
|
||||||
value: {},
|
|
||||||
errors: {},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('root', [ 'cacheKey']),
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
periodList: [],
|
|
||||||
repeat_freq: this.value,
|
|
||||||
loading: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapMutations('root', ['refreshCacheKey',]),
|
|
||||||
loadPeriods: function () {
|
|
||||||
configureAxios().then(async (api) => {
|
|
||||||
api.get('./api/v1/configuration/firefly.bill_periods?key=' + this.cacheKey)
|
|
||||||
.then(response => {
|
|
||||||
let content = response.data.data.value;
|
|
||||||
for (let i in content) {
|
|
||||||
if (content.hasOwnProperty(i)) {
|
|
||||||
let current = content[i];
|
|
||||||
this.periodList.push({slug: current, title: this.$t('firefly.repeat_freq_' + current)})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
repeat_freq: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'repeat_freq', value: value});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.loadPeriods()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Index.vue
|
|
||||||
- Copyright (c) 2021 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>
|
|
||||||
<p>
|
|
||||||
<span class="d-block">(all)</span>
|
|
||||||
<span class="d-none d-xl-block">xl</span>
|
|
||||||
<span class="d-none d-lg-block d-xl-none">lg</span>
|
|
||||||
<span class="d-none d-md-block d-lg-none">md</span>
|
|
||||||
<span class="d-none d-sm-block d-md-none">sm</span>
|
|
||||||
<span class="d-block d-sm-none">xs</span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-2 col-lg-4 col-md-4 col-sm-4 col-6">
|
|
||||||
<div class="card card-primary">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">Budgets</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
Budget X<br>
|
|
||||||
Budget Y<br>
|
|
||||||
Budget X<br>
|
|
||||||
Budget Y<br>
|
|
||||||
Budget X<br>
|
|
||||||
Budget Y<br>
|
|
||||||
Budget X<br>
|
|
||||||
Budget Y<br>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-10 col-lg-8 col-md-8 col-sm-8 col-6">
|
|
||||||
<div class="container-fluid" style="overflow:scroll;">
|
|
||||||
<div class="d-flex flex-row flex-nowrap">
|
|
||||||
<div class="card card-body-budget" v-for="n in 5">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">Maand yXz</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
Some text<br>
|
|
||||||
Some text<br>
|
|
||||||
Some text<br>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "Index"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
.card-body-budget {
|
|
||||||
min-width: 300px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.holder-titles {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title-block {
|
|
||||||
border: 1px red solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.holder-blocks {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.budget-block {
|
|
||||||
border: 1px blue solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.budget-block-unused {
|
|
||||||
border: 1px green solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.budget-block-unset {
|
|
||||||
border: 1px purple solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
<!--
|
|
||||||
- DataConverter.vue
|
|
||||||
- Copyright (c) 2020 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/>.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "DataConverter",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
dataSet: null,
|
|
||||||
newDataSet: null,
|
|
||||||
locale: localStorage.local,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
convertChart(dataSet) {
|
|
||||||
this.dataSet = dataSet;
|
|
||||||
this.newDataSet = {
|
|
||||||
//count: 0,
|
|
||||||
labels: [],
|
|
||||||
datasets: []
|
|
||||||
}
|
|
||||||
this.getLabels();
|
|
||||||
this.getDataSets();
|
|
||||||
//this.newDataSet.count = this.newDataSet.datasets.length;
|
|
||||||
return this.newDataSet;
|
|
||||||
},
|
|
||||||
|
|
||||||
colorizeBarData(dataSet) {
|
|
||||||
this.dataSet = dataSet;
|
|
||||||
this.newDataSet = {
|
|
||||||
//count: 0,
|
|
||||||
labels: [],
|
|
||||||
datasets: []
|
|
||||||
};
|
|
||||||
// colors
|
|
||||||
let colourSet = [
|
|
||||||
[53, 124, 165],
|
|
||||||
[0, 141, 76], // green
|
|
||||||
[219, 139, 11],
|
|
||||||
[202, 25, 90], // paars rood-ish #CA195A
|
|
||||||
[85, 82, 153],
|
|
||||||
[66, 133, 244],
|
|
||||||
[219, 68, 55], // red #DB4437
|
|
||||||
[244, 180, 0],
|
|
||||||
[15, 157, 88],
|
|
||||||
[171, 71, 188],
|
|
||||||
[0, 172, 193],
|
|
||||||
[255, 112, 67],
|
|
||||||
[158, 157, 36],
|
|
||||||
[92, 107, 192],
|
|
||||||
[240, 98, 146],
|
|
||||||
[0, 121, 107],
|
|
||||||
[194, 24, 91]
|
|
||||||
];
|
|
||||||
|
|
||||||
let fillColors = [];
|
|
||||||
//let strokePointHighColors = [];
|
|
||||||
|
|
||||||
|
|
||||||
//for (let i = 0; i < colourSet.length; i++) {
|
|
||||||
for (let value of colourSet) {
|
|
||||||
fillColors.push("rgba(" + value[0] + ", " + value[1] + ", " + value[2] + ", 0.5)");
|
|
||||||
//strokePointHighColors.push("rgba(" + colourSet[i][0] + ", " + colourSet[i][1] + ", " + colourSet[i][2] + ", 0.9)");
|
|
||||||
}
|
|
||||||
this.newDataSet.labels = this.dataSet.labels;
|
|
||||||
//this.newDataSet.count = this.dataSet.count;
|
|
||||||
for (let setKey in this.dataSet.datasets) {
|
|
||||||
if (this.dataSet.datasets.hasOwnProperty(setKey)) {
|
|
||||||
var dataset = this.dataSet.datasets[setKey];
|
|
||||||
dataset.fill = false;
|
|
||||||
dataset.backgroundColor = dataset.borderColor = fillColors[setKey];
|
|
||||||
this.newDataSet.datasets.push(dataset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.newDataSet;
|
|
||||||
},
|
|
||||||
|
|
||||||
colorizeLineData(dataSet) {
|
|
||||||
this.dataSet = dataSet;
|
|
||||||
this.newDataSet = {
|
|
||||||
//count: 0,
|
|
||||||
labels: [],
|
|
||||||
datasets: []
|
|
||||||
};
|
|
||||||
// colors
|
|
||||||
let colourSet = [
|
|
||||||
[53, 124, 165],
|
|
||||||
[0, 141, 76], // green
|
|
||||||
[219, 139, 11],
|
|
||||||
[202, 25, 90], // paars rood-ish #CA195A
|
|
||||||
[85, 82, 153],
|
|
||||||
[66, 133, 244],
|
|
||||||
[219, 68, 55], // red #DB4437
|
|
||||||
[244, 180, 0],
|
|
||||||
[15, 157, 88],
|
|
||||||
[171, 71, 188],
|
|
||||||
[0, 172, 193],
|
|
||||||
[255, 112, 67],
|
|
||||||
[158, 157, 36],
|
|
||||||
[92, 107, 192],
|
|
||||||
[240, 98, 146],
|
|
||||||
[0, 121, 107],
|
|
||||||
[194, 24, 91]
|
|
||||||
];
|
|
||||||
|
|
||||||
let fillColors = [];
|
|
||||||
//let strokePointHighColors = [];
|
|
||||||
|
|
||||||
|
|
||||||
//for (let i = 0; i < colourSet.length; i++) {
|
|
||||||
for (let value of colourSet) {
|
|
||||||
fillColors.push("rgba(" + value[0] + ", " + value[1] + ", " + value[2] + ", 0.5)");
|
|
||||||
//strokePointHighColors.push("rgba(" + colourSet[i][0] + ", " + colourSet[i][1] + ", " + colourSet[i][2] + ", 0.9)");
|
|
||||||
}
|
|
||||||
this.newDataSet.labels = this.dataSet.labels;
|
|
||||||
//this.newDataSet.count = this.dataSet.count;
|
|
||||||
for (let setKey in this.dataSet.datasets) {
|
|
||||||
if (this.dataSet.datasets.hasOwnProperty(setKey)) {
|
|
||||||
let dataset = this.dataSet.datasets[setKey];
|
|
||||||
dataset.fill = false;
|
|
||||||
dataset.backgroundColor = dataset.borderColor = fillColors[setKey];
|
|
||||||
this.newDataSet.datasets.push(dataset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.newDataSet;
|
|
||||||
},
|
|
||||||
convertLabelsToDate(dataSet) {
|
|
||||||
for (let labelKey in dataSet.labels) {
|
|
||||||
if (dataSet.labels.hasOwnProperty(labelKey)) {
|
|
||||||
const unixTimeZero = Date.parse(dataSet.labels[labelKey]);
|
|
||||||
dataSet.labels[labelKey] = new Intl.DateTimeFormat(this.locale).format(unixTimeZero);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dataSet;
|
|
||||||
},
|
|
||||||
getLabels() {
|
|
||||||
let firstSet = this.dataSet[0];
|
|
||||||
if (typeof firstSet !== 'undefined') {
|
|
||||||
for (const entryLabel in firstSet.entries) {
|
|
||||||
if (firstSet.entries.hasOwnProperty(entryLabel)) {
|
|
||||||
this.newDataSet.labels.push(entryLabel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getDataSets() {
|
|
||||||
for (const setKey in this.dataSet) {
|
|
||||||
if (this.dataSet.hasOwnProperty(setKey)) {
|
|
||||||
let newSet = {};
|
|
||||||
let oldSet = this.dataSet[setKey];
|
|
||||||
if (typeof oldSet !== 'undefined') {
|
|
||||||
newSet.label = oldSet.label;
|
|
||||||
newSet.type = oldSet.type;
|
|
||||||
newSet.currency_symbol = oldSet.currency_symbol;
|
|
||||||
newSet.currency_code = oldSet.currency_code;
|
|
||||||
//newSet.yAxisID = oldSet.yAxisID;
|
|
||||||
newSet.data = [];
|
|
||||||
for (const entryLabel in oldSet.entries) {
|
|
||||||
if (oldSet.entries.hasOwnProperty(entryLabel)) {
|
|
||||||
newSet.data.push(oldSet.entries[entryLabel]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.newDataSet.datasets.push(newSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
<!--
|
|
||||||
- DefaultLineOptions.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import FormatLabel from "../charts/FormatLabel";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "DefaultBarOptions",
|
|
||||||
data() {
|
|
||||||
return {}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getDefaultOptions() {
|
|
||||||
return {
|
|
||||||
type: 'bar',
|
|
||||||
layout: {
|
|
||||||
padding: {
|
|
||||||
left: 50,
|
|
||||||
right: 50,
|
|
||||||
top: 0,
|
|
||||||
bottom: 0
|
|
||||||
},
|
|
||||||
},
|
|
||||||
stacked: true,
|
|
||||||
elements: {
|
|
||||||
line: {
|
|
||||||
cubicInterpolationMode: 'monotone'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
animation: {
|
|
||||||
duration: 0,
|
|
||||||
},
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
scales: {
|
|
||||||
xAxes: [
|
|
||||||
{
|
|
||||||
stacked: true,
|
|
||||||
gridLines: {
|
|
||||||
display: false
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
// break ticks when too long.
|
|
||||||
callback: function (value, index, values) {
|
|
||||||
return FormatLabel.methods.formatLabel(value, 20);
|
|
||||||
//return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
yAxes: [{
|
|
||||||
stacked: false,
|
|
||||||
display: true,
|
|
||||||
drawOnChartArea: false,
|
|
||||||
offset: true,
|
|
||||||
beginAtZero: true,
|
|
||||||
ticks: {
|
|
||||||
callback: function (tickValue) {
|
|
||||||
"use strict";
|
|
||||||
let currencyCode = this.chart.data.datasets[0] ? this.chart.data.datasets[0].currency_code : 'EUR';
|
|
||||||
return new Intl.NumberFormat(localStorage.locale, {style: 'currency', currency: currencyCode}).format(tickValue);
|
|
||||||
},
|
|
||||||
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
tooltips: {
|
|
||||||
mode: 'label',
|
|
||||||
callbacks: {
|
|
||||||
label: function (tooltipItem, data) {
|
|
||||||
"use strict";
|
|
||||||
let currencyCode = data.datasets[tooltipItem.datasetIndex] ? data.datasets[tooltipItem.datasetIndex].currency_code : 'EUR';
|
|
||||||
let nrString = new Intl.NumberFormat(localStorage.locale, {
|
|
||||||
style: 'currency',
|
|
||||||
currency: currencyCode
|
|
||||||
}).format(tooltipItem.yLabel);
|
|
||||||
|
|
||||||
return data.datasets[tooltipItem.datasetIndex].label + ': ' + nrString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
<!--
|
|
||||||
- DefaultLineOptions.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "DefaultLineOptions",
|
|
||||||
data() {
|
|
||||||
return {}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/**
|
|
||||||
* Takes a string phrase and breaks it into separate phrases no bigger than 'maxwidth', breaks are made at complete words.
|
|
||||||
* https://stackoverflow.com/questions/21409717/chart-js-and-long-labels
|
|
||||||
*
|
|
||||||
* @param str
|
|
||||||
* @param maxwidth
|
|
||||||
* @returns {Array}
|
|
||||||
*/
|
|
||||||
formatLabel(str, maxwidth) {
|
|
||||||
var sections = [];
|
|
||||||
str = String(str);
|
|
||||||
var words = str.split(" ");
|
|
||||||
var temp = "";
|
|
||||||
|
|
||||||
words.forEach(function (item, index) {
|
|
||||||
if (temp.length > 0) {
|
|
||||||
var concat = temp + ' ' + item;
|
|
||||||
|
|
||||||
if (concat.length > maxwidth) {
|
|
||||||
sections.push(temp);
|
|
||||||
temp = "";
|
|
||||||
} else {
|
|
||||||
if (index === (words.length - 1)) {
|
|
||||||
sections.push(concat);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
temp = concat;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index === (words.length - 1)) {
|
|
||||||
sections.push(item);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.length < maxwidth) {
|
|
||||||
temp = item;
|
|
||||||
} else {
|
|
||||||
sections.push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
return sections;
|
|
||||||
},
|
|
||||||
getDefaultOptions() {
|
|
||||||
return {
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
animations: false,
|
|
||||||
|
|
||||||
elements: {
|
|
||||||
line: {
|
|
||||||
cubicInterpolationMode: 'monotone'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
//type: 'linear'
|
|
||||||
grid: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
callback: function (value, index, values) {
|
|
||||||
let dateObj = new Date(this.getLabelForValue(value).split('T')[0]);
|
|
||||||
return new Intl.DateTimeFormat(localStorage.locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(dateObj);
|
|
||||||
//return str;
|
|
||||||
// // //console.log();
|
|
||||||
// // //return self.formatLabel(value, 20);
|
|
||||||
// // return self.formatLabel(str, 20);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
suggestedMin: 0
|
|
||||||
|
|
||||||
//type: 'linear'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// scales: {
|
|
||||||
// xAxes: [
|
|
||||||
// {
|
|
||||||
// gridLines: {
|
|
||||||
// display: false
|
|
||||||
// },
|
|
||||||
// ticks: {
|
|
||||||
// // break ticks when too long
|
|
||||||
// callback: function (value, index, values) {
|
|
||||||
// return value;
|
|
||||||
// // date format
|
|
||||||
// // let dateObj = new Date(value);
|
|
||||||
// // let options = {year: 'numeric', month: 'long', day: 'numeric'};
|
|
||||||
// // let str = new Intl.DateTimeFormat(localStorage.locale, options).format(dateObj);
|
|
||||||
// // //console.log();
|
|
||||||
// // //return self.formatLabel(value, 20);
|
|
||||||
// // return self.formatLabel(str, 20);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ],
|
|
||||||
// yAxes: [{
|
|
||||||
// display: true,
|
|
||||||
// ticks: {
|
|
||||||
// callback: function (tickValue) {
|
|
||||||
// "use strict";
|
|
||||||
// return tickValue;
|
|
||||||
// // let currencyCode = this.chart.data.datasets[0].currency_code ? this.chart.data.datasets[0].currency_code : 'EUR';
|
|
||||||
// // return new Intl.NumberFormat(localStorage.locale, {style: 'currency', currency: currencyCode}).format(tickValue);
|
|
||||||
// },
|
|
||||||
// beginAtZero: true
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }]
|
|
||||||
// },
|
|
||||||
// tooltips: {
|
|
||||||
// mode: 'index',
|
|
||||||
// // callbacks: {
|
|
||||||
// // label: function (tooltipItem, data) {
|
|
||||||
// // "use strict";
|
|
||||||
// // let currencyCode = data.datasets[tooltipItem.datasetIndex].currency_code ? data.datasets[tooltipItem.datasetIndex].currency_code : 'EUR';
|
|
||||||
// // let nrString =
|
|
||||||
// // new Intl.NumberFormat(localStorage.locale, {style: 'currency', currency: currencyCode}).format(tooltipItem.yLabel)
|
|
||||||
// //
|
|
||||||
// // return data.datasets[tooltipItem.datasetIndex].label + ': ' + nrString;
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<!--
|
|
||||||
- DefaultPieOptions.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "DefaultPieOptions"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
<!--
|
|
||||||
- FormatLabel.vue
|
|
||||||
- Copyright (c) 2020 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/>.
|
|
||||||
-->
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "FormatLabel",
|
|
||||||
methods: {
|
|
||||||
/**
|
|
||||||
* Takes a string phrase and breaks it into separate phrases no bigger than 'maxwidth', breaks are made at complete words.
|
|
||||||
* https://stackoverflow.com/questions/21409717/chart-js-and-long-labels
|
|
||||||
*
|
|
||||||
* @param str
|
|
||||||
* @param maxwidth
|
|
||||||
* @returns {Array}
|
|
||||||
*/
|
|
||||||
formatLabel(str, maxwidth) {
|
|
||||||
var sections = [];
|
|
||||||
str = String(str);
|
|
||||||
var words = str.split(" ");
|
|
||||||
var temp = "";
|
|
||||||
|
|
||||||
words.forEach(function (item, index) {
|
|
||||||
if (temp.length > 0) {
|
|
||||||
var concat = temp + ' ' + item;
|
|
||||||
|
|
||||||
if (concat.length > maxwidth) {
|
|
||||||
sections.push(temp);
|
|
||||||
temp = "";
|
|
||||||
} else {
|
|
||||||
if (index === (words.length - 1)) {
|
|
||||||
sections.push(concat);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
temp = concat;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index === (words.length - 1)) {
|
|
||||||
sections.push(item);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.length < maxwidth) {
|
|
||||||
temp = item;
|
|
||||||
} else {
|
|
||||||
sections.push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
return sections;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
<!--
|
|
||||||
- BudgetRow.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<tr>
|
|
||||||
<td style="width:25%;">
|
|
||||||
<a :href="'./budgets/show/' + budgetLimit.budget_id">{{ budgetLimit.budget_name }}</a>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td style="vertical-align: middle">
|
|
||||||
<div class="progress progress active">
|
|
||||||
<div :aria-valuenow="budgetLimit.pctGreen" :style="'width: '+ budgetLimit.pctGreen + '%;'"
|
|
||||||
aria-valuemax="100" aria-valuemin="0" class="progress-bar bg-success" role="progressbar">
|
|
||||||
<span v-if="budgetLimit.pctGreen > 35">
|
|
||||||
{{ $t('firefly.spent_x_of_y', {amount: Intl.NumberFormat(locale, {style: 'currency', currency: budgetLimit.currency_code}).format(budgetLimit.spent), total: Intl.NumberFormat(locale, {style: 'currency', currency: budgetLimit.currency_code}).format(budgetLimit.amount)}) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div :aria-valuenow="budgetLimit.pctOrange" :style="'width: '+ budgetLimit.pctOrange + '%;'"
|
|
||||||
aria-valuemax="100" aria-valuemin="0" class="progress-bar bg-warning" role="progressbar">
|
|
||||||
<span v-if="budgetLimit.pctRed <= 50 && budgetLimit.pctOrange > 35">
|
|
||||||
{{ $t('firefly.spent_x_of_y', {amount: Intl.NumberFormat(locale, {style: 'currency', currency: budgetLimit.currency_code}).format(budgetLimit.spent), total: Intl.NumberFormat(locale, {style: 'currency', currency: budgetLimit.currency_code}).format(budgetLimit.amount)}) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div :aria-valuenow="budgetLimit.pctRed" :style="'width: '+ budgetLimit.pctRed + '%;'"
|
|
||||||
aria-valuemax="100" aria-valuemin="0" class="progress-bar bg-danger" role="progressbar">
|
|
||||||
<span v-if="budgetLimit.pctOrange <= 50 && budgetLimit.pctRed > 35" class="text-white">
|
|
||||||
{{ $t('firefly.spent_x_of_y', {amount: Intl.NumberFormat(locale, {style: 'currency', currency: budgetLimit.currency_code}).format(budgetLimit.spent), total: Intl.NumberFormat(locale, {style: 'currency', currency: budgetLimit.currency_code}).format(budgetLimit.amount)}) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- amount if bar is very small -->
|
|
||||||
<span v-if="budgetLimit.pctGreen <= 35 && 0 === budgetLimit.pctOrange && 0 === budgetLimit.pctRed && 0 !== budgetLimit.pctGreen" style="line-height: 16px;">
|
|
||||||
{{ $t('firefly.spent_x_of_y', {amount: Intl.NumberFormat(locale, {style: 'currency', currency: budgetLimit.currency_code}).format(budgetLimit.spent), total: Intl.NumberFormat(locale, {style: 'currency', currency: budgetLimit.currency_code}).format(budgetLimit.amount)}) }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<small class="d-none d-lg-block">
|
|
||||||
{{ new Intl.DateTimeFormat(locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(budgetLimit.start) }}
|
|
||||||
→
|
|
||||||
{{ new Intl.DateTimeFormat(locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(budgetLimit.end) }}
|
|
||||||
</small>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="align-middle d-none d-lg-table-cell" style="width:10%;">
|
|
||||||
<span v-if="parseFloat(budgetLimit.amount) + parseFloat(budgetLimit.spent) > 0" class="text-success">
|
|
||||||
{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency',
|
|
||||||
currency: budgetLimit.currency_code
|
|
||||||
}).format(parseFloat(budgetLimit.amount) + parseFloat(budgetLimit.spent))
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
<span v-if="0.0 === parseFloat(budgetLimit.amount) + parseFloat(budgetLimit.spent)" class="text-muted">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: budgetLimit.currency_code}).format(0) }}
|
|
||||||
</span>
|
|
||||||
<span v-if="parseFloat(budgetLimit.amount) + parseFloat(budgetLimit.spent) < 0" class="text-danger">
|
|
||||||
{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency',
|
|
||||||
currency: budgetLimit.currency_code
|
|
||||||
}).format(parseFloat(budgetLimit.amount) + parseFloat(budgetLimit.spent))
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "BudgetLimitRow",
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
locale: 'en-US',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
budgetLimit: {
|
|
||||||
type: Object,
|
|
||||||
default: function () {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
budget: {
|
|
||||||
type: Object,
|
|
||||||
default: function () {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
<!--
|
|
||||||
- BudgetListGroup.vue
|
|
||||||
- Copyright (c) 2020 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="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">{{ title }}</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body table-responsive p-0">
|
|
||||||
<table class="table table-sm">
|
|
||||||
<caption style="display:none;">{{ title }}</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">{{ $t('firefly.budget') }}</th>
|
|
||||||
<th scope="col">{{ $t('firefly.spent') }}</th>
|
|
||||||
<th scope="col">{{ $t('firefly.left') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<BudgetLimitRow v-for="(budgetLimit, key) in budgetLimits" v-bind:key="key" :budgetLimit="budgetLimit"/>
|
|
||||||
<BudgetRow v-for="(budget, key) in budgets" v-bind:key="key" :budget="budget"/>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<a class="btn btn-default button-sm" href="./budgets"><span class="far fa-money-bill-alt"></span> {{ $t('firefly.go_to_budgets') }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import BudgetLimitRow from "./BudgetLimitRow";
|
|
||||||
import BudgetRow from "./BudgetRow";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "BudgetListGroup",
|
|
||||||
components: {BudgetLimitRow, BudgetRow},
|
|
||||||
props: {
|
|
||||||
title: String,
|
|
||||||
budgetLimits: Array,
|
|
||||||
budgets: Array,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
<!--
|
|
||||||
- BudgetRow.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<tr>
|
|
||||||
<td style="width:25%;">
|
|
||||||
<a :href="'./budgets/show/' + budget.id">{{ budget.name }}</a>
|
|
||||||
</td>
|
|
||||||
<td> </td>
|
|
||||||
<td class="align-middle text-right">
|
|
||||||
<span class="text-danger">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: budget.currency_code}).format(parseFloat(budget.spent)) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "BudgetRow",
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
locale: 'en-US',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
budget: {
|
|
||||||
type: Object,
|
|
||||||
default: {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,602 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Calendar.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">Start</div>
|
|
||||||
<div class="col-8">{{ new Intl.DateTimeFormat(locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(range.start) }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">End</div>
|
|
||||||
<div class="col-8">{{ new Intl.DateTimeFormat(locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(range.end) }}</div>
|
|
||||||
</div>
|
|
||||||
<date-picker
|
|
||||||
v-model="range"
|
|
||||||
:rows="2"
|
|
||||||
is-range
|
|
||||||
mode="date"
|
|
||||||
>
|
|
||||||
<template v-slot="{ inputValue, inputEvents, isDragging, togglePopover }">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="btn-group btn-group-sm d-flex">
|
|
||||||
<button
|
|
||||||
:title="$t('firefly.custom_period')" class="btn btn-secondary btn-sm"
|
|
||||||
@click="togglePopover({ placement: 'auto-start', positionFixed: true })"
|
|
||||||
><span class="fas fa-calendar-alt"></span></button>
|
|
||||||
<button :title="$t('firefly.reset_to_current')"
|
|
||||||
class="btn btn-secondary"
|
|
||||||
@click="resetDate"
|
|
||||||
><span class="fas fa-history"></span></button>
|
|
||||||
<button id="dropdownMenuButton" :title="$t('firefly.select_period')" aria-expanded="false" aria-haspopup="true"
|
|
||||||
class="btn btn-secondary dropdown-toggle"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
type="button">
|
|
||||||
<span class="fas fa-list"></span>
|
|
||||||
</button>
|
|
||||||
<div aria-labelledby="dropdownMenuButton" class="dropdown-menu">
|
|
||||||
<a v-for="period in periods" class="dropdown-item" href="#" @click="customDate(period.start, period.end)">{{ period.title }}</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<input v-on="inputEvents.start"
|
|
||||||
:class="isDragging ? 'text-gray-600' : 'text-gray-900'"
|
|
||||||
:value="inputValue.start"
|
|
||||||
type="hidden"
|
|
||||||
/>
|
|
||||||
<input v-on="inputEvents.end"
|
|
||||||
:class="isDragging ? 'text-gray-600' : 'text-gray-900'"
|
|
||||||
:value="inputValue.end"
|
|
||||||
type="hidden"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</date-picker>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import {createNamespacedHelpers} from "vuex";
|
|
||||||
import Vue from "vue";
|
|
||||||
import DatePicker from "v-calendar/lib/components/date-picker.umd";
|
|
||||||
import subDays from 'date-fns/subDays';
|
|
||||||
import addDays from 'date-fns/addDays';
|
|
||||||
import addMonths from 'date-fns/addMonths';
|
|
||||||
import startOfDay from 'date-fns/startOfDay';
|
|
||||||
import endOfDay from 'date-fns/endOfDay';
|
|
||||||
import startOfWeek from 'date-fns/startOfWeek';
|
|
||||||
import endOfWeek from 'date-fns/endOfWeek';
|
|
||||||
import endOfMonth from 'date-fns/endOfMonth';
|
|
||||||
import format from 'date-fns/format';
|
|
||||||
import startOfQuarter from 'date-fns/startOfQuarter';
|
|
||||||
import subMonths from 'date-fns/subMonths';
|
|
||||||
import endOfQuarter from 'date-fns/endOfQuarter';
|
|
||||||
import subQuarters from 'date-fns/subQuarters';
|
|
||||||
import addQuarters from 'date-fns/addQuarters';
|
|
||||||
import startOfMonth from 'date-fns/startOfMonth';
|
|
||||||
|
|
||||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('dashboard/index')
|
|
||||||
|
|
||||||
Vue.component('date-picker', DatePicker)
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Calendar",
|
|
||||||
created() {
|
|
||||||
// console.log('Now in calendar created');
|
|
||||||
this.ready = true;
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
locale: 'en-US',
|
|
||||||
ready: false,
|
|
||||||
range: {
|
|
||||||
start: null,
|
|
||||||
end: null,
|
|
||||||
},
|
|
||||||
defaultRange: {
|
|
||||||
start: null,
|
|
||||||
end: null,
|
|
||||||
},
|
|
||||||
periods: []
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapMutations(
|
|
||||||
[
|
|
||||||
'setEnd',
|
|
||||||
'setStart',
|
|
||||||
],
|
|
||||||
),
|
|
||||||
resetDate: function () {
|
|
||||||
// console.log('Reset date to');
|
|
||||||
// console.log(this.defaultStart);
|
|
||||||
// console.log(this.defaultEnd);
|
|
||||||
this.range.start = this.defaultStart;
|
|
||||||
this.range.end = this.defaultEnd;
|
|
||||||
this.setStart(this.defaultStart);
|
|
||||||
this.setEnd(this.defaultEnd);
|
|
||||||
},
|
|
||||||
customDate: function (startStr, endStr) {
|
|
||||||
let start = new Date(startStr);
|
|
||||||
let end = new Date(endStr);
|
|
||||||
this.setStart(start);
|
|
||||||
this.setEnd(end);
|
|
||||||
this.range.start = start;
|
|
||||||
this.range.end = end;
|
|
||||||
this.generatePeriods()
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
generateDaily: function () {
|
|
||||||
let today = new Date(this.range.start);
|
|
||||||
// yesterday
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: startOfDay(subDays(today, 1)).toDateString(),
|
|
||||||
end: endOfDay(subDays(today, 1)).toDateString(),
|
|
||||||
title: new Intl.DateTimeFormat(this.locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(subDays(today, 1))
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// today
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: startOfDay(today).toDateString(),
|
|
||||||
end: endOfDay(today).toDateString(),
|
|
||||||
title: new Intl.DateTimeFormat(this.locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(today)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// tomorrow:
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: startOfDay(addDays(today, 1)).toDateString(),
|
|
||||||
end: endOfDay(addDays(today, 1)).toDateString(),
|
|
||||||
title: new Intl.DateTimeFormat(this.locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(addDays(today, 1))
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// The Day After Tomorrow dun-dun-dun!
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: startOfDay(addDays(today, 2)).toDateString(),
|
|
||||||
end: endOfDay(addDays(today, 2)).toDateString(),
|
|
||||||
title: new Intl.DateTimeFormat(this.locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(addDays(today, 2))
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
generateWeekly: function () {
|
|
||||||
//console.log('weekly');
|
|
||||||
let today = new Date(this.range.start);
|
|
||||||
//console.log('Today is ' + today);
|
|
||||||
let start = startOfDay(startOfWeek(subDays(today, 7), {weekStartsOn: 1}));
|
|
||||||
let end = endOfDay(endOfWeek(subDays(today, 7), {weekStartsOn: 1}));
|
|
||||||
let dateFormat = this.$t('config.week_in_year_fns');
|
|
||||||
//console.log('Date format: "'+dateFormat+'"');
|
|
||||||
let title = format(start, dateFormat);
|
|
||||||
|
|
||||||
// last week
|
|
||||||
// console.log('Last week');
|
|
||||||
// console.log(start);
|
|
||||||
// console.log(end);
|
|
||||||
// console.log(title);
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// this week
|
|
||||||
start = startOfDay(startOfWeek(today, {weekStartsOn: 1}));
|
|
||||||
end = endOfDay(endOfWeek(today, {weekStartsOn: 1}));
|
|
||||||
title = format(start, dateFormat);
|
|
||||||
// console.log('This week');
|
|
||||||
// console.log(start);
|
|
||||||
// console.log(end);
|
|
||||||
// console.log(title);
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// next week
|
|
||||||
start = startOfDay(startOfWeek(addDays(today, 7), {weekStartsOn: 1}));
|
|
||||||
end = endOfDay(endOfWeek(addDays(today, 7), {weekStartsOn: 1}));
|
|
||||||
title = format(start, dateFormat);
|
|
||||||
// console.log('Next week');
|
|
||||||
// console.log(start);
|
|
||||||
// console.log(end);
|
|
||||||
// console.log(title);
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
generateMonthly: function () {
|
|
||||||
let today = new Date(this.range.start);
|
|
||||||
// previous month
|
|
||||||
let start = startOfDay(startOfMonth(subMonths(today, 1)));
|
|
||||||
let end = endOfDay(endOfMonth(subMonths(today, 1)));
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: new Intl.DateTimeFormat(this.locale, {year: 'numeric', month: 'long'}).format(start)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// this month
|
|
||||||
start = startOfDay(startOfMonth(today));
|
|
||||||
end = endOfDay(endOfMonth(today));
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: new Intl.DateTimeFormat(this.locale, {year: 'numeric', month: 'long'}).format(start)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// next month
|
|
||||||
start = startOfDay(startOfMonth(addMonths(today, 1)));
|
|
||||||
end = endOfDay(endOfMonth(addMonths(today, 1)));
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: new Intl.DateTimeFormat(this.locale, {year: 'numeric', month: 'long'}).format(start)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
},
|
|
||||||
generateQuarterly: function () {
|
|
||||||
let today = new Date(this.range.start);
|
|
||||||
|
|
||||||
// last quarter
|
|
||||||
let start = startOfDay(startOfQuarter(subQuarters(today, 1)));
|
|
||||||
let end = endOfDay(endOfQuarter(subQuarters(today, 1)));
|
|
||||||
let dateFormat = this.$t('config.quarter_fns');
|
|
||||||
let title = format(start, dateFormat);
|
|
||||||
|
|
||||||
// last week
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// this quarter
|
|
||||||
start = startOfDay(startOfQuarter(today));
|
|
||||||
end = endOfDay(endOfQuarter(today));
|
|
||||||
title = format(start, dateFormat);
|
|
||||||
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// next quarter
|
|
||||||
start = startOfDay(startOfQuarter(addQuarters(today, 1)));
|
|
||||||
end = endOfDay(endOfQuarter(addQuarters(today, 1)));
|
|
||||||
title = format(start, dateFormat);
|
|
||||||
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
generateHalfYearly: function () {
|
|
||||||
let today = new Date(this.range.start);
|
|
||||||
let start;
|
|
||||||
let end;
|
|
||||||
let title = 'tbd';
|
|
||||||
let half = 1;
|
|
||||||
|
|
||||||
// its currently first half of year:
|
|
||||||
if (today.getMonth() <= 5) {
|
|
||||||
// previous year, last half:
|
|
||||||
start = today;
|
|
||||||
start.setFullYear(start.getFullYear() - 1);
|
|
||||||
start.setMonth(6);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
end = start;
|
|
||||||
end.setMonth(11);
|
|
||||||
end.setDate(31);
|
|
||||||
end = endOfDay(end);
|
|
||||||
half = 2;
|
|
||||||
title = format(start, this.$t('config.half_year_fns', {half: half}));
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// this year, first half:
|
|
||||||
start = today;
|
|
||||||
start.setMonth(0);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
end = today;
|
|
||||||
end.setMonth(5);
|
|
||||||
end.setDate(30);
|
|
||||||
end = endOfDay(start);
|
|
||||||
half = 1;
|
|
||||||
title = format(start, this.$t('config.half_year_fns', {half: half}));
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// this year, second half:
|
|
||||||
start = today;
|
|
||||||
start.setMonth(6);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
end = start;
|
|
||||||
end.setMonth(11);
|
|
||||||
end.setDate(31);
|
|
||||||
end = endOfDay(end);
|
|
||||||
half = 2;
|
|
||||||
title = format(start, this.$t('config.half_year_fns', {half: half}));
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// this year, first half:
|
|
||||||
start = today;
|
|
||||||
start.setMonth(0);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
end = start;
|
|
||||||
end.setMonth(5);
|
|
||||||
end.setDate(30);
|
|
||||||
end = endOfDay(end);
|
|
||||||
title = format(start, this.$t('config.half_year_fns', {half: half}));
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// this year, current (second) half:
|
|
||||||
start = today;
|
|
||||||
start.setMonth(6);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
end = today;
|
|
||||||
end.setMonth(11);
|
|
||||||
end.setDate(31);
|
|
||||||
end = endOfDay(start);
|
|
||||||
half = 2;
|
|
||||||
title = format(start, this.$t('config.half_year_fns', {half: half}));
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// next year, first half:
|
|
||||||
start = today;
|
|
||||||
start.setMonth(0);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
end = start;
|
|
||||||
end.setMonth(5);
|
|
||||||
end.setDate(30);
|
|
||||||
end = endOfDay(end);
|
|
||||||
half = 1;
|
|
||||||
title = format(start, this.$t('config.half_year_fns', {half: half}));
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
generateYearly: function () {
|
|
||||||
let today = new Date(this.range.start);
|
|
||||||
let start;
|
|
||||||
let end;
|
|
||||||
|
|
||||||
// last year
|
|
||||||
start = new Date(today);
|
|
||||||
start.setFullYear(start.getFullYear() - 1);
|
|
||||||
start.setMonth(0);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
|
|
||||||
end = new Date(today);
|
|
||||||
end.setFullYear(end.getFullYear() - 1);
|
|
||||||
end.setMonth(11);
|
|
||||||
end.setDate(31);
|
|
||||||
end = endOfDay(end);
|
|
||||||
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: start.getFullYear()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// this year
|
|
||||||
start = new Date(today);
|
|
||||||
start.setMonth(0);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
|
|
||||||
end = new Date(today);
|
|
||||||
end.setMonth(11);
|
|
||||||
end.setDate(31);
|
|
||||||
end = endOfDay(end);
|
|
||||||
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: start.getFullYear()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// next year
|
|
||||||
start = new Date(today);
|
|
||||||
start.setFullYear(start.getFullYear() + 1);
|
|
||||||
start.setMonth(0);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
|
|
||||||
end = new Date(today);
|
|
||||||
end.setFullYear(end.getFullYear() + 1);
|
|
||||||
end.setMonth(11);
|
|
||||||
end.setDate(31);
|
|
||||||
end = endOfDay(end);
|
|
||||||
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: start.toDateString(),
|
|
||||||
end: end.toDateString(),
|
|
||||||
title: start.getFullYear()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
generatePeriods: function () {
|
|
||||||
this.periods = [];
|
|
||||||
// console.log('The view range is "' + this.viewRange + '".');
|
|
||||||
switch (this.viewRange) {
|
|
||||||
case '1D':
|
|
||||||
this.generateDaily();
|
|
||||||
break;
|
|
||||||
case '1W':
|
|
||||||
this.generateWeekly();
|
|
||||||
break;
|
|
||||||
case '1M':
|
|
||||||
this.generateMonthly();
|
|
||||||
break;
|
|
||||||
case '3M':
|
|
||||||
this.generateQuarterly();
|
|
||||||
break;
|
|
||||||
case '6M':
|
|
||||||
this.generateHalfYearly();
|
|
||||||
break;
|
|
||||||
case '1Y':
|
|
||||||
this.generateYearly();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// last 7 days
|
|
||||||
let today = new Date;
|
|
||||||
let end = new Date;
|
|
||||||
end.setDate(end.getDate() - 7);
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: end.toDateString(),
|
|
||||||
end: today.toDateString(),
|
|
||||||
title: this.$t('firefly.last_seven_days')
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// last 30 days:
|
|
||||||
end.setDate(end.getDate() - 23);
|
|
||||||
this.periods.push(
|
|
||||||
{
|
|
||||||
start: end.toDateString(),
|
|
||||||
end: today.toDateString(),
|
|
||||||
title: this.$t('firefly.last_thirty_days')
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// last 30 days
|
|
||||||
// everything
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters([
|
|
||||||
'viewRange',
|
|
||||||
'start',
|
|
||||||
'end',
|
|
||||||
'defaultStart',
|
|
||||||
'defaultEnd'
|
|
||||||
]),
|
|
||||||
'datesReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && this.ready;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
datesReady: function (value) {
|
|
||||||
if (false === value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.range.start = new Date(this.start);
|
|
||||||
this.range.end = new Date(this.end);
|
|
||||||
this.generatePeriods();
|
|
||||||
|
|
||||||
},
|
|
||||||
range: function (value) {
|
|
||||||
//console.log('User updated range');
|
|
||||||
this.setStart(value.start);
|
|
||||||
this.setEnd(value.end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.dropdown-item {
|
|
||||||
color: #212529;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item:hover {
|
|
||||||
color: #212529;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
<!--
|
|
||||||
- ExampleComponent.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>
|
|
||||||
<top-boxes/>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<main-account/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<main-account-list/>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<main-budget-list/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<main-category-list/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<main-debit-list/>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<main-credit-list/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<main-piggy-list/>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<main-bills-list/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "Dashboard",
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
<!--
|
|
||||||
- DashboardListLarge.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<table class="table table-striped table-sm">
|
|
||||||
<caption style="display:none;">{{ $t('firefly.transaction_table_description') }}</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="text-left" scope="col">{{ $t('firefly.description') }}</th>
|
|
||||||
<th scope="col">{{ $t('firefly.opposing_account') }}</th>
|
|
||||||
<th class="text-right" scope="col">{{ $t('firefly.amount') }}</th>
|
|
||||||
<th scope="col">{{ $t('firefly.category') }}</th>
|
|
||||||
<th scope="col">{{ $t('firefly.budget') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="transaction in this.transactions">
|
|
||||||
<td>
|
|
||||||
<a :href="'transactions/show/' + transaction.id " :title="transaction.date">
|
|
||||||
<span v-if="transaction.attributes.transactions.length > 1">{{ transaction.attributes.group_title }}</span>
|
|
||||||
<span v-if="1===transaction.attributes.transactions.length">{{ transaction.attributes.transactions[0].description }}</span>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span v-for="tr in transaction.attributes.transactions">
|
|
||||||
<a v-if="'withdrawal' === tr.type" :href="'accounts/show/' + tr.destination_id">{{ tr.destination_name }}</a>
|
|
||||||
<a v-if="'deposit' === tr.type" :href="'accounts/show/' + tr.source_id">{{ tr.source_name }}</a>
|
|
||||||
<a v-if="'transfer' === tr.type && parseInt(tr.source_id) === account_id" :href="'accounts/show/' + tr.destination_id">{{ tr.destination_name }}</a>
|
|
||||||
<a v-if="'transfer' === tr.type && parseInt(tr.destination_id) === account_id" :href="'accounts/show/' + tr.source_id">{{ tr.source_name }}</a>
|
|
||||||
<br/>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td style="text-align:right;">
|
|
||||||
<span v-for="tr in transaction.attributes.transactions">
|
|
||||||
<span v-if="'withdrawal' === tr.type" class="text-danger">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount * -1) }}<br>
|
|
||||||
</span>
|
|
||||||
<span v-if="'deposit' === tr.type" class="text-success">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount) }}<br>
|
|
||||||
</span>
|
|
||||||
<span v-if="'transfer' === tr.type && parseInt(tr.source_id) === account_id" class="text-info">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount * -1) }}<br>
|
|
||||||
</span>
|
|
||||||
<span v-if="'transfer' === tr.type && parseInt(tr.destination_id) === account_id" class="text-info">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount) }}<br>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span v-for="tr in transaction.attributes.transactions">
|
|
||||||
<a v-if="0!==tr.category_id" :href="'categories/show/' + tr.category_id">{{ tr.category_name }}</a><br/>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span v-for="tr in transaction.attributes.transactions">
|
|
||||||
<a v-if="0!==tr.budget_id" :href="'budgets/show/' + tr.budget_id">{{ tr.budget_name }}</a><br/>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "DashboardListLarge",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
locale: 'en-US'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
transactions: {
|
|
||||||
type: Array,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
account_id: {
|
|
||||||
type: Number,
|
|
||||||
default: function () {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
<!--
|
|
||||||
- DashboardListMedium.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<table class="table table-striped table-sm">
|
|
||||||
<caption style="display:none;">{{ $t('firefly.transaction_table_description') }}</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="text-left" scope="col">{{ $t('firefly.description') }}</th>
|
|
||||||
<th scope="col">{{ $t('firefly.opposing_account') }}</th>
|
|
||||||
<th class="text-right" scope="col">{{ $t('firefly.amount') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="transaction in this.transactions">
|
|
||||||
<td>
|
|
||||||
<a :href="'transactions/show/' + transaction.id " :title="transaction.date">
|
|
||||||
<span v-if="transaction.attributes.transactions.length > 1">{{ transaction.attributes.group_title }}</span>
|
|
||||||
<span v-if="1===transaction.attributes.transactions.length">{{ transaction.attributes.transactions[0].description }}</span>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span v-for="tr in transaction.attributes.transactions">
|
|
||||||
<a v-if="'withdrawal' === tr.type" :href="'accounts/show/' + tr.destination_id">{{ tr.destination_name }}</a>
|
|
||||||
<a v-if="'deposit' === tr.type" :href="'accounts/show/' + tr.source_id">{{ tr.source_name }}</a>
|
|
||||||
<a v-if="'transfer' === tr.type && parseInt(tr.source_id) === account_id" :href="'accounts/show/' + tr.destination_id">{{ tr.destination_name }}</a>
|
|
||||||
<a v-if="'transfer' === tr.type && parseInt(tr.destination_id) === account_id" :href="'accounts/show/' + tr.source_id">{{ tr.source_name }}</a>
|
|
||||||
<br/>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td style="text-align:right;">
|
|
||||||
<span v-for="tr in transaction.attributes.transactions">
|
|
||||||
<span v-if="'withdrawal' === tr.type" class="text-danger">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount * -1) }}<br>
|
|
||||||
</span>
|
|
||||||
<span v-if="'deposit' === tr.type" class="text-success">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount) }}<br>
|
|
||||||
</span>
|
|
||||||
<span v-if="'transfer' === tr.type && parseInt(tr.source_id) === account_id" class="text-info">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount * -1) }}<br>
|
|
||||||
</span>
|
|
||||||
<span v-if="'transfer' === tr.type && parseInt(tr.destination_id) === account_id" class="text-info">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount) }}<br>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "DashboardListMedium",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
locale: 'en-US'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
transactions: {
|
|
||||||
type: Array,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
account_id: {
|
|
||||||
type: Number,
|
|
||||||
default: function () {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
<!--
|
|
||||||
- DashboardListSmall.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<table class="table table-striped table-sm">
|
|
||||||
<caption style="display:none;">{{ $t('firefly.transaction_table_description') }}</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="text-left" scope="col">{{ $t('firefly.description') }}</th>
|
|
||||||
<th class="text-right" scope="col">{{ $t('firefly.amount') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="transaction in this.transactions">
|
|
||||||
<td>
|
|
||||||
<a :href="'transactions/show/' + transaction.id "
|
|
||||||
:title="new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'long', day: 'numeric' }).format(new Date(transaction.attributes.transactions[0].date))">
|
|
||||||
<span v-if="transaction.attributes.transactions.length > 1">{{ transaction.attributes.group_title }}</span>
|
|
||||||
<span v-if="1===transaction.attributes.transactions.length">{{ transaction.attributes.transactions[0].description }}</span>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td style="text-align:right;">
|
|
||||||
<span v-for="tr in transaction.attributes.transactions">
|
|
||||||
<span v-if="'withdrawal' === tr.type" class="text-danger">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount * -1) }}<br>
|
|
||||||
</span>
|
|
||||||
<span v-if="'deposit' === tr.type" class="text-success">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount) }}<br>
|
|
||||||
</span>
|
|
||||||
<span v-if="'transfer' === tr.type && parseInt(tr.source_id) === account_id" class="text-info">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount * -1) }}<br>
|
|
||||||
</span>
|
|
||||||
<span v-if="'transfer' === tr.type && parseInt(tr.destination_id) === account_id" class="text-info">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: tr.currency_code}).format(tr.amount) }}<br>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "DashboardListSmall",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
locale: 'en-US'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
},
|
|
||||||
methods: {},
|
|
||||||
props: {
|
|
||||||
transactions: {
|
|
||||||
type: Array,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
account_id: {
|
|
||||||
type: Number,
|
|
||||||
default: function () {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
<!--
|
|
||||||
- MainAccount.vue
|
|
||||||
- Copyright (c) 2020 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="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">{{ $t('firefly.yourAccounts') }}</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div>
|
|
||||||
<canvas id="canvas" ref="canvas" width="400" height="400"></canvas>
|
|
||||||
</div>
|
|
||||||
<div v-if="loading && !error" class="text-center">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
<div v-if="error" class="text-center">
|
|
||||||
<span class="fas fa-exclamation-triangle text-danger"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<a class="btn btn-default button-sm" href="./accounts/asset"><span class="far fa-money-bill-alt"></span> {{ $t('firefly.go_to_asset_accounts') }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import DataConverter from "../charts/DataConverter";
|
|
||||||
import DefaultLineOptions from "../charts/DefaultLineOptions";
|
|
||||||
import {mapGetters} from "vuex";
|
|
||||||
import * as ChartJs from 'chart.js'
|
|
||||||
import format from "date-fns/format";
|
|
||||||
|
|
||||||
ChartJs.Chart.register.apply(null, Object.values(ChartJs).filter((chartClass) => (chartClass.id)));
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "MainAccount",
|
|
||||||
components: {}, // MainAccountChart
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
error: false,
|
|
||||||
ready: false,
|
|
||||||
initialised: false,
|
|
||||||
dataCollection: {},
|
|
||||||
chartOptions: {},
|
|
||||||
_chart: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.chartOptions = DefaultLineOptions.methods.getDefaultOptions();
|
|
||||||
this.ready = true;
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('dashboard/index', ['start', 'end']),
|
|
||||||
'datesReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && this.ready;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
datesReady: function (value) {
|
|
||||||
if (true === value) {
|
|
||||||
this.initialiseChart();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
start: function () {
|
|
||||||
this.updateChart();
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
this.updateChart();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initialiseChart: function () {
|
|
||||||
this.loading = true;
|
|
||||||
this.error = false;
|
|
||||||
//let startStr = this.start.toISOString().split('T')[0];
|
|
||||||
//let endStr = this.end.toISOString().split('T')[0];
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
let url = './api/v1/chart/account/overview?start=' + startStr + '&end=' + endStr;
|
|
||||||
axios.get(url)
|
|
||||||
.then(response => {
|
|
||||||
let chartData = DataConverter.methods.convertChart(response.data);
|
|
||||||
chartData = DataConverter.methods.colorizeLineData(chartData);
|
|
||||||
|
|
||||||
this.dataCollection = chartData;
|
|
||||||
this.loading = false;
|
|
||||||
this.drawChart();
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Has error!');
|
|
||||||
console.error(error);
|
|
||||||
this.error = true;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
drawChart: function () {
|
|
||||||
//console.log('drawChart');
|
|
||||||
if ('undefined' !== typeof this._chart) {
|
|
||||||
// console.log('update!');
|
|
||||||
this._chart.data = this.dataCollection;
|
|
||||||
this._chart.update();
|
|
||||||
this.initialised = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('undefined' === typeof this._chart) {
|
|
||||||
// console.log('new!');
|
|
||||||
this._chart = new ChartJs.Chart(this.$refs.canvas.getContext('2d'), {
|
|
||||||
type: 'line',
|
|
||||||
data: this.dataCollection,
|
|
||||||
options: this.chartOptions
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.initialised = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updateChart: function () {
|
|
||||||
// console.log('updateChart');
|
|
||||||
if (this.initialised) {
|
|
||||||
// console.log('MUST Update chart!');
|
|
||||||
// reset some vars so it wont trigger again:
|
|
||||||
this.initialised = false;
|
|
||||||
this.initialiseChart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
<!--
|
|
||||||
- MainAccountChart.vue
|
|
||||||
- Copyright (c) 2020 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/>.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
//import {Line, mixins} from 'vue-chartjs'
|
|
||||||
|
|
||||||
const {reactiveProp} = mixins
|
|
||||||
|
|
||||||
export default {
|
|
||||||
extends: Line,
|
|
||||||
mixins: [reactiveProp],
|
|
||||||
props: ['options'],
|
|
||||||
mounted() {
|
|
||||||
this.renderChart(this.chartData, this.options)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,181 +0,0 @@
|
|||||||
<!--
|
|
||||||
- MainAccountList.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<!-- row if loading -->
|
|
||||||
<div v-if="loading && !error" class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- row if error -->
|
|
||||||
<div v-if="error" class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-exclamation-triangle text-danger"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- row if normal -->
|
|
||||||
<div v-if="!loading && !error" class="row">
|
|
||||||
<div
|
|
||||||
v-for="account in accounts"
|
|
||||||
v-bind:class="{ 'col-lg-12': 1 === accounts.length, 'col-lg-6': 2 === accounts.length, 'col-lg-4': accounts.length > 2 }">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title"><a :href="account.url">{{ account.title }}</a></h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<span :class="parseFloat(account.current_balance) < 0 ? 'text-danger' : 'text-success'">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: account.currency_code}).format(parseFloat(account.current_balance)) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body table-responsive p-0">
|
|
||||||
<div>
|
|
||||||
<dashboard-list-large v-if="1===accounts.length" :account_id="account.id" :transactions="account.transactions"/>
|
|
||||||
<dashboard-list-medium v-if="2===accounts.length" :account_id="account.id" :transactions="account.transactions"/>
|
|
||||||
<dashboard-list-small v-if="accounts.length > 2" :account_id="account.id" :transactions="account.transactions"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {createNamespacedHelpers} from "vuex";
|
|
||||||
import format from "date-fns/format";
|
|
||||||
|
|
||||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('dashboard/index')
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "MainAccountList",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
error: false,
|
|
||||||
ready: false,
|
|
||||||
accounts: [],
|
|
||||||
locale: 'en-US'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
this.ready = true;
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters([
|
|
||||||
'start',
|
|
||||||
'end'
|
|
||||||
]),
|
|
||||||
'datesReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && this.ready;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
datesReady: function (value) {
|
|
||||||
if (true === value) {
|
|
||||||
this.initialiseList();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
start: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.initialiseList();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.initialiseList();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initialiseList: function () {
|
|
||||||
this.loading = true;
|
|
||||||
this.accounts = [];
|
|
||||||
axios.get('./api/v1/preferences/frontPageAccounts')
|
|
||||||
.then(response => {
|
|
||||||
this.loadAccounts(response);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
loadAccounts(response) {
|
|
||||||
let accountIds = response.data.data.attributes.data;
|
|
||||||
for (let key in accountIds) {
|
|
||||||
if (accountIds.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
|
||||||
this.accounts.push({
|
|
||||||
id: accountIds[key],
|
|
||||||
title: '',
|
|
||||||
url: '',
|
|
||||||
include: false,
|
|
||||||
current_balance: '0',
|
|
||||||
currency_code: 'EUR',
|
|
||||||
transactions: []
|
|
||||||
});
|
|
||||||
this.loadSingleAccount(key, accountIds[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
loadSingleAccount(key, accountId) {
|
|
||||||
axios.get('./api/v1/accounts/' + accountId)
|
|
||||||
.then(response => {
|
|
||||||
let account = response.data.data;
|
|
||||||
if ('asset' === account.attributes.type || 'liabilities' === account.attributes.type) {
|
|
||||||
this.accounts[key].title = account.attributes.name;
|
|
||||||
this.accounts[key].url = './accounts/show/' + account.id;
|
|
||||||
this.accounts[key].current_balance = account.attributes.current_balance;
|
|
||||||
this.accounts[key].currency_code = account.attributes.currency_code;
|
|
||||||
this.accounts[key].include = true;
|
|
||||||
this.loadTransactions(key, accountId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
loadTransactions(key, accountId) {
|
|
||||||
// let startStr = this.start.toISOString().split('T')[0];
|
|
||||||
// let endStr = this.end.toISOString().split('T')[0];
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
axios.get('./api/v1/accounts/' + accountId + '/transactions?page=1&limit=10&start=' + startStr + '&end=' + endStr)
|
|
||||||
.then(response => {
|
|
||||||
this.accounts[key].transactions = response.data.data;
|
|
||||||
this.loading = false;
|
|
||||||
this.error = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
<!--
|
|
||||||
- MainBills.vue
|
|
||||||
- Copyright (c) 2020 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="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">{{ $t('firefly.bills') }}</h3>
|
|
||||||
</div>
|
|
||||||
<!-- body if loading -->
|
|
||||||
<div v-if="loading && !error" class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- body if error -->
|
|
||||||
<div v-if="error" class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-exclamation-triangle text-danger"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- body if normal -->
|
|
||||||
<div v-if="!loading && !error" class="card-body table-responsive p-0">
|
|
||||||
<table class="table table-striped">
|
|
||||||
<caption style="display:none;">{{ $t('firefly.bills') }}</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col" style="width:35%;">{{ $t('list.name') }}</th>
|
|
||||||
<th scope="col" style="width:25%;">{{ $t('list.next_expected_match') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="bill in this.bills">
|
|
||||||
<td><a :href="'./bills/show/' + bill.id" :title="bill.attributes.name">{{ bill.attributes.name }}</a>
|
|
||||||
(~ <span class="text-danger">{{
|
|
||||||
Intl.NumberFormat(locale, {style: 'currency', currency: bill.attributes.currency_code}).format((parseFloat(bill.attributes.amount_min) +
|
|
||||||
parseFloat(bill.attributes.amount_max)) / -2)
|
|
||||||
}}</span>)
|
|
||||||
<small v-if="bill.attributes.object_group_title" class="text-muted">
|
|
||||||
<br/>
|
|
||||||
{{ bill.attributes.object_group_title }}
|
|
||||||
</small>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span v-for="paidDate in bill.attributes.paid_dates">
|
|
||||||
<span v-html="renderPaidDate(paidDate)"/><br/>
|
|
||||||
</span>
|
|
||||||
<span v-for="payDate in bill.attributes.pay_dates" v-if="0===bill.attributes.paid_dates.length">
|
|
||||||
{{ new Intl.DateTimeFormat(locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(new Date(payDate)) }}
|
|
||||||
<br/>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<a class="btn btn-default button-sm" href="./bills"><span class="far fa-money-bill-alt"></span> {{ $t('firefly.go_to_bills') }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import {createNamespacedHelpers} from "vuex";
|
|
||||||
import format from "date-fns/format";
|
|
||||||
|
|
||||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('dashboard/index')
|
|
||||||
export default {
|
|
||||||
name: "MainBillsList",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
bills: [],
|
|
||||||
locale: 'en-US',
|
|
||||||
ready: false,
|
|
||||||
loading: true,
|
|
||||||
error: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters([
|
|
||||||
'start',
|
|
||||||
'end'
|
|
||||||
]),
|
|
||||||
'datesReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && this.ready;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
datesReady: function (value) {
|
|
||||||
if (true === value) {
|
|
||||||
this.initialiseBills();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
start: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.initialiseBills();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.initialiseBills();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.ready = true;
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
},
|
|
||||||
components: {},
|
|
||||||
methods: {
|
|
||||||
initialiseBills: function () {
|
|
||||||
this.loading = true;
|
|
||||||
this.bills = [];
|
|
||||||
// let startStr = this.start.toISOString().split('T')[0];
|
|
||||||
// let endStr = this.end.toISOString().split('T')[0];
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
|
|
||||||
axios.get('./api/v1/bills?start=' + startStr + '&end=' + endStr)
|
|
||||||
.then(response => {
|
|
||||||
this.loadBills(response.data.data);
|
|
||||||
}
|
|
||||||
).catch(error => {
|
|
||||||
this.error = true;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
renderPaidDate: function (obj) {
|
|
||||||
let dateStr = new Intl.DateTimeFormat(this.locale, {year: 'numeric', month: 'long', day: 'numeric'}).format(new Date(obj.date));
|
|
||||||
let str = this.$t('firefly.bill_paid_on', {date: dateStr});
|
|
||||||
return '<a href="./transactions/show/' + obj.transaction_group_id + '" title="' + str + '">' + str + '</a>';
|
|
||||||
},
|
|
||||||
loadBills: function (data) {
|
|
||||||
for (let key in data) {
|
|
||||||
if (data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
|
||||||
|
|
||||||
let bill = data[key];
|
|
||||||
let active = bill.attributes.active;
|
|
||||||
if (bill.attributes.pay_dates.length > 0 && active) {
|
|
||||||
this.bills.push(bill);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.error = false;
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,278 +0,0 @@
|
|||||||
<!--
|
|
||||||
- MainBudgetList.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<!-- daily budgets (will be the exception, I expect) -->
|
|
||||||
<div v-if="!loading" class="row">
|
|
||||||
<div v-if="budgetLimits.daily.length > 0" class="col-xl-6 col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<BudgetListGroup :budgetLimits=budgetLimits.daily :title="$t('firefly.daily_budgets')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-if="budgetLimits.weekly.length > 0" class="col-xl-6 col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<BudgetListGroup :budgetLimits=budgetLimits.weekly :title="$t('firefly.weekly_budgets')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-if="budgetLimits.monthly.length > 0" class="col-xl-6 col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<BudgetListGroup :budgetLimits=budgetLimits.monthly :title="$t('firefly.monthly_budgets')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-if="budgetLimits.quarterly.length > 0" class="col-xl-6 col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<BudgetListGroup :budgetLimits=budgetLimits.quarterly :title="$t('firefly.quarterly_budgets')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-if="budgetLimits.half_year.length > 0" class="col-xl-6 col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<BudgetListGroup :budgetLimits=budgetLimits.half_year :title="$t('firefly.half_year_budgets')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-if="budgetLimits.yearly.length > 0" class="col-xl-6 col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<BudgetListGroup :budgetLimits=budgetLimits.yearly :title="$t('firefly.yearly_budgets')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-if="budgetLimits.other.length > 0 || rawBudgets.length > 0" class="col-xl-6 col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<BudgetListGroup :budgetLimits=budgetLimits.other :budgets="rawBudgets" :title="$t('firefly.other_budgets')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="loading && !error" class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import BudgetListGroup from "./BudgetListGroup";
|
|
||||||
import {createNamespacedHelpers} from "vuex";
|
|
||||||
import format from "date-fns/format";
|
|
||||||
|
|
||||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('dashboard/index')
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "MainBudgetList",
|
|
||||||
components: {BudgetListGroup},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
budgetList: ['daily', 'weekly', 'monthly', 'quarterly', 'half_year', 'yearly', 'other'],
|
|
||||||
budgetLimits: {
|
|
||||||
daily: [],
|
|
||||||
weekly: [],
|
|
||||||
monthly: [],
|
|
||||||
quarterly: [],
|
|
||||||
half_year: [],
|
|
||||||
yearly: [],
|
|
||||||
other: [],
|
|
||||||
},
|
|
||||||
budgets: {}, // used to collect some meta data.
|
|
||||||
rawBudgets: [],
|
|
||||||
locale: 'en-US',
|
|
||||||
ready: false,
|
|
||||||
loading: true,
|
|
||||||
error: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.ready = true;
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
datesReady: function (value) {
|
|
||||||
if (true === value) {
|
|
||||||
this.getBudgets();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
start: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.getBudgets();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.getBudgets();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters(['start', 'end']),
|
|
||||||
'datesReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && this.ready;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods:
|
|
||||||
{
|
|
||||||
getBudgets: function () {
|
|
||||||
this.budgets = {};
|
|
||||||
this.rawBudgets = [];
|
|
||||||
this.budgetLimits = {
|
|
||||||
daily: [],
|
|
||||||
weekly: [],
|
|
||||||
monthly: [],
|
|
||||||
quarterly: [],
|
|
||||||
half_year: [],
|
|
||||||
yearly: [],
|
|
||||||
other: [],
|
|
||||||
};
|
|
||||||
this.loading = true;
|
|
||||||
// let startStr = this.start.toISOString().split('T')[0];
|
|
||||||
// let endStr = this.end.toISOString().split('T')[0];
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
axios.get('./api/v1/budgets?start=' + startStr + '&end=' + endStr)
|
|
||||||
.then(response => {
|
|
||||||
this.parseBudgets(response.data);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
parseBudgets(data) {
|
|
||||||
for (let i in data.data) {
|
|
||||||
if (data.data.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = data.data[i];
|
|
||||||
if (false === current.attributes.active) {
|
|
||||||
// skip inactive budgets
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (let ii in current.attributes.spent) {
|
|
||||||
if (current.attributes.spent.hasOwnProperty(ii) && /^0$|^[1-9]\d*$/.test(ii) && ii <= 4294967294) {
|
|
||||||
let spentData = current.attributes.spent[ii];
|
|
||||||
this.rawBudgets.push(
|
|
||||||
{
|
|
||||||
id: parseInt(current.id),
|
|
||||||
name: current.attributes.name,
|
|
||||||
currency_id: parseInt(spentData.currency_id),
|
|
||||||
currency_code: spentData.currency_code,
|
|
||||||
spent: spentData.sum
|
|
||||||
}
|
|
||||||
);
|
|
||||||
//console.log('Added budget ' + current.attributes.name + ' (' + spentData.currency_code + ')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.getBudgetLimits();
|
|
||||||
},
|
|
||||||
getBudgetLimits() {
|
|
||||||
// let startStr = this.start.toISOString().split('T')[0];
|
|
||||||
// let endStr = this.end.toISOString().split('T')[0];
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
axios.get('./api/v1/budget-limits?start=' + startStr + '&end=' + endStr)
|
|
||||||
.then(response => {
|
|
||||||
this.parseBudgetLimits(response.data);
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
parseBudgetLimits(data) {
|
|
||||||
// collect budget meta data.
|
|
||||||
for (let i in data.included) {
|
|
||||||
if (data.included.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = data.included[i];
|
|
||||||
let currentId = parseInt(current.id);
|
|
||||||
this.budgets[currentId] =
|
|
||||||
{
|
|
||||||
id: currentId,
|
|
||||||
name: current.attributes.name,
|
|
||||||
};
|
|
||||||
//console.log('Collected meta data: budget #' + currentId + ' is named ' + current.attributes.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i in data.data) {
|
|
||||||
if (data.data.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = data.data[i];
|
|
||||||
let currentId = parseInt(current.id);
|
|
||||||
let budgetId = parseInt(current.attributes.budget_id);
|
|
||||||
let currencyId = parseInt(current.attributes.currency_id);
|
|
||||||
let spentFloat = parseFloat(current.attributes.spent);
|
|
||||||
let spentFloatPos = parseFloat(current.attributes.spent) * -1;
|
|
||||||
let amount = parseFloat(current.attributes.amount);
|
|
||||||
let period = current.attributes.period ?? 'other';
|
|
||||||
let pctGreen = 0;
|
|
||||||
let pctOrange = 0;
|
|
||||||
let pctRed = 0;
|
|
||||||
//console.log('Collected "' + period + '" budget limit #' + currentId + ' (part of budget #' + budgetId + ')');
|
|
||||||
// console.log('Spent ' + spentFloatPos + ' of ' + amount);
|
|
||||||
|
|
||||||
// remove budget info from rawBudgets if it's there:
|
|
||||||
this.filterBudgets(budgetId, currencyId);
|
|
||||||
// let name = this.budgets[current.attributes.budget_id].name;
|
|
||||||
// spent within budget:
|
|
||||||
if (0.0 !== spentFloat && spentFloatPos < amount) {
|
|
||||||
// console.log('Spent ' + name + ' in budget');
|
|
||||||
pctGreen = (spentFloatPos / amount) * 100;
|
|
||||||
// console.log('pctGreen is ' + pctGreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
// spent over budget
|
|
||||||
if (0.0 !== spentFloatPos && spentFloatPos > amount) {
|
|
||||||
//console.log('Spent ' + name + ' OVER budget');
|
|
||||||
pctOrange = (amount / spentFloatPos) * 100;
|
|
||||||
pctRed = 100 - pctOrange;
|
|
||||||
//console.log('orange is ' + pctOrange);
|
|
||||||
//console.log('red is ' + pctRed);
|
|
||||||
}
|
|
||||||
// spent exactly on budget
|
|
||||||
if (0.0 !== spentFloatPos && spentFloatPos === amount) {
|
|
||||||
pctOrange = 100;
|
|
||||||
pctRed = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let obj = {
|
|
||||||
id: currentId,
|
|
||||||
amount: current.attributes.amount,
|
|
||||||
budget_id: budgetId,
|
|
||||||
budget_name: this.budgets[current.attributes.budget_id].name,
|
|
||||||
currency_id: currencyId,
|
|
||||||
currency_code: current.attributes.currency_code,
|
|
||||||
period: current.attributes.period,
|
|
||||||
start: new Date(current.attributes.start),
|
|
||||||
end: new Date(current.attributes.end),
|
|
||||||
spent: current.attributes.spent,
|
|
||||||
pctGreen: pctGreen,
|
|
||||||
pctOrange: pctOrange,
|
|
||||||
pctRed: pctRed,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.budgetLimits[period].push(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
filterBudgets(budgetId, currencyId) {
|
|
||||||
for (let i in this.rawBudgets) {
|
|
||||||
if (this.rawBudgets.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
if (this.rawBudgets[i].currency_id === currencyId && this.rawBudgets[i].id === budgetId) {
|
|
||||||
//console.log('Budget ' + this.rawBudgets[i].name + ' with currency ' + this.rawBudgets[i].currency_code + ' will be removed in favor of a budget limit.');
|
|
||||||
this.rawBudgets.splice(parseInt(i), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,250 +0,0 @@
|
|||||||
<!--
|
|
||||||
- MainCategoryList.vue
|
|
||||||
- Copyright (c) 2020 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="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">{{ $t('firefly.categories') }}</h3>
|
|
||||||
</div>
|
|
||||||
<!-- body if loading -->
|
|
||||||
<div v-if="loading && !error" class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- body if error -->
|
|
||||||
<div v-if="error" class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-exclamation-triangle text-danger"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- body if normal -->
|
|
||||||
<div v-if="!loading && !error" class="card-body table-responsive p-0">
|
|
||||||
<table class="table table-sm">
|
|
||||||
<caption style="display:none;">{{ $t('firefly.categories') }}</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">{{ $t('firefly.category') }}</th>
|
|
||||||
<th scope="col">{{ $t('firefly.spent') }} / {{ $t('firefly.earned') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="category in sortedList">
|
|
||||||
<td style="width:20%;">
|
|
||||||
<a :href="'./categories/show/' + category.id">{{ category.name }}</a>
|
|
||||||
</td>
|
|
||||||
<td class="align-middle">
|
|
||||||
<!-- SPENT -->
|
|
||||||
<div v-if="category.spentPct > 0" class="progress">
|
|
||||||
<div :aria-valuenow="category.spentPct" :style="{ width: category.spentPct + '%'}" aria-valuemax="100"
|
|
||||||
aria-valuemin="0" class="progress-bar progress-bar-striped bg-danger"
|
|
||||||
role="progressbar">
|
|
||||||
<span v-if="category.spentPct > 20">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: category.currency_code}).format(category.spent) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span v-if="category.spentPct <= 20" class="progress-label" style="line-height: 16px;">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: category.currency_code}).format(category.spent) }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- EARNED -->
|
|
||||||
<div v-if="category.earnedPct > 0" class="progress justify-content-end" title="hello2">
|
|
||||||
<span v-if="category.earnedPct <= 20" style="line-height: 16px;">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: category.currency_code}).format(category.earned) }}
|
|
||||||
</span>
|
|
||||||
<div :aria-valuenow="category.earnedPct" :style="{ width: category.earnedPct + '%'}" aria-valuemax="100"
|
|
||||||
aria-valuemin="0" class="progress-bar progress-bar-striped bg-success"
|
|
||||||
role="progressbar" title="hello">
|
|
||||||
<span v-if="category.earnedPct > 20">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: category.currency_code}).format(category.earned) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {createNamespacedHelpers} from "vuex";
|
|
||||||
import format from "date-fns/format";
|
|
||||||
|
|
||||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('dashboard/index')
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "MainCategoryList",
|
|
||||||
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
this.ready = true;
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
locale: 'en-US',
|
|
||||||
categories: [],
|
|
||||||
sortedList: [],
|
|
||||||
spent: 0,
|
|
||||||
earned: 0,
|
|
||||||
loading: true,
|
|
||||||
error: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters(['start', 'end']),
|
|
||||||
'datesReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && this.ready;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
datesReady: function (value) {
|
|
||||||
if (true === value) {
|
|
||||||
this.getCategories();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
start: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.getCategories();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.getCategories();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods:
|
|
||||||
{
|
|
||||||
getCategories: function () {
|
|
||||||
this.categories = [];
|
|
||||||
this.sortedList = [];
|
|
||||||
this.spent = 0;
|
|
||||||
this.earned = 0;
|
|
||||||
this.loading = true;
|
|
||||||
// let startStr = this.start.toISOString().split('T')[0];
|
|
||||||
// let endStr = this.end.toISOString().split('T')[0];
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
this.getCategoryPage(startStr, endStr, 1);
|
|
||||||
},
|
|
||||||
getCategoryPage: function (start, end, page) {
|
|
||||||
axios.get('./api/v1/categories?start=' + start + '&end=' + end + '&page=' + page)
|
|
||||||
.then(response => {
|
|
||||||
let categories = response.data.data;
|
|
||||||
let currentPage = parseInt(response.data.meta.pagination.current_page);
|
|
||||||
let totalPages = parseInt(response.data.meta.pagination.total_pages);
|
|
||||||
this.parseCategories(categories);
|
|
||||||
if (currentPage < totalPages) {
|
|
||||||
let nextPage = currentPage + 1;
|
|
||||||
this.getCategoryPage(start, end, nextPage);
|
|
||||||
}
|
|
||||||
if (currentPage === totalPages) {
|
|
||||||
this.loading = false;
|
|
||||||
this.sortCategories();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
).catch(error => {
|
|
||||||
this.error = true;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
parseCategories(data) {
|
|
||||||
for (let i in data) {
|
|
||||||
if (data.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = data[i];
|
|
||||||
let entryKey = null;
|
|
||||||
let categoryId = parseInt(current.id);
|
|
||||||
|
|
||||||
// loop spent info:
|
|
||||||
for (let ii in current.attributes.spent) {
|
|
||||||
if (current.attributes.spent.hasOwnProperty(ii) && /^0$|^[1-9]\d*$/.test(ii) && ii <= 4294967294) {
|
|
||||||
let spentData = current.attributes.spent[ii];
|
|
||||||
entryKey = spentData.currency_id + '-' + current.id;
|
|
||||||
|
|
||||||
// does the categories list thing have this combo? if not, create it.
|
|
||||||
this.categories[entryKey] = this.categories[entryKey] ??
|
|
||||||
{
|
|
||||||
id: categoryId,
|
|
||||||
name: current.attributes.name,
|
|
||||||
currency_code: spentData.currency_code,
|
|
||||||
currency_symbol: spentData.currency_symbol,
|
|
||||||
spent: 0,
|
|
||||||
earned: 0,
|
|
||||||
spentPct: 0,
|
|
||||||
earnedPct: 0,
|
|
||||||
};
|
|
||||||
this.categories[entryKey].spent = parseFloat(spentData.sum);
|
|
||||||
this.spent = parseFloat(spentData.sum) < this.spent ? parseFloat(spentData.sum) : this.spent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop earned info
|
|
||||||
for (let ii in current.attributes.earned) {
|
|
||||||
if (current.attributes.earned.hasOwnProperty(ii) && /^0$|^[1-9]\d*$/.test(ii) && ii <= 4294967294) {
|
|
||||||
let earnedData = current.attributes.earned[ii];
|
|
||||||
entryKey = earnedData.currency_id + '-' + current.id;
|
|
||||||
|
|
||||||
// does the categories list thing have this combo? if not, create it.
|
|
||||||
this.categories[entryKey] = this.categories[entryKey] ??
|
|
||||||
{
|
|
||||||
id: categoryId,
|
|
||||||
name: current.attributes.name,
|
|
||||||
currency_code: earnedData.currency_code,
|
|
||||||
currency_symbol: earnedData.currency_symbol,
|
|
||||||
spent: 0,
|
|
||||||
earned: 0,
|
|
||||||
spentPct: 0,
|
|
||||||
earnedPct: 0,
|
|
||||||
};
|
|
||||||
this.categories[entryKey].earned = parseFloat(earnedData.sum);
|
|
||||||
this.earned = parseFloat(earnedData.sum) > this.earned ? parseFloat(earnedData.sum) : this.earned;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
sortCategories() {
|
|
||||||
// no longer care about keys:
|
|
||||||
let array = [];
|
|
||||||
for (let i in this.categories) {
|
|
||||||
if (this.categories.hasOwnProperty(i)) {
|
|
||||||
array.push(this.categories[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
array.sort(function (one, two) {
|
|
||||||
return (one.spent + one.earned) - (two.spent + two.earned);
|
|
||||||
});
|
|
||||||
for (let i in array) {
|
|
||||||
if (array.hasOwnProperty(i)) {
|
|
||||||
let current = array[i];
|
|
||||||
current.spentPct = (current.spent / this.spent) * 100;
|
|
||||||
current.earnedPct = (current.earned / this.earned) * 100;
|
|
||||||
this.sortedList.push(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
<!--
|
|
||||||
- MainCreditList.vue
|
|
||||||
- Copyright (c) 2020 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="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">{{ $t('firefly.revenue_accounts') }}</h3>
|
|
||||||
</div>
|
|
||||||
<!-- body if loading -->
|
|
||||||
<div v-if="loading && !error" class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- body if error -->
|
|
||||||
<div v-if="error" class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-exclamation-triangle text-danger"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- body if normal -->
|
|
||||||
<div v-if="!loading && !error" class="card-body table-responsive p-0">
|
|
||||||
<table class="table table-sm">
|
|
||||||
<caption style="display:none;">{{ $t('firefly.revenue_accounts') }}</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">{{ $t('firefly.account') }}</th>
|
|
||||||
<th scope="col">{{ $t('firefly.earned') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="entry in income">
|
|
||||||
<td style="width:20%;"><a :href="'./accounts/show/' + entry.id">{{ entry.name }}</a></td>
|
|
||||||
<td class="align-middle">
|
|
||||||
<div v-if="entry.pct > 0" class="progress">
|
|
||||||
<div :aria-valuenow="entry.pct" :style="{ width: entry.pct + '%'}" aria-valuemax="100"
|
|
||||||
aria-valuemin="0" class="progress-bar bg-success"
|
|
||||||
role="progressbar">
|
|
||||||
<span v-if="entry.pct > 20">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: entry.currency_code}).format(entry.difference_float) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span v-if="entry.pct <= 20" style="line-height: 16px;">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: entry.currency_code}).format(entry.difference_float) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<a class="btn btn-default button-sm" href="./transactions/deposit"><span class="far fa-money-bill-alt"></span> {{ $t('firefly.go_to_deposits') }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import {createNamespacedHelpers} from "vuex";
|
|
||||||
import format from "date-fns/format";
|
|
||||||
|
|
||||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('dashboard/index')
|
|
||||||
|
|
||||||
// See reference nr. 2
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "MainCreditList",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
locale: 'en-US',
|
|
||||||
income: [],
|
|
||||||
max: 0,
|
|
||||||
loading: true,
|
|
||||||
error: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
this.ready = true;
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters([
|
|
||||||
'start',
|
|
||||||
'end'
|
|
||||||
]),
|
|
||||||
'datesReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && this.ready;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
datesReady: function (value) {
|
|
||||||
if (true === value) {
|
|
||||||
this.getIncome();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
start: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.getIncome();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.getIncome();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getIncome() {
|
|
||||||
this.loading = true;
|
|
||||||
this.income = [];
|
|
||||||
this.error = false;
|
|
||||||
// let startStr = this.start.toISOString().split('T')[0];
|
|
||||||
// let endStr = this.end.toISOString().split('T')[0];
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
axios.get('./api/v1/insight/income/revenue?start=' + startStr + '&end=' + endStr)
|
|
||||||
.then(response => {
|
|
||||||
// do something with response.
|
|
||||||
this.parseIncome(response.data);
|
|
||||||
this.loading = false;
|
|
||||||
}).catch(error => {
|
|
||||||
this.error = true
|
|
||||||
});
|
|
||||||
},
|
|
||||||
parseIncome(data) {
|
|
||||||
for (let i in data) {
|
|
||||||
if (data.hasOwnProperty(i)) {
|
|
||||||
let mainKey = parseInt(i);
|
|
||||||
// contains currency info and entries.
|
|
||||||
let current = data[mainKey];
|
|
||||||
current.pct = 0;
|
|
||||||
this.max = current.difference_float > this.max ? current.difference_float : this.max;
|
|
||||||
this.income.push(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (0 === this.max) {
|
|
||||||
this.max = 1;
|
|
||||||
}
|
|
||||||
// now sort + pct:
|
|
||||||
for (let i in this.income) {
|
|
||||||
if (this.income.hasOwnProperty(i)) {
|
|
||||||
let current = this.income[i];
|
|
||||||
current.pct = (current.difference_float / this.max) * 100;
|
|
||||||
this.income[i] = current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.income.sort((a,b) => (a.pct > b.pct) ? -1 : ((b.pct > a.pct) ? 1 : 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
<!--
|
|
||||||
- MainDebitList.vue
|
|
||||||
- Copyright (c) 2020 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="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">{{ $t('firefly.expense_accounts') }}</h3>
|
|
||||||
</div>
|
|
||||||
<!-- body if loading -->
|
|
||||||
<div v-if="loading && !error" class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- body if error -->
|
|
||||||
<div v-if="error" class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-exclamation-triangle text-danger"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- body if normal -->
|
|
||||||
<div v-if="!loading && !error" class="card-body table-responsive p-0">
|
|
||||||
<table class="table table-sm">
|
|
||||||
<caption style="display:none;">{{ $t('firefly.expense_accounts') }}</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">{{ $t('firefly.account') }}</th>
|
|
||||||
<th scope="col">{{ $t('firefly.spent') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="entry in expenses">
|
|
||||||
<td style="width:20%;"><a :href="'./accounts/show/' + entry.id">{{ entry.name }}</a></td>
|
|
||||||
<td class="align-middle">
|
|
||||||
<div v-if="entry.pct > 0" class="progress">
|
|
||||||
<div :aria-valuenow="entry.pct" :style="{ width: entry.pct + '%'}" aria-valuemax="100"
|
|
||||||
aria-valuemin="0" class="progress-bar bg-danger"
|
|
||||||
role="progressbar">
|
|
||||||
<span v-if="entry.pct > 20">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: entry.currency_code}).format(entry.difference_float) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span v-if="entry.pct <= 20" style="line-height: 16px;">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: entry.currency_code}).format(entry.difference_float) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<a class="btn btn-default button-sm" href="./transactions/withdrawal"><span class="far fa-money-bill-alt"></span> {{ $t('firefly.go_to_withdrawals') }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import {createNamespacedHelpers} from "vuex";
|
|
||||||
import format from "date-fns/format";
|
|
||||||
|
|
||||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('dashboard/index')
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "MainDebitList",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
locale: 'en-US',
|
|
||||||
expenses: [],
|
|
||||||
min: 0,
|
|
||||||
loading: true,
|
|
||||||
error: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
this.ready = true;
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters([
|
|
||||||
'start',
|
|
||||||
'end'
|
|
||||||
]),
|
|
||||||
'datesReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && this.ready;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
datesReady: function (value) {
|
|
||||||
if (true === value) {
|
|
||||||
this.getExpenses();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
start: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.getExpenses();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.getExpenses();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getExpenses() {
|
|
||||||
this.loading = true;
|
|
||||||
this.error = false;
|
|
||||||
this.expenses = [];
|
|
||||||
// let startStr = this.start.toISOString().split('T')[0];
|
|
||||||
// let endStr = this.end.toISOString().split('T')[0];
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
axios.get('./api/v1/insight/expense/expense?start=' + startStr + '&end=' + endStr)
|
|
||||||
.then(response => {
|
|
||||||
// do something with response.
|
|
||||||
this.parseExpenses(response.data);
|
|
||||||
this.loading = false
|
|
||||||
}).catch(error => {
|
|
||||||
this.error = true
|
|
||||||
});
|
|
||||||
},
|
|
||||||
parseExpenses(data) {
|
|
||||||
for (let mainKey in data) {
|
|
||||||
if (data.hasOwnProperty(mainKey) && /^0$|^[1-9]\d*$/.test(mainKey) && mainKey <= 4294967294) {
|
|
||||||
let current = data[mainKey];
|
|
||||||
current.pct = 0;
|
|
||||||
|
|
||||||
this.min = current.difference_float < this.min ? current.difference_float : this.min;
|
|
||||||
this.expenses.push(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 === this.min) {
|
|
||||||
this.min = -1;
|
|
||||||
}
|
|
||||||
// now sort + pct:
|
|
||||||
for (let i in this.expenses) {
|
|
||||||
if (this.expenses.hasOwnProperty(i)) {
|
|
||||||
let current = this.expenses[i];
|
|
||||||
current.pct = (current.difference_float*-1 / this.min*-1) * 100;
|
|
||||||
this.expenses[i] = current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.expenses.sort((a,b) => (a.pct > b.pct) ? -1 : ((b.pct > a.pct) ? 1 : 0));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
<!--
|
|
||||||
- MainPiggyList.vue
|
|
||||||
- Copyright (c) 2020 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="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">{{ $t('firefly.piggy_banks') }}</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- body if loading -->
|
|
||||||
<div v-if="loading && !error" class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- body if error -->
|
|
||||||
<div v-if="error" class="card-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="fas fa-exclamation-triangle text-danger"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- body if normal -->
|
|
||||||
<div v-if="!loading && !error" class="card-body table-responsive p-0">
|
|
||||||
<table class="table table-striped">
|
|
||||||
<caption style="display:none;">{{ $t('firefly.piggy_banks') }}</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col" style="width:35%;">{{ $t('list.piggy_bank') }}</th>
|
|
||||||
<th scope="col" style="width:40%;">{{ $t('list.percentage') }} <small>/ {{ $t('list.amount') }}</small></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="piggy in this.piggy_banks">
|
|
||||||
<td>
|
|
||||||
<a :href="'./piggy-banks/show/' + piggy.id" :title="piggy.attributes.name">{{ piggy.attributes.name }}</a>
|
|
||||||
<small v-if="piggy.attributes.object_group_title" class="text-muted">
|
|
||||||
<br/>
|
|
||||||
{{ piggy.attributes.object_group_title }}
|
|
||||||
</small>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="progress-group">
|
|
||||||
<div class="progress progress-sm">
|
|
||||||
<div v-if="piggy.attributes.pct < 100" :style="{'width': piggy.attributes.pct + '%'}" class="progress-bar primary"></div>
|
|
||||||
<div v-if="100 === piggy.attributes.pct" :style="{'width': piggy.attributes.pct + '%'}"
|
|
||||||
class="progress-bar progress-bar-striped bg-success"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span class="text-success">
|
|
||||||
{{
|
|
||||||
Intl.NumberFormat(locale, {style: 'currency', currency: piggy.attributes.currency_code}).format(piggy.attributes.current_amount)
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
of
|
|
||||||
<span class="text-success">{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency',
|
|
||||||
currency: piggy.attributes.currency_code
|
|
||||||
}).format(piggy.attributes.target_amount)
|
|
||||||
}}</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<a class="btn btn-default button-sm" href="./piggy-banks"><span class="far fa-money-bill-alt"></span> {{ $t('firefly.go_to_piggies') }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "MainPiggyList",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
piggy_banks: [],
|
|
||||||
loading: true,
|
|
||||||
error: false,
|
|
||||||
locale: 'en-US'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
axios.get('./api/v1/piggy_banks')
|
|
||||||
.then(response => {
|
|
||||||
this.loadPiggyBanks(response.data.data);
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
).catch(error => {
|
|
||||||
this.error = true
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadPiggyBanks(data) {
|
|
||||||
for (let key in data) {
|
|
||||||
if (data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
|
||||||
let piggy = data[key];
|
|
||||||
if (0.0 !== parseFloat(piggy.attributes.left_to_save)) {
|
|
||||||
piggy.attributes.pct = (parseFloat(piggy.attributes.current_amount) / parseFloat(piggy.attributes.target_amount)) * 100;
|
|
||||||
this.piggy_banks.push(piggy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.piggy_banks.sort(function (a, b) {
|
|
||||||
return b.attributes.pct - a.attributes.pct;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,313 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TopBoxes.vue
|
|
||||||
- Copyright (c) 2020 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="row">
|
|
||||||
<div class="col" v-if="0 !== prefCurrencyBalances.length || 0 !== notPrefCurrencyBalances.length">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon"><span class="far fa-bookmark text-info"></span></span>
|
|
||||||
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span v-if="!loading && !error" class="info-box-text">{{ $t("firefly.balance") }}</span>
|
|
||||||
<span v-if="loading && !error" class="info-box-text"><span class="fas fa-spinner fa-spin"></span></span>
|
|
||||||
<span v-if="error" class="info-box-text"><span class="fas fa-exclamation-triangle text-danger"></span></span>
|
|
||||||
<!-- balance in preferred currency -->
|
|
||||||
<span v-for="balance in prefCurrencyBalances" :title="balance.sub_title" class="info-box-number">{{ balance.value_parsed }}</span>
|
|
||||||
<span v-if="0 === prefCurrencyBalances.length" class="info-box-number"> </span>
|
|
||||||
<div class="progress bg-info">
|
|
||||||
<div class="progress-bar" style="width: 0"></div>
|
|
||||||
</div>
|
|
||||||
<!-- balance in not preferred currency -->
|
|
||||||
<span class="progress-description">
|
|
||||||
<span v-for="(balance, index) in notPrefCurrencyBalances" :title="balance.sub_title">
|
|
||||||
{{ balance.value_parsed }}<span v-if="index+1 !== notPrefCurrencyBalances.length">, </span>
|
|
||||||
</span>
|
|
||||||
<span v-if="0===notPrefCurrencyBalances.length"> </span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col" v-if="0!==prefBillsUnpaid.length || 0 !== notPrefBillsUnpaid.length">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon"><span class="far fa-calendar-alt text-teal"></span></span>
|
|
||||||
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span v-if="!loading && !error" class="info-box-text">{{ $t('firefly.bills_to_pay') }}</span>
|
|
||||||
<span v-if="loading && !error" class="info-box-text"><span class="fas fa-spinner fa-spin"></span></span>
|
|
||||||
<span v-if="error" class="info-box-text"><span class="fas fa-exclamation-triangle text-danger"></span></span>
|
|
||||||
<!-- bills unpaid, in preferred currency. -->
|
|
||||||
<span v-for="balance in prefBillsUnpaid" class="info-box-number">{{ balance.value_parsed }}</span>
|
|
||||||
|
|
||||||
<div class="progress bg-teal">
|
|
||||||
<div class="progress-bar" style="width: 0"></div>
|
|
||||||
</div>
|
|
||||||
<!-- bills unpaid, in other currencies. -->
|
|
||||||
<span class="progress-description">
|
|
||||||
<span v-for="(bill, index) in notPrefBillsUnpaid">
|
|
||||||
{{ bill.value_parsed }}<span v-if="index+1 !== notPrefBillsUnpaid.length">, </span>
|
|
||||||
</span>
|
|
||||||
<span v-if="0===notPrefBillsUnpaid.length"> </span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- left to spend -->
|
|
||||||
<div class="col" v-if="0 !== prefLeftToSpend.length || 0 !== notPrefLeftToSpend.length">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon"><span class="fas fa-money-bill text-success"></span></span>
|
|
||||||
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span v-if="!loading && !error" class="info-box-text">{{ $t('firefly.left_to_spend') }}</span>
|
|
||||||
<span v-if="loading && !error" class="info-box-text"><span class="fas fa-spinner fa-spin"></span></span>
|
|
||||||
<span v-if="error" class="info-box-text"><span class="fas fa-exclamation-triangle text-danger"></span></span>
|
|
||||||
<!-- left to spend in preferred currency -->
|
|
||||||
<span v-for="left in prefLeftToSpend" :title="left.sub_title" class="info-box-number">{{ left.value_parsed }}</span>
|
|
||||||
<span v-if="0 === prefLeftToSpend.length" class="info-box-number"> </span>
|
|
||||||
|
|
||||||
<div class="progress bg-success">
|
|
||||||
<div class="progress-bar" style="width: 0"></div>
|
|
||||||
</div>
|
|
||||||
<!-- other currencies-->
|
|
||||||
<span class="progress-description">
|
|
||||||
<span v-for="(left, index) in notPrefLeftToSpend">
|
|
||||||
{{ left.value_parsed }}<span v-if="index+1 !== notPrefLeftToSpend.length">, </span>
|
|
||||||
</span>
|
|
||||||
<span v-if="0===notPrefLeftToSpend.length"> </span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- net worth -->
|
|
||||||
<div class="col" v-if="0 !== notPrefNetWorth.length || 0 !== prefNetWorth.length">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon"><span class="fas fa-money-bill text-success"></span></span>
|
|
||||||
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span v-if="!loading && !error" class="info-box-text">{{ $t('firefly.net_worth') }}</span>
|
|
||||||
<span v-if="loading && !error" class="info-box-text"><span class="fas fa-spinner fa-spin"></span></span>
|
|
||||||
<span v-if="error" class="info-box-text"><span class="fas fa-exclamation-triangle text-danger"></span></span>
|
|
||||||
<span v-for="nw in prefNetWorth" :title="nw.sub_title" class="info-box-number">{{ nw.value_parsed }}</span>
|
|
||||||
<span v-if="0===prefNetWorth.length"> </span>
|
|
||||||
<div class="progress bg-success">
|
|
||||||
<div class="progress-bar" style="width: 0"></div>
|
|
||||||
</div>
|
|
||||||
<span class="progress-description">
|
|
||||||
<span v-for="(nw, index) in notPrefNetWorth">
|
|
||||||
{{ nw.value_parsed }}<span v-if="index+1 !== notPrefNetWorth.length">, </span>
|
|
||||||
</span>
|
|
||||||
<span v-if="0===notPrefNetWorth.length"> </span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {createNamespacedHelpers} from "vuex";
|
|
||||||
import format from 'date-fns/format';
|
|
||||||
|
|
||||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('dashboard/index')
|
|
||||||
export default {
|
|
||||||
name: "TopBoxes",
|
|
||||||
props: {},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
summary: [],
|
|
||||||
balances: [],
|
|
||||||
billsPaid: [],
|
|
||||||
billsUnpaid: [],
|
|
||||||
leftToSpend: [],
|
|
||||||
netWorth: [],
|
|
||||||
loading: true,
|
|
||||||
error: false,
|
|
||||||
ready: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters([
|
|
||||||
'start',
|
|
||||||
'end'
|
|
||||||
]),
|
|
||||||
'datesReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && this.ready;
|
|
||||||
},
|
|
||||||
|
|
||||||
// contains only balances with preferred currency.
|
|
||||||
prefCurrencyBalances: function () {
|
|
||||||
return this.filterOnCurrency(this.balances);
|
|
||||||
},
|
|
||||||
notPrefCurrencyBalances: function () {
|
|
||||||
return this.filterOnNotCurrency(this.balances);
|
|
||||||
},
|
|
||||||
|
|
||||||
// contains only bills unpaid in preferred currency or first one.
|
|
||||||
prefBillsUnpaid: function () {
|
|
||||||
return this.filterOnCurrency(this.billsUnpaid);
|
|
||||||
},
|
|
||||||
notPrefBillsUnpaid: function () {
|
|
||||||
return this.filterOnNotCurrency(this.billsUnpaid);
|
|
||||||
},
|
|
||||||
|
|
||||||
// left to spend
|
|
||||||
prefLeftToSpend: function () {
|
|
||||||
return this.filterOnCurrency(this.leftToSpend);
|
|
||||||
},
|
|
||||||
notPrefLeftToSpend: function () {
|
|
||||||
return this.filterOnNotCurrency(this.leftToSpend);
|
|
||||||
},
|
|
||||||
|
|
||||||
// net worth
|
|
||||||
prefNetWorth: function () {
|
|
||||||
return this.filterOnCurrency(this.netWorth);
|
|
||||||
},
|
|
||||||
notPrefNetWorth: function () {
|
|
||||||
return this.filterOnNotCurrency(this.netWorth);
|
|
||||||
},
|
|
||||||
currencyCode() {
|
|
||||||
return this.$store.getters.currencyCode;
|
|
||||||
},
|
|
||||||
currencyId() {
|
|
||||||
return this.$store.getters.currencyId;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
datesReady: function (value) {
|
|
||||||
if (true === value) {
|
|
||||||
this.prepareComponent();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
start: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.prepareComponent();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
if (false === this.loading) {
|
|
||||||
this.prepareComponent();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.ready = true;
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
filterOnCurrency(array) {
|
|
||||||
let ret = [];
|
|
||||||
for (const key in array) {
|
|
||||||
if (array.hasOwnProperty(key)) {
|
|
||||||
// console.log('Currency ID seems to be ' + this.currencyId);
|
|
||||||
if (array[key].currency_id === this.currencyId) {
|
|
||||||
ret.push(array[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// or just the first one:
|
|
||||||
if (0 === ret.length && array.hasOwnProperty(0)) {
|
|
||||||
ret.push(array[0]);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
},
|
|
||||||
filterOnNotCurrency(array) {
|
|
||||||
let ret = [];
|
|
||||||
for (const key in array) {
|
|
||||||
if (array.hasOwnProperty(key)) {
|
|
||||||
if (array[key].currency_id !== this.currencyId) {
|
|
||||||
ret.push(array[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Prepare the component.
|
|
||||||
*/
|
|
||||||
prepareComponent() {
|
|
||||||
this.error = false;
|
|
||||||
this.loading = true;
|
|
||||||
this.summary = [];
|
|
||||||
this.balances = [];
|
|
||||||
this.billsPaid = [];
|
|
||||||
this.billsUnpaid = [];
|
|
||||||
this.leftToSpend = [];
|
|
||||||
this.netWorth = [];
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
//let startStr = this.start.toISOString().split('T')[0];
|
|
||||||
//let endStr = this.end.toISOString().split('T')[0];
|
|
||||||
//console.log(startStr);
|
|
||||||
//console.log(endStr);
|
|
||||||
axios.get('./api/v1/summary/basic?start=' + startStr + '&end=' + endStr)
|
|
||||||
.then(response => {
|
|
||||||
this.summary = response.data;
|
|
||||||
this.buildComponent();
|
|
||||||
this.loading = false
|
|
||||||
}).catch(error => {
|
|
||||||
this.error = true
|
|
||||||
});
|
|
||||||
},
|
|
||||||
buildComponent() {
|
|
||||||
this.getBalanceEntries();
|
|
||||||
this.getBillsEntries();
|
|
||||||
this.getLeftToSpend();
|
|
||||||
this.getNetWorth();
|
|
||||||
},
|
|
||||||
|
|
||||||
hasCurrency: function (array) {
|
|
||||||
for (const key in array) {
|
|
||||||
if (array.hasOwnProperty(key)) {
|
|
||||||
if (array[key].currency_id === this.currencyId) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
getBalanceEntries() {
|
|
||||||
this.balances = this.getKeyedEntries('balance-in-');
|
|
||||||
},
|
|
||||||
getNetWorth() {
|
|
||||||
this.netWorth = this.getKeyedEntries('net-worth-in-');
|
|
||||||
},
|
|
||||||
getLeftToSpend() {
|
|
||||||
this.leftToSpend = this.getKeyedEntries('left-to-spend-in-');
|
|
||||||
},
|
|
||||||
getBillsEntries() {
|
|
||||||
this.billsPaid = this.getKeyedEntries('bills-paid-in-');
|
|
||||||
this.billsUnpaid = this.getKeyedEntries('bills-unpaid-in-');
|
|
||||||
},
|
|
||||||
getKeyedEntries(expected) {
|
|
||||||
let result = [];
|
|
||||||
for (const key in this.summary) {
|
|
||||||
if (this.summary.hasOwnProperty(key)) {
|
|
||||||
if (expected === key.substr(0, expected.length)) {
|
|
||||||
result.push(this.summary[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
<!--
|
|
||||||
- GenericAttachments.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ title }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="title"
|
|
||||||
:name="fieldName"
|
|
||||||
multiple
|
|
||||||
ref="att"
|
|
||||||
@change="selectedFile"
|
|
||||||
type="file"
|
|
||||||
:disabled=disabled
|
|
||||||
/>
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button
|
|
||||||
class="btn btn-default"
|
|
||||||
type="button"
|
|
||||||
v-on:click="clearAtt"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "GenericAttachments",
|
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
fieldName: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
errors: {
|
|
||||||
type: Array,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uploadTrigger: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
uploadObjectType: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
uploadObjectId: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
localValue: this.value,
|
|
||||||
uploaded: 0,
|
|
||||||
uploads: 0,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
uploadTrigger: function (value) {
|
|
||||||
if (true === value) {
|
|
||||||
// this.createAttachment().then(response => {
|
|
||||||
// this.uploadAttachment(response.data.data.id, new Blob([evt.target.result]));
|
|
||||||
// });
|
|
||||||
|
|
||||||
// new code
|
|
||||||
// console.log('start of new');
|
|
||||||
let files = this.$refs.att.files;
|
|
||||||
this.uploads = files.length;
|
|
||||||
// loop all files and create attachments.
|
|
||||||
for (let i in files) {
|
|
||||||
if (files.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
// console.log('Now at file ' + (parseInt(i) + 1) + ' / ' + files.length);
|
|
||||||
// read file into file reader:
|
|
||||||
let current = files[i];
|
|
||||||
let fileReader = new FileReader();
|
|
||||||
let theParent = this; // dont ask me why i need to do this.
|
|
||||||
fileReader.onloadend = evt => {
|
|
||||||
if (evt.target.readyState === FileReader.DONE) {
|
|
||||||
// console.log('I am done reading file ' + (parseInt(i) + 1));
|
|
||||||
this.createAttachment(current.name).then(response => {
|
|
||||||
// console.log('Created attachment. Now upload (1)');
|
|
||||||
return theParent.uploadAttachment(response.data.data.id, new Blob([evt.target.result]));
|
|
||||||
}).then(theParent.countAttachment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fileReader.readAsArrayBuffer(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (0 === files.length) {
|
|
||||||
// console.log('No files to upload. Emit event!');
|
|
||||||
this.$emit('uploaded-attachments', this.transaction_journal_id);
|
|
||||||
}
|
|
||||||
// Promise.all(promises).then(response => {
|
|
||||||
// console.log('All files uploaded. Emit event!');
|
|
||||||
// this.$emit('uploaded-attachments', this.transaction_journal_id);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// end new code
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
countAttachment: function () {
|
|
||||||
this.uploaded++;
|
|
||||||
// console.log('Uploaded ' + this.uploaded + ' / ' + this.uploads);
|
|
||||||
if (this.uploaded >= this.uploads) {
|
|
||||||
// console.log('All files uploaded. Emit event for ' + this.uploadObjectId);
|
|
||||||
this.$emit('uploaded-attachments', this.uploadObjectId);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uploadAttachment: function (attachmentId, data) {
|
|
||||||
this.created++;
|
|
||||||
// console.log('Now in uploadAttachment()');
|
|
||||||
const uploadUri = './api/v1/attachments/' + attachmentId + '/upload';
|
|
||||||
return axios.post(uploadUri, data)
|
|
||||||
},
|
|
||||||
createAttachment: function (name) {
|
|
||||||
const uri = './api/v1/attachments';
|
|
||||||
const data = {
|
|
||||||
filename: name,
|
|
||||||
attachable_type: this.uploadObjectType,
|
|
||||||
attachable_id: this.uploadObjectId,
|
|
||||||
};
|
|
||||||
return axios.post(uri, data);
|
|
||||||
},
|
|
||||||
selectedFile: function () {
|
|
||||||
this.$emit('selected-attachments');
|
|
||||||
},
|
|
||||||
clearAtt: function () {
|
|
||||||
this.$refs.att.value = '';
|
|
||||||
this.$emit('selected-no-attachments');
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
<!--
|
|
||||||
- GenericTextInput.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ title }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" :disabled=disabled type="checkbox" v-model="localValue" :id="fieldName">
|
|
||||||
<label class="form-check-label" :for="fieldName">
|
|
||||||
{{ description }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "GenericCheckbox",
|
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
description: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
fieldName: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
errors: {
|
|
||||||
type: Array,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
localValue: this.value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
localValue: function (value) {
|
|
||||||
this.$emit('set-field', {field: this.fieldName, value: value});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Currency.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('form.currency_id') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="loading">
|
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
|
||||||
</div>
|
|
||||||
<div class="input-group" v-if="!loading">
|
|
||||||
<select
|
|
||||||
ref="currency_id"
|
|
||||||
v-model="currency_id"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:title="$t('form.currency_id')"
|
|
||||||
autocomplete="off"
|
|
||||||
:disabled=disabled
|
|
||||||
name="currency_id"
|
|
||||||
>
|
|
||||||
<option v-for="currency in this.currencyList" :label="currency.name" :value="currency.id" :selected="value === currency.id">{{ currency.name }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "GenericCurrency",
|
|
||||||
props: {
|
|
||||||
value: 0,
|
|
||||||
errors: [],
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
currency_id: this.value,
|
|
||||||
currencyList: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadCurrencies: function () {
|
|
||||||
this.loadCurrencyPage(1);
|
|
||||||
},
|
|
||||||
loadCurrencyPage: function (page) {
|
|
||||||
axios.get('./api/v1/currencies?page=' + page)
|
|
||||||
.then(response => {
|
|
||||||
let totalPages = parseInt(response.data.meta.pagination.total_pages);
|
|
||||||
let currentPage = parseInt(response.data.meta.pagination.current_page);
|
|
||||||
let currencies = response.data.data;
|
|
||||||
for (let i in currencies) {
|
|
||||||
if (currencies.hasOwnProperty(i)) {
|
|
||||||
let current = currencies[i];
|
|
||||||
if (true === current.attributes.default && null === this.value) {
|
|
||||||
this.currency_id = parseInt(current.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (false === current.attributes.enabled) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let currency = {
|
|
||||||
id: parseInt(current.id),
|
|
||||||
name: current.attributes.name,
|
|
||||||
};
|
|
||||||
this.currencyList.push(currency);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currentPage < totalPages) {
|
|
||||||
this.loadCurrencyPage(currentPage++);
|
|
||||||
}
|
|
||||||
if (currentPage >= totalPages) {
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
currency_id: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'currency_id', value: value});
|
|
||||||
},
|
|
||||||
value: function(value) {
|
|
||||||
this.currency_id = value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.loadCurrencies();
|
|
||||||
if (typeof this.value === 'number' && 0 !== this.value) {
|
|
||||||
this.currency_id = tthis.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
<!--
|
|
||||||
- GenericTextInput.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ title }}
|
|
||||||
</div>
|
|
||||||
<vue-typeahead-bootstrap
|
|
||||||
v-model="localValue"
|
|
||||||
:data="groupTitles"
|
|
||||||
:inputClass="errors.length > 0 ? 'is-invalid' : ''"
|
|
||||||
:minMatchingChars="3"
|
|
||||||
:placeholder="title"
|
|
||||||
:serializer="item => item.title"
|
|
||||||
:showOnFocus=true
|
|
||||||
autofocus
|
|
||||||
inputName="description[]"
|
|
||||||
@input="lookupGroupTitle"
|
|
||||||
>
|
|
||||||
<template slot="append">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" tabindex="-1" type="button" v-on:click="clearGroupTitle"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</vue-typeahead-bootstrap>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
import VueTypeaheadBootstrap from 'vue-typeahead-bootstrap';
|
|
||||||
import {debounce} from "lodash";
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import VueTypeaheadBootstrap from "vue-typeahead-bootstrap";
|
|
||||||
import {debounce} from "lodash";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "GenericGroup",
|
|
||||||
components: {VueTypeaheadBootstrap},
|
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
description: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
fieldName: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
errors: {
|
|
||||||
type: Array,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
clearGroupTitle: function () {
|
|
||||||
this.localValue = '';
|
|
||||||
},
|
|
||||||
getACURL: function (query) {
|
|
||||||
// update autocomplete URL:
|
|
||||||
return document.getElementsByTagName('base')[0].href + 'api/v1/autocomplete/object-groups?query=' + query;
|
|
||||||
},
|
|
||||||
lookupGroupTitle: debounce(function () {
|
|
||||||
// update autocomplete URL:
|
|
||||||
axios.get(this.getACURL(this.value))
|
|
||||||
.then(response => {
|
|
||||||
this.groupTitles = response.data;
|
|
||||||
})
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
localValue: this.value,
|
|
||||||
groupTitles: [],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
localValue: function (value) {
|
|
||||||
this.$emit('set-field', {field: this.fieldName, value: value});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
<!--
|
|
||||||
- GenericLocation.vue
|
|
||||||
- Copyright (c) 2021 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-if="enableExternalMap">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ title }}
|
|
||||||
</div>
|
|
||||||
<div style="width:100%;height:300px;">
|
|
||||||
<LMap
|
|
||||||
ref="myMap"
|
|
||||||
:center="center"
|
|
||||||
:zoom="zoom" style="width:100%;height:300px;"
|
|
||||||
@ready="prepMap"
|
|
||||||
@update:zoom="zoomUpdated"
|
|
||||||
@update:center="centerUpdated"
|
|
||||||
@update:bounds="boundsUpdated"
|
|
||||||
>
|
|
||||||
<l-tile-layer :url="url"></l-tile-layer>
|
|
||||||
<l-marker :lat-lng="marker" :visible="hasMarker"></l-marker>
|
|
||||||
</LMap>
|
|
||||||
<span>
|
|
||||||
<button class="btn btn-default btn-xs" @click="clearLocation">{{ $t('firefly.clear_location') }}</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<p> </p>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
// If you need to reference 'L', such as in 'L.icon', then be sure to
|
|
||||||
// explicitly import 'leaflet' into your component
|
|
||||||
// import L from 'leaflet';
|
|
||||||
|
|
||||||
|
|
||||||
// OLD
|
|
||||||
// import {LMap, LMarker, LTileLayer} from 'vue2-leaflet';
|
|
||||||
// import 'leaflet/dist/leaflet.css';
|
|
||||||
//
|
|
||||||
// import L from 'leaflet';
|
|
||||||
//
|
|
||||||
// delete L.Icon.Default.prototype._getIconUrl;
|
|
||||||
//
|
|
||||||
// L.Icon.Default.mergeOptions({
|
|
||||||
// iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
|
|
||||||
// iconUrl: require('leaflet/dist/images/marker-icon.png'),
|
|
||||||
// shadowUrl: require('leaflet/dist/images/marker-shadow.png')
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
import {LMap, LMarker, LTileLayer} from 'vue2-leaflet';
|
|
||||||
import 'leaflet/dist/leaflet.css';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "GenericLocation",
|
|
||||||
components: {LMap, LTileLayer, LMarker,},
|
|
||||||
props: {
|
|
||||||
title: {},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
default: function () {
|
|
||||||
return {
|
|
||||||
// some defaults here.
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
errors: {},
|
|
||||||
customFields: {},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
availableFields: this.customFields,
|
|
||||||
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
|
||||||
zoom: 3,
|
|
||||||
center: [0, 0],
|
|
||||||
bounds: null,
|
|
||||||
map: null,
|
|
||||||
enableExternalMap: false,
|
|
||||||
hasMarker: false,
|
|
||||||
marker: [0, 0],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// enable_external_map
|
|
||||||
this.verifyMapEnabled();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
verifyMapEnabled: function () {
|
|
||||||
axios.get('./api/v1/configuration/firefly.enable_external_map').then(response => {
|
|
||||||
this.enableExternalMap = response.data.data.value;
|
|
||||||
if (true === this.enableExternalMap) {
|
|
||||||
this.loadMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
},
|
|
||||||
loadMap: function () {
|
|
||||||
if (null === this.value || typeof this.value === 'undefined' || 0 === Object.keys(this.value).length) {
|
|
||||||
axios.get('./api/v1/configuration/firefly.default_location').then(response => {
|
|
||||||
this.zoom = parseInt(response.data.data.value.zoom_level);
|
|
||||||
this.center =
|
|
||||||
[
|
|
||||||
parseFloat(response.data.data.value.latitude),
|
|
||||||
parseFloat(response.data.data.value.longitude),
|
|
||||||
]
|
|
||||||
;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (null !== this.value.zoom_level && null !== this.value.latitude && null !== this.value.longitude) {
|
|
||||||
this.zoom = this.value.zoom_level;
|
|
||||||
this.center = [
|
|
||||||
parseFloat(this.value.latitude),
|
|
||||||
parseFloat(this.value.longitude),
|
|
||||||
];
|
|
||||||
this.hasMarker = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
prepMap: function () {
|
|
||||||
this.map = this.$refs.myMap.mapObject;
|
|
||||||
this.map.on('contextmenu', this.setObjectLocation);
|
|
||||||
this.map.on('zoomend', this.saveZoomLevel);
|
|
||||||
},
|
|
||||||
setObjectLocation: function (event) {
|
|
||||||
this.marker = [event.latlng.lat, event.latlng.lng];
|
|
||||||
this.hasMarker = true;
|
|
||||||
this.emitEvent();
|
|
||||||
},
|
|
||||||
saveZoomLevel: function () {
|
|
||||||
this.emitEvent();
|
|
||||||
},
|
|
||||||
clearLocation: function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.hasMarker = false;
|
|
||||||
this.emitEvent();
|
|
||||||
},
|
|
||||||
emitEvent() {
|
|
||||||
this.$emit('set-field', {
|
|
||||||
field: "location",
|
|
||||||
value: {
|
|
||||||
zoomLevel: this.zoom,
|
|
||||||
lat: this.marker[0],
|
|
||||||
lng: this.marker[1],
|
|
||||||
hasMarker: this.hasMarker
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
zoomUpdated(zoom) {
|
|
||||||
this.zoom = zoom;
|
|
||||||
},
|
|
||||||
centerUpdated(center) {
|
|
||||||
this.center = center;
|
|
||||||
},
|
|
||||||
boundsUpdated(bounds) {
|
|
||||||
this.bounds = bounds;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
<!--
|
|
||||||
- GenericTextInput.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ title }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
v-model="localValue"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="title"
|
|
||||||
:name="fieldName"
|
|
||||||
ref="textInput"
|
|
||||||
:type="fieldType"
|
|
||||||
:disabled=disabled
|
|
||||||
:step="fieldStep"
|
|
||||||
/>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" v-on:click="clearText" tabindex="-1" type="button"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "GenericTextInput",
|
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
fieldName: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
fieldType: {
|
|
||||||
type: String,
|
|
||||||
default: 'text'
|
|
||||||
},
|
|
||||||
fieldStep: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
errors: {
|
|
||||||
type: Array,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
localValue: this.value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
clearText: function () {
|
|
||||||
this.localValue = '';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
localValue: function (value) {
|
|
||||||
this.$emit('set-field', {field: this.fieldName, value: value});
|
|
||||||
},
|
|
||||||
value: function(value) {
|
|
||||||
this.localValue = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
<!--
|
|
||||||
- GenericTextarea.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ title }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<textarea
|
|
||||||
v-model="localValue"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="title"
|
|
||||||
:disabled=disabled
|
|
||||||
:name="fieldName"
|
|
||||||
>{{ localValue }}</textarea>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "GenericTextarea",
|
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
fieldName: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
errors: {
|
|
||||||
type: Array,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
localValue: this.value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
localValue: function (value) {
|
|
||||||
this.$emit('set-field', {field: this.fieldName, value: value});
|
|
||||||
},
|
|
||||||
value: function(value) {
|
|
||||||
this.localValue = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Index.vue
|
|
||||||
- Copyright (c) 2020 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="row">
|
|
||||||
<div class="col">
|
|
||||||
<div id="accordion">
|
|
||||||
<!-- we are adding the .class so bootstrap.js collapse plugin detects it -->
|
|
||||||
<div class="card card-primary">
|
|
||||||
<div class="card-header">
|
|
||||||
<h4 class="card-title">
|
|
||||||
<a data-parent="#accordion" data-toggle="collapse" href="#collapseOne">
|
|
||||||
Create new accounts
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapseOne" class="panel-collapse collapse show">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<p>Explain</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-4">
|
|
||||||
A
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-8">
|
|
||||||
B
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card card-secondary">
|
|
||||||
<div class="card-header">
|
|
||||||
<h4 class="card-title">
|
|
||||||
<a data-parent="#accordion" data-toggle="collapse" href="#collapseTwo">
|
|
||||||
Collapsible Group Danger
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapseTwo" class="panel-collapse collapse">
|
|
||||||
<div class="card-body">
|
|
||||||
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid.
|
|
||||||
3
|
|
||||||
wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt
|
|
||||||
laborum
|
|
||||||
eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee
|
|
||||||
nulla
|
|
||||||
assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred
|
|
||||||
nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft
|
|
||||||
beer
|
|
||||||
farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus
|
|
||||||
labore sustainable VHS.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card card-secondary">
|
|
||||||
<div class="card-header">
|
|
||||||
<h4 class="card-title">
|
|
||||||
<a data-parent="#accordion" data-toggle="collapse" href="#collapseThree">
|
|
||||||
Collapsible Group Success
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapseThree" class="panel-collapse collapse">
|
|
||||||
<div class="card-body">
|
|
||||||
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid.
|
|
||||||
3
|
|
||||||
wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt
|
|
||||||
laborum
|
|
||||||
eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee
|
|
||||||
nulla
|
|
||||||
assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred
|
|
||||||
nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft
|
|
||||||
beer
|
|
||||||
farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus
|
|
||||||
labore sustainable VHS.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "Index"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Alert.vue
|
|
||||||
- Copyright (c) 2021 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="message.length > 0" :class="'alert alert-' + type + ' alert-dismissible'">
|
|
||||||
<button aria-hidden="true" class="close" data-dismiss="alert" type="button">×</button>
|
|
||||||
<h5>
|
|
||||||
<span v-if="'danger' === type" class="icon fas fa-ban"></span>
|
|
||||||
<span v-if="'success' === type" class="icon fas fa-thumbs-up"></span>
|
|
||||||
<span v-if="'danger' === type">{{ $t("firefly.flash_error") }}</span>
|
|
||||||
<span v-if="'success' === type">{{ $t("firefly.flash_success") }}</span>
|
|
||||||
</h5>
|
|
||||||
<span v-html="message"></span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "Alert",
|
|
||||||
props: ['message', 'type']
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
136
frontend/src/components/store/index.js
vendored
136
frontend/src/components/store/index.js
vendored
@@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* index.js
|
|
||||||
* Copyright (c) 2020 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import Vue from 'vue'
|
|
||||||
import Vuex, {createLogger} from 'vuex'
|
|
||||||
import transactions_create from './modules/transactions/create';
|
|
||||||
import transactions_edit from './modules/transactions/edit';
|
|
||||||
import dashboard_index from './modules/dashboard/index';
|
|
||||||
import root_store from './modules/root';
|
|
||||||
import accounts_index from './modules/accounts/index';
|
|
||||||
|
|
||||||
Vue.use(Vuex)
|
|
||||||
const debug = process.env.NODE_ENV !== 'production'
|
|
||||||
|
|
||||||
export default new Vuex.Store(
|
|
||||||
{
|
|
||||||
namespaced: true,
|
|
||||||
modules: {
|
|
||||||
root: root_store,
|
|
||||||
transactions: {
|
|
||||||
namespaced: true,
|
|
||||||
modules: {
|
|
||||||
create: transactions_create,
|
|
||||||
edit: transactions_edit
|
|
||||||
}
|
|
||||||
},
|
|
||||||
accounts: {
|
|
||||||
namespaced: true,
|
|
||||||
modules: {
|
|
||||||
index: accounts_index
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dashboard: {
|
|
||||||
namespaced: true,
|
|
||||||
modules: {
|
|
||||||
index: dashboard_index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
strict: debug,
|
|
||||||
plugins: debug ? [createLogger()] : [],
|
|
||||||
state: {
|
|
||||||
currencyPreference: {},
|
|
||||||
locale: 'en-US',
|
|
||||||
listPageSize: 50
|
|
||||||
},
|
|
||||||
mutations: {
|
|
||||||
setCurrencyPreference(state, payload) {
|
|
||||||
state.currencyPreference = payload.payload;
|
|
||||||
},
|
|
||||||
initialiseStore(state) {
|
|
||||||
// console.log('Now in initialiseStore()')
|
|
||||||
// if locale in local storage:
|
|
||||||
if (localStorage.locale) {
|
|
||||||
state.locale = localStorage.locale;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set locale from HTML:
|
|
||||||
let localeToken = document.head.querySelector('meta[name="locale"]');
|
|
||||||
if (localeToken) {
|
|
||||||
state.locale = localeToken.content;
|
|
||||||
localStorage.locale = localeToken.content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getters: {
|
|
||||||
currencyCode: state => {
|
|
||||||
return state.currencyPreference.code;
|
|
||||||
},
|
|
||||||
currencyPreference: state => {
|
|
||||||
return state.currencyPreference;
|
|
||||||
},
|
|
||||||
currencyId: state => {
|
|
||||||
return state.currencyPreference.id;
|
|
||||||
},
|
|
||||||
locale: state => {
|
|
||||||
return state.locale;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
updateCurrencyPreference(context) {
|
|
||||||
// console.log('Now in updateCurrencyPreference');
|
|
||||||
if (localStorage.currencyPreference) {
|
|
||||||
context.commit('setCurrencyPreference', {payload: JSON.parse(localStorage.currencyPreference)});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
axios.get('./api/v1/currencies/default')
|
|
||||||
.then(response => {
|
|
||||||
let currencyResponse = {
|
|
||||||
id: parseInt(response.data.data.id),
|
|
||||||
name: response.data.data.attributes.name,
|
|
||||||
symbol: response.data.data.attributes.symbol,
|
|
||||||
code: response.data.data.attributes.code,
|
|
||||||
decimal_places: parseInt(response.data.data.attributes.decimal_places),
|
|
||||||
};
|
|
||||||
localStorage.currencyPreference = JSON.stringify(currencyResponse);
|
|
||||||
//console.log('getCurrencyPreference from server')
|
|
||||||
//console.log(JSON.stringify(currencyResponse));
|
|
||||||
context.commit('setCurrencyPreference', {payload: currencyResponse});
|
|
||||||
}).catch(err => {
|
|
||||||
// console.log('Got error response.');
|
|
||||||
console.error(err);
|
|
||||||
context.commit('setCurrencyPreference', {
|
|
||||||
payload: {
|
|
||||||
id: 1,
|
|
||||||
name: 'Euro',
|
|
||||||
symbol: '€',
|
|
||||||
code: 'EUR',
|
|
||||||
decimal_places: 2
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* index.js
|
|
||||||
* Copyright (c) 2021 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// initial state
|
|
||||||
const state = () => (
|
|
||||||
{
|
|
||||||
orderMode: false,
|
|
||||||
activeFilter: 1
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
// getters
|
|
||||||
const getters = {
|
|
||||||
orderMode: state => {
|
|
||||||
return state.orderMode;
|
|
||||||
},
|
|
||||||
activeFilter: state => {
|
|
||||||
return state.activeFilter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
const actions = {}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
const mutations = {
|
|
||||||
setOrderMode(state, payload) {
|
|
||||||
state.orderMode = payload;
|
|
||||||
},
|
|
||||||
setActiveFilter(state, payload) {
|
|
||||||
state.activeFilter = payload;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
getters,
|
|
||||||
actions,
|
|
||||||
mutations
|
|
||||||
}
|
|
||||||
@@ -1,222 +0,0 @@
|
|||||||
/*
|
|
||||||
* index.js
|
|
||||||
* Copyright (c) 2020 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// initial state
|
|
||||||
import startOfDay from "date-fns/startOfDay";
|
|
||||||
import endOfDay from 'date-fns/endOfDay'
|
|
||||||
import startOfWeek from 'date-fns/startOfWeek'
|
|
||||||
import endOfWeek from 'date-fns/endOfWeek'
|
|
||||||
import startOfQuarter from 'date-fns/startOfQuarter';
|
|
||||||
import endOfQuarter from 'date-fns/endOfQuarter';
|
|
||||||
import endOfMonth from "date-fns/endOfMonth";
|
|
||||||
import startOfMonth from 'date-fns/startOfMonth';
|
|
||||||
|
|
||||||
const state = () => (
|
|
||||||
{
|
|
||||||
viewRange: 'default',
|
|
||||||
start: null,
|
|
||||||
end: null,
|
|
||||||
defaultStart: null,
|
|
||||||
defaultEnd: null,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
// getters
|
|
||||||
const getters = {
|
|
||||||
start: state => {
|
|
||||||
return state.start;
|
|
||||||
},
|
|
||||||
end: state => {
|
|
||||||
return state.end;
|
|
||||||
},
|
|
||||||
defaultStart: state => {
|
|
||||||
return state.defaultStart;
|
|
||||||
},
|
|
||||||
defaultEnd: state => {
|
|
||||||
return state.defaultEnd;
|
|
||||||
},
|
|
||||||
viewRange: state => {
|
|
||||||
return state.viewRange;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
const actions = {
|
|
||||||
initialiseStore(context) {
|
|
||||||
// console.log('initialiseStore for dashboard.');
|
|
||||||
|
|
||||||
// restore from local storage:
|
|
||||||
context.dispatch('restoreViewRange');
|
|
||||||
|
|
||||||
axios.get('./api/v1/preferences/viewRange')
|
|
||||||
.then(response => {
|
|
||||||
let viewRange = response.data.data.attributes.data;
|
|
||||||
let oldViewRange = context.getters.viewRange;
|
|
||||||
context.commit('setViewRange', viewRange);
|
|
||||||
if (viewRange !== oldViewRange) {
|
|
||||||
// console.log('View range changed from "' + oldViewRange + '" to "' + viewRange + '"');
|
|
||||||
context.dispatch('setDatesFromViewRange');
|
|
||||||
}
|
|
||||||
if (viewRange === oldViewRange) {
|
|
||||||
// console.log('Restore view range dates');
|
|
||||||
context.dispatch('restoreViewRangeDates');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
).catch(() => {
|
|
||||||
context.commit('setViewRange', '1M');
|
|
||||||
context.dispatch('setDatesFromViewRange');
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
restoreViewRangeDates: function (context) {
|
|
||||||
// check local storage first?
|
|
||||||
if (localStorage.viewRangeStart) {
|
|
||||||
// console.log('view range start set from local storage.');
|
|
||||||
context.commit('setStart', new Date(localStorage.viewRangeStart));
|
|
||||||
}
|
|
||||||
if (localStorage.viewRangeEnd) {
|
|
||||||
// console.log('view range end set from local storage.');
|
|
||||||
context.commit('setEnd', new Date(localStorage.viewRangeEnd));
|
|
||||||
}
|
|
||||||
// also set default:
|
|
||||||
if (localStorage.viewRangeDefaultStart) {
|
|
||||||
// console.log('view range default start set from local storage.');
|
|
||||||
// console.log(localStorage.viewRangeDefaultStart);
|
|
||||||
context.commit('setDefaultStart', new Date(localStorage.viewRangeDefaultStart));
|
|
||||||
}
|
|
||||||
if (localStorage.viewRangeDefaultEnd) {
|
|
||||||
// console.log('view range default end set from local storage.');
|
|
||||||
// console.log(localStorage.viewRangeDefaultEnd);
|
|
||||||
context.commit('setDefaultEnd', new Date(localStorage.viewRangeDefaultEnd));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
restoreViewRange: function (context) {
|
|
||||||
// console.log('restoreViewRange');
|
|
||||||
let viewRange = localStorage.getItem('viewRange');
|
|
||||||
if (null !== viewRange) {
|
|
||||||
// console.log('restored restoreViewRange ' + viewRange );
|
|
||||||
context.commit('setViewRange', viewRange);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setDatesFromViewRange(context) {
|
|
||||||
let start;
|
|
||||||
let end;
|
|
||||||
let viewRange = context.getters.viewRange;
|
|
||||||
let today = new Date;
|
|
||||||
// console.log('Will recreate view range on ' + viewRange);
|
|
||||||
switch (viewRange) {
|
|
||||||
case '1D':
|
|
||||||
// today:
|
|
||||||
start = startOfDay(today);
|
|
||||||
end = endOfDay(today);
|
|
||||||
break;
|
|
||||||
case '1W':
|
|
||||||
// this week:
|
|
||||||
start = startOfDay(startOfWeek(today, {weekStartsOn: 1}));
|
|
||||||
end = endOfDay(endOfWeek(today, {weekStartsOn: 1}));
|
|
||||||
break;
|
|
||||||
case '1M':
|
|
||||||
// this month:
|
|
||||||
start = startOfDay(startOfMonth(today));
|
|
||||||
end = endOfDay(endOfMonth(today));
|
|
||||||
break;
|
|
||||||
case '3M':
|
|
||||||
// this quarter
|
|
||||||
start = startOfDay(startOfQuarter(today));
|
|
||||||
end = endOfDay(endOfQuarter(today));
|
|
||||||
break;
|
|
||||||
case '6M':
|
|
||||||
// this half-year
|
|
||||||
if (today.getMonth() <= 5) {
|
|
||||||
start = new Date(today);
|
|
||||||
start.setMonth(0);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
end = new Date(today);
|
|
||||||
end.setMonth(5);
|
|
||||||
end.setDate(30);
|
|
||||||
end = endOfDay(start);
|
|
||||||
}
|
|
||||||
if (today.getMonth() > 5) {
|
|
||||||
start = new Date(today);
|
|
||||||
start.setMonth(6);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
end = new Date(today);
|
|
||||||
end.setMonth(11);
|
|
||||||
end.setDate(31);
|
|
||||||
end = endOfDay(start);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '1Y':
|
|
||||||
// this year
|
|
||||||
start = new Date(today);
|
|
||||||
start.setMonth(0);
|
|
||||||
start.setDate(1);
|
|
||||||
start = startOfDay(start);
|
|
||||||
|
|
||||||
end = new Date(today);
|
|
||||||
end.setMonth(11);
|
|
||||||
end.setDate(31);
|
|
||||||
end = endOfDay(end);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// console.log('Range is ' + viewRange);
|
|
||||||
// console.log('Start is ' + start);
|
|
||||||
// console.log('End is ' + end);
|
|
||||||
context.commit('setStart', start);
|
|
||||||
context.commit('setEnd', end);
|
|
||||||
context.commit('setDefaultStart', start);
|
|
||||||
context.commit('setDefaultEnd', end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
const mutations = {
|
|
||||||
setStart(state, value) {
|
|
||||||
state.start = value;
|
|
||||||
window.localStorage.setItem('viewRangeStart', value);
|
|
||||||
},
|
|
||||||
setEnd(state, value) {
|
|
||||||
state.end = value;
|
|
||||||
window.localStorage.setItem('viewRangeEnd', value);
|
|
||||||
},
|
|
||||||
setDefaultStart(state, value) {
|
|
||||||
state.defaultStart = value;
|
|
||||||
window.localStorage.setItem('viewRangeDefaultStart', value);
|
|
||||||
},
|
|
||||||
setDefaultEnd(state, value) {
|
|
||||||
state.defaultEnd = value;
|
|
||||||
window.localStorage.setItem('viewRangeDefaultEnd', value);
|
|
||||||
},
|
|
||||||
setViewRange(state, range) {
|
|
||||||
state.viewRange = range;
|
|
||||||
window.localStorage.setItem('viewRange', range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
getters,
|
|
||||||
actions,
|
|
||||||
mutations
|
|
||||||
}
|
|
||||||
138
frontend/src/components/store/modules/root.js
vendored
138
frontend/src/components/store/modules/root.js
vendored
@@ -1,138 +0,0 @@
|
|||||||
/*
|
|
||||||
* root.js
|
|
||||||
* Copyright (c) 2021 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// initial state
|
|
||||||
const state = () => (
|
|
||||||
{
|
|
||||||
listPageSize: 33,
|
|
||||||
timezone: '',
|
|
||||||
cacheKey: {
|
|
||||||
age: 0,
|
|
||||||
value: 'empty',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
// getters
|
|
||||||
const getters = {
|
|
||||||
listPageSize: state => {
|
|
||||||
return state.listPageSize;
|
|
||||||
},
|
|
||||||
timezone: state => {
|
|
||||||
// console.log('Wil return ' + state.listPageSize);
|
|
||||||
return state.timezone;
|
|
||||||
},
|
|
||||||
cacheKey: state => {
|
|
||||||
return state.cacheKey.value;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
const actions = {
|
|
||||||
initialiseStore(context) {
|
|
||||||
// cache key auto refreshes every day
|
|
||||||
// console.log('Now in initialize store.')
|
|
||||||
if (localStorage.cacheKey) {
|
|
||||||
// console.log('Storage has cache key: ');
|
|
||||||
// console.log(localStorage.cacheKey);
|
|
||||||
let object = JSON.parse(localStorage.cacheKey);
|
|
||||||
if (Date.now() - object.age > 86400000) {
|
|
||||||
// console.log('Key is here but is old.');
|
|
||||||
context.commit('refreshCacheKey');
|
|
||||||
} else {
|
|
||||||
// console.log('Cache key from local storage: ' + object.value);
|
|
||||||
context.commit('setCacheKey', object);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// console.log('No key need new one.');
|
|
||||||
context.commit('refreshCacheKey');
|
|
||||||
}
|
|
||||||
if (localStorage.listPageSize) {
|
|
||||||
state.listPageSize = localStorage.listPageSize;
|
|
||||||
context.commit('setListPageSize', {length: localStorage.listPageSize});
|
|
||||||
}
|
|
||||||
if (!localStorage.listPageSize) {
|
|
||||||
axios.get('./api/v1/preferences/listPageSize')
|
|
||||||
.then(response => {
|
|
||||||
// console.log('from API: listPageSize is ' + parseInt(response.data.data.attributes.data));
|
|
||||||
context.commit('setListPageSize', {length: parseInt(response.data.data.attributes.data)});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (localStorage.timezone) {
|
|
||||||
state.timezone = localStorage.timezone;
|
|
||||||
context.commit('setTimezone', {timezone: localStorage.timezone});
|
|
||||||
}
|
|
||||||
if (!localStorage.timezone) {
|
|
||||||
axios.get('./api/v1/configuration/app.timezone')
|
|
||||||
.then(response => {
|
|
||||||
context.commit('setTimezone', {timezone: response.data.data.value});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
const mutations = {
|
|
||||||
refreshCacheKey(state) {
|
|
||||||
let age = Date.now();
|
|
||||||
let N = 8;
|
|
||||||
let cacheKey = Array(N+1).join((Math.random().toString(36)+'00000000000000000').slice(2, 18)).slice(0, N);
|
|
||||||
let object = {age: age, value: cacheKey};
|
|
||||||
// console.log('Store new key in string JSON');
|
|
||||||
// console.log(JSON.stringify(object));
|
|
||||||
localStorage.cacheKey = JSON.stringify(object);
|
|
||||||
state.cacheKey = {age: age, value: cacheKey};
|
|
||||||
// console.log('Refresh: cachekey is now ' + cacheKey);
|
|
||||||
},
|
|
||||||
setCacheKey(state, payload) {
|
|
||||||
// console.log('Stored cache key in localstorage.');
|
|
||||||
// console.log(payload);
|
|
||||||
// console.log(JSON.stringify(payload));
|
|
||||||
localStorage.cacheKey = JSON.stringify(payload);
|
|
||||||
state.cacheKey = payload;
|
|
||||||
},
|
|
||||||
setListPageSize(state, payload) {
|
|
||||||
// console.log('Got a payload in setListPageSize');
|
|
||||||
// console.log(payload);
|
|
||||||
let number = parseInt(payload.length);
|
|
||||||
if (0 !== number) {
|
|
||||||
state.listPageSize = number;
|
|
||||||
localStorage.listPageSize = number;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setTimezone(state, payload) {
|
|
||||||
|
|
||||||
if ('' !== payload.timezone) {
|
|
||||||
state.timezone = payload.timezone;
|
|
||||||
localStorage.timezone = payload.timezone;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
getters,
|
|
||||||
actions,
|
|
||||||
mutations
|
|
||||||
}
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
/*
|
|
||||||
* create.js
|
|
||||||
* Copyright (c) 2020 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const lodashClonedeep = require('lodash.clonedeep');
|
|
||||||
|
|
||||||
import {getDefaultErrors, getDefaultTransaction} from '../../../../shared/transactions';
|
|
||||||
|
|
||||||
// initial state
|
|
||||||
const state = () => ({
|
|
||||||
transactionType: 'any',
|
|
||||||
groupTitle: '',
|
|
||||||
transactions: [],
|
|
||||||
customDateFields: {
|
|
||||||
interest_date: false,
|
|
||||||
book_date: false,
|
|
||||||
process_date: false,
|
|
||||||
due_date: false,
|
|
||||||
payment_date: false,
|
|
||||||
invoice_date: false,
|
|
||||||
},
|
|
||||||
defaultTransaction: getDefaultTransaction(),
|
|
||||||
defaultErrors: getDefaultErrors()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
// getters
|
|
||||||
const getters = {
|
|
||||||
transactions: state => {
|
|
||||||
return state.transactions;
|
|
||||||
},
|
|
||||||
defaultErrors: state => {
|
|
||||||
return state.defaultErrors;
|
|
||||||
},
|
|
||||||
groupTitle: state => {
|
|
||||||
return state.groupTitle;
|
|
||||||
},
|
|
||||||
transactionType: state => {
|
|
||||||
return state.transactionType;
|
|
||||||
},
|
|
||||||
accountToTransaction: state => {
|
|
||||||
// See reference nr. 1
|
|
||||||
// possible API point!!
|
|
||||||
return state.accountToTransaction;
|
|
||||||
},
|
|
||||||
defaultTransaction: state => {
|
|
||||||
return state.defaultTransaction;
|
|
||||||
},
|
|
||||||
sourceAllowedTypes: state => {
|
|
||||||
return state.sourceAllowedTypes;
|
|
||||||
},
|
|
||||||
destinationAllowedTypes: state => {
|
|
||||||
return state.destinationAllowedTypes;
|
|
||||||
},
|
|
||||||
allowedOpposingTypes: state => {
|
|
||||||
return state.allowedOpposingTypes;
|
|
||||||
},
|
|
||||||
customDateFields: state => {
|
|
||||||
return state.customDateFields;
|
|
||||||
}
|
|
||||||
// // `getters` is localized to this module's getters
|
|
||||||
// // you can use rootGetters via 4th argument of getters
|
|
||||||
// someGetter (state, getters, rootState, rootGetters) {
|
|
||||||
// getters.someOtherGetter // -> 'foo/someOtherGetter'
|
|
||||||
// rootGetters.someOtherGetter // -> 'someOtherGetter'
|
|
||||||
// rootGetters['bar/someOtherGetter'] // -> 'bar/someOtherGetter'
|
|
||||||
// },
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
const actions = {}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
const mutations = {
|
|
||||||
addTransaction(state) {
|
|
||||||
let newTransaction = lodashClonedeep(state.defaultTransaction);
|
|
||||||
newTransaction.errors = lodashClonedeep(state.defaultErrors);
|
|
||||||
state.transactions.push(newTransaction);
|
|
||||||
},
|
|
||||||
resetErrors(state, payload) {
|
|
||||||
//console.log('resetErrors for index ' + payload.index);
|
|
||||||
state.transactions[payload.index].errors = lodashClonedeep(state.defaultErrors);
|
|
||||||
},
|
|
||||||
resetTransactions(state) {
|
|
||||||
// console.log('Store: Record call to resetTransactions :(');
|
|
||||||
state.transactions = [];
|
|
||||||
},
|
|
||||||
setGroupTitle(state, payload) {
|
|
||||||
state.groupTitle = payload.groupTitle;
|
|
||||||
},
|
|
||||||
setCustomDateFields(state, payload) {
|
|
||||||
state.customDateFields = payload;
|
|
||||||
},
|
|
||||||
deleteTransaction(state, payload) {
|
|
||||||
// console.log('Record call to deleteTransaction!');
|
|
||||||
state.transactions.splice(payload.index, 1);
|
|
||||||
// console.log('Deleted transaction ' + payload.index);
|
|
||||||
// console.log(state.transactions);
|
|
||||||
// if (0 === state.transactions.length) {
|
|
||||||
// console.log('array is empty!');
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
setTransactionType(state, transactionType) {
|
|
||||||
state.transactionType = transactionType;
|
|
||||||
},
|
|
||||||
setAllowedOpposingTypes(state, allowedOpposingTypes) {
|
|
||||||
state.allowedOpposingTypes = allowedOpposingTypes;
|
|
||||||
},
|
|
||||||
setAccountToTransaction(state, payload) {
|
|
||||||
state.accountToTransaction = payload;
|
|
||||||
},
|
|
||||||
updateField(state, payload) {
|
|
||||||
state.transactions[payload.index][payload.field] = payload.value;
|
|
||||||
},
|
|
||||||
setTransactionError(state, payload) {
|
|
||||||
//console.log('Will set transactions[' + payload.index + '][errors][' + payload.field + '] to ');
|
|
||||||
//console.log(payload.errors);
|
|
||||||
state.transactions[payload.index].errors[payload.field] = payload.errors;
|
|
||||||
},
|
|
||||||
setDestinationAllowedTypes(state, payload) {
|
|
||||||
// console.log('Destination allowed types was changed!');
|
|
||||||
state.destinationAllowedTypes = payload;
|
|
||||||
},
|
|
||||||
setSourceAllowedTypes(state, payload) {
|
|
||||||
state.sourceAllowedTypes = payload;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
getters,
|
|
||||||
actions,
|
|
||||||
mutations
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* edit.js
|
|
||||||
* Copyright (c) 2021 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// initial state
|
|
||||||
const state = () => ({});
|
|
||||||
|
|
||||||
|
|
||||||
// getters
|
|
||||||
const getters = {};
|
|
||||||
|
|
||||||
// actions
|
|
||||||
const actions = {};
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
const mutations = {};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
getters,
|
|
||||||
actions,
|
|
||||||
mutations
|
|
||||||
}
|
|
||||||
@@ -1,905 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Create.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<alert :message="errorMessage" type="danger"/>
|
|
||||||
<alert :message="successMessage" type="success"/>
|
|
||||||
<form @submit="submitTransaction" autocomplete="off">
|
|
||||||
<SplitPills ref="pills" :transactions="transactions" :count="transactions.length"/>
|
|
||||||
<div class="tab-content">
|
|
||||||
<SplitForm
|
|
||||||
v-for="(transaction, index) in this.transactions"
|
|
||||||
v-bind:key="index"
|
|
||||||
:count="transactions.length"
|
|
||||||
:custom-fields="customFields"
|
|
||||||
:date="date"
|
|
||||||
ref="splitForms"
|
|
||||||
:destination-allowed-types="destinationAllowedTypes"
|
|
||||||
:index="index"
|
|
||||||
:source-allowed-types="sourceAllowedTypes"
|
|
||||||
:submitted-transaction="submittedTransaction"
|
|
||||||
:transaction="transaction"
|
|
||||||
:transaction-type="transactionType"
|
|
||||||
v-on:uploaded-attachments="uploadedAttachment($event)"
|
|
||||||
v-on:selected-attachments="selectedAttachment($event)"
|
|
||||||
v-on:set-marker-location="storeLocation($event)"
|
|
||||||
v-on:set-account="storeAccountValue($event)"
|
|
||||||
v-on:set-date="storeDate($event)"
|
|
||||||
v-on:set-field="storeField($event)"
|
|
||||||
v-on:remove-transaction="removeTransaction($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<!-- group title -->
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div v-if="transactions.length > 1" class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<TransactionGroupTitle v-model="this.groupTitle" :errors="this.groupTitleErrors" v-on:set-group-title="storeGroupTitle($event)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<!-- buttons -->
|
|
||||||
<div class="card card-primary">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<button type="button" class="btn btn-outline-primary btn-block" @click="addTransactionArray"><span class="far fa-clone"></span> {{
|
|
||||||
$t('firefly.add_another_split')
|
|
||||||
}}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<button :disabled="!enableSubmit" class="btn btn-success btn-block" @click="submitTransaction">
|
|
||||||
<span v-if="enableSubmit"><span class="far fa-save"></span> {{ $t('firefly.store_transaction') }}</span>
|
|
||||||
<span v-if="!enableSubmit"><span class="fas fa-spinner fa-spin"></span></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="form-check">
|
|
||||||
<input id="createAnother" v-model="createAnother" class="form-check-input" type="checkbox">
|
|
||||||
<label class="form-check-label" for="createAnother">
|
|
||||||
<span class="small">{{ $t('firefly.create_another') }}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check">
|
|
||||||
<input id="resetFormAfter" v-model="resetFormAfter" :disabled="!createAnother" class="form-check-input" type="checkbox">
|
|
||||||
<label class="form-check-label" for="resetFormAfter">
|
|
||||||
<span class="small">{{ $t('firefly.reset_after') }}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Alert from '../partials/Alert';
|
|
||||||
import SplitPills from "./SplitPills";
|
|
||||||
import TransactionGroupTitle from "./TransactionGroupTitle";
|
|
||||||
import SplitForm from "./SplitForm";
|
|
||||||
import {mapGetters, mapMutations} from "vuex";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Create",
|
|
||||||
components: {
|
|
||||||
SplitForm,
|
|
||||||
Alert,
|
|
||||||
SplitPills,
|
|
||||||
TransactionGroupTitle,
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Grab some stuff from the API, add the first transaction.
|
|
||||||
*/
|
|
||||||
created() {
|
|
||||||
// set transaction type:
|
|
||||||
let pathName = window.location.pathname;
|
|
||||||
let parts = pathName.split('/');
|
|
||||||
let type = parts[parts.length - 1];
|
|
||||||
|
|
||||||
// set a basic date-time string:
|
|
||||||
let date = new Date;
|
|
||||||
this.date = [date.getFullYear(), ('0' + (date.getMonth() + 1)).slice(-2), ('0' + date.getDate()).slice(-2)].join('-') + 'T00:00';
|
|
||||||
|
|
||||||
//console.log('Date is set to "' + this.date + '"');
|
|
||||||
|
|
||||||
this.setTransactionType(type[0].toUpperCase() + type.substring(1));
|
|
||||||
this.getExpectedSourceTypes();
|
|
||||||
this.getAccountToTransaction();
|
|
||||||
this.getCustomFields();
|
|
||||||
this.addTransaction();
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// error or success message
|
|
||||||
errorMessage: '',
|
|
||||||
successMessage: '',
|
|
||||||
|
|
||||||
// custom fields to show, useful for components:
|
|
||||||
customFields: {},
|
|
||||||
|
|
||||||
// states for the form (makes sense right)
|
|
||||||
enableSubmit: true,
|
|
||||||
createAnother: false,
|
|
||||||
resetFormAfter: false,
|
|
||||||
|
|
||||||
// things the process is done working on (3 phases):
|
|
||||||
submittedTransaction: false,
|
|
||||||
submittedLinks: false,
|
|
||||||
submittedAttachments: -1, // -1 (no attachments), 0 = uploading, 1 = uploaded
|
|
||||||
|
|
||||||
// transaction was actually submitted?
|
|
||||||
inError: false,
|
|
||||||
|
|
||||||
// number of uploaded attachments
|
|
||||||
// its an object because we count per transaction journal (which can have multiple attachments)
|
|
||||||
// and array doesn't work right.
|
|
||||||
submittedAttCount: {},
|
|
||||||
|
|
||||||
// errors in the group title:
|
|
||||||
groupTitleErrors: [],
|
|
||||||
|
|
||||||
// group ID + title once submitted:
|
|
||||||
returnedGroupId: 0,
|
|
||||||
returnedGroupTitle: '',
|
|
||||||
|
|
||||||
// meta data for accounts
|
|
||||||
accountToTransaction: {},
|
|
||||||
allowedOpposingTypes: {},
|
|
||||||
sourceAllowedTypes: ['Asset account', 'Loan', 'Debt', 'Mortgage', 'Revenue account'],
|
|
||||||
destinationAllowedTypes: ['Asset account', 'Loan', 'Debt', 'Mortgage', 'Expense account'],
|
|
||||||
|
|
||||||
// date not in the store because it was buggy
|
|
||||||
date: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
/**
|
|
||||||
* Grabbed from the store.
|
|
||||||
*/
|
|
||||||
...mapGetters('transactions/create', ['transactionType', 'transactions', 'groupTitle', 'defaultErrors']),
|
|
||||||
...mapGetters('root', ['listPageSize'])
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
submittedAttachments: function () {
|
|
||||||
this.finaliseSubmission();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/**
|
|
||||||
* Store related mutators used by this component.
|
|
||||||
*/
|
|
||||||
...mapMutations('transactions/create',
|
|
||||||
[
|
|
||||||
'setGroupTitle',
|
|
||||||
'addTransaction',
|
|
||||||
'deleteTransaction',
|
|
||||||
'setTransactionError',
|
|
||||||
'setTransactionType',
|
|
||||||
'resetErrors',
|
|
||||||
'updateField',
|
|
||||||
'resetTransactions',
|
|
||||||
]
|
|
||||||
),
|
|
||||||
addTransactionArray: function (event) {
|
|
||||||
// console.log('Record call to addTransactionArray');
|
|
||||||
event.preventDefault();
|
|
||||||
this.addTransaction();
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Removes a split from the array.
|
|
||||||
*/
|
|
||||||
removeTransaction: function (payload) {
|
|
||||||
// console.log('Record call to removeTransaction');
|
|
||||||
// console.log('Triggered to remove transaction ' + payload.index);
|
|
||||||
window.$('#tab_split_' + (payload.index - 1)).click();
|
|
||||||
this.$store.commit('transactions/create/deleteTransaction', payload);
|
|
||||||
},
|
|
||||||
submitData: function (url, data) {
|
|
||||||
return axios.post(url, data);
|
|
||||||
},
|
|
||||||
handleSubmissionResponse: function (response) {
|
|
||||||
// console.log('In handleSubmissionResponse()');
|
|
||||||
// save some meta data:
|
|
||||||
this.returnedGroupId = parseInt(response.data.data.id);
|
|
||||||
this.returnedGroupTitle = null === response.data.data.attributes.group_title ? response.data.data.attributes.transactions[0].description : response.data.data.attributes.group_title;
|
|
||||||
let journals = [];
|
|
||||||
|
|
||||||
// save separate journal ID's (useful ahead in the process):
|
|
||||||
let result = response.data.data.attributes.transactions
|
|
||||||
for (let i in result) {
|
|
||||||
if (result.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
journals.push(parseInt(result[i].transaction_journal_id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.resolve({journals: journals});
|
|
||||||
},
|
|
||||||
submitLinks: function (response, submission) {
|
|
||||||
let promises = [];
|
|
||||||
// for
|
|
||||||
for (let i in response.journals) {
|
|
||||||
if (response.journals.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let journalId = response.journals[i];
|
|
||||||
let links = submission.transactions[i].links;
|
|
||||||
for (let ii in links) {
|
|
||||||
if (links.hasOwnProperty(ii) && /^0$|^[1-9]\d*$/.test(ii) && ii <= 4294967294) {
|
|
||||||
let currentLink = links[ii];
|
|
||||||
if (0 === currentLink.outward_id) {
|
|
||||||
currentLink.outward_id = journalId;
|
|
||||||
}
|
|
||||||
if (0 === currentLink.inward_id) {
|
|
||||||
currentLink.inward_id = journalId;
|
|
||||||
}
|
|
||||||
promises.push(axios.post('./api/v1/transaction_links', currentLink));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (0 === promises.length) {
|
|
||||||
return Promise.resolve({response: 'from submitLinks'});
|
|
||||||
}
|
|
||||||
return Promise.all(promises);
|
|
||||||
},
|
|
||||||
submitAttachments: function (response, submission) {
|
|
||||||
let anyAttachments = false;
|
|
||||||
for (let i in response.journals) {
|
|
||||||
if (response.journals.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let journalId = response.journals[i];
|
|
||||||
let hasAttachments = submission.transactions[i].attachments;
|
|
||||||
// console.log('Decided that ' + journalId);
|
|
||||||
// console.log(hasAttachments);
|
|
||||||
if (hasAttachments) {
|
|
||||||
// console.log('upload!');
|
|
||||||
this.updateField({index: i, field: 'transaction_journal_id', value: journalId});
|
|
||||||
// set upload trigger?
|
|
||||||
this.updateField({index: i, field: 'uploadTrigger', value: true});
|
|
||||||
//this.transactions[i].uploadTrigger = true;
|
|
||||||
anyAttachments = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (true === anyAttachments) {
|
|
||||||
this.submittedAttachments = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.resolve({response: 'from submitAttachments'});
|
|
||||||
},
|
|
||||||
selectedAttachment: function (payload) {
|
|
||||||
this.updateField({index: payload.index, field: 'attachments', value: true});
|
|
||||||
},
|
|
||||||
finaliseSubmission: function () {
|
|
||||||
// console.log('finaliseSubmission');
|
|
||||||
if (0 === this.submittedAttachments) {
|
|
||||||
// console.log('submittedAttachments = ' + this.submittedAttachments);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// console.log('In finaliseSubmission');
|
|
||||||
if (false === this.createAnother) {
|
|
||||||
window.location.href = (window.previousURL ?? '/') + '?transaction_group_id=' + this.returnedGroupId + '&message=created';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//console.log('Is in error?');
|
|
||||||
//console.log(this.inError);
|
|
||||||
if (false === this.inError) {
|
|
||||||
// show message:
|
|
||||||
this.errorMessage = '';
|
|
||||||
this.successMessage = this.$t('firefly.transaction_stored_link', {ID: this.returnedGroupId, title: this.returnedGroupTitle});
|
|
||||||
}
|
|
||||||
// console.log('here we are');
|
|
||||||
// enable flags:
|
|
||||||
this.enableSubmit = true;
|
|
||||||
this.submittedTransaction = false;
|
|
||||||
this.submittedAttachments = -1;
|
|
||||||
|
|
||||||
// reset attachments + errors
|
|
||||||
if (!this.resetFormAfter) {
|
|
||||||
for (let i in this.transactions) {
|
|
||||||
if (this.transactions.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
if (this.transactions.hasOwnProperty(i)) {
|
|
||||||
// console.log('Reset attachment #' + i);
|
|
||||||
this.updateField({index: i, field: 'transaction_journal_id', value: 0});
|
|
||||||
this.updateField({index: i, field: 'errors', value: this.defaultErrors})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// reset the form:
|
|
||||||
if (this.resetFormAfter) {
|
|
||||||
this.resetTransactions();
|
|
||||||
setTimeout(this.addTransaction, 50);
|
|
||||||
|
|
||||||
}
|
|
||||||
return Promise.resolve({response: 'from finaliseSubmission'});
|
|
||||||
},
|
|
||||||
handleSubmissionError: function (error) {
|
|
||||||
//console.log('in handleSubmissionError');
|
|
||||||
// oh noes Firefly III has something to bitch about.
|
|
||||||
this.enableSubmit = true;
|
|
||||||
|
|
||||||
// but report an error because error:
|
|
||||||
this.inError = true;
|
|
||||||
this.parseErrors(error.response.data);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Actually submit the transaction to Firefly III. This is a fairly complex beast of a thing because multiple things
|
|
||||||
* need to happen in the right order.
|
|
||||||
*/
|
|
||||||
submitTransaction: function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
// console.log('submitTransaction()');
|
|
||||||
// disable the submit button:
|
|
||||||
this.enableSubmit = false;
|
|
||||||
|
|
||||||
// assume nothing breaks
|
|
||||||
this.inError = false;
|
|
||||||
|
|
||||||
// remove old warnings etc.
|
|
||||||
this.successMessage = '';
|
|
||||||
this.errorMessage = '';
|
|
||||||
|
|
||||||
// convert the data so its ready to be submitted:
|
|
||||||
const url = './api/v1/transactions';
|
|
||||||
const data = this.convertData();
|
|
||||||
|
|
||||||
this.submitData(url, data)
|
|
||||||
.then(this.handleSubmissionResponse)
|
|
||||||
.then(response => {
|
|
||||||
return Promise.all([this.submitLinks(response, data), this.submitAttachments(response, data)]);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then(this.finaliseSubmission)
|
|
||||||
.catch(this.handleSubmissionError);
|
|
||||||
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* When a attachment component is done uploading it ends up here. We create an object where we count how many
|
|
||||||
* attachment components have reported back they're done uploading. Of course if they have nothing to upload
|
|
||||||
* they will be pretty fast in reporting they're done.
|
|
||||||
*
|
|
||||||
* Once the number of components matches the number of splits we know all attachments have been uploaded.
|
|
||||||
*/
|
|
||||||
uploadedAttachment: function (journalId) {
|
|
||||||
this.submittedAttachments = 0;
|
|
||||||
// console.log('Triggered uploadedAttachment(' + journalId + ')');
|
|
||||||
let key = 'str' + journalId;
|
|
||||||
this.submittedAttCount[key] = 1;
|
|
||||||
let count = Object.keys(this.submittedAttCount).length;
|
|
||||||
// console.log('Count is now ' + count);
|
|
||||||
// console.log('Length is ' + this.transactions.length);
|
|
||||||
if (count === this.transactions.length) {
|
|
||||||
// console.log('Got them all!');
|
|
||||||
// mark the attachments as stored:
|
|
||||||
this.submittedAttachments = 1;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Responds to changed location.
|
|
||||||
*/
|
|
||||||
storeLocation: function (payload) {
|
|
||||||
let zoomLevel = payload.hasMarker ? payload.zoomLevel : null;
|
|
||||||
let lat = payload.hasMarker ? payload.lat : null;
|
|
||||||
let lng = payload.hasMarker ? payload.lng : null;
|
|
||||||
this.updateField({index: payload.index, field: 'zoom_level', value: zoomLevel});
|
|
||||||
this.updateField({index: payload.index, field: 'latitude', value: lat});
|
|
||||||
this.updateField({index: payload.index, field: 'longitude', value: lng});
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Responds to changed account.
|
|
||||||
*/
|
|
||||||
storeAccountValue: function (payload) {
|
|
||||||
this.updateField({index: payload.index, field: payload.direction + '_account_id', value: payload.id});
|
|
||||||
this.updateField({index: payload.index, field: payload.direction + '_account_type', value: payload.type});
|
|
||||||
this.updateField({index: payload.index, field: payload.direction + '_account_name', value: payload.name});
|
|
||||||
|
|
||||||
this.updateField({index: payload.index, field: payload.direction + '_account_currency_id', value: payload.currency_id});
|
|
||||||
this.updateField({index: payload.index, field: payload.direction + '_account_currency_code', value: payload.currency_code});
|
|
||||||
this.updateField({index: payload.index, field: payload.direction + '_account_currency_symbol', value: payload.currency_symbol});
|
|
||||||
|
|
||||||
//this.calculateTransactionType(payload.index);
|
|
||||||
if ('source' === payload.direction && true === payload.user_selected) {
|
|
||||||
this.$refs.splitForms[payload.index].$refs.destinationAccount.giveFocus();
|
|
||||||
}
|
|
||||||
if ('destination' === payload.direction && true === payload.user_selected) {
|
|
||||||
this.$refs.splitForms[payload.index].$refs.amount.giveFocus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
storeField: function (payload) {
|
|
||||||
this.updateField(payload);
|
|
||||||
if('description' === payload.field) {
|
|
||||||
// jump to account
|
|
||||||
//this.$refs.splitForms[payload.index].$refs.sourceAccount.giveFocus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
storeDate: function (payload) {
|
|
||||||
this.date = payload.date;
|
|
||||||
},
|
|
||||||
storeGroupTitle: function (value) {
|
|
||||||
// console.log('set group title: ' + value);
|
|
||||||
this.setGroupTitle({groupTitle: value});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Submit transaction links.
|
|
||||||
*/
|
|
||||||
submitTransactionLinks(data, response) {
|
|
||||||
//console.log('submitTransactionLinks()');
|
|
||||||
let promises = [];
|
|
||||||
let result = response.data.data.attributes.transactions;
|
|
||||||
let total = 0;
|
|
||||||
for (let i in data.transactions) {
|
|
||||||
if (data.transactions.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let submitted = data.transactions[i];
|
|
||||||
if (result.hasOwnProperty(i)) {
|
|
||||||
// found matching created transaction.
|
|
||||||
let received = result[i];
|
|
||||||
// grab ID from received, loop "submitted" transaction links
|
|
||||||
for (let ii in submitted.links) {
|
|
||||||
if (submitted.links.hasOwnProperty(ii) && /^0$|^[1-9]\d*$/.test(ii) && ii <= 4294967294) {
|
|
||||||
let currentLink = submitted.links[ii];
|
|
||||||
total++;
|
|
||||||
if (0 === currentLink.outward_id) {
|
|
||||||
currentLink.outward_id = received.transaction_journal_id;
|
|
||||||
}
|
|
||||||
if (0 === currentLink.inward_id) {
|
|
||||||
currentLink.inward_id = received.transaction_journal_id;
|
|
||||||
}
|
|
||||||
// submit transaction link:
|
|
||||||
promises.push(axios.post('./api/v1/transaction_links', currentLink).then(response => {
|
|
||||||
// See reference nr. 4
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (0 === total) {
|
|
||||||
this.submittedLinks = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Promise.all(promises).then(function () {
|
|
||||||
this.submittedLinks = true;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
parseErrors: function (errors) {
|
|
||||||
for (let i in this.transactions) {
|
|
||||||
if (this.transactions.hasOwnProperty(i)) {
|
|
||||||
this.resetErrors({index: i});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.successMessage = '';
|
|
||||||
this.errorMessage = this.$t('firefly.errors_submission');
|
|
||||||
if (typeof errors.errors === 'undefined') {
|
|
||||||
this.successMessage = '';
|
|
||||||
this.errorMessage = errors.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
let payload;
|
|
||||||
let transactionIndex;
|
|
||||||
let fieldName;
|
|
||||||
|
|
||||||
// fairly basic way of exploding the error array.
|
|
||||||
for (const key in errors.errors) {
|
|
||||||
// console.log('Error index: "' + key + '"');
|
|
||||||
if (errors.errors.hasOwnProperty(key)) {
|
|
||||||
if (key === 'group_title') {
|
|
||||||
this.groupTitleErrors = errors.errors[key];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
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.
|
|
||||||
// console.log('The errors in key "' + key + '" are');
|
|
||||||
// console.log(errors.errors[key]);
|
|
||||||
switch (fieldName) {
|
|
||||||
case 'amount':
|
|
||||||
case 'description':
|
|
||||||
case 'date':
|
|
||||||
case 'tags':
|
|
||||||
payload = {index: transactionIndex, field: fieldName, errors: errors.errors[key]};
|
|
||||||
this.setTransactionError(payload);
|
|
||||||
break;
|
|
||||||
case 'budget_id':
|
|
||||||
payload = {index: transactionIndex, field: 'budget', errors: errors.errors[key]};
|
|
||||||
this.setTransactionError(payload);
|
|
||||||
break;
|
|
||||||
case 'bill_id':
|
|
||||||
payload = {index: transactionIndex, field: 'bill', errors: errors.errors[key]};
|
|
||||||
this.setTransactionError(payload);
|
|
||||||
break;
|
|
||||||
case 'piggy_bank_id':
|
|
||||||
payload = {index: transactionIndex, field: 'piggy_bank', errors: errors.errors[key]};
|
|
||||||
this.setTransactionError(payload);
|
|
||||||
break;
|
|
||||||
case 'category_name':
|
|
||||||
payload = {index: transactionIndex, field: 'category', errors: errors.errors[key]};
|
|
||||||
this.setTransactionError(payload);
|
|
||||||
break;
|
|
||||||
case 'source_name':
|
|
||||||
case 'source_id':
|
|
||||||
payload = {index: transactionIndex, field: 'source', errors: errors.errors[key]};
|
|
||||||
this.setTransactionError(payload);
|
|
||||||
break;
|
|
||||||
case 'destination_name':
|
|
||||||
case 'destination_id':
|
|
||||||
payload = {index: transactionIndex, field: 'destination', errors: errors.errors[key]};
|
|
||||||
this.setTransactionError(payload);
|
|
||||||
break;
|
|
||||||
case 'foreign_amount':
|
|
||||||
case 'foreign_currency':
|
|
||||||
payload = {index: transactionIndex, field: 'foreign_amount', errors: errors.errors[key]};
|
|
||||||
this.setTransactionError(payload);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// unique some things
|
|
||||||
if (typeof this.transactions[transactionIndex] !== 'undefined') {
|
|
||||||
//this.transactions[transactionIndex].errors.source = Array.from(new Set(this.transactions[transactionIndex].errors.source));
|
|
||||||
//this.transactions[transactionIndex].errors.destination = Array.from(new Set(this.transactions[transactionIndex].errors.destination));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
convertData: function () {
|
|
||||||
//console.log('now in convertData');
|
|
||||||
let data = {
|
|
||||||
'transactions': []
|
|
||||||
};
|
|
||||||
//console.log('Group title is: "' + this.groupTitle + '"');
|
|
||||||
if (this.groupTitle.length > 0) {
|
|
||||||
data.group_title = this.groupTitle;
|
|
||||||
//console.log('1) data.group_title is now "'+data.group_title+'"');
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i in this.transactions) {
|
|
||||||
if (this.transactions.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
data.transactions.push(this.convertSplit(i, this.transactions[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.transactions.length > 1 && '' !== data.transactions[0].description && (null === data.group_title || '' === data.group_title)) {
|
|
||||||
data.group_title = data.transactions[0].description;
|
|
||||||
//console.log('2) data.group_title is now "'+data.group_title+'"');
|
|
||||||
}
|
|
||||||
|
|
||||||
// depending on the transaction type for this thing, we need to
|
|
||||||
// make sure other splits match the data we submit.
|
|
||||||
if (data.transactions.length > 1) {
|
|
||||||
// console.log('This is a split!');
|
|
||||||
data = this.synchronizeAccounts(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
synchronizeAccounts: function (data) {
|
|
||||||
// console.log('synchronizeAccounts: ' + this.transactionType);
|
|
||||||
// make sure all splits have whatever is in split 0.
|
|
||||||
// since its a transfer we can drop the name and use ID's only.
|
|
||||||
for (let i in data.transactions) {
|
|
||||||
if (data.transactions.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
// console.log('now at ' + i);
|
|
||||||
|
|
||||||
// for transfers, overrule both the source and the destination:
|
|
||||||
if ('transfer' === this.transactionType.toLowerCase()) {
|
|
||||||
data.transactions[i].source_name = null;
|
|
||||||
data.transactions[i].destination_name = null;
|
|
||||||
if (i > 0) {
|
|
||||||
data.transactions[i].source_id = data.transactions[0].source_id;
|
|
||||||
data.transactions[i].destination_id = data.transactions[0].destination_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// for deposits, overrule the destination and ignore the rest.
|
|
||||||
if ('deposit' === this.transactionType.toLowerCase()) {
|
|
||||||
data.transactions[i].destination_name = null;
|
|
||||||
if (i > 0) {
|
|
||||||
data.transactions[i].destination_id = data.transactions[0].destination_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// for withdrawals, overrule the source and ignore the rest.
|
|
||||||
if ('withdrawal' === this.transactionType.toLowerCase()) {
|
|
||||||
data.transactions[i].source_name = null;
|
|
||||||
if (i > 0) {
|
|
||||||
data.transactions[i].source_id = data.transactions[0].source_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param key
|
|
||||||
* @param array
|
|
||||||
*/
|
|
||||||
convertSplit: function (key, array) {
|
|
||||||
if ('' === array.destination_account_name) {
|
|
||||||
array.destination_account_name = null;
|
|
||||||
}
|
|
||||||
if (0 === array.destination_account_id) {
|
|
||||||
array.destination_account_name = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('' === array.source_account_name) {
|
|
||||||
array.source_account_name = null;
|
|
||||||
}
|
|
||||||
if (0 === array.source_account_id) {
|
|
||||||
array.source_account_id = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let currentSplit = {
|
|
||||||
// basic
|
|
||||||
description: array.description,
|
|
||||||
date: this.date,
|
|
||||||
type: this.transactionType.toLowerCase(),
|
|
||||||
|
|
||||||
// account
|
|
||||||
source_id: array.source_account_id ?? null,
|
|
||||||
source_name: array.source_account_name ?? null,
|
|
||||||
destination_id: array.destination_account_id ?? null,
|
|
||||||
destination_name: array.destination_account_name ?? null,
|
|
||||||
|
|
||||||
// amount:
|
|
||||||
currency_id: array.currency_id,
|
|
||||||
amount: array.amount,
|
|
||||||
|
|
||||||
// meta data
|
|
||||||
budget_id: array.budget_id,
|
|
||||||
category_name: array.category,
|
|
||||||
|
|
||||||
// optional date fields (6x):
|
|
||||||
interest_date: array.interest_date,
|
|
||||||
book_date: array.book_date,
|
|
||||||
process_date: array.process_date,
|
|
||||||
due_date: array.due_date,
|
|
||||||
payment_date: array.payment_date,
|
|
||||||
invoice_date: array.invoice_date,
|
|
||||||
|
|
||||||
// other optional fields:
|
|
||||||
internal_reference: array.internal_reference,
|
|
||||||
external_url: array.external_url,
|
|
||||||
notes: array.notes,
|
|
||||||
external_id: array.external_id,
|
|
||||||
|
|
||||||
// location:
|
|
||||||
zoom_level: array.zoom_level,
|
|
||||||
longitude: array.longitude,
|
|
||||||
latitude: array.latitude,
|
|
||||||
tags: [],
|
|
||||||
|
|
||||||
// from thing:
|
|
||||||
order: 0,
|
|
||||||
reconciled: false,
|
|
||||||
attachments: array.attachments,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (0 !== array.tags.length) {
|
|
||||||
for (let i in array.tags) {
|
|
||||||
if (array.tags.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
// array.tags
|
|
||||||
let current = array.tags[i];
|
|
||||||
if (typeof current === 'object' && null !== current) {
|
|
||||||
currentSplit.tags.push(current.text);
|
|
||||||
// console.log('Add tag "' + current.text + '" from object.');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (typeof current === 'string') {
|
|
||||||
currentSplit.tags.push(current);
|
|
||||||
// console.log('Add tag "' + current + '" from string.');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// console.log('Is neither.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// console.log('Current split tags is now: ');
|
|
||||||
// console.log(currentSplit.tags);
|
|
||||||
|
|
||||||
// bills and piggy banks
|
|
||||||
if (0 !== array.piggy_bank_id) {
|
|
||||||
currentSplit.piggy_bank_id = array.piggy_bank_id;
|
|
||||||
}
|
|
||||||
if (0 !== array.bill_id) {
|
|
||||||
currentSplit.bill_id = array.bill_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// foreign amount:
|
|
||||||
if (0 !== array.foreign_currency_id && '' !== array.foreign_amount) {
|
|
||||||
currentSplit.foreign_currency_id = array.foreign_currency_id;
|
|
||||||
}
|
|
||||||
if ('' !== array.foreign_amount) {
|
|
||||||
currentSplit.foreign_amount = array.foreign_amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do transaction type
|
|
||||||
// let transactionType;
|
|
||||||
// let firstSource;
|
|
||||||
// let firstDestination;
|
|
||||||
|
|
||||||
// get transaction type from first transaction
|
|
||||||
//transactionType = this.transactionType ? this.transactionType.toLowerCase() : 'any';
|
|
||||||
//console.log('Transaction type is now ' + transactionType);
|
|
||||||
// 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(this.transactions[0].source_account);
|
|
||||||
//console.log(this.transactions[0].destination_account);
|
|
||||||
//console.log('Type of first source is ' + firstSource);
|
|
||||||
//console.log('Type of first destination is ' + firstDestination);
|
|
||||||
|
|
||||||
// default to source:
|
|
||||||
currentSplit.currency_id = array.source_account_currency_id;
|
|
||||||
// if ('any' === transactionType && ['asset', 'Asset account', 'Loan', 'Debt', 'Mortgage'].includes(firstSource)) {
|
|
||||||
// transactionType = 'withdrawal';
|
|
||||||
// }
|
|
||||||
|
|
||||||
if ('Deposit' === this.transactionType) {
|
|
||||||
// transactionType = 'deposit';
|
|
||||||
currentSplit.currency_id = array.destination_account_currency_id;
|
|
||||||
}
|
|
||||||
//currentSplit.type = transactionType;
|
|
||||||
//console.log('Final type is ' + transactionType);
|
|
||||||
|
|
||||||
let links = [];
|
|
||||||
for (let i in array.links) {
|
|
||||||
if (array.links.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = array.links[i];
|
|
||||||
let linkTypeParts = current.link_type_id.split('-');
|
|
||||||
let inwardId = 'outward' === linkTypeParts[1] ? 0 : parseInt(current.transaction_journal_id);
|
|
||||||
let outwardId = 'inward' === linkTypeParts[1] ? 0 : parseInt(current.transaction_journal_id);
|
|
||||||
let newLink = {
|
|
||||||
link_type_id: parseInt(linkTypeParts[0]),
|
|
||||||
inward_id: inwardId,
|
|
||||||
outward_id: outwardId,
|
|
||||||
};
|
|
||||||
links.push(newLink);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentSplit.links = links;
|
|
||||||
if (null === currentSplit.source_id) {
|
|
||||||
delete currentSplit.source_id;
|
|
||||||
}
|
|
||||||
if (null === currentSplit.source_name) {
|
|
||||||
delete currentSplit.source_name;
|
|
||||||
}
|
|
||||||
if (null === currentSplit.destination_id) {
|
|
||||||
delete currentSplit.destination_id;
|
|
||||||
}
|
|
||||||
if (null === currentSplit.destination_name) {
|
|
||||||
delete currentSplit.destination_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log('Current split is: ');
|
|
||||||
// console.log(currentSplit);
|
|
||||||
|
|
||||||
// return it.
|
|
||||||
return currentSplit;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Get API value.
|
|
||||||
*/
|
|
||||||
getAllowedOpposingTypes: function () {
|
|
||||||
axios.get('./api/v1/configuration/firefly.allowed_opposing_types')
|
|
||||||
.then(response => {
|
|
||||||
// console.log('opposing types things.');
|
|
||||||
// console.log(response.data.data.value);
|
|
||||||
this.allowedOpposingTypes = response.data.data.value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getExpectedSourceTypes: function () {
|
|
||||||
axios.get('./api/v1/configuration/firefly.expected_source_types')
|
|
||||||
.then(response => {
|
|
||||||
//console.log('getExpectedSourceTypes.');
|
|
||||||
this.sourceAllowedTypes = response.data.data.value.source[this.transactionType];
|
|
||||||
this.destinationAllowedTypes = response.data.data.value.destination[this.transactionType];
|
|
||||||
|
|
||||||
// console.log('sourceAllowedTypes');
|
|
||||||
// console.log(this.sourceAllowedTypes);
|
|
||||||
|
|
||||||
// console.log('Source allowed types for ' + this.transactionType + ' is: ');
|
|
||||||
// console.log(this.sourceAllowedTypes);
|
|
||||||
|
|
||||||
// console.log('Destination allowed types for ' + this.transactionType + ' is: ');
|
|
||||||
// console.log(this.destinationAllowedTypes);
|
|
||||||
|
|
||||||
//this.allowedOpposingTypes = response.data.data.value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Get API value.
|
|
||||||
*/
|
|
||||||
getAccountToTransaction: function () {
|
|
||||||
axios.get('./api/v1/configuration/firefly.account_to_transaction')
|
|
||||||
.then(response => {
|
|
||||||
this.accountToTransaction = response.data.data.value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* This method grabs the users preferred custom transaction fields. It's used when configuring the
|
|
||||||
* custom date selects that will be available. It could be something the component does by itself,
|
|
||||||
* thereby separating concerns. This is on my list. If it changes to a per-component thing, then
|
|
||||||
* it should be done via the create.js Vue store because multiple components are interested in the
|
|
||||||
* user's custom transaction fields.
|
|
||||||
*/
|
|
||||||
getCustomFields: function () {
|
|
||||||
axios.get('./api/v1/preferences/transaction_journal_optional_fields').then(response => {
|
|
||||||
this.customFields = response.data.data.attributes.data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
setDestinationAllowedTypes: function (value) {
|
|
||||||
// console.log('Create::setDestinationAllowedTypes');
|
|
||||||
// console.log(value);
|
|
||||||
if (0 === value.length) {
|
|
||||||
this.destinationAllowedTypes = this.defaultDestinationAllowedTypes;
|
|
||||||
//console.log('empty so back to defaults');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.destinationAllowedTypes = value;
|
|
||||||
},
|
|
||||||
setSourceAllowedTypes(value) {
|
|
||||||
// console.log('Create::setSourceAllowedTypes');
|
|
||||||
// console.log(value);
|
|
||||||
if (0 === value.length) {
|
|
||||||
this.sourceAllowedTypes = this.defaultSourceAllowedTypes;
|
|
||||||
// console.log('empty so back to defaults');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.sourceAllowedTypes = value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,177 +0,0 @@
|
|||||||
<!--
|
|
||||||
- Index.vue
|
|
||||||
- Copyright (c) 2021 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>
|
|
||||||
<!-- charts here (see file history) -->
|
|
||||||
<!-- page is ignored for the time being -->
|
|
||||||
<TransactionListLarge
|
|
||||||
:entries="rawTransactions"
|
|
||||||
:page="currentPage"
|
|
||||||
:total="total"
|
|
||||||
:per-page="perPage"
|
|
||||||
:sort-desc="sortDesc"
|
|
||||||
v-on:jump-page="jumpToPage($event)"
|
|
||||||
v-on:refreshed-cache-key="refreshedKey"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import {mapGetters, mapMutations} from "vuex";
|
|
||||||
import format from "date-fns/format";
|
|
||||||
import sub from "date-fns/sub";
|
|
||||||
import startOfMonth from "date-fns/startOfMonth";
|
|
||||||
import endOfMonth from "date-fns/endOfMonth";
|
|
||||||
import {configureAxios} from "../../shared/forageStore";
|
|
||||||
import TransactionListLarge from "./TransactionListLarge";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Index",
|
|
||||||
components: {TransactionListLarge},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
rawTransactions: [],
|
|
||||||
type: 'all',
|
|
||||||
downloaded: false,
|
|
||||||
loading: false,
|
|
||||||
ready: false,
|
|
||||||
currentPage: 1,
|
|
||||||
perPage: 5,
|
|
||||||
total: 1,
|
|
||||||
sortBy: 'order',
|
|
||||||
sortDesc: false,
|
|
||||||
api: null,
|
|
||||||
sortableOptions: {
|
|
||||||
disabled: false,
|
|
||||||
chosenClass: 'is-selected',
|
|
||||||
onEnd: null
|
|
||||||
},
|
|
||||||
sortable: null,
|
|
||||||
locale: 'en-US',
|
|
||||||
ranges: [],
|
|
||||||
urlStart: null,
|
|
||||||
urlEnd: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
storeReady: function () {
|
|
||||||
this.getTransactionList();
|
|
||||||
},
|
|
||||||
start: function () {
|
|
||||||
this.getTransactionList();
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
this.getTransactionList();
|
|
||||||
},
|
|
||||||
activeFilter: function (value) {
|
|
||||||
this.filterAccountList();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('root', ['listPageSize', 'cacheKey']),
|
|
||||||
...mapGetters('dashboard/index', ['start', 'end',]),
|
|
||||||
'indexReady': function () {
|
|
||||||
return null !== this.start && null !== this.end && null !== this.listPageSize && this.ready;
|
|
||||||
},
|
|
||||||
cardTitle: function () {
|
|
||||||
return this.$t('firefly.' + this.type + '_transactions');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
let pathName = window.location.pathname;
|
|
||||||
let parts = pathName.split('/');
|
|
||||||
this.type = parts[parts.length - 1];
|
|
||||||
this.perPage = this.listPageSize ?? 51;
|
|
||||||
|
|
||||||
if (5 === parts.length) {
|
|
||||||
this.urlStart = new Date(parts[3]);
|
|
||||||
this.urlEnd = new Date(parts[4]);
|
|
||||||
this.type = parts[parts.length - 3];
|
|
||||||
}
|
|
||||||
|
|
||||||
let params = new URLSearchParams(window.location.search);
|
|
||||||
this.currentPage = params.get('page') ? parseInt(params.get('page')) : 1;
|
|
||||||
this.ready = true;
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapMutations('root', ['refreshCacheKey',]),
|
|
||||||
refreshedKey: function () {
|
|
||||||
this.downloaded = false;
|
|
||||||
this.rawTransactions = [];
|
|
||||||
this.getTransactionList();
|
|
||||||
},
|
|
||||||
jumpToPage: function (event) {
|
|
||||||
// console.log('noticed a change in transactions/index.vue!');
|
|
||||||
this.currentPage = event.page;
|
|
||||||
this.downloadTransactionList(event.page);
|
|
||||||
},
|
|
||||||
getTransactionList: function () {
|
|
||||||
if (this.indexReady && !this.loading && !this.downloaded) {
|
|
||||||
this.loading = true;
|
|
||||||
this.perPage = this.listPageSize ?? 51;
|
|
||||||
this.rawTransactions = [];
|
|
||||||
this.downloadTransactionList(this.currentPage);
|
|
||||||
this.calculateDateRanges();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
calculateDateRanges: function () {
|
|
||||||
let yearAgo = sub(this.start, {years: 1});
|
|
||||||
let currentDate = this.start;
|
|
||||||
|
|
||||||
while (currentDate > yearAgo) {
|
|
||||||
let st = startOfMonth(currentDate);
|
|
||||||
let en = endOfMonth(currentDate);
|
|
||||||
|
|
||||||
this.ranges.push({start: st, end: en});
|
|
||||||
|
|
||||||
currentDate = sub(currentDate, {months: 1});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
formatDate: function (date, frm) {
|
|
||||||
return format(date, frm);
|
|
||||||
},
|
|
||||||
downloadTransactionList: function (page) {
|
|
||||||
configureAxios().then(async (api) => {
|
|
||||||
let startStr = format(this.start, 'y-MM-dd');
|
|
||||||
let endStr = format(this.end, 'y-MM-dd');
|
|
||||||
|
|
||||||
if (null !== this.urlEnd && null !== this.urlStart) {
|
|
||||||
startStr = format(this.urlStart, 'y-MM-dd');
|
|
||||||
endStr = format(this.urlEnd, 'y-MM-dd');
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = './api/v1/transactions?type=' + this.type + '&page=' + page + "&start=" + startStr + "&end=" + endStr + '&cache=' + this.cacheKey;
|
|
||||||
api.get(url)
|
|
||||||
.then(response => {
|
|
||||||
this.total = parseInt(response.data.meta.pagination.total);
|
|
||||||
this.rawTransactions = response.data.data;
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,464 +0,0 @@
|
|||||||
<!--
|
|
||||||
- SplitForm.vue
|
|
||||||
- Copyright (c) 2021 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 :id="'split_' + index" :class="'tab-pane' + (0 === index ? ' active' : '')">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
{{ $t('firefly.basic_journal_information') }}
|
|
||||||
<span v-if="count > 1">({{ index + 1 }} / {{ count }}) </span>
|
|
||||||
</h3>
|
|
||||||
<div v-if="count>1" class="card-tools">
|
|
||||||
<button type="button" class="btn btn-danger btn-xs" @click="removeTransaction"><span class="fas fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
<!-- start of body -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<TransactionDescription
|
|
||||||
v-model="transaction.description"
|
|
||||||
v-on="$listeners"
|
|
||||||
:errors="transaction.errors.description"
|
|
||||||
:index="index"
|
|
||||||
></TransactionDescription>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- source and destination -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-5 col-lg-5 col-md-10 col-sm-12 col-xs-12">
|
|
||||||
<!-- SOURCE -->
|
|
||||||
<TransactionAccount
|
|
||||||
v-model="sourceAccount"
|
|
||||||
v-on="$listeners"
|
|
||||||
:destination-allowed-types="destinationAllowedTypes"
|
|
||||||
:errors="transaction.errors.source"
|
|
||||||
:index="index"
|
|
||||||
:source-allowed-types="sourceAllowedTypes"
|
|
||||||
:transaction-type="transactionType"
|
|
||||||
direction="source"
|
|
||||||
ref="sourceAccount"
|
|
||||||
v-on:selected-account="triggerNextAccount($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<!-- switcharoo! -->
|
|
||||||
<div class="col-xl-2 col-lg-2 col-md-2 col-sm-12 text-center d-none d-sm-block">
|
|
||||||
<SwitchAccount
|
|
||||||
v-if="0 === index && allowSwitch"
|
|
||||||
v-on="$listeners"
|
|
||||||
:index="index"
|
|
||||||
:transaction-type="transactionType"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- destination -->
|
|
||||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<!-- DESTINATION -->
|
|
||||||
<TransactionAccount
|
|
||||||
v-model="destinationAccount"
|
|
||||||
v-on="$listeners"
|
|
||||||
:destination-allowed-types="destinationAllowedTypes"
|
|
||||||
:errors="transaction.errors.destination"
|
|
||||||
:index="index"
|
|
||||||
ref="destinationAccount"
|
|
||||||
:transaction-type="transactionType"
|
|
||||||
:source-allowed-types="sourceAllowedTypes"
|
|
||||||
direction="destination"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- amount -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-5 col-lg-5 col-md-10 col-sm-12 col-xs-12">
|
|
||||||
<!-- AMOUNT -->
|
|
||||||
<TransactionAmount
|
|
||||||
v-on="$listeners"
|
|
||||||
ref="amount"
|
|
||||||
:amount="transaction.amount"
|
|
||||||
:destination-currency-symbol="this.transaction.destination_account_currency_symbol"
|
|
||||||
:errors="transaction.errors.amount"
|
|
||||||
:index="index"
|
|
||||||
:source-currency-symbol="this.transaction.source_account_currency_symbol"
|
|
||||||
:transaction-type="this.transactionType"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-2 col-lg-2 col-md-2 col-sm-12 text-center d-none d-sm-block">
|
|
||||||
<TransactionForeignCurrency
|
|
||||||
v-model="transaction.foreign_currency_id"
|
|
||||||
v-on="$listeners"
|
|
||||||
:destination-currency-id="this.transaction.destination_account_currency_id"
|
|
||||||
:index="index"
|
|
||||||
:selected-currency-id="this.transaction.foreign_currency_id"
|
|
||||||
:source-currency-id="this.transaction.source_account_currency_id"
|
|
||||||
:transaction-type="this.transactionType"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<!--
|
|
||||||
The reason that TransactionAmount gets the symbols and
|
|
||||||
TransactionForeignAmount gets the ID's of the currencies is
|
|
||||||
because ultimately TransactionAmount doesn't decide which
|
|
||||||
currency id is submitted to Firefly III.
|
|
||||||
-->
|
|
||||||
<TransactionForeignAmount
|
|
||||||
v-model="transaction.foreign_amount"
|
|
||||||
v-on="$listeners"
|
|
||||||
:destination-currency-id="this.transaction.destination_account_currency_id"
|
|
||||||
:errors="transaction.errors.foreign_amount"
|
|
||||||
:index="index"
|
|
||||||
:selected-currency-id="this.transaction.foreign_currency_id"
|
|
||||||
:source-currency-id="this.transaction.source_account_currency_id"
|
|
||||||
:transaction-type="this.transactionType"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- dates -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<TransactionDate
|
|
||||||
v-on="$listeners"
|
|
||||||
:date="splitDate"
|
|
||||||
:errors="transaction.errors.date"
|
|
||||||
:index="index"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12 offset-xl-2 offset-lg-2">
|
|
||||||
<TransactionCustomDates
|
|
||||||
v-on="$listeners"
|
|
||||||
:book-date="transaction.book_date"
|
|
||||||
:custom-fields.sync="customFields"
|
|
||||||
:due-date="transaction.due_date"
|
|
||||||
:errors="transaction.errors.custom_dates"
|
|
||||||
:index="index"
|
|
||||||
:interest-date="transaction.interest_date"
|
|
||||||
:invoice-date="transaction.invoice_date"
|
|
||||||
:payment-date="transaction.payment_date"
|
|
||||||
:process-date="transaction.process_date"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- end of body -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div> <!-- end of basic card -->
|
|
||||||
|
|
||||||
<!-- card for meta -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
{{ $t('firefly.transaction_journal_meta') }}
|
|
||||||
<span v-if="count > 1">({{ index + 1 }} / {{ count }}) </span>
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<!-- start of body -->
|
|
||||||
<!-- meta -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<TransactionBudget
|
|
||||||
v-if="!('Transfer' === transactionType || 'Deposit' === transactionType)"
|
|
||||||
v-model="transaction.budget_id"
|
|
||||||
v-on="$listeners"
|
|
||||||
:errors="transaction.errors.budget"
|
|
||||||
:index="index"
|
|
||||||
/>
|
|
||||||
<TransactionCategory
|
|
||||||
v-model="transaction.category"
|
|
||||||
v-on="$listeners"
|
|
||||||
:errors="transaction.errors.category"
|
|
||||||
:index="index"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<TransactionBill
|
|
||||||
v-if="!('Transfer' === transactionType || 'Deposit' === transactionType)"
|
|
||||||
v-model="transaction.bill_id"
|
|
||||||
v-on="$listeners"
|
|
||||||
:errors="transaction.errors.bill"
|
|
||||||
:index="index"
|
|
||||||
/>
|
|
||||||
<TransactionTags
|
|
||||||
v-model="transaction.tags"
|
|
||||||
v-on="$listeners"
|
|
||||||
ref="tags"
|
|
||||||
:errors="transaction.errors.tags"
|
|
||||||
:index="index"
|
|
||||||
/>
|
|
||||||
<TransactionPiggyBank
|
|
||||||
v-if="!('Withdrawal' === transactionType || 'Deposit' === transactionType)"
|
|
||||||
v-model="transaction.piggy_bank_id"
|
|
||||||
v-on="$listeners"
|
|
||||||
:errors="transaction.errors.piggy_bank"
|
|
||||||
:index="index"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- end card for meta -->
|
|
||||||
<!-- card for extra -->
|
|
||||||
<div v-if="hasMetaFields" class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title">
|
|
||||||
{{ $t('firefly.transaction_journal_extra') }}
|
|
||||||
<span v-if="count > 1">({{ index + 1 }} / {{ count }}) </span>
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<!-- start of body -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
|
|
||||||
<TransactionInternalReference
|
|
||||||
v-model="transaction.internal_reference"
|
|
||||||
v-on="$listeners"
|
|
||||||
:custom-fields.sync="customFields"
|
|
||||||
:errors="transaction.errors.internal_reference"
|
|
||||||
:index="index"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TransactionExternalUrl
|
|
||||||
v-model="transaction.external_url"
|
|
||||||
v-on="$listeners"
|
|
||||||
:custom-fields.sync="customFields"
|
|
||||||
:errors="transaction.errors.external_url"
|
|
||||||
:index="index"
|
|
||||||
/>
|
|
||||||
<TransactionNotes
|
|
||||||
v-model="transaction.notes"
|
|
||||||
v-on="$listeners"
|
|
||||||
:custom-fields.sync="customFields"
|
|
||||||
:errors="transaction.errors.notes"
|
|
||||||
:index="index"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
|
||||||
|
|
||||||
<TransactionAttachments
|
|
||||||
ref="attachments"
|
|
||||||
v-model="transaction.attachments"
|
|
||||||
v-on="$listeners"
|
|
||||||
:custom-fields.sync="customFields"
|
|
||||||
:index="index"
|
|
||||||
:transaction_journal_id="transaction.transaction_journal_id"
|
|
||||||
:upload-trigger="transaction.uploadTrigger"
|
|
||||||
:clear-trigger="transaction.clearTrigger"
|
|
||||||
/>
|
|
||||||
<TransactionLocation
|
|
||||||
v-model="transaction.location"
|
|
||||||
v-on="$listeners"
|
|
||||||
:custom-fields.sync="customFields"
|
|
||||||
:errors="transaction.errors.location"
|
|
||||||
:index="index"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TransactionLinks
|
|
||||||
v-model="transaction.links"
|
|
||||||
v-on="$listeners"
|
|
||||||
:custom-fields.sync="customFields"
|
|
||||||
:index="index"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<!-- end of body -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- end card for extra -->
|
|
||||||
<!-- end of card -->
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import TransactionDescription from "./TransactionDescription";
|
|
||||||
import TransactionDate from "./TransactionDate";
|
|
||||||
import TransactionBudget from "./TransactionBudget";
|
|
||||||
import TransactionAccount from "./TransactionAccount";
|
|
||||||
import SwitchAccount from "./SwitchAccount";
|
|
||||||
import TransactionAmount from "./TransactionAmount";
|
|
||||||
import TransactionForeignAmount from "./TransactionForeignAmount";
|
|
||||||
import TransactionForeignCurrency from "./TransactionForeignCurrency";
|
|
||||||
import TransactionCustomDates from "./TransactionCustomDates";
|
|
||||||
import TransactionCategory from "./TransactionCategory";
|
|
||||||
import TransactionBill from "./TransactionBill";
|
|
||||||
import TransactionTags from "./TransactionTags";
|
|
||||||
import TransactionPiggyBank from "./TransactionPiggyBank";
|
|
||||||
import TransactionInternalReference from "./TransactionInternalReference";
|
|
||||||
import TransactionExternalUrl from "./TransactionExternalUrl";
|
|
||||||
import TransactionNotes from "./TransactionNotes";
|
|
||||||
import TransactionLinks from "./TransactionLinks";
|
|
||||||
import TransactionAttachments from "./TransactionAttachments";
|
|
||||||
import SplitPills from "./SplitPills";
|
|
||||||
import TransactionLocation from "./TransactionLocation";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "SplitForm",
|
|
||||||
props: {
|
|
||||||
transaction: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
count: {
|
|
||||||
type: Number,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
customFields: {
|
|
||||||
type: Object,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
index: {
|
|
||||||
type: Number,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
date: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
transactionType: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
sourceAllowedTypes: {
|
|
||||||
type: Array,
|
|
||||||
required: false,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}, // allowed source account types.
|
|
||||||
destinationAllowedTypes: {
|
|
||||||
type: Array,
|
|
||||||
required: false,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// allow switch?
|
|
||||||
allowSwitch: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// console.log('SplitForm(' + this.index + ')');
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
removeTransaction: function () {
|
|
||||||
// console.log('Will remove transaction ' + this.index);
|
|
||||||
|
|
||||||
this.$emit('remove-transaction', {index: this.index});
|
|
||||||
},
|
|
||||||
triggerNextAccount: function (e) {
|
|
||||||
//alert(e);
|
|
||||||
if ('source' === e) {
|
|
||||||
// console.log('Jump to destination!');
|
|
||||||
this.$refs.destinationAccount.giveFocus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
splitDate: function () {
|
|
||||||
return this.date;
|
|
||||||
},
|
|
||||||
sourceAccount: function () {
|
|
||||||
//console.log('computed::sourceAccount(' + this.index + ')');
|
|
||||||
return {
|
|
||||||
id: this.transaction.source_account_id,
|
|
||||||
name: this.transaction.source_account_name,
|
|
||||||
type: this.transaction.source_account_type,
|
|
||||||
};
|
|
||||||
//console.log(JSON.stringify(value));
|
|
||||||
//return value;
|
|
||||||
},
|
|
||||||
destinationAccount: function () {
|
|
||||||
//console.log('computed::destinationAccount(' + this.index + ')');
|
|
||||||
return {
|
|
||||||
id: this.transaction.destination_account_id,
|
|
||||||
name: this.transaction.destination_account_name,
|
|
||||||
type: this.transaction.destination_account_type,
|
|
||||||
};
|
|
||||||
//console.log(JSON.stringify(value));
|
|
||||||
//return value;
|
|
||||||
},
|
|
||||||
hasMetaFields: function () {
|
|
||||||
let requiredFields = [
|
|
||||||
'internal_reference',
|
|
||||||
'notes',
|
|
||||||
'attachments',
|
|
||||||
'external_uri',
|
|
||||||
'location',
|
|
||||||
'links',
|
|
||||||
];
|
|
||||||
for (let field in this.customFields) {
|
|
||||||
if (this.customFields.hasOwnProperty(field)) {
|
|
||||||
if (requiredFields.includes(field)) {
|
|
||||||
if (true === this.customFields[field]) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
TransactionLocation,
|
|
||||||
SplitPills,
|
|
||||||
TransactionAttachments,
|
|
||||||
TransactionNotes,
|
|
||||||
TransactionExternalUrl,
|
|
||||||
TransactionInternalReference,
|
|
||||||
TransactionPiggyBank,
|
|
||||||
TransactionTags,
|
|
||||||
TransactionLinks,
|
|
||||||
TransactionBill,
|
|
||||||
TransactionCategory,
|
|
||||||
TransactionCustomDates,
|
|
||||||
TransactionForeignCurrency,
|
|
||||||
TransactionForeignAmount,
|
|
||||||
TransactionAmount,
|
|
||||||
SwitchAccount,
|
|
||||||
TransactionAccount,
|
|
||||||
TransactionBudget,
|
|
||||||
TransactionDescription,
|
|
||||||
TransactionDate
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
<!--
|
|
||||||
- SplitPills.vue
|
|
||||||
- Copyright (c) 2021 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>
|
|
||||||
<div v-if="transactions.length > 1" class="row">
|
|
||||||
<div class="col">
|
|
||||||
<!-- tabs -->
|
|
||||||
<ul class="nav nav-pills ml-auto p-2" id="transactionTabs">
|
|
||||||
<li v-for="(transaction, index) in this.transactions" class="nav-item"><a :class="'nav-link' + (0 === index ? ' active' : '')"
|
|
||||||
:href="'#split_' + index"
|
|
||||||
:id="'tab_split_' + index"
|
|
||||||
data-toggle="pill">
|
|
||||||
<span v-if="'' !== transaction.description">{{ transaction.description }}</span>
|
|
||||||
<span v-if="'' === transaction.description">Split {{ index + 1 }}</span>
|
|
||||||
</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "SplitPills",
|
|
||||||
props: {
|
|
||||||
transactions: {
|
|
||||||
type: Array,
|
|
||||||
required: true,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
count: {
|
|
||||||
type: Number,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
<!--
|
|
||||||
- SwitchAccount.vue
|
|
||||||
- Copyright (c) 2020 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
<span v-if="'any' !== this.transactionType" class="text-muted">
|
|
||||||
{{ $t('firefly.' + this.transactionType) }}
|
|
||||||
</span>
|
|
||||||
<span v-if="'any' === this.transactionType" class="text-muted"> </span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "SwitchAccount",
|
|
||||||
props: ['index', 'transactionType'],
|
|
||||||
methods: {
|
|
||||||
// switchAccounts() {
|
|
||||||
// this.$emit('switch-accounts', this.index);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,309 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionAccount.vue
|
|
||||||
- Copyright (c) 2020 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">
|
|
||||||
<div v-if="visible" class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
<span v-if="0 === this.index">{{ $t('firefly.' + this.direction + '_account') }}</span>
|
|
||||||
<span v-if="this.index > 0" class="text-warning">{{ $t('firefly.first_split_overrules_' + this.direction) }}</span>
|
|
||||||
</div>
|
|
||||||
<div v-if="!visible" class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<vue-typeahead-bootstrap
|
|
||||||
v-if="visible"
|
|
||||||
v-model="accountName"
|
|
||||||
:data="accounts"
|
|
||||||
:inputClass="errors.length > 0 ? 'is-invalid' : ''"
|
|
||||||
:inputName="direction + '[]'"
|
|
||||||
:minMatchingChars="3"
|
|
||||||
:placeholder="$t('firefly.' + direction + '_account')"
|
|
||||||
:serializer="item => item.name_with_balance"
|
|
||||||
:showOnFocus=true
|
|
||||||
ref="inputThing"
|
|
||||||
aria-autocomplete="none"
|
|
||||||
autocomplete="off"
|
|
||||||
@hit="userSelectedAccount"
|
|
||||||
@input="lookupAccount"
|
|
||||||
>
|
|
||||||
|
|
||||||
<template slot="suggestion" slot-scope="{ data, htmlText }">
|
|
||||||
<div :title="data.type" class="d-flex">
|
|
||||||
<span v-html="htmlText"></span><br>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template slot="append">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" tabindex="-1" type="button" v-on:click="clearAccount"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</vue-typeahead-bootstrap>
|
|
||||||
<div v-if="!visible" class="form-control-static">
|
|
||||||
<span class="small text-muted"><em>{{ $t('firefly.first_split_decides') }}</em></span>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import VueTypeaheadBootstrap from 'vue-typeahead-bootstrap';
|
|
||||||
import {debounce} from 'lodash';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "TransactionAccount",
|
|
||||||
components: {VueTypeaheadBootstrap},
|
|
||||||
props: {
|
|
||||||
index: {
|
|
||||||
type: Number,
|
|
||||||
},
|
|
||||||
direction: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
errors: {
|
|
||||||
type: Array,
|
|
||||||
default: () => ([])
|
|
||||||
},
|
|
||||||
sourceAllowedTypes: {
|
|
||||||
type: Array,
|
|
||||||
default: () => ([])
|
|
||||||
},
|
|
||||||
destinationAllowedTypes: {
|
|
||||||
type: Array,
|
|
||||||
default: () => ([])
|
|
||||||
},
|
|
||||||
transactionType: {
|
|
||||||
type: String,
|
|
||||||
default: 'any'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
query: '',
|
|
||||||
accounts: [],
|
|
||||||
accountTypes: [],
|
|
||||||
initialSet: [],
|
|
||||||
selectedAccount: {},
|
|
||||||
accountName: '',
|
|
||||||
selectedAccountTrigger: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.accountName = this.value.name ?? '';
|
|
||||||
// console.log('TransactionAccount::created() direction=' + this.direction + ', type=' + this.transactionType + ' , name="' + this.accountName + '"');
|
|
||||||
this.selectedAccountTrigger = true;
|
|
||||||
},
|
|
||||||
mounted: function () {
|
|
||||||
this.$nextTick(function () {
|
|
||||||
this.$refs.inputThing.$refs.input.tabIndex = 2;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getACURL: function (types, query) {
|
|
||||||
return './api/v1/autocomplete/accounts?types=' + types.join(',') + '&query=' + query;
|
|
||||||
},
|
|
||||||
giveFocus: function () {
|
|
||||||
// console.log('I want focus! now OK: ' + this.direction + ' l: ' + this.accounts.length);
|
|
||||||
//console.log(this.$refs.inputThing.$refs.input.value);
|
|
||||||
this.$refs.inputThing.$refs.input.focus();
|
|
||||||
//console.log(this.$refs.inputThing.isFocused);
|
|
||||||
},
|
|
||||||
userSelectedAccount: function (event) {
|
|
||||||
// console.log('userSelectedAccount!');
|
|
||||||
// console.log('To prevent invalid propogation, set selectedAccountTrigger = true');
|
|
||||||
this.selectedAccountTrigger = true;
|
|
||||||
this.selectedAccount = event;
|
|
||||||
},
|
|
||||||
systemReturnedAccount: function (event) {
|
|
||||||
//console.log('systemReturnedAccount!');
|
|
||||||
//console.log('To prevent invalid propogation, set selectedAccountTrigger = false');
|
|
||||||
this.selectedAccountTrigger = false;
|
|
||||||
this.selectedAccount = event;
|
|
||||||
},
|
|
||||||
clearAccount: function () {
|
|
||||||
//// console.log('TransactionAccount::clearAccount()');
|
|
||||||
this.accounts = this.initialSet;
|
|
||||||
//this.account = {name: '', type: 'no_type', id: null, currency_id: null, currency_code: null, currency_symbol: null};
|
|
||||||
this.accountName = '';
|
|
||||||
},
|
|
||||||
lookupAccount: debounce(function () {
|
|
||||||
//// console.log('TransactionAccount::lookupAccount()');
|
|
||||||
//// console.log('In lookupAccount()');
|
|
||||||
if (0 === this.accountTypes.length) {
|
|
||||||
// set the types from the default types for this direction:
|
|
||||||
this.accountTypes = 'source' === this.direction ? this.sourceAllowedTypes : this.destinationAllowedTypes;
|
|
||||||
}
|
|
||||||
// // console.log(this.direction + ': Will search for types:');
|
|
||||||
// // console.log(this.accountTypes);
|
|
||||||
|
|
||||||
// update autocomplete URL:
|
|
||||||
axios.get(this.getACURL(this.accountTypes, this.accountName))
|
|
||||||
.then(response => {
|
|
||||||
//// console.log('Got a response!');
|
|
||||||
this.accounts = response.data;
|
|
||||||
//// console.log(response.data);
|
|
||||||
})
|
|
||||||
}, 300),
|
|
||||||
|
|
||||||
createInitialSet: function () {
|
|
||||||
//// console.log('TransactionAccount::createInitialSet()');
|
|
||||||
let types = this.sourceAllowedTypes;
|
|
||||||
if ('destination' === this.direction) {
|
|
||||||
types = this.destinationAllowedTypes;
|
|
||||||
}
|
|
||||||
// // console.log('createInitialSet() direction=' + this.direction + ' resets to these types:');
|
|
||||||
// // console.log(types);
|
|
||||||
|
|
||||||
axios.get(this.getACURL(types, ''))
|
|
||||||
.then(response => {
|
|
||||||
this.accounts = response.data;
|
|
||||||
this.initialSet = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
sourceAllowedTypes: function (value) {
|
|
||||||
//// console.log('TransactionAccount::sourceAllowedTypes()');
|
|
||||||
// // console.log(this.direction + ' account noticed change in sourceAllowedTypes');
|
|
||||||
// // console.log(value);
|
|
||||||
this.createInitialSet();
|
|
||||||
},
|
|
||||||
destinationAllowedTypes: function (value) {
|
|
||||||
//// console.log('TransactionAccount::destinationAllowedTypes()');
|
|
||||||
// // console.log(this.direction + ' account noticed change in destinationAllowedTypes');
|
|
||||||
// // console.log(value);
|
|
||||||
this.createInitialSet();
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Triggered when the user selects an account from the auto-complete.
|
|
||||||
*
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
selectedAccount: function (value) {
|
|
||||||
//console.log('TransactionAccount::watch selectedAccount()');
|
|
||||||
// console.log(value);
|
|
||||||
if (true === this.selectedAccountTrigger) {
|
|
||||||
// console.log('$emit alles!');
|
|
||||||
this.$emit('set-account',
|
|
||||||
{
|
|
||||||
index: this.index,
|
|
||||||
direction: this.direction,
|
|
||||||
id: value.id,
|
|
||||||
type: value.type,
|
|
||||||
name: value.name,
|
|
||||||
currency_id: value.currency_id,
|
|
||||||
currency_code: value.currency_code,
|
|
||||||
currency_symbol: value.currency_symbol,
|
|
||||||
user_selected: true,
|
|
||||||
}
|
|
||||||
// jump to next field somehow.
|
|
||||||
|
|
||||||
);
|
|
||||||
//console.log('watch::selectedAccount() will now set accountName because selectedAccountTrigger = true');
|
|
||||||
this.accountName = value.name;
|
|
||||||
|
|
||||||
}
|
|
||||||
if (false === this.selectedAccountTrigger) {
|
|
||||||
//console.log('watch::selectedAccount() will NOT set accountName because selectedAccountTrigger = false');
|
|
||||||
}
|
|
||||||
if (false === this.selectedAccountTrigger && this.accountName !== value.name && null !== value.name) {
|
|
||||||
//console.log('watch::selectedAccount() will set accountName. selectedAccountTrigger = false but name is different ("' + this.accountName + '" > "' + value.name + '")');
|
|
||||||
this.selectedAccountTrigger = true;
|
|
||||||
this.accountName = value.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
accountName: function (value) {
|
|
||||||
// console.log('now at watch accountName("' + value + '")');
|
|
||||||
// console.log(this.selectedAccountTrigger);
|
|
||||||
if (true === this.selectedAccountTrigger) {
|
|
||||||
// console.log('Do nothing because selectedAccountTrigger = true');
|
|
||||||
}
|
|
||||||
if (false === this.selectedAccountTrigger) {
|
|
||||||
// console.log('$emit name from watch::accountName() because selectedAccountTrigger = false');
|
|
||||||
this.$emit('set-account',
|
|
||||||
{
|
|
||||||
index: this.index,
|
|
||||||
direction: this.direction,
|
|
||||||
id: null,
|
|
||||||
type: null,
|
|
||||||
name: value,
|
|
||||||
currency_id: null,
|
|
||||||
currency_code: null,
|
|
||||||
currency_symbol: null,
|
|
||||||
user_selected: false
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// this.account = {name: value, type: null, id: null, currency_id: null, currency_code: null, currency_symbol: null};
|
|
||||||
}
|
|
||||||
// console.log('set selectedAccountTrigger to be FALSE');
|
|
||||||
this.selectedAccountTrigger = false;
|
|
||||||
},
|
|
||||||
value: function (value) {
|
|
||||||
//console.log('TransactionAccount(' + this.index + ')::watch value(' + JSON.stringify(value) + ')');
|
|
||||||
this.systemReturnedAccount(value);
|
|
||||||
|
|
||||||
// // console.log('Index ' + this.index + ' nwAct: ', value);
|
|
||||||
// // console.log(this.direction + ' account overruled by external forces.');
|
|
||||||
// // console.log(value);
|
|
||||||
//this.account = value;
|
|
||||||
//this.selectedAccountTrigger = true;
|
|
||||||
// this.accountName = value.name ?? '';
|
|
||||||
// if(null !== value.id) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// this.selectedAccountTrigger = true;
|
|
||||||
//
|
|
||||||
// // console.log('Set selectedAccountTrigger = true');
|
|
||||||
// this.selectedAccount = value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
accountKey: {
|
|
||||||
get() {
|
|
||||||
return 'source' === this.direction ? 'source_account' : 'destination_account';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
visible: {
|
|
||||||
get() {
|
|
||||||
// index 0 is always visible:
|
|
||||||
if (0 === this.index) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// // console.log('Direction of account ' + this.index + ' is ' + this.direction + '(' + this.transactionType + ')');
|
|
||||||
// // console.log(this.transactionType);
|
|
||||||
if ('source' === this.direction) {
|
|
||||||
return 'any' === this.transactionType || 'Deposit' === this.transactionType || typeof this.transactionType === 'undefined';
|
|
||||||
}
|
|
||||||
if ('destination' === this.direction) {
|
|
||||||
return 'any' === this.transactionType || 'Withdrawal' === this.transactionType || typeof this.transactionType === 'undefined';
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionAmount.vue
|
|
||||||
- Copyright (c) 2020 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">
|
|
||||||
<div class="text-xs">{{ $t('firefly.amount') }}</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<div v-if="currencySymbol" class="input-group-prepend">
|
|
||||||
<div class="input-group-text">{{ currencySymbol }}</div>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
v-model="transactionAmount"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="$t('firefly.amount')"
|
|
||||||
:title="$t('firefly.amount')"
|
|
||||||
autocomplete="off"
|
|
||||||
name="amount[]"
|
|
||||||
type="number"
|
|
||||||
ref="input"
|
|
||||||
step="any"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "TransactionAmount",
|
|
||||||
props: {
|
|
||||||
index: {
|
|
||||||
type: Number,
|
|
||||||
default: 0,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
errors: {},
|
|
||||||
amount: {},
|
|
||||||
transactionType: {},
|
|
||||||
sourceCurrencySymbol: {},
|
|
||||||
destinationCurrencySymbol: {},
|
|
||||||
fractionDigits: {
|
|
||||||
default: 2,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
if ('' !== this.amount) {
|
|
||||||
this.emitEvent = false;
|
|
||||||
this.transactionAmount = this.formatNumber(this.amount);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted: function () {
|
|
||||||
this.$nextTick(function () {
|
|
||||||
this.$refs.input.tabIndex = 3;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
formatNumber(str) {
|
|
||||||
return parseFloat(str).toFixed(this.fractionDigits);
|
|
||||||
},
|
|
||||||
giveFocus: function () {
|
|
||||||
this.$refs.input.focus();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
transactionAmount: this.amount,
|
|
||||||
currencySymbol: null,
|
|
||||||
srcCurrencySymbol: this.sourceCurrencySymbol,
|
|
||||||
dstCurrencySymbol: this.destinationCurrencySymbol,
|
|
||||||
emitEvent: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
transactionAmount: function (value) {
|
|
||||||
if (true === this.emitEvent) {
|
|
||||||
this.$emit('set-field', {field: 'amount', index: this.index, value: value});
|
|
||||||
}
|
|
||||||
this.emitEvent = true;
|
|
||||||
},
|
|
||||||
amount: function (value) {
|
|
||||||
this.transactionAmount = value;
|
|
||||||
},
|
|
||||||
sourceCurrencySymbol: function (value) {
|
|
||||||
this.srcCurrencySymbol = value;
|
|
||||||
},
|
|
||||||
destinationCurrencySymbol: function (value) {
|
|
||||||
this.dstCurrencySymbol = value;
|
|
||||||
},
|
|
||||||
transactionType: function (value) {
|
|
||||||
switch (value) {
|
|
||||||
case 'Transfer':
|
|
||||||
case 'Withdrawal':
|
|
||||||
this.currencySymbol = this.srcCurrencySymbol;
|
|
||||||
break;
|
|
||||||
case 'Deposit':
|
|
||||||
this.currencySymbol = this.dstCurrencySymbol;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionAttachments.vue
|
|
||||||
- Copyright (c) 2021 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="showField" class="form-group">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.attachments') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
ref="att"
|
|
||||||
class="form-control"
|
|
||||||
multiple
|
|
||||||
@change="selectedFile"
|
|
||||||
name="attachments[]"
|
|
||||||
type="file"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "TransactionAttachments",
|
|
||||||
props: ['transaction_journal_id', 'customFields', 'index', 'uploadTrigger', 'clearTrigger'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
availableFields: this.customFields,
|
|
||||||
uploads: 0,
|
|
||||||
created: 0,
|
|
||||||
uploaded: 0,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
customFields: function (value) {
|
|
||||||
this.availableFields = value;
|
|
||||||
},
|
|
||||||
uploadTrigger: function () {
|
|
||||||
// console.log('uploadTrigger(' + this.transaction_journal_id + ',' + this.index + ')');
|
|
||||||
this.doUpload();
|
|
||||||
},
|
|
||||||
clearTrigger: function () {
|
|
||||||
// console.log('clearTrigger(' + this.transaction_journal_id + ',' + this.index + ')');
|
|
||||||
this.$refs.att.value = null;
|
|
||||||
},
|
|
||||||
transaction_journal_id: function (value) {
|
|
||||||
// console.log('watch transaction_journal_id: ' + value + ' (index ' + this.index + ')');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
showField: function () {
|
|
||||||
if ('attachments' in this.availableFields) {
|
|
||||||
return this.availableFields.attachments;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
selectedFile: function () {
|
|
||||||
this.$emit('selected-attachments', {index: this.index, id: this.transaction_journal_id});
|
|
||||||
},
|
|
||||||
createAttachment: function (name) {
|
|
||||||
// console.log('Now in createAttachment()');
|
|
||||||
const uri = './api/v1/attachments';
|
|
||||||
const data = {
|
|
||||||
filename: name,
|
|
||||||
attachable_type: 'TransactionJournal',
|
|
||||||
attachable_id: this.transaction_journal_id,
|
|
||||||
};
|
|
||||||
// create new attachment:
|
|
||||||
return axios.post(uri, data);
|
|
||||||
},
|
|
||||||
uploadAttachment: function (attachmentId, data) {
|
|
||||||
this.created++;
|
|
||||||
// console.log('Now in uploadAttachment()');
|
|
||||||
const uploadUri = './api/v1/attachments/' + attachmentId + '/upload';
|
|
||||||
return axios.post(uploadUri, data)
|
|
||||||
},
|
|
||||||
countAttachment: function () {
|
|
||||||
this.uploaded++;
|
|
||||||
// console.log('Uploaded ' + this.uploaded + ' / ' + this.uploads);
|
|
||||||
if (this.uploaded >= this.uploads) {
|
|
||||||
// console.log('All files uploaded. Emit event for ' + this.transaction_journal_id + '(' + this.index + ')');
|
|
||||||
this.$emit('uploaded-attachments', this.transaction_journal_id);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
doUpload: function () {
|
|
||||||
let files = this.$refs.att.files;
|
|
||||||
this.uploads = files.length;
|
|
||||||
// loop all files and create attachments.
|
|
||||||
for (let i in files) {
|
|
||||||
if (files.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
// console.log('Now at file ' + (parseInt(i) + 1) + ' / ' + files.length);
|
|
||||||
// read file into file reader:
|
|
||||||
let current = files[i];
|
|
||||||
let fileReader = new FileReader();
|
|
||||||
let theParent = this; // dont ask me why i need to do this.
|
|
||||||
fileReader.onloadend = evt => {
|
|
||||||
if (evt.target.readyState === FileReader.DONE) {
|
|
||||||
// console.log('I am done reading file ' + (parseInt(i) + 1));
|
|
||||||
this.createAttachment(current.name).then(response => {
|
|
||||||
// console.log('Created attachment. Now upload (1)');
|
|
||||||
return theParent.uploadAttachment(response.data.data.id, new Blob([evt.target.result]));
|
|
||||||
}).then(theParent.countAttachment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fileReader.readAsArrayBuffer(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (0 === files.length) {
|
|
||||||
//console.log('No files to upload. Emit event!');
|
|
||||||
this.$emit('uploaded-attachments', this.transaction_journal_id);
|
|
||||||
}
|
|
||||||
// Promise.all(promises).then(response => {
|
|
||||||
// console.log('All files uploaded. Emit event!');
|
|
||||||
// this.$emit('uploaded-attachments', this.transaction_journal_id);
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionBill.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.bill') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<select
|
|
||||||
ref="bill"
|
|
||||||
v-model="bill"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:title="$t('firefly.bill')"
|
|
||||||
autocomplete="off"
|
|
||||||
name="bill_id[]"
|
|
||||||
>
|
|
||||||
<option v-for="bill in this.billList" :label="bill.name" :value="bill.id">{{ bill.name }}</option>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: ['value', 'index', 'errors'],
|
|
||||||
name: "TransactionBill",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
billList: [],
|
|
||||||
bill: this.value,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted: function () {
|
|
||||||
this.$nextTick(function () {
|
|
||||||
this.$refs.bill.tabIndex = 9;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.collectData();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
collectData() {
|
|
||||||
this.billList.push(
|
|
||||||
{
|
|
||||||
id: 0,
|
|
||||||
name: this.$t('firefly.no_bill'),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.getBills();
|
|
||||||
},
|
|
||||||
getBills() {
|
|
||||||
axios.get('./api/v1/bills')
|
|
||||||
.then(response => {
|
|
||||||
this.parseBills(response.data);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
parseBills(data) {
|
|
||||||
for (let key in data.data) {
|
|
||||||
if (data.data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
|
||||||
let current = data.data[key];
|
|
||||||
this.billList.push(
|
|
||||||
{
|
|
||||||
id: parseInt(current.id),
|
|
||||||
name: current.attributes.name
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
value: function (value) {
|
|
||||||
this.emitEvent = false;
|
|
||||||
this.bill = value;
|
|
||||||
},
|
|
||||||
bill: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'bill_id', index: this.index, value: value});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionBudget.vue
|
|
||||||
- Copyright (c) 2020 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.budget') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<select
|
|
||||||
ref="budget"
|
|
||||||
v-model="budget"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:title="$t('firefly.budget')"
|
|
||||||
autocomplete="off"
|
|
||||||
name="budget_id[]"
|
|
||||||
>
|
|
||||||
<option v-for="budget in this.budgetList" :label="budget.name" :value="budget.id">{{ budget.name }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: ['index', 'value', 'errors'],
|
|
||||||
name: "TransactionBudget",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
budgetList: [],
|
|
||||||
budget: this.value,
|
|
||||||
emitEvent: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted: function () {
|
|
||||||
this.$nextTick(function () {
|
|
||||||
this.$refs.budget.tabIndex = 8;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.collectData();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
collectData() {
|
|
||||||
this.budgetList.push(
|
|
||||||
{
|
|
||||||
id: 0,
|
|
||||||
name: this.$t('firefly.no_budget'),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.getBudgets();
|
|
||||||
},
|
|
||||||
getBudgets() {
|
|
||||||
axios.get('./api/v1/budgets')
|
|
||||||
.then(response => {
|
|
||||||
this.parseBudgets(response.data);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
parseBudgets(data) {
|
|
||||||
for (let key in data.data) {
|
|
||||||
if (data.data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
|
||||||
let current = data.data[key];
|
|
||||||
if(!current.attributes.active) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.budgetList.push(
|
|
||||||
{
|
|
||||||
id: parseInt(current.id),
|
|
||||||
name: current.attributes.name
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
value: function (value) {
|
|
||||||
this.emitEvent = false;
|
|
||||||
this.budget = value;
|
|
||||||
},
|
|
||||||
budget: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'budget_id', index: this.index, value: value});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionCategory.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.category') }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<vue-typeahead-bootstrap
|
|
||||||
v-model="category"
|
|
||||||
:data="categories"
|
|
||||||
:inputClass="errors.length > 0 ? 'is-invalid' : ''"
|
|
||||||
:minMatchingChars="3"
|
|
||||||
:placeholder="$t('firefly.category')"
|
|
||||||
:serializer="item => item.name"
|
|
||||||
:showOnFocus=true
|
|
||||||
inputName="category[]"
|
|
||||||
@hit="selectedCategory = $event"
|
|
||||||
@input="lookupCategory"
|
|
||||||
ref="input"
|
|
||||||
>
|
|
||||||
<template slot="append">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" tabindex="-1" type="button" v-on:click="clearCategory"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</vue-typeahead-bootstrap>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import VueTypeaheadBootstrap from 'vue-typeahead-bootstrap';
|
|
||||||
import {debounce} from "lodash";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: ['value', 'index', 'errors'],
|
|
||||||
components: {VueTypeaheadBootstrap},
|
|
||||||
name: "TransactionCategory",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
categories: [],
|
|
||||||
initialSet: [],
|
|
||||||
category: this.value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted: function () {
|
|
||||||
this.$nextTick(function () {
|
|
||||||
this.$refs.input.$refs.input.tabIndex = 10;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
//console.log('Created category(' + this.index + ') "' + this.value + '"');
|
|
||||||
// initial list of accounts:
|
|
||||||
axios.get(this.getACURL(''))
|
|
||||||
.then(response => {
|
|
||||||
this.categories = response.data;
|
|
||||||
this.initialSet = response.data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
clearCategory: function () {
|
|
||||||
this.category = '';
|
|
||||||
},
|
|
||||||
getACURL: function (query) {
|
|
||||||
// update autocomplete URL:
|
|
||||||
// console.log('getACURL("' + query + '")');
|
|
||||||
return document.getElementsByTagName('base')[0].href + 'api/v1/autocomplete/categories?query=' + query;
|
|
||||||
},
|
|
||||||
lookupCategory: debounce(function () {
|
|
||||||
// update autocomplete URL:
|
|
||||||
//console.log('Do a search for "'+this.category+'"');
|
|
||||||
axios.get(this.getACURL(this.category))
|
|
||||||
.then(response => {
|
|
||||||
this.categories = response.data;
|
|
||||||
})
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
value: function (value) {
|
|
||||||
this.category = value ?? '';
|
|
||||||
},
|
|
||||||
category: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'category', index: this.index, value: value});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
selectedCategory: {
|
|
||||||
get() {
|
|
||||||
return this.categories[this.index].name;
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
this.category = value.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionCustomDates.vue
|
|
||||||
- Copyright (c) 2021 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>
|
|
||||||
<div v-for="(enabled, name) in availableFields" class="form-group">
|
|
||||||
<div v-if="enabled && isDateField(name)" class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('form.' + name) }}
|
|
||||||
</div>
|
|
||||||
<div v-if="enabled && isDateField(name)" class="input-group">
|
|
||||||
<input
|
|
||||||
:ref="name"
|
|
||||||
:name="name + '[]'"
|
|
||||||
:placeholder="$t('form.' + name)"
|
|
||||||
:title="$t('form.' + name)"
|
|
||||||
:value="getFieldValue(name)"
|
|
||||||
autocomplete="off"
|
|
||||||
class="form-control"
|
|
||||||
type="date"
|
|
||||||
@change="setFieldValue($event, name)"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "TransactionCustomDates",
|
|
||||||
props: [
|
|
||||||
'index',
|
|
||||||
'errors',
|
|
||||||
'customFields',
|
|
||||||
'interestDate',
|
|
||||||
'bookDate',
|
|
||||||
'processDate',
|
|
||||||
'dueDate',
|
|
||||||
'paymentDate',
|
|
||||||
'invoiceDate'
|
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
dateFields: ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'],
|
|
||||||
availableFields: this.customFields,
|
|
||||||
dates: {
|
|
||||||
interest_date: this.interestDate,
|
|
||||||
book_date: this.bookDate,
|
|
||||||
process_date: this.processDate,
|
|
||||||
due_date: this.dueDate,
|
|
||||||
payment_date: this.paymentDate,
|
|
||||||
invoice_date: this.invoiceDate,
|
|
||||||
}
|
|
||||||
,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
customFields: function (value) {
|
|
||||||
this.availableFields = value;
|
|
||||||
},
|
|
||||||
interestDate: function (value) {
|
|
||||||
this.dates.interest_date = value;
|
|
||||||
},
|
|
||||||
bookDate: function (value) {
|
|
||||||
this.dates.book_date = value;
|
|
||||||
},
|
|
||||||
processDate: function (value) {
|
|
||||||
this.dates.process_date = value;
|
|
||||||
},
|
|
||||||
dueDate: function (value) {
|
|
||||||
this.dates.due_date = value;
|
|
||||||
},
|
|
||||||
paymentDate: function (value) {
|
|
||||||
this.dates.payment_date = value;
|
|
||||||
},
|
|
||||||
invoiceDate: function (value) {
|
|
||||||
this.dates.invoice_date = value;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
isDateField: function (name) {
|
|
||||||
return this.dateFields.includes(name)
|
|
||||||
},
|
|
||||||
getFieldValue(field) {
|
|
||||||
return this.dates[field] ?? '';
|
|
||||||
},
|
|
||||||
setFieldValue(event, field) {
|
|
||||||
this.$emit('set-field', {field: field, index: this.index, value: event.target.value});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionDate.vue
|
|
||||||
- Copyright (c) 2020 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-if="0===index">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.date_and_time') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
ref="date"
|
|
||||||
v-model="dateStr"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="dateStr"
|
|
||||||
:title="$t('firefly.date')"
|
|
||||||
autocomplete="off"
|
|
||||||
name="date[]"
|
|
||||||
type="date"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
ref="time"
|
|
||||||
v-model="timeStr"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="timeStr"
|
|
||||||
:title="$t('firefly.time')"
|
|
||||||
autocomplete="off"
|
|
||||||
name="time[]"
|
|
||||||
type="time"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
<span class="text-muted small">{{ localTimeZone }}:{{ systemTimeZone }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import {mapGetters} from "vuex";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: ['index', 'errors', 'date'],
|
|
||||||
name: "TransactionDate",
|
|
||||||
created() {
|
|
||||||
this.localTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
||||||
this.systemTimeZone = this.timezone;
|
|
||||||
// console.log('TransactionDate: ' + this.date);
|
|
||||||
// split date and time:
|
|
||||||
let parts = this.date.split('T');
|
|
||||||
this.dateStr = parts[0];
|
|
||||||
this.timeStr = parts[1];
|
|
||||||
},
|
|
||||||
mounted: function () {
|
|
||||||
this.$nextTick(function () {
|
|
||||||
this.$refs.date.tabIndex = 6;
|
|
||||||
this.$refs.time.tabIndex = 7;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
localDate: this.date,
|
|
||||||
localTimeZone: '',
|
|
||||||
systemTimeZone: '',
|
|
||||||
timeStr: '',
|
|
||||||
dateStr: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
dateStr: function (value) {
|
|
||||||
this.$emit('set-date', {date: value + 'T' + this.timeStr});
|
|
||||||
},
|
|
||||||
timeStr: function (value) {
|
|
||||||
this.$emit('set-date', {date: this.dateStr + 'T' + value});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('root', ['timezone']),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionDescription.vue
|
|
||||||
- Copyright (c) 2020 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">
|
|
||||||
<vue-typeahead-bootstrap
|
|
||||||
v-model="description"
|
|
||||||
:data="descriptions"
|
|
||||||
:inputClass="errors.length > 0 ? 'is-invalid' : ''"
|
|
||||||
:minMatchingChars="3"
|
|
||||||
:placeholder="$t('firefly.description')"
|
|
||||||
:serializer="item => item.description"
|
|
||||||
:showOnFocus=true
|
|
||||||
autofocus
|
|
||||||
tabindex="1"
|
|
||||||
ref="autoComplete"
|
|
||||||
inputName="description[]"
|
|
||||||
@input="lookupDescription"
|
|
||||||
>
|
|
||||||
<template slot="append">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" tabindex="-1" type="button" v-on:click="clearDescription"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</vue-typeahead-bootstrap>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import VueTypeaheadBootstrap from 'vue-typeahead-bootstrap';
|
|
||||||
import {debounce} from "lodash";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: ['index', 'value', 'errors'],
|
|
||||||
components: {VueTypeaheadBootstrap},
|
|
||||||
name: "TransactionDescription",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
descriptions: [],
|
|
||||||
initialSet: [],
|
|
||||||
description: this.value,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
axios.get(this.getACURL(''))
|
|
||||||
.then(response => {
|
|
||||||
this.descriptions = response.data;
|
|
||||||
this.initialSet = response.data;
|
|
||||||
this.$refs.autoComplete.$refs.input.tabIndex = 1;
|
|
||||||
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
clearDescription: function () {
|
|
||||||
this.description = '';
|
|
||||||
},
|
|
||||||
getACURL: function (query) {
|
|
||||||
// update autocomplete URL:
|
|
||||||
return document.getElementsByTagName('base')[0].href + 'api/v1/autocomplete/transactions?query=' + query;
|
|
||||||
},
|
|
||||||
lookupDescription: debounce(function () {
|
|
||||||
// update autocomplete URL:
|
|
||||||
axios.get(this.getACURL(this.value))
|
|
||||||
.then(response => {
|
|
||||||
this.descriptions = response.data;
|
|
||||||
})
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
value: function (value) {
|
|
||||||
this.description = value;
|
|
||||||
},
|
|
||||||
description: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'description', index: this.index, value: value});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionInternalReference.vue
|
|
||||||
- Copyright (c) 2021 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="showField" class="form-group">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.external_url') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
v-model="url"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="$t('firefly.external_url')"
|
|
||||||
name="external_url[]"
|
|
||||||
type="url"
|
|
||||||
/>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" tabindex="-1" type="button"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: ['index', 'value', 'errors', 'customFields'],
|
|
||||||
name: "TransactionExternalUrl",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
url: this.value,
|
|
||||||
availableFields: this.customFields,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
showField: function () {
|
|
||||||
if ('external_uri' in this.availableFields) {
|
|
||||||
return this.availableFields.external_uri;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {},
|
|
||||||
watch: {
|
|
||||||
customFields: function (value) {
|
|
||||||
this.availableFields = value;
|
|
||||||
},
|
|
||||||
value: function (value) {
|
|
||||||
this.url = value;
|
|
||||||
},
|
|
||||||
url: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'external_url', index: this.index, value: value});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionForeignAmount.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<!-- FOREIGN AMOUNT -->
|
|
||||||
<div v-if="isVisible" class="form-group">
|
|
||||||
<div class="text-xs">{{ $t('form.foreign_amount') }}</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
v-model="amount"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="$t('form.foreign_amount')"
|
|
||||||
:title="$t('form.foreign_amount')"
|
|
||||||
autocomplete="off"
|
|
||||||
name="foreign_amount[]"
|
|
||||||
type="number"
|
|
||||||
ref="input"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "TransactionForeignAmount",
|
|
||||||
props: {
|
|
||||||
index: {},
|
|
||||||
errors: {},
|
|
||||||
value: {},
|
|
||||||
transactionType: {},
|
|
||||||
sourceCurrencyId: {},
|
|
||||||
destinationCurrencyId: {},
|
|
||||||
fractionDigits: {
|
|
||||||
type: Number,
|
|
||||||
default: 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
amount: this.value,
|
|
||||||
emitEvent: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
if ('' !== this.amount) {
|
|
||||||
this.emitEvent = false;
|
|
||||||
this.amount = this.formatNumber(this.amount);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted: function () {
|
|
||||||
this.$nextTick(function () {
|
|
||||||
this.$refs.input.tabIndex = 5;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
formatNumber(str) {
|
|
||||||
return parseFloat(str).toFixed(this.fractionDigits);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
amount: function (value) {
|
|
||||||
if (true === this.emitEvent) {
|
|
||||||
this.$emit('set-field', {field: 'foreign_amount', index: this.index, value: value});
|
|
||||||
}
|
|
||||||
this.emitEvent = true;
|
|
||||||
},
|
|
||||||
value: function (value) {
|
|
||||||
this.amount = value;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
isVisible: {
|
|
||||||
get() {
|
|
||||||
return !('transfer' === this.transactionType.toLowerCase() && parseInt(this.sourceCurrencyId) === parseInt(this.destinationCurrencyId));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionForeignCurrency.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<!-- FOREIGN Currency -->
|
|
||||||
<div v-if="isVisible" class="form-group">
|
|
||||||
<div class="text-xs"> </div>
|
|
||||||
<div class="input-group">
|
|
||||||
<select v-model="selectedCurrency" class="form-control" ref="input" name="foreign_currency_id[]">
|
|
||||||
<option v-for="currency in selectableCurrencies" :label="currency.name" :value="currency.id">{{ currency.name }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "TransactionForeignCurrency",
|
|
||||||
props: [
|
|
||||||
'index',
|
|
||||||
'transactionType',
|
|
||||||
'sourceCurrencyId',
|
|
||||||
'destinationCurrencyId',
|
|
||||||
'selectedCurrencyId',
|
|
||||||
'value'
|
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectedCurrency: this.value,
|
|
||||||
allCurrencies: [],
|
|
||||||
selectableCurrencies: [],
|
|
||||||
dstCurrencyId: this.destinationCurrencyId,
|
|
||||||
srcCurrencyId: this.sourceCurrencyId,
|
|
||||||
lockedCurrency: 0,
|
|
||||||
emitEvent: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
value: function (value) {
|
|
||||||
this.selectedCurrency = value;
|
|
||||||
},
|
|
||||||
sourceCurrencyId: function (value) {
|
|
||||||
// console.log('Watch sourceCurrencyId');
|
|
||||||
this.srcCurrencyId = value;
|
|
||||||
this.lockCurrency();
|
|
||||||
},
|
|
||||||
destinationCurrencyId: function (value) {
|
|
||||||
// console.log('Watch destinationCurrencyId');
|
|
||||||
this.dstCurrencyId = value;
|
|
||||||
this.lockCurrency();
|
|
||||||
},
|
|
||||||
selectedCurrency: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'foreign_currency_id', index: this.index, value: value});
|
|
||||||
},
|
|
||||||
transactionType: function (value) {
|
|
||||||
this.lockCurrency();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created: function () {
|
|
||||||
// console.log('Created TransactionForeignCurrency');
|
|
||||||
this.getAllCurrencies();
|
|
||||||
},
|
|
||||||
mounted: function () {
|
|
||||||
this.$nextTick(function () {
|
|
||||||
this.$refs.input.tabIndex = 4;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
lockCurrency: function () {
|
|
||||||
// console.log('Lock currency (' + this.transactionType + ')');
|
|
||||||
this.lockedCurrency = 0;
|
|
||||||
if ('transfer' === this.transactionType.toLowerCase()) {
|
|
||||||
// console.log('IS a transfer!');
|
|
||||||
this.lockedCurrency = parseInt(this.dstCurrencyId);
|
|
||||||
this.selectedCurrency = parseInt(this.dstCurrencyId);
|
|
||||||
}
|
|
||||||
this.filterCurrencies();
|
|
||||||
},
|
|
||||||
getAllCurrencies: function () {
|
|
||||||
axios.get('./api/v1/autocomplete/currencies')
|
|
||||||
.then(response => {
|
|
||||||
this.allCurrencies = response.data;
|
|
||||||
this.filterCurrencies();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
},
|
|
||||||
filterCurrencies() {
|
|
||||||
// console.log('filterCurrencies');
|
|
||||||
// console.log(this.lockedCurrency);
|
|
||||||
// if a currency is locked only that currency can (and must) be selected:
|
|
||||||
if (0 !== this.lockedCurrency) {
|
|
||||||
// console.log('Here we are');
|
|
||||||
for (let key in this.allCurrencies) {
|
|
||||||
if (this.allCurrencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
|
||||||
let current = this.allCurrencies[key];
|
|
||||||
if (parseInt(current.id) === this.lockedCurrency) {
|
|
||||||
this.selectableCurrencies = [current];
|
|
||||||
this.selectedCurrency = current.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if source + dest ID are the same, skip the whole field.
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selectableCurrencies = [
|
|
||||||
{
|
|
||||||
"id": 0,
|
|
||||||
"name": this.$t('firefly.no_currency')
|
|
||||||
}
|
|
||||||
];
|
|
||||||
for (let key in this.allCurrencies) {
|
|
||||||
if (this.allCurrencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
|
||||||
let current = this.allCurrencies[key];
|
|
||||||
this.selectableCurrencies.push(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
isVisible: function () {
|
|
||||||
return !('transfer' === this.transactionType.toLowerCase() && parseInt(this.srcCurrencyId) === parseInt(this.dstCurrencyId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionGroupTitle.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.split_transaction_title') }}
|
|
||||||
</div>
|
|
||||||
<vue-typeahead-bootstrap
|
|
||||||
v-model="title"
|
|
||||||
:data="descriptions"
|
|
||||||
:inputClass="errors.length > 0 ? 'is-invalid' : ''"
|
|
||||||
:minMatchingChars="3"
|
|
||||||
:placeholder="$t('firefly.split_transaction_title')"
|
|
||||||
:serializer="item => item.description"
|
|
||||||
:showOnFocus=true
|
|
||||||
inputName="group_title"
|
|
||||||
@input="lookupDescription"
|
|
||||||
>
|
|
||||||
<template slot="append">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" tabindex="-1" type="button" v-on:click="clearDescription"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</vue-typeahead-bootstrap>
|
|
||||||
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import VueTypeaheadBootstrap from 'vue-typeahead-bootstrap';
|
|
||||||
import {debounce} from "lodash";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: ['value', 'errors'],
|
|
||||||
name: "TransactionGroupTitle",
|
|
||||||
components: {VueTypeaheadBootstrap},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
descriptions: [],
|
|
||||||
initialSet: [],
|
|
||||||
title: this.value,
|
|
||||||
emitEvent: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
axios.get(this.getACURL(''))
|
|
||||||
.then(response => {
|
|
||||||
this.descriptions = response.data;
|
|
||||||
this.initialSet = response.data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
value: function (value) {
|
|
||||||
this.title = value;
|
|
||||||
},
|
|
||||||
title: function (value) {
|
|
||||||
this.$emit('set-group-title', value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
clearDescription: function () {
|
|
||||||
this.title = '';
|
|
||||||
},
|
|
||||||
getACURL: function (query) {
|
|
||||||
// update autocomplete URL:
|
|
||||||
return document.getElementsByTagName('base')[0].href + 'api/v1/autocomplete/transactions?query=' + query;
|
|
||||||
},
|
|
||||||
lookupDescription: debounce(function () {
|
|
||||||
// update autocomplete URL:
|
|
||||||
axios.get(this.getACURL(this.title))
|
|
||||||
.then(response => {
|
|
||||||
this.descriptions = response.data;
|
|
||||||
})
|
|
||||||
}, 300)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionInternalReference.vue
|
|
||||||
- Copyright (c) 2021 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="showField" class="form-group">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.internal_reference') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
v-model="reference"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="$t('firefly.internal_reference')"
|
|
||||||
name="internal_reference[]"
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" tabindex="-1" type="button"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: ['index', 'value', 'errors', 'customFields'],
|
|
||||||
name: "TransactionInternalReference",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
reference: this.value,
|
|
||||||
availableFields: this.customFields,
|
|
||||||
emitEvent: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
showField: function () {
|
|
||||||
if ('internal_reference' in this.availableFields) {
|
|
||||||
return this.availableFields.internal_reference;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {},
|
|
||||||
watch: {
|
|
||||||
customFields: function (value) {
|
|
||||||
this.availableFields = value;
|
|
||||||
},
|
|
||||||
value: function (value) {
|
|
||||||
this.emitEvent = false;
|
|
||||||
this.reference = value;
|
|
||||||
},
|
|
||||||
reference: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'internal_reference', index: this.index, value: value});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,390 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionLinks.vue
|
|
||||||
- Copyright (c) 2021 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="showField">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.journal_links') }}
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<p v-if="links.length === 0">
|
|
||||||
<button type="button" class="btn btn-default btn-xs" data-target="#linkModal" @click="resetModal" data-toggle="modal"><span class="fas fa-plus"></span> Add transaction link</button>
|
|
||||||
</p>
|
|
||||||
<ul v-if="links.length > 0" class="list-group">
|
|
||||||
<li v-for="(transaction, index) in links" class="list-group-item" v-bind:key="index">
|
|
||||||
<em>{{ getTextForLinkType(transaction.link_type_id) }}</em>
|
|
||||||
<a :href='"./transaction/show/" + transaction.transaction_group_id'>{{ transaction.description }}</a>
|
|
||||||
|
|
||||||
<span v-if="transaction.type === 'withdrawal'">
|
|
||||||
(<span class="text-danger">{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency',
|
|
||||||
currency: transaction.currency_code
|
|
||||||
}).format(parseFloat(transaction.amount) * -1)
|
|
||||||
}}</span>)
|
|
||||||
</span>
|
|
||||||
<span v-if="transaction.type === 'deposit'">
|
|
||||||
(<span class="text-success">{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency',
|
|
||||||
currency: transaction.currency_code
|
|
||||||
}).format(parseFloat(transaction.amount))
|
|
||||||
}}</span>)
|
|
||||||
</span>
|
|
||||||
<span v-if="transaction.type === 'transfer'">
|
|
||||||
(<span class="text-info">{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency',
|
|
||||||
currency: transaction.currency_code
|
|
||||||
}).format(parseFloat(transaction.amount))
|
|
||||||
}}</span>)
|
|
||||||
</span>
|
|
||||||
<div class="btn-group btn-group-xs float-right">
|
|
||||||
<button type="button" class="btn btn-xs btn-danger" @click="removeLink(index)" tabindex="-1"><span class="far fa-trash-alt"></span></button>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div v-if="links.length > 0" class="form-text">
|
|
||||||
<button type="button" class="btn btn-default" @click="resetModal" data-target="#linkModal" data-toggle="modal"><span class="fas fa-plus"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- modal -->
|
|
||||||
<div id="linkModal" class="modal" tabindex="-1" ref="linkModal">
|
|
||||||
<div class="modal-dialog modal-lg">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title">Transaction thing dialog.</h5>
|
|
||||||
<button aria-label="Close" class="close" data-dismiss="modal" type="button">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<p>
|
|
||||||
Use this form to search for transactions you wish to link to this one. When in doubt, use <code>id:*</code> where the ID is the number from
|
|
||||||
the URL.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<form v-on:submit.prevent="search" autocomplete="off">
|
|
||||||
<div class="input-group">
|
|
||||||
<input id="query" v-model="query" autocomplete="off" class="form-control" maxlength="255" name="search"
|
|
||||||
placeholder="Search query" type="text">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-default" type="submit"><span class="fas fa-search"></span> Search</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<span v-if="searching"><span class="fas fa-spinner fa-spin"></span></span>
|
|
||||||
<h4 v-if="searchResults.length > 0">{{ $t('firefly.search_results') }}</h4>
|
|
||||||
<table v-if="searchResults.length > 0" class="table table-sm">
|
|
||||||
<caption style="display:none;">{{ $t('firefly.search_results') }}</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col" colspan="2" style="width:33%">{{ $t('firefly.include') }}</th>
|
|
||||||
<th scope="col">{{ $t('firefly.transaction') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="result in searchResults">
|
|
||||||
<td>
|
|
||||||
<input v-model="result.selected" class="form-control"
|
|
||||||
type="checkbox"
|
|
||||||
@change="selectTransaction($event)"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<select
|
|
||||||
v-model="result.link_type_id"
|
|
||||||
class="form-control"
|
|
||||||
@change="selectLinkType($event)"
|
|
||||||
>
|
|
||||||
<option v-for="linkType in linkTypes" :label="linkType.type" :value="linkType.id + '-' + linkType.direction">{{
|
|
||||||
linkType.type
|
|
||||||
}}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a :href="'./transactions/show/' + result.transaction_group_id">{{ result.description }}</a>
|
|
||||||
<span v-if="result.type === 'withdrawal'">
|
|
||||||
(<span class="text-danger">{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency',
|
|
||||||
currency: result.currency_code
|
|
||||||
}).format(parseFloat(result.amount) * -1)
|
|
||||||
}}</span>)
|
|
||||||
</span>
|
|
||||||
<span v-if="result.type === 'deposit'">
|
|
||||||
(<span class="text-success">{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency',
|
|
||||||
currency: result.currency_code
|
|
||||||
}).format(parseFloat(result.amount))
|
|
||||||
}}</span>)
|
|
||||||
</span>
|
|
||||||
<span v-if="result.type === 'transfer'">
|
|
||||||
(<span class="text-info">{{
|
|
||||||
Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency',
|
|
||||||
currency: result.currency_code
|
|
||||||
}).format(parseFloat(result.amount))
|
|
||||||
}}</span>)
|
|
||||||
</span>
|
|
||||||
<br/>
|
|
||||||
<em>
|
|
||||||
<a :href="'./accounts/show/' + result.source_id">{{ result.source_name }}</a>
|
|
||||||
→
|
|
||||||
<a :href="'./accounts/show/' + result.destination_id">{{ result.destination_name }}</a>
|
|
||||||
</em>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button class="btn btn-secondary" data-dismiss="modal" type="button">Close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const lodashClonedeep = require('lodash.clonedeep');
|
|
||||||
// See reference nr. 3
|
|
||||||
export default {
|
|
||||||
props: ['index', 'value', 'errors', 'customFields'],
|
|
||||||
name: "TransactionLinks",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
searchResults: [],
|
|
||||||
include: [],
|
|
||||||
locale: 'en-US',
|
|
||||||
linkTypes: [],
|
|
||||||
query: '',
|
|
||||||
searching: false,
|
|
||||||
links: this.value,
|
|
||||||
availableFields: this.customFields,
|
|
||||||
emitEvent: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
this.emitEvent = false;
|
|
||||||
this.links = lodashClonedeep(this.value);
|
|
||||||
this.getLinkTypes();
|
|
||||||
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
showField: function () {
|
|
||||||
if ('links' in this.availableFields) {
|
|
||||||
return this.availableFields.links;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
value: function (value) {
|
|
||||||
if (null !== value) {
|
|
||||||
this.emitEvent = false;
|
|
||||||
this.links = lodashClonedeep(value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
links: function (value) {
|
|
||||||
if (true === this.emitEvent) {
|
|
||||||
this.$emit('set-field', {index: this.index, field: 'links', value: lodashClonedeep(value)});
|
|
||||||
}
|
|
||||||
this.emitEvent = true;
|
|
||||||
},
|
|
||||||
customFields: function (value) {
|
|
||||||
this.availableFields = value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
removeLink: function (index) {
|
|
||||||
this.links.splice(index, 1);
|
|
||||||
},
|
|
||||||
getTextForLinkType: function (linkTypeId) {
|
|
||||||
let parts = linkTypeId.split('-');
|
|
||||||
for (let i in this.linkTypes) {
|
|
||||||
if (this.linkTypes.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = this.linkTypes[i];
|
|
||||||
if (parts[0] === current.id && parts[1] === current.direction) {
|
|
||||||
return current.type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 'text for #' + linkTypeId;
|
|
||||||
},
|
|
||||||
selectTransaction: function (event) {
|
|
||||||
for (let i in this.searchResults) {
|
|
||||||
if (this.searchResults.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = this.searchResults[i];
|
|
||||||
if (current.selected) {
|
|
||||||
this.addToSelected(current);
|
|
||||||
}
|
|
||||||
if (!current.selected) {
|
|
||||||
// remove from
|
|
||||||
this.removeFromSelected(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectLinkType: function (event) {
|
|
||||||
for (let i in this.searchResults) {
|
|
||||||
if (this.searchResults.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = this.searchResults[i];
|
|
||||||
this.updateSelected(current.transaction_journal_id, current.link_type_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updateSelected(journalId, linkTypeId) {
|
|
||||||
for (let i in this.links) {
|
|
||||||
if (this.links.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = this.links[i];
|
|
||||||
if (parseInt(current.transaction_journal_id) === journalId) {
|
|
||||||
this.links[i].link_type_id = linkTypeId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addToSelected(journal) {
|
|
||||||
let result = this.links.find(({transaction_journal_id}) => transaction_journal_id === journal.transaction_journal_id);
|
|
||||||
if (typeof result === 'undefined') {
|
|
||||||
this.links.push(journal);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeFromSelected(journal) {
|
|
||||||
for (let i in this.links) {
|
|
||||||
if (this.links.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = this.links[i];
|
|
||||||
if (current.transaction_journal_id === journal.transaction_journal_id) {
|
|
||||||
this.links.splice(parseInt(i), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getLinkTypes: function () {
|
|
||||||
let url = './api/v1/link_types';
|
|
||||||
axios.get(url)
|
|
||||||
.then(response => {
|
|
||||||
this.parseLinkTypes(response.data);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
resetModal: function() {
|
|
||||||
this.search();
|
|
||||||
},
|
|
||||||
parseLinkTypes: function (data) {
|
|
||||||
for (let i in data.data) {
|
|
||||||
if (data.data.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = data.data[i];
|
|
||||||
let linkTypeInward = {
|
|
||||||
id: current.id,
|
|
||||||
type: current.attributes.inward,
|
|
||||||
direction: 'inward'
|
|
||||||
};
|
|
||||||
let linkTypeOutward = {
|
|
||||||
id: current.id,
|
|
||||||
type: current.attributes.outward,
|
|
||||||
direction: 'outward'
|
|
||||||
};
|
|
||||||
if (linkTypeInward.type === linkTypeOutward.type) {
|
|
||||||
linkTypeInward.type = linkTypeInward.type + ' (←)';
|
|
||||||
linkTypeOutward.type = linkTypeOutward.type + ' (→)';
|
|
||||||
}
|
|
||||||
this.linkTypes.push(linkTypeInward);
|
|
||||||
this.linkTypes.push(linkTypeOutward);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
search: function () {
|
|
||||||
if('' === this.query) {
|
|
||||||
this.searchResults = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.searching = true;
|
|
||||||
this.searchResults = [];
|
|
||||||
let url = './api/v1/search/transactions?limit=10&query=' + this.query;
|
|
||||||
axios.get(url)
|
|
||||||
.then(response => {
|
|
||||||
this.parseSearch(response.data);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
parseSearch: function (data) {
|
|
||||||
for (let i in data.data) {
|
|
||||||
if (data.data.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
for (let ii in data.data[i].attributes.transactions) {
|
|
||||||
if (data.data[i].attributes.transactions.hasOwnProperty(ii) && /^0$|^[1-9]\d*$/.test(ii) && ii <= 4294967294) {
|
|
||||||
let current = data.data[i].attributes.transactions[ii];
|
|
||||||
current.transaction_group_id = parseInt(data.data[i].id);
|
|
||||||
current.selected = this.isJournalSelected(current.transaction_journal_id);
|
|
||||||
current.link_type_id = this.getJournalLinkType(current.transaction_journal_id);
|
|
||||||
current.link_type_text = '';
|
|
||||||
this.searchResults.push(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.searching = false;
|
|
||||||
},
|
|
||||||
getJournalLinkType: function (journalId) {
|
|
||||||
for (let i in this.links) {
|
|
||||||
if (this.links.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = this.links[i];
|
|
||||||
if (current.transaction_journal_id === journalId) {
|
|
||||||
return current.link_type_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '1-inward';
|
|
||||||
},
|
|
||||||
isJournalSelected: function (journalId) {
|
|
||||||
for (let i in this.links) {
|
|
||||||
if (this.links.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
let current = this.links[i];
|
|
||||||
if (current.transaction_journal_id === journalId) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,435 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionListLarge.vue
|
|
||||||
- Copyright (c) 2020 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>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-8 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
<BPagination v-if="!loading"
|
|
||||||
v-model="currentPage"
|
|
||||||
:total-rows="total"
|
|
||||||
:per-page="perPage"
|
|
||||||
aria-controls="my-table"
|
|
||||||
></BPagination>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
<button @click="newCacheKey" class="btn btn-sm float-right btn-info"><span class="fas fa-sync"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body p-0">
|
|
||||||
<BTable id="my-table" small striped hover responsive="md" primary-key="key" :no-local-sorting="false"
|
|
||||||
:items="transactions"
|
|
||||||
:fields="fields"
|
|
||||||
:per-page="perPage"
|
|
||||||
sort-icon-left
|
|
||||||
ref="table"
|
|
||||||
:current-page="currentPage"
|
|
||||||
:busy.sync="loading"
|
|
||||||
:sort-desc.sync="sortDesc"
|
|
||||||
:sort-compare="tableSortCompare"
|
|
||||||
>
|
|
||||||
<template #table-busy>
|
|
||||||
<span class="fa fa-spinner fa-spin"></span>
|
|
||||||
</template>
|
|
||||||
<template #cell(type)="data">
|
|
||||||
<span v-if="!data.item.dummy">
|
|
||||||
<span class="fas fa-long-arrow-alt-right" v-if="'deposit' === data.item.type.toLowerCase()"></span>
|
|
||||||
<span class="fas fa-long-arrow-alt-left" v-if="'withdrawal' === data.item.type.toLowerCase()"></span>
|
|
||||||
<span class="fas fa-arrows-alt-h" v-if="'transfer' === data.item.type.toLowerCase()"></span>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #cell(description)="data">
|
|
||||||
<span class="fa fa-spinner fa-spin" v-if="data.item.dummy"></span>
|
|
||||||
<span v-if="!data.item.split">
|
|
||||||
<span v-if="data.item.hasAttachments" class="fas fa-paperclip"></span>
|
|
||||||
<a :href="'./transactions/show/' + data.item.id" :title="data.value">
|
|
||||||
{{ data.item.description }}
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span v-if="data.item.split">
|
|
||||||
<!-- title first -->
|
|
||||||
<span class="fas fa-angle-right" @click="toggleCollapse(data.item.id)" style="cursor: pointer;"></span>
|
|
||||||
<span v-if="data.item.hasAttachments" class="fas fa-paperclip"></span>
|
|
||||||
<a :href="'./transactions/show/' + data.item.id" :title="data.value">
|
|
||||||
{{ data.item.description }}
|
|
||||||
</a><br/>
|
|
||||||
<span v-if="!data.item.collapsed">
|
|
||||||
<span v-for="(split, index) in data.item.splits" v-bind:key="index">
|
|
||||||
{{ split.description }}<br/>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #cell(amount)="data">
|
|
||||||
<!-- row amount first (3x) -->
|
|
||||||
<span :class="'text-success ' + (!data.item.collapsed ? 'font-weight-bold' : '')" v-if="'deposit' === data.item.type">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: data.item.currency_code}).format(data.item.amount) }}
|
|
||||||
</span>
|
|
||||||
<span :class="'text-danger ' + (!data.item.collapsed ? 'font-weight-bold' : '')" v-if="'withdrawal' === data.item.type">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: data.item.currency_code}).format(-data.item.amount) }}
|
|
||||||
</span>
|
|
||||||
<span :class="'text-muted ' + (!data.item.collapsed ? 'font-weight-bold' : '')" v-if="'transfer' === data.item.type.toLowerCase()">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: data.item.currency_code}).format(data.item.amount) }}
|
|
||||||
</span>
|
|
||||||
<br/>
|
|
||||||
<!-- splits -->
|
|
||||||
<span v-if="!data.item.collapsed">
|
|
||||||
<span v-for="(split, index) in data.item.splits" v-bind:key="index">
|
|
||||||
{{ Intl.NumberFormat(locale, {style: 'currency', currency: split.currency_code}).format(split.amount) }}<br/>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #cell(date)="data">
|
|
||||||
{{ data.item.date_formatted }}
|
|
||||||
</template>
|
|
||||||
<template #cell(source_account)="data">
|
|
||||||
<!-- extra break for splits -->
|
|
||||||
<span v-if="true===data.item.split && !data.item.collapsed">
|
|
||||||
<br/>
|
|
||||||
</span>
|
|
||||||
<em v-if="true===data.item.split && data.item.collapsed">
|
|
||||||
...
|
|
||||||
</em>
|
|
||||||
|
|
||||||
<!-- loop all accounts, hidden if split -->
|
|
||||||
<span v-for="(split, index) in data.item.splits" v-bind:key="index"
|
|
||||||
v-if="false===data.item.split || (true===data.item.split && !data.item.collapsed)">
|
|
||||||
<a :href="'./accounts/show/' + split.source_id" :title="split.source_name">{{ split.source_name }}</a><br/>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #cell(destination_account)="data">
|
|
||||||
<!-- extra break for splits -->
|
|
||||||
<span v-if="true===data.item.split && !data.item.collapsed">
|
|
||||||
<br/>
|
|
||||||
</span>
|
|
||||||
<em v-if="true===data.item.split && data.item.collapsed">
|
|
||||||
...
|
|
||||||
</em>
|
|
||||||
|
|
||||||
<!-- loop all accounts, hidden if split -->
|
|
||||||
<span v-for="(split, index) in data.item.splits" v-bind:key="index"
|
|
||||||
v-if="false===data.item.split || (true===data.item.split && !data.item.collapsed)">
|
|
||||||
<a :href="'./accounts/show/' + split.destination_id" :title="split.destination_name">{{ split.destination_name }}</a><br/>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #cell(menu)="data">
|
|
||||||
<div class="btn-group btn-group-sm">
|
|
||||||
<div class="dropdown">
|
|
||||||
<button class="btn btn-light btn-sm dropdown-toggle" type="button" :id="'dropdownMenuButton' + data.item.id" data-toggle="dropdown"
|
|
||||||
aria-haspopup="true" aria-expanded="false">
|
|
||||||
{{ $t('firefly.actions') }}
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" :aria-labelledby="'dropdownMenuButton' + data.item.id">
|
|
||||||
<a class="dropdown-item" :href="'./transactions/edit/' + data.item.id"><span class="fa fas fa-pencil-alt"></span> {{
|
|
||||||
$t('firefly.edit')
|
|
||||||
}}</a>
|
|
||||||
<a class="dropdown-item" :href="'./transactions/delete/' + data.item.id"><span class="fa far fa-trash"></span> {{
|
|
||||||
$t('firefly.delete')
|
|
||||||
}}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #cell(category_name)="data">
|
|
||||||
<!-- extra break for splits -->
|
|
||||||
<span v-if="true===data.item.split && !data.item.collapsed">
|
|
||||||
<br/>
|
|
||||||
</span>
|
|
||||||
<em v-if="true===data.item.split && data.item.collapsed">
|
|
||||||
...
|
|
||||||
</em>
|
|
||||||
|
|
||||||
<!-- loop all categories, hidden if split -->
|
|
||||||
<span v-for="(split, index) in data.item.splits" v-bind:key="index"
|
|
||||||
v-if="false===data.item.split || (true===data.item.split && !data.item.collapsed)">
|
|
||||||
<a :href="'./categories/show/' + split.category_id" :title="split.category_name">{{ split.category_name }}</a><br/>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</BTable>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="card-footer"> (button)
|
|
||||||
<a :href="'./transactions/create/TODO'" class="btn btn-success"
|
|
||||||
:title="$t('firefly.create_new_transaction')">{{ $t('firefly.create_new_transaction') }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-8 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
<BPagination
|
|
||||||
v-model="currentPage"
|
|
||||||
:total-rows="total"
|
|
||||||
:per-page="perPage"
|
|
||||||
aria-controls="my-table"
|
|
||||||
></BPagination>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
<button @click="newCacheKey" class="btn btn-sm float-right btn-info"><span class="fas fa-sync"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {mapGetters, mapMutations} from "vuex";
|
|
||||||
import {BPagination, BTable} from 'bootstrap-vue';
|
|
||||||
import format from "date-fns/format";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "TransactionListLarge",
|
|
||||||
components: {BPagination, BTable},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
locale: 'en-US',
|
|
||||||
fields: [],
|
|
||||||
currentPage: 1,
|
|
||||||
transactions: [],
|
|
||||||
loading: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('root', ['listPageSize', 'cacheKey']),
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.locale = localStorage.locale ?? 'en-US';
|
|
||||||
this.updateFieldList();
|
|
||||||
//this.currentPage = this.page;
|
|
||||||
this.parseTransactions();
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
currentPage: function (value) {
|
|
||||||
// console.log('Watch currentPage go to ' + value);
|
|
||||||
this.$emit('jump-page', {page: value});
|
|
||||||
},
|
|
||||||
entries: function (value) {
|
|
||||||
// console.log('detected new transactions! (' + value.length + ')');
|
|
||||||
this.parseTransactions();
|
|
||||||
if(this.isEmpty) {
|
|
||||||
this.loading=false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// value: function (value) {
|
|
||||||
// // console.log('Watch value!');
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapMutations('root', ['refreshCacheKey',]),
|
|
||||||
parseTransactions: function () {
|
|
||||||
this.transactions = [];
|
|
||||||
// console.log('Start of parseTransactions. Count of entries is ' + this.entries.length + ' and page is ' + this.page);
|
|
||||||
// console.log('Reported total is ' + this.total);
|
|
||||||
if (0 === this.entries.length) {
|
|
||||||
// console.log('Will not render now because length is 0.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// console.log('Now have ' + this.transactions.length + ' transactions');
|
|
||||||
for (let i = 0; i < this.total; i++) {
|
|
||||||
this.transactions.push({dummy: true, type: 'x'});
|
|
||||||
// console.log('Push dummy to index ' + i);
|
|
||||||
// console.log('Now have ' + this.transactions.length + ' transactions');
|
|
||||||
}
|
|
||||||
// console.log('Generated ' + this.total + ' dummies');
|
|
||||||
// console.log('Now have ' + this.transactions.length + ' transactions');
|
|
||||||
let index = (this.page - 1) * this.perPage;
|
|
||||||
// console.log('Start index is ' + index);
|
|
||||||
for (let i in this.entries) {
|
|
||||||
let transaction = this.entries[i];
|
|
||||||
|
|
||||||
// build split
|
|
||||||
this.transactions[index] = this.parseTransaction(transaction);
|
|
||||||
// console.log('Push transaction to index ' + index);
|
|
||||||
// console.log('Now have ' + this.transactions.length + ' transactions');
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
// console.log('Added ' + this.entries.length + ' entries');
|
|
||||||
// console.log('Now have ' + this.transactions.length + ' transactions');
|
|
||||||
// console.log(this.transactions);
|
|
||||||
|
|
||||||
|
|
||||||
this.loading = false;
|
|
||||||
},
|
|
||||||
newCacheKey: function () {
|
|
||||||
this.refreshCacheKey();
|
|
||||||
// console.log('Cache key is now ' + this.cacheKey);
|
|
||||||
this.$emit('refreshed-cache-key');
|
|
||||||
},
|
|
||||||
updateFieldList: function () {
|
|
||||||
this.fields = [
|
|
||||||
{key: 'type', label: ' ', sortable: false},
|
|
||||||
{key: 'description', label: this.$t('list.description'), sortable: true},
|
|
||||||
{key: 'amount', label: this.$t('list.amount'), sortable: true},
|
|
||||||
{key: 'date', label: this.$t('list.date'), sortable: true},
|
|
||||||
{key: 'source_account', label: this.$t('list.source_account'), sortable: true},
|
|
||||||
{key: 'destination_account', label: this.$t('list.destination_account'), sortable: true},
|
|
||||||
{key: 'category_name', label: this.$t('list.category'), sortable: true},
|
|
||||||
{key: 'menu', label: ' ', sortable: false},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Parse a single transaction.
|
|
||||||
* @param transaction
|
|
||||||
*/
|
|
||||||
parseTransaction: function (transaction) {
|
|
||||||
let row = {};
|
|
||||||
|
|
||||||
// default values:
|
|
||||||
row.splits = [];
|
|
||||||
row.key = transaction.id;
|
|
||||||
row.id = transaction.id
|
|
||||||
row.dummy = false;
|
|
||||||
row.hasAttachments = false;
|
|
||||||
|
|
||||||
// pick this up from the first transaction
|
|
||||||
let first = transaction.attributes.transactions[0];
|
|
||||||
row.type = first.type;
|
|
||||||
row.date = new Date(first.date);
|
|
||||||
row.date_formatted = format(row.date, this.$t('config.month_and_day_fns'));
|
|
||||||
row.description = first.description;
|
|
||||||
row.collapsed = true;
|
|
||||||
row.split = false;
|
|
||||||
row.amount = 0;
|
|
||||||
row.currency_code = first.currency_code;
|
|
||||||
if (transaction.attributes.transactions.length > 1) {
|
|
||||||
row.split = true;
|
|
||||||
row.description = transaction.attributes.group_title;
|
|
||||||
}
|
|
||||||
|
|
||||||
// collapsed?
|
|
||||||
if (typeof transaction.collapsed !== 'undefined') {
|
|
||||||
row.collapsed = transaction.collapsed;
|
|
||||||
}
|
|
||||||
//console.log('is collapsed? ' + row.collapsed);
|
|
||||||
|
|
||||||
// then loop each split
|
|
||||||
for (let i in transaction.attributes.transactions) {
|
|
||||||
if (transaction.attributes.transactions.hasOwnProperty(i)) {
|
|
||||||
let info = transaction.attributes.transactions[i];
|
|
||||||
let split = {};
|
|
||||||
row.amount = row.amount + parseFloat(info.amount);
|
|
||||||
split.type = info.type;
|
|
||||||
split.description = info.description;
|
|
||||||
split.amount = info.amount;
|
|
||||||
split.currency_code = info.currency_code;
|
|
||||||
split.source_name = info.source_name;
|
|
||||||
split.source_id = info.source_id;
|
|
||||||
split.destination_name = info.destination_name;
|
|
||||||
split.destination_id = info.destination_id;
|
|
||||||
split.category_id = info.category_id;
|
|
||||||
split.category_name = info.category_name;
|
|
||||||
split.split_index = i;
|
|
||||||
if(true === info.has_attachments) {
|
|
||||||
row.hasAttachments = true;
|
|
||||||
}
|
|
||||||
row.splits.push(split);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return row;
|
|
||||||
},
|
|
||||||
toggleCollapse: function (id) {
|
|
||||||
let transaction = this.transactions.filter(transaction => transaction.id === id)[0];
|
|
||||||
transaction.collapsed = !transaction.collapsed;
|
|
||||||
},
|
|
||||||
tableSortCompare: function (aRow, bRow, key, sortDesc, formatter, compareOptions, compareLocale) {
|
|
||||||
let a = aRow[key]
|
|
||||||
let b = bRow[key]
|
|
||||||
|
|
||||||
if (aRow.id === bRow.id) {
|
|
||||||
// Order split transactions normally when compared to each other, except always put the header first
|
|
||||||
if (aRow.split_parent === null) {
|
|
||||||
return sortDesc ? 1 : -1;
|
|
||||||
} else if (bRow.split_parent === null) {
|
|
||||||
return sortDesc ? -1 : 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Sort split transactions based on their parent when compared to other transactions
|
|
||||||
if (aRow.split && aRow.split_parent !== null) {
|
|
||||||
a = aRow.split_parent[key]
|
|
||||||
}
|
|
||||||
if (bRow.split && bRow.split_parent !== null) {
|
|
||||||
b = bRow.split_parent[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(typeof a === 'number' && typeof b === 'number') ||
|
|
||||||
(a instanceof Date && b instanceof Date)
|
|
||||||
) {
|
|
||||||
// If both compared fields are native numbers or both are native dates
|
|
||||||
return a < b ? -1 : a > b ? 1 : 0
|
|
||||||
} else {
|
|
||||||
// Otherwise stringify the field data and use String.prototype.localeCompare
|
|
||||||
return toString(a).localeCompare(toString(b), compareLocale, compareOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
function toString(value) {
|
|
||||||
if (value === null || typeof value === 'undefined') {
|
|
||||||
return ''
|
|
||||||
} else if (value instanceof Object) {
|
|
||||||
return Object.keys(value)
|
|
||||||
.sort()
|
|
||||||
.map(key => toString(value[key]))
|
|
||||||
.join(' ')
|
|
||||||
} else {
|
|
||||||
return String(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
props: {
|
|
||||||
page: {
|
|
||||||
type: Number
|
|
||||||
},
|
|
||||||
perPage: {
|
|
||||||
type: Number,
|
|
||||||
default: 1
|
|
||||||
},
|
|
||||||
sortDesc: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
isEmpty: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
total: {
|
|
||||||
type: Number,
|
|
||||||
default: 1
|
|
||||||
},
|
|
||||||
entries: {
|
|
||||||
type: Array,
|
|
||||||
default: function () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
accountId: {
|
|
||||||
type: Number,
|
|
||||||
default: function () {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionLocation.vue
|
|
||||||
- Copyright (c) 2021 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="showField" class="form-group">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.location') }}
|
|
||||||
</div>
|
|
||||||
<div style="width:100%;height:300px;">
|
|
||||||
<l-map
|
|
||||||
ref="myMap"
|
|
||||||
:center="center"
|
|
||||||
:zoom="zoom" style="width:100%;height:300px;"
|
|
||||||
@ready="prepMap()"
|
|
||||||
@update:zoom="zoomUpdated"
|
|
||||||
@update:center="centerUpdated"
|
|
||||||
@update:bounds="boundsUpdated"
|
|
||||||
>
|
|
||||||
<l-tile-layer :url="url"></l-tile-layer>
|
|
||||||
<l-marker :lat-lng="marker" :visible="hasMarker"></l-marker>
|
|
||||||
</l-map>
|
|
||||||
<span>
|
|
||||||
<button class="btn btn-default btn-xs" @click="clearLocation">{{ $t('firefly.clear_location') }}</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<p> </p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
// If you need to reference 'L', such as in 'L.icon', then be sure to
|
|
||||||
// explicitly import 'leaflet' into your component
|
|
||||||
// import L from 'leaflet';
|
|
||||||
import {LMap, LMarker, LTileLayer} from 'vue2-leaflet';
|
|
||||||
import 'leaflet/dist/leaflet.css';
|
|
||||||
|
|
||||||
import L from 'leaflet';
|
|
||||||
|
|
||||||
delete L.Icon.Default.prototype._getIconUrl;
|
|
||||||
|
|
||||||
L.Icon.Default.mergeOptions({
|
|
||||||
iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
|
|
||||||
iconUrl: require('leaflet/dist/images/marker-icon.png'),
|
|
||||||
shadowUrl: require('leaflet/dist/images/marker-shadow.png')
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "TransactionLocation",
|
|
||||||
props: {
|
|
||||||
index: {},
|
|
||||||
value: {
|
|
||||||
type: Object,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
errors: {},
|
|
||||||
customFields: {},
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
LMap,
|
|
||||||
LTileLayer,
|
|
||||||
LMarker,
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
if (null === this.value || typeof this.value === 'undefined') {
|
|
||||||
axios.get('./api/v1/configuration/firefly.default_location').then(response => {
|
|
||||||
this.zoom = parseInt(response.data.data.value.zoom_level);
|
|
||||||
this.center =
|
|
||||||
[
|
|
||||||
parseFloat(response.data.data.value.latitude),
|
|
||||||
parseFloat(response.data.data.value.longitude),
|
|
||||||
]
|
|
||||||
;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (null !== this.value.zoom_level && null !== this.value.latitude && null !== this.value.longitude) {
|
|
||||||
this.zoom = this.value.zoom_level;
|
|
||||||
this.center = [
|
|
||||||
parseFloat(this.value.latitude),
|
|
||||||
parseFloat(this.value.longitude),
|
|
||||||
];
|
|
||||||
this.hasMarker = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
availableFields: this.customFields,
|
|
||||||
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
|
||||||
zoom: 3,
|
|
||||||
center: [0, 0],
|
|
||||||
bounds: null,
|
|
||||||
map: null,
|
|
||||||
hasMarker: false,
|
|
||||||
marker: [0, 0],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
prepMap: function () {
|
|
||||||
this.map = this.$refs.myMap.mapObject;
|
|
||||||
this.map.on('contextmenu', this.setObjectLocation);
|
|
||||||
this.map.on('zoomend', this.saveZoomLevel);
|
|
||||||
},
|
|
||||||
setObjectLocation: function (event) {
|
|
||||||
this.marker = [event.latlng.lat, event.latlng.lng];
|
|
||||||
this.hasMarker = true;
|
|
||||||
this.emitEvent();
|
|
||||||
},
|
|
||||||
saveZoomLevel: function () {
|
|
||||||
this.emitEvent();
|
|
||||||
},
|
|
||||||
clearLocation: function () {
|
|
||||||
this.hasMarker = false;
|
|
||||||
this.emitEvent();
|
|
||||||
},
|
|
||||||
emitEvent() {
|
|
||||||
this.$emit('set-marker-location', {
|
|
||||||
index: this.index,
|
|
||||||
zoomLevel: this.zoom,
|
|
||||||
lat: this.marker[0],
|
|
||||||
lng: this.marker[1],
|
|
||||||
hasMarker: this.hasMarker
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
zoomUpdated(zoom) {
|
|
||||||
this.zoom = zoom;
|
|
||||||
},
|
|
||||||
centerUpdated(center) {
|
|
||||||
this.center = center;
|
|
||||||
},
|
|
||||||
boundsUpdated(bounds) {
|
|
||||||
this.bounds = bounds;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
showField: function () {
|
|
||||||
if ('location' in this.availableFields) {
|
|
||||||
return this.availableFields.location;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
customFields: function (value) {
|
|
||||||
this.availableFields = value;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionNotes.vue
|
|
||||||
- Copyright (c) 2021 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="showField" class="form-group">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.notes') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<textarea
|
|
||||||
v-model="notes"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:placeholder="$t('firefly.notes')"
|
|
||||||
></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: ['index', 'value', 'errors', 'customFields'],
|
|
||||||
name: "TransactionNotes",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
notes: this.value,
|
|
||||||
availableFields: this.customFields,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
showField: function () {
|
|
||||||
if ('notes' in this.availableFields) {
|
|
||||||
return this.availableFields.notes;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
value: function (value) {
|
|
||||||
this.notes = value;
|
|
||||||
},
|
|
||||||
customFields: function (value) {
|
|
||||||
this.availableFields = value;
|
|
||||||
},
|
|
||||||
notes: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'notes', index: this.index, value: value});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionPiggyBank.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.piggy_bank') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<select
|
|
||||||
ref="piggy_bank_id"
|
|
||||||
v-model="piggy_bank_id"
|
|
||||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
|
||||||
:title="$t('firefly.piggy_bank')"
|
|
||||||
autocomplete="off"
|
|
||||||
name="piggy_bank_id[]"
|
|
||||||
>
|
|
||||||
<option v-for="piggy in this.piggyList" :label="piggy.name_with_balance" :value="piggy.id">{{ piggy.name_with_balance }}</option>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: ['index', 'value', 'errors'],
|
|
||||||
name: "TransactionPiggyBank",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
piggyList: [],
|
|
||||||
piggy_bank_id: this.value,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.collectData();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
collectData() {
|
|
||||||
this.piggyList.push(
|
|
||||||
{
|
|
||||||
id: 0,
|
|
||||||
name_with_balance: this.$t('firefly.no_piggy_bank'),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.getPiggies();
|
|
||||||
},
|
|
||||||
getPiggies() {
|
|
||||||
axios.get('./api/v1/autocomplete/piggy-banks-with-balance')
|
|
||||||
.then(response => {
|
|
||||||
this.parsePiggies(response.data);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
parsePiggies(data) {
|
|
||||||
for (let key in data) {
|
|
||||||
if (data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
|
||||||
let current = data[key];
|
|
||||||
this.piggyList.push(
|
|
||||||
{
|
|
||||||
id: parseInt(current.id),
|
|
||||||
name_with_balance: current.name_with_balance
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
value: function (value) {
|
|
||||||
this.piggy_bank_id = value;
|
|
||||||
},
|
|
||||||
piggy_bank_id: function (value) {
|
|
||||||
this.$emit('set-field', {field: 'piggy_bank_id', index: this.index, value: value});
|
|
||||||
this.emitEvent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
<!--
|
|
||||||
- TransactionTags.vue
|
|
||||||
- Copyright (c) 2021 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">
|
|
||||||
<div class="text-xs d-none d-lg-block d-xl-block">
|
|
||||||
{{ $t('firefly.tags') }}
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<vue-tags-input
|
|
||||||
v-model="currentTag"
|
|
||||||
:add-only-from-autocomplete="false"
|
|
||||||
:autocomplete-items="autocompleteItems"
|
|
||||||
:tags="tags"
|
|
||||||
ref="input"
|
|
||||||
:title="$t('firefly.tags')"
|
|
||||||
v-bind:placeholder="$t('firefly.tags')"
|
|
||||||
@tags-changed="newTags => this.tags = newTags"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<span v-if="errors.length > 0">
|
|
||||||
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import VueTagsInput from "@johmun/vue-tags-input";
|
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "TransactionTags",
|
|
||||||
components: {
|
|
||||||
VueTagsInput
|
|
||||||
},
|
|
||||||
props: ['value', 'index', 'errors'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
autocompleteItems: [],
|
|
||||||
debounce: null,
|
|
||||||
tags: [],
|
|
||||||
currentTag: '',
|
|
||||||
updateTags: true, // the idea is that this is always true, except when the tags-function sets the value.
|
|
||||||
tagList: this.value,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
let tags = [];
|
|
||||||
for (let i in this.value) {
|
|
||||||
if (this.value.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
|
||||||
tags.push({text: this.value[i]});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.updateTags = false;
|
|
||||||
this.tags = tags;
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
'currentTag': 'initItems',
|
|
||||||
value: function (value) {
|
|
||||||
this.tagList = value;
|
|
||||||
},
|
|
||||||
tagList: function (value) {
|
|
||||||
// console.log('watch tagList');
|
|
||||||
this.$emit('set-field', {field: 'tags', index: this.index, value: value});
|
|
||||||
this.updateTags = false;
|
|
||||||
this.tags = value;
|
|
||||||
},
|
|
||||||
tags: function (value) {
|
|
||||||
if (this.updateTags) {
|
|
||||||
let shortList = [];
|
|
||||||
for (let key in value) {
|
|
||||||
if (value.hasOwnProperty(key)) {
|
|
||||||
shortList.push({text: value[key].text});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.tagList = shortList;
|
|
||||||
}
|
|
||||||
this.updateTags = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initItems() {
|
|
||||||
if (this.currentTag.length < 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const url = document.getElementsByTagName('base')[0].href + `api/v1/autocomplete/tags?query=${this.currentTag}`;
|
|
||||||
|
|
||||||
clearTimeout(this.debounce);
|
|
||||||
this.debounce = setTimeout(() => {
|
|
||||||
axios.get(url).then(response => {
|
|
||||||
this.autocompleteItems = response.data.map(item => {
|
|
||||||
return {text: item.tag};
|
|
||||||
});
|
|
||||||
}).catch(() => console.warn('Oh. Something went wrong loading tags.'));
|
|
||||||
}, 300);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
.vue-tags-input {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100% !important;
|
|
||||||
display: block;
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ti-input {
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
max-width: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ti-new-tag-input {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
54
frontend/src/i18n.js
vendored
54
frontend/src/i18n.js
vendored
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* i18n.js
|
|
||||||
* Copyright (c) 2020 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Create VueI18n instance with options
|
|
||||||
module.exports = new vuei18n({
|
|
||||||
locale: document.documentElement.lang, // set locale
|
|
||||||
fallbackLocale: 'en',
|
|
||||||
messages: {
|
|
||||||
'bg': require('./locales/bg.json'),
|
|
||||||
'cs': require('./locales/cs.json'),
|
|
||||||
'de': require('./locales/de.json'),
|
|
||||||
'en': require('./locales/en.json'),
|
|
||||||
'en-us': require('./locales/en.json'),
|
|
||||||
'en-gb': require('./locales/en-gb.json'),
|
|
||||||
'es': require('./locales/es.json'),
|
|
||||||
'el': require('./locales/el.json'),
|
|
||||||
'fr': require('./locales/fr.json'),
|
|
||||||
'hu': require('./locales/hu.json'),
|
|
||||||
//'id': require('./locales/id.json'),
|
|
||||||
'it': require('./locales/it.json'),
|
|
||||||
'ja': require('./locales/ja.json'),
|
|
||||||
'nl': require('./locales/nl.json'),
|
|
||||||
'nb': require('./locales/nb.json'),
|
|
||||||
'pl': require('./locales/pl.json'),
|
|
||||||
'fi': require('./locales/fi.json'),
|
|
||||||
'pt-br': require('./locales/pt-br.json'),
|
|
||||||
'pt-pt': require('./locales/pt.json'),
|
|
||||||
'ro': require('./locales/ro.json'),
|
|
||||||
'ru': require('./locales/ru.json'),
|
|
||||||
//'zh': require('./locales/zh.json'),
|
|
||||||
'zh-tw': require('./locales/zh-tw.json'),
|
|
||||||
'zh-cn': require('./locales/zh-cn.json'),
|
|
||||||
'sk': require('./locales/sk.json'),
|
|
||||||
'sv': require('./locales/sv.json'),
|
|
||||||
'vi': require('./locales/vi.json'),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
{
|
|
||||||
"firefly": {
|
|
||||||
"Transfer": "\u041f\u0440\u0435\u0445\u0432\u044a\u0440\u043b\u044f\u043d\u0435",
|
|
||||||
"Withdrawal": "\u0422\u0435\u0433\u043b\u0435\u043d\u0435",
|
|
||||||
"Deposit": "\u0414\u0435\u043f\u043e\u0437\u0438\u0442",
|
|
||||||
"date_and_time": "Date and time",
|
|
||||||
"no_currency": "(\u0431\u0435\u0437 \u0432\u0430\u043b\u0443\u0442\u0430)",
|
|
||||||
"date": "\u0414\u0430\u0442\u0430",
|
|
||||||
"time": "Time",
|
|
||||||
"no_budget": "(\u0431\u0435\u0437 \u0431\u044e\u0434\u0436\u0435\u0442)",
|
|
||||||
"destination_account": "\u041f\u0440\u0438\u0445\u043e\u0434\u043d\u0430 \u0441\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"source_account": "\u0420\u0430\u0437\u0445\u043e\u0434\u043d\u0430 \u0441\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"single_split": "\u0420\u0430\u0437\u0434\u0435\u043b",
|
|
||||||
"create_new_transaction": "Create a new transaction",
|
|
||||||
"balance": "\u0421\u0430\u043b\u0434\u043e",
|
|
||||||
"transaction_journal_extra": "Extra information",
|
|
||||||
"transaction_journal_meta": "\u041c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f",
|
|
||||||
"basic_journal_information": "Basic transaction information",
|
|
||||||
"bills_to_pay": "\u0421\u043c\u0435\u0442\u043a\u0438 \u0437\u0430 \u043f\u043b\u0430\u0449\u0430\u043d\u0435",
|
|
||||||
"left_to_spend": "\u041e\u0441\u0442\u0430\u043d\u0430\u043b\u0438 \u0437\u0430 \u0445\u0430\u0440\u0447\u0435\u043d\u0435",
|
|
||||||
"attachments": "\u041f\u0440\u0438\u043a\u0430\u0447\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435",
|
|
||||||
"net_worth": "\u041d\u0435\u0442\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442",
|
|
||||||
"bill": "\u0421\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"no_bill": "(\u043d\u044f\u043c\u0430 \u0441\u043c\u0435\u0442\u043a\u0430)",
|
|
||||||
"tags": "\u0415\u0442\u0438\u043a\u0435\u0442\u0438",
|
|
||||||
"internal_reference": "Internal reference",
|
|
||||||
"external_url": "External URL",
|
|
||||||
"no_piggy_bank": "(\u0431\u0435\u0437 \u043a\u0430\u0441\u0438\u0447\u043a\u0430)",
|
|
||||||
"paid": "\u041f\u043b\u0430\u0442\u0435\u043d\u0438",
|
|
||||||
"notes": "\u0411\u0435\u043b\u0435\u0436\u043a\u0438",
|
|
||||||
"yourAccounts": "\u0412\u0430\u0448\u0438\u0442\u0435 \u0441\u043c\u0435\u0442\u043a\u0438",
|
|
||||||
"go_to_asset_accounts": "\u0412\u0438\u0436\u0442\u0435 \u0430\u043a\u0442\u0438\u0432\u0438\u0442\u0435 \u0441\u0438",
|
|
||||||
"delete_account": "\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u043e\u0444\u0438\u043b",
|
|
||||||
"transaction_table_description": "\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u0449\u0430 \u0432\u0430\u0448\u0438\u0442\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438",
|
|
||||||
"account": "\u0421\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"description": "\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435",
|
|
||||||
"amount": "\u0421\u0443\u043c\u0430",
|
|
||||||
"budget": "\u0411\u044e\u0434\u0436\u0435\u0442",
|
|
||||||
"category": "\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f",
|
|
||||||
"opposing_account": "\u041f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u043b\u043e\u0436\u043d\u0430 \u0441\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"budgets": "\u0411\u044e\u0434\u0436\u0435\u0442\u0438",
|
|
||||||
"categories": "\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438",
|
|
||||||
"go_to_budgets": "\u0412\u0438\u0436\u0442\u0435 \u0431\u044e\u0434\u0436\u0435\u0442\u0438\u0442\u0435 \u0441\u0438",
|
|
||||||
"income": "\u041f\u0440\u0438\u0445\u043e\u0434\u0438",
|
|
||||||
"go_to_deposits": "\u041e\u0442\u0438\u0434\u0438 \u0432 \u0434\u0435\u043f\u043e\u0437\u0438\u0442\u0438",
|
|
||||||
"go_to_categories": "\u0412\u0438\u0436 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438\u0442\u0435 \u0441\u0438",
|
|
||||||
"expense_accounts": "\u0421\u043c\u0435\u0442\u043a\u0438 \u0437\u0430 \u0440\u0430\u0437\u0445\u043e\u0434\u0438",
|
|
||||||
"go_to_expenses": "\u041e\u0442\u0438\u0434\u0438 \u0432 \u0420\u0430\u0437\u0445\u043e\u0434\u0438",
|
|
||||||
"go_to_bills": "\u0412\u0438\u0436 \u0441\u043c\u0435\u0442\u043a\u0438\u0442\u0435 \u0441\u0438",
|
|
||||||
"bills": "\u0421\u043c\u0435\u0442\u043a\u0438",
|
|
||||||
"last_thirty_days": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0442\u0435 \u0442\u0440\u0438\u0439\u0441\u0435\u0442 \u0434\u043d\u0438",
|
|
||||||
"last_seven_days": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0442\u0435 \u0441\u0435\u0434\u0435\u043c \u0434\u043d\u0438",
|
|
||||||
"go_to_piggies": "\u0412\u0438\u0436 \u043a\u0430\u0441\u0438\u0447\u043a\u0438\u0442\u0435 \u0441\u0438",
|
|
||||||
"saved": "\u0417\u0430\u043f\u0438\u0441\u0430\u043d",
|
|
||||||
"piggy_banks": "\u041a\u0430\u0441\u0438\u0447\u043a\u0438",
|
|
||||||
"piggy_bank": "\u041a\u0430\u0441\u0438\u0447\u043a\u0430",
|
|
||||||
"amounts": "\u0421\u0443\u043c\u0438",
|
|
||||||
"left": "\u041e\u0441\u0442\u0430\u043d\u0430\u043b\u0438",
|
|
||||||
"spent": "\u041f\u043e\u0445\u0430\u0440\u0447\u0435\u043d\u0438",
|
|
||||||
"Default asset account": "\u0421\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0438 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435",
|
|
||||||
"search_results": "\u0420\u0435\u0437\u0443\u043b\u0442\u0430\u0442\u0438 \u043e\u0442 \u0442\u044a\u0440\u0441\u0435\u043d\u0435\u0442\u043e",
|
|
||||||
"include": "Include?",
|
|
||||||
"transaction": "\u0422\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f",
|
|
||||||
"account_role_defaultAsset": "\u0421\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0438 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435",
|
|
||||||
"account_role_savingAsset": "\u0421\u043f\u0435\u0441\u0442\u043e\u0432\u043d\u0430 \u0441\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"account_role_sharedAsset": "\u0421\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u0435\u043d\u0438 \u0430\u043a\u0442\u0438\u0432\u0438",
|
|
||||||
"clear_location": "\u0418\u0437\u0447\u0438\u0441\u0442\u0438 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u0442\u043e",
|
|
||||||
"account_role_ccAsset": "\u041a\u0440\u0435\u0434\u0438\u0442\u043d\u0430 \u043a\u0430\u0440\u0442\u0430",
|
|
||||||
"account_role_cashWalletAsset": "\u041f\u0430\u0440\u0438\u0447\u0435\u043d \u043f\u043e\u0440\u0442\u0444\u0435\u0439\u043b",
|
|
||||||
"daily_budgets": "\u0414\u043d\u0435\u0432\u043d\u0438 \u0431\u044e\u0434\u0436\u0435\u0442\u0438",
|
|
||||||
"weekly_budgets": "\u0421\u0435\u0434\u043c\u0438\u0447\u043d\u0438 \u0431\u044e\u0434\u0436\u0435\u0442\u0438",
|
|
||||||
"monthly_budgets": "\u041c\u0435\u0441\u0435\u0447\u043d\u0438 \u0431\u044e\u0434\u0436\u0435\u0442\u0438",
|
|
||||||
"journals_in_period_for_account_js": "All transactions for account {title} between {start} and {end}",
|
|
||||||
"quarterly_budgets": "\u0422\u0440\u0438\u043c\u0435\u0441\u0435\u0447\u043d\u0438 \u0431\u044e\u0434\u0436\u0435\u0442\u0438",
|
|
||||||
"create_new_expense": "\u0421\u044a\u0437\u0434\u0430\u0439 \u043d\u043e\u0432\u0430 \u0441\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u0440\u0430\u0437\u0445\u043e\u0434\u0438",
|
|
||||||
"create_new_revenue": "\u0421\u044a\u0437\u0434\u0430\u0439 \u043d\u043e\u0432\u0430 \u0441\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u0438",
|
|
||||||
"create_new_liabilities": "Create new liability",
|
|
||||||
"half_year_budgets": "\u0428\u0435\u0441\u0442\u043c\u0435\u0441\u0435\u0447\u043d\u0438 \u0431\u044e\u0434\u0436\u0435\u0442\u0438",
|
|
||||||
"yearly_budgets": "\u0413\u043e\u0434\u0438\u0448\u043d\u0438 \u0431\u044e\u0434\u0436\u0435\u0442\u0438",
|
|
||||||
"split_transaction_title": "\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f",
|
|
||||||
"errors_submission": "\u0418\u043c\u0430\u0448\u0435 \u043d\u0435\u0449\u043e \u043d\u0435\u0440\u0435\u0434\u043d\u043e \u0441 \u0432\u0430\u0448\u0438\u0442\u0435 \u0434\u0430\u043d\u043d\u0438. \u041c\u043e\u043b\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u0442\u0435 \u0433\u0440\u0435\u0448\u043a\u0438\u0442\u0435.",
|
|
||||||
"flash_error": "\u0413\u0440\u0435\u0448\u043a\u0430!",
|
|
||||||
"store_transaction": "Store transaction",
|
|
||||||
"flash_success": "\u0423\u0441\u043f\u0435\u0445!",
|
|
||||||
"create_another": "\u0421\u043b\u0435\u0434 \u0441\u044a\u0445\u0440\u0430\u043d\u044f\u0432\u0430\u043d\u0435\u0442\u043e \u0441\u0435 \u0432\u044a\u0440\u043d\u0435\u0442\u0435 \u0442\u0443\u043a, \u0437\u0430 \u0434\u0430 \u0441\u044a\u0437\u0434\u0430\u0434\u0435\u0442\u0435 \u043d\u043e\u0432\u0430.",
|
|
||||||
"update_transaction": "\u041e\u0431\u043d\u043e\u0432\u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u0442\u0430",
|
|
||||||
"after_update_create_another": "\u0421\u043b\u0435\u0434 \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435\u0442\u043e \u0441\u0435 \u0432\u044a\u0440\u043d\u0435\u0442\u0435 \u0442\u0443\u043a, \u0437\u0430 \u0434\u0430 \u043f\u0440\u043e\u0434\u044a\u043b\u0436\u0438\u0442\u0435 \u0441 \u0440\u0435\u0434\u0430\u043a\u0446\u0438\u044f\u0442\u0430.",
|
|
||||||
"transaction_updated_no_changes": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") did not receive any changes.",
|
|
||||||
"transaction_updated_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") has been updated.",
|
|
||||||
"spent_x_of_y": "Spent {amount} of {total}",
|
|
||||||
"search": "\u0422\u044a\u0440\u0441\u0435\u043d\u0435",
|
|
||||||
"create_new_asset": "\u0421\u044a\u0437\u0434\u0430\u0439 \u043d\u043e\u0432\u0430 \u0441\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0438",
|
|
||||||
"asset_accounts": "\u0421\u043c\u0435\u0442\u043a\u0438 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0438",
|
|
||||||
"reset_after": "\u0418\u0437\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u043e\u0440\u043c\u0443\u043b\u044f\u0440\u0430 \u0441\u043b\u0435\u0434 \u0438\u0437\u043f\u0440\u0430\u0449\u0430\u043d\u0435",
|
|
||||||
"bill_paid_on": "Paid on {date}",
|
|
||||||
"first_split_decides": "The first split determines the value of this field",
|
|
||||||
"first_split_overrules_source": "The first split may overrule the source account",
|
|
||||||
"first_split_overrules_destination": "The first split may overrule the destination account",
|
|
||||||
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">\u0422\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f #{ID}(\"{title}\")<\/a> \u0431\u0435\u0448\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u0430.",
|
|
||||||
"custom_period": "Custom period",
|
|
||||||
"reset_to_current": "Reset to current period",
|
|
||||||
"select_period": "Select a period",
|
|
||||||
"location": "\u041c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435",
|
|
||||||
"other_budgets": "\u0412\u0440\u0435\u043c\u0435\u0432\u043e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0438 \u0431\u044e\u0434\u0436\u0435\u0442\u0438",
|
|
||||||
"journal_links": "\u0412\u0440\u044a\u0437\u043a\u0438 \u043d\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f",
|
|
||||||
"go_to_withdrawals": "\u0412\u0438\u0436\u0442\u0435 \u0442\u0435\u0433\u043b\u0435\u043d\u0438\u044f\u0442\u0430 \u0441\u0438",
|
|
||||||
"revenue_accounts": "\u0421\u043c\u0435\u0442\u043a\u0438 \u0437\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u0438",
|
|
||||||
"add_another_split": "\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433 \u0440\u0430\u0437\u0434\u0435\u043b",
|
|
||||||
"actions": "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f",
|
|
||||||
"earned": "\u0421\u043f\u0435\u0447\u0435\u043b\u0435\u043d\u0438",
|
|
||||||
"empty": "(\u043f\u0440\u0430\u0437\u043d\u043e)",
|
|
||||||
"edit": "\u041f\u0440\u043e\u043c\u0435\u043d\u0438",
|
|
||||||
"never": "\u041d\u0438\u043a\u043e\u0433\u0430",
|
|
||||||
"account_type_Loan": "\u0417\u0430\u0435\u043c",
|
|
||||||
"account_type_Mortgage": "\u0418\u043f\u043e\u0442\u0435\u043a\u0430",
|
|
||||||
"stored_new_account_js": "New account \"<a href=\"accounts\/show\/{ID}\">{name}<\/a>\" stored!",
|
|
||||||
"account_type_Debt": "\u0414\u044a\u043b\u0433",
|
|
||||||
"liability_direction_null_short": "Unknown",
|
|
||||||
"delete": "\u0418\u0437\u0442\u0440\u0438\u0439",
|
|
||||||
"store_new_asset_account": "\u0417\u0430\u043f\u0430\u043c\u0435\u0442\u0438 \u043d\u043e\u0432\u0430 \u0441\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0438",
|
|
||||||
"store_new_expense_account": "\u0417\u0430\u043f\u0430\u043c\u0435\u0442\u0438 \u043d\u043e\u0432\u0430 \u0441\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u0440\u0430\u0437\u0445\u043e\u0434\u0438",
|
|
||||||
"store_new_liabilities_account": "\u0417\u0430\u043f\u0430\u043c\u0435\u0442\u0438 \u043d\u043e\u0432\u043e \u0437\u0430\u0434\u044a\u043b\u0436\u0435\u043d\u0438\u0435",
|
|
||||||
"store_new_revenue_account": "\u0417\u0430\u043f\u0430\u043c\u0435\u0442\u0438 \u043d\u043e\u0432\u0430 \u0441\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u0438",
|
|
||||||
"mandatoryFields": "\u0417\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u0438 \u043f\u043e\u043b\u0435\u0442\u0430",
|
|
||||||
"optionalFields": "\u041d\u0435\u0437\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u0438 \u043f\u043e\u043b\u0435\u0442\u0430",
|
|
||||||
"reconcile_this_account": "\u0421\u044a\u0433\u043b\u0430\u0441\u0443\u0432\u0430\u0439 \u0442\u0430\u0437\u0438 \u0441\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"interest_calc_weekly": "Per week",
|
|
||||||
"interest_calc_monthly": "\u041d\u0430 \u043c\u0435\u0441\u0435\u0446",
|
|
||||||
"interest_calc_quarterly": "Per quarter",
|
|
||||||
"interest_calc_half-year": "Per half year",
|
|
||||||
"interest_calc_yearly": "\u0413\u043e\u0434\u0438\u0448\u043d\u043e",
|
|
||||||
"liability_direction_credit": "I am owed this debt",
|
|
||||||
"liability_direction_debit": "I owe this debt to somebody else",
|
|
||||||
"liability_direction_credit_short": "Owed this debt",
|
|
||||||
"liability_direction_debit_short": "Owe this debt",
|
|
||||||
"account_type_debt": "Debt",
|
|
||||||
"account_type_loan": "Loan",
|
|
||||||
"left_in_debt": "Amount due",
|
|
||||||
"account_type_mortgage": "Mortgage",
|
|
||||||
"save_transactions_by_moving_js": "No transactions|Save this transaction by moving it to another account. |Save these transactions by moving them to another account.",
|
|
||||||
"none_in_select_list": "(\u043d\u0438\u0449\u043e)",
|
|
||||||
"transaction_expand_split": "Expand split",
|
|
||||||
"transaction_collapse_split": "Collapse split",
|
|
||||||
"default_group_title_name": "(\u0431\u0435\u0437 \u0433\u0440\u0443\u043f\u0430)",
|
|
||||||
"bill_repeats_weekly": "Repeats weekly",
|
|
||||||
"bill_repeats_monthly": "Repeats monthly",
|
|
||||||
"bill_repeats_quarterly": "Repeats quarterly",
|
|
||||||
"bill_repeats_half-year": "Repeats every half year",
|
|
||||||
"bill_repeats_yearly": "Repeats yearly",
|
|
||||||
"bill_repeats_weekly_other": "Repeats every other week",
|
|
||||||
"bill_repeats_monthly_other": "Repeats every other month",
|
|
||||||
"bill_repeats_quarterly_other": "Repeats every other quarter",
|
|
||||||
"bill_repeats_half-year_other": "Repeats yearly",
|
|
||||||
"bill_repeats_yearly_other": "Repeats every other year",
|
|
||||||
"bill_repeats_weekly_skip": "Repeats every {skip} weeks",
|
|
||||||
"bill_repeats_monthly_skip": "Repeats every {skip} months",
|
|
||||||
"bill_repeats_quarterly_skip": "Repeats every {skip} quarters",
|
|
||||||
"bill_repeats_half-year_skip": "Repeats every {skip} half years",
|
|
||||||
"bill_repeats_yearly_skip": "Repeats every {skip} years",
|
|
||||||
"not_expected_period": "\u041d\u0435 \u0441\u0435 \u043e\u0447\u0430\u043a\u0432\u0430 \u0442\u043e\u0437\u0438 \u043f\u0435\u0440\u0438\u043e\u0434",
|
|
||||||
"subscriptions": "Subscriptions",
|
|
||||||
"bill_expected_date_js": "Expected {date}",
|
|
||||||
"inactive": "\u041d\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e",
|
|
||||||
"forever": "Forever",
|
|
||||||
"extension_date_is": "Extension date is {date}",
|
|
||||||
"create_new_bill": "\u0421\u044a\u0437\u0434\u0430\u0439 \u043d\u043e\u0432\u0430 \u0441\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"store_new_bill": "\u0417\u0430\u043f\u0430\u043c\u0435\u0442\u0435\u0442\u0435 \u043d\u043e\u0432\u0430 \u0441\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"repeat_freq_yearly": "\u0435\u0436\u0435\u0433\u043e\u0434\u043d\u043e",
|
|
||||||
"repeat_freq_half-year": "\u043d\u0430 \u0432\u0441\u0435\u043a\u0438 6 \u043c\u0435\u0441\u0435\u0446\u0430",
|
|
||||||
"repeat_freq_quarterly": "\u0442\u0440\u0438\u043c\u0435\u0441\u0435\u0447\u043d\u043e",
|
|
||||||
"repeat_freq_monthly": "\u043c\u0435\u0441\u0435\u0447\u043d\u043e",
|
|
||||||
"repeat_freq_weekly": "\u0435\u0436\u0435\u0441\u0435\u0434\u043c\u0438\u0447\u043d\u043e",
|
|
||||||
"credit_card_type_monthlyFull": "Full payment every month",
|
|
||||||
"update_liabilities_account": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u0439 \u0437\u0430\u0434\u044a\u043b\u0436\u0435\u043d\u0438\u0435",
|
|
||||||
"update_expense_account": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u0439 \u0441\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u0440\u0430\u0437\u0445\u043e\u0434\u0438",
|
|
||||||
"update_revenue_account": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u0439 \u0441\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u0438",
|
|
||||||
"update_undefined_account": "Update account",
|
|
||||||
"update_asset_account": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u0439 \u0441\u043c\u0435\u0442\u043a\u0430 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0438",
|
|
||||||
"updated_account_js": "Updated account \"<a href=\"accounts\/show\/{ID}\">{title}<\/a>\"."
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"piggy_bank": "\u041a\u0430\u0441\u0438\u0447\u043a\u0430",
|
|
||||||
"percentage": "%",
|
|
||||||
"amount": "\u0421\u0443\u043c\u0430",
|
|
||||||
"lastActivity": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0430 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442",
|
|
||||||
"name": "\u0418\u043c\u0435",
|
|
||||||
"role": "\u041f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0438",
|
|
||||||
"description": "\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435",
|
|
||||||
"date": "\u0414\u0430\u0442\u0430",
|
|
||||||
"source_account": "\u0420\u0430\u0437\u0445\u043e\u0434\u043d\u0430 \u0441\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"destination_account": "\u041f\u0440\u0438\u0445\u043e\u0434\u043d\u0430 \u0441\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"category": "\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"interest": "\u041b\u0438\u0445\u0432\u0430",
|
|
||||||
"interest_period": "Interest period",
|
|
||||||
"liability_type": "\u0412\u0438\u0434 \u043d\u0430 \u0437\u0430\u0434\u044a\u043b\u0436\u0435\u043d\u0438\u0435\u0442\u043e",
|
|
||||||
"liability_direction": "Liability in\/out",
|
|
||||||
"currentBalance": "\u0422\u0435\u043a\u0443\u0449 \u0431\u0430\u043b\u0430\u043d\u0441",
|
|
||||||
"next_expected_match": "\u0421\u043b\u0435\u0434\u0432\u0430\u0449o \u043e\u0447\u0430\u043a\u0432\u0430\u043do \u0441\u044a\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435",
|
|
||||||
"expected_info": "Next expected transaction",
|
|
||||||
"start_date": "Start date",
|
|
||||||
"end_date": "End date",
|
|
||||||
"payment_info": "Payment information"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"html_language": "bg",
|
|
||||||
"week_in_year_fns": "'Week' w, yyyy",
|
|
||||||
"month_and_day_fns": "MMMM d, y",
|
|
||||||
"quarter_fns": "'Q'Q, yyyy",
|
|
||||||
"half_year_fns": "'H{half}', yyyy"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"foreign_amount": "\u0421\u0443\u043c\u0430 \u0432\u044a\u0432 \u0432\u0430\u043b\u0443\u0442\u0430",
|
|
||||||
"interest_date": "\u041f\u0430\u0434\u0435\u0436 \u043d\u0430 \u043b\u0438\u0445\u0432\u0430",
|
|
||||||
"name": "\u0418\u043c\u0435",
|
|
||||||
"amount": "\u0421\u0443\u043c\u0430",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"BIC": "BIC",
|
|
||||||
"notes": "\u0411\u0435\u043b\u0435\u0436\u043a\u0438",
|
|
||||||
"location": "\u041c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435",
|
|
||||||
"repeat_freq": "\u041f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u044f",
|
|
||||||
"skip": "\u041f\u0440\u043e\u043f\u0443\u0441\u043d\u0438",
|
|
||||||
"startdate": "\u041d\u0430\u0447\u0430\u043b\u043d\u0430 \u0434\u0430\u0442\u0430",
|
|
||||||
"enddate": "End date",
|
|
||||||
"object_group": "\u0413\u0440\u0443\u043f\u0430",
|
|
||||||
"attachments": "\u041f\u0440\u0438\u043a\u0430\u0447\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435",
|
|
||||||
"deletePermanently": "\u0411\u0435\u0437\u0432\u044a\u0437\u0432\u0440\u0430\u0442\u043d\u043e \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435",
|
|
||||||
"active": "\u0410\u043a\u0442\u0438\u0432\u0435\u043d",
|
|
||||||
"include_net_worth": "\u0412\u043a\u043b\u044e\u0447\u0438 \u0432 \u043e\u0431\u0449\u043e\u0442\u043e \u0431\u043e\u0433\u0430\u0442\u0441\u0442\u0432\u043e",
|
|
||||||
"cc_type": "\u041f\u043e\u0433\u0430\u0441\u0438\u0442\u0435\u043b\u0435\u043d \u043f\u043b\u0430\u043d \u043d\u0430 \u043a\u0440\u0435\u0434\u0438\u0442\u043d\u0430 \u043a\u0430\u0440\u0442\u0430",
|
|
||||||
"account_number": "\u041d\u043e\u043c\u0435\u0440 \u043d\u0430 \u0441\u043c\u0435\u0442\u043a\u0430",
|
|
||||||
"cc_monthly_payment_date": "\u0414\u0430\u0442\u0430 \u0437\u0430 \u043c\u0435\u0441\u0435\u0447\u043d\u043e \u043f\u043b\u0430\u0449\u0430\u043d\u0435 \u043f\u043e \u043a\u0440\u0435\u0434\u0438\u0442\u043d\u0430 \u043a\u0430\u0440\u0442\u0430",
|
|
||||||
"virtual_balance": "\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u0435\u043d \u0431\u0430\u043b\u0430\u043d\u0441",
|
|
||||||
"opening_balance": "\u041d\u0430\u0447\u0430\u043b\u043d\u043e \u0441\u0430\u043b\u0434\u043e",
|
|
||||||
"opening_balance_date": "\u0414\u0430\u0442\u0430 \u043d\u0430 \u043d\u0430\u0447\u0430\u043b\u043d\u043e\u0442\u043e \u0441\u0430\u043b\u0434\u043e",
|
|
||||||
"date": "\u0414\u0430\u0442\u0430",
|
|
||||||
"interest": "\u041b\u0438\u0445\u0432\u0430",
|
|
||||||
"interest_period": "\u041b\u0438\u0445\u0432\u0435\u043d \u043f\u0435\u0440\u0438\u043e\u0434",
|
|
||||||
"currency_id": "\u0412\u0430\u043b\u0443\u0442\u0430",
|
|
||||||
"liability_type": "Liability type",
|
|
||||||
"account_role": "\u0420\u043e\u043b\u044f \u043d\u0430 \u0441\u043c\u0435\u0442\u043a\u0430\u0442\u0430",
|
|
||||||
"liability_direction": "Liability in\/out",
|
|
||||||
"book_date": "\u0414\u0430\u0442\u0430 \u043d\u0430 \u043e\u0441\u0447\u0435\u0442\u043e\u0432\u043e\u0434\u044f\u0432\u0430\u043d\u0435",
|
|
||||||
"permDeleteWarning": "\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043d\u0435\u0449\u0430 \u043e\u0442 Firefly III \u0435 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u0432\u044a\u0437\u0441\u0442\u0430\u043d\u043e\u0432\u0435\u043d\u043e.",
|
|
||||||
"account_areYouSure_js": "Are you sure you want to delete the account named \"{name}\"?",
|
|
||||||
"also_delete_piggyBanks_js": "No piggy banks|The only piggy bank connected to this account will be deleted as well.|All {count} piggy banks connected to this account will be deleted as well.",
|
|
||||||
"also_delete_transactions_js": "No transactions|The only transaction connected to this account will be deleted as well.|All {count} transactions connected to this account will be deleted as well.",
|
|
||||||
"process_date": "\u0414\u0430\u0442\u0430 \u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430",
|
|
||||||
"due_date": "\u0414\u0430\u0442\u0430 \u043d\u0430 \u043f\u0430\u0434\u0435\u0436",
|
|
||||||
"payment_date": "\u0414\u0430\u0442\u0430 \u043d\u0430 \u043f\u043b\u0430\u0449\u0430\u043d\u0435",
|
|
||||||
"invoice_date": "\u0414\u0430\u0442\u0430 \u043d\u0430 \u0444\u0430\u043a\u0442\u0443\u0440\u0430",
|
|
||||||
"amount_min": "\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u043d\u0430 \u0441\u0443\u043c\u0430",
|
|
||||||
"amount_max": "\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u043d\u0430 \u0441\u0443\u043c\u0430",
|
|
||||||
"start_date": "\u041d\u0430\u0447\u0430\u043b\u043e \u043d\u0430 \u043e\u0431\u0445\u0432\u0430\u0442\u0430",
|
|
||||||
"end_date": "\u041a\u0440\u0430\u0439 \u043d\u0430 \u043e\u0431\u0445\u0432\u0430\u0442\u0430",
|
|
||||||
"extension_date": "Extension date"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
{
|
|
||||||
"firefly": {
|
|
||||||
"Transfer": "P\u0159evod",
|
|
||||||
"Withdrawal": "V\u00fdb\u011br",
|
|
||||||
"Deposit": "Vklad",
|
|
||||||
"date_and_time": "Datum a \u010das",
|
|
||||||
"no_currency": "(\u017e\u00e1dn\u00e1 m\u011bna)",
|
|
||||||
"date": "Datum",
|
|
||||||
"time": "\u010cas",
|
|
||||||
"no_budget": "(\u017e\u00e1dn\u00fd rozpo\u010det)",
|
|
||||||
"destination_account": "C\u00edlov\u00fd \u00fa\u010det",
|
|
||||||
"source_account": "Zdrojov\u00fd \u00fa\u010det",
|
|
||||||
"single_split": "Rozd\u011blit",
|
|
||||||
"create_new_transaction": "Vytvo\u0159it novou transakci",
|
|
||||||
"balance": "Z\u016fstatek",
|
|
||||||
"transaction_journal_extra": "V\u00edce informac\u00ed",
|
|
||||||
"transaction_journal_meta": "Meta informace",
|
|
||||||
"basic_journal_information": "Basic transaction information",
|
|
||||||
"bills_to_pay": "Faktury k zaplacen\u00ed",
|
|
||||||
"left_to_spend": "Zb\u00fdv\u00e1 k utracen\u00ed",
|
|
||||||
"attachments": "P\u0159\u00edlohy",
|
|
||||||
"net_worth": "\u010cist\u00e9 jm\u011bn\u00ed",
|
|
||||||
"bill": "\u00da\u010det",
|
|
||||||
"no_bill": "(no bill)",
|
|
||||||
"tags": "\u0160t\u00edtky",
|
|
||||||
"internal_reference": "Intern\u00ed odkaz",
|
|
||||||
"external_url": "Extern\u00ed URL adresa",
|
|
||||||
"no_piggy_bank": "(\u017e\u00e1dn\u00e1 pokladni\u010dka)",
|
|
||||||
"paid": "Zaplaceno",
|
|
||||||
"notes": "Pozn\u00e1mky",
|
|
||||||
"yourAccounts": "Va\u0161e \u00fa\u010dty",
|
|
||||||
"go_to_asset_accounts": "Zobrazit \u00fa\u010dty s aktivy",
|
|
||||||
"delete_account": "Smazat \u00fa\u010det",
|
|
||||||
"transaction_table_description": "A table containing your transactions",
|
|
||||||
"account": "\u00da\u010det",
|
|
||||||
"description": "Popis",
|
|
||||||
"amount": "\u010c\u00e1stka",
|
|
||||||
"budget": "Rozpo\u010det",
|
|
||||||
"category": "Kategorie",
|
|
||||||
"opposing_account": "Proti\u00fa\u010det",
|
|
||||||
"budgets": "Rozpo\u010dty",
|
|
||||||
"categories": "Kategorie",
|
|
||||||
"go_to_budgets": "P\u0159ej\u00edt k rozpo\u010dt\u016fm",
|
|
||||||
"income": "Odm\u011bna\/p\u0159\u00edjem",
|
|
||||||
"go_to_deposits": "P\u0159ej\u00edt na vklady",
|
|
||||||
"go_to_categories": "P\u0159ej\u00edt ke kategori\u00edm",
|
|
||||||
"expense_accounts": "V\u00fddajov\u00e9 \u00fa\u010dty",
|
|
||||||
"go_to_expenses": "P\u0159ej\u00edt na v\u00fddaje",
|
|
||||||
"go_to_bills": "P\u0159ej\u00edt k \u00fa\u010dt\u016fm",
|
|
||||||
"bills": "\u00da\u010dty",
|
|
||||||
"last_thirty_days": "Uplynul\u00fdch 30 dn\u00ed",
|
|
||||||
"last_seven_days": "Uplynul\u00fdch 7 dn\u016f",
|
|
||||||
"go_to_piggies": "P\u0159ej\u00edt k pokladni\u010dk\u00e1m",
|
|
||||||
"saved": "Ulo\u017eeno",
|
|
||||||
"piggy_banks": "Pokladni\u010dky",
|
|
||||||
"piggy_bank": "Pokladni\u010dka",
|
|
||||||
"amounts": "Amounts",
|
|
||||||
"left": "Zb\u00fdv\u00e1",
|
|
||||||
"spent": "Utraceno",
|
|
||||||
"Default asset account": "V\u00fdchoz\u00ed \u00fa\u010det s aktivy",
|
|
||||||
"search_results": "V\u00fdsledky hled\u00e1n\u00ed",
|
|
||||||
"include": "Include?",
|
|
||||||
"transaction": "Transakce",
|
|
||||||
"account_role_defaultAsset": "V\u00fdchoz\u00ed \u00fa\u010det aktiv",
|
|
||||||
"account_role_savingAsset": "Spo\u0159ic\u00ed \u00fa\u010det",
|
|
||||||
"account_role_sharedAsset": "Sd\u00edlen\u00fd \u00fa\u010det aktiv",
|
|
||||||
"clear_location": "Vymazat um\u00edst\u011bn\u00ed",
|
|
||||||
"account_role_ccAsset": "Kreditn\u00ed karta",
|
|
||||||
"account_role_cashWalletAsset": "Pen\u011b\u017eenka",
|
|
||||||
"daily_budgets": "Denn\u00ed rozpo\u010dty",
|
|
||||||
"weekly_budgets": "T\u00fddenn\u00ed rozpo\u010dty",
|
|
||||||
"monthly_budgets": "M\u011bs\u00ed\u010dn\u00ed rozpo\u010dty",
|
|
||||||
"journals_in_period_for_account_js": "Ve\u0161ker\u00e9 transakce pro \u00fa\u010det {title} mezi {start} a {end}",
|
|
||||||
"quarterly_budgets": "\u010ctvrtletn\u00ed rozpo\u010dty",
|
|
||||||
"create_new_expense": "Vytvo\u0159it v\u00fddajov\u00fd \u00fa\u010det",
|
|
||||||
"create_new_revenue": "Vytvo\u0159it nov\u00fd p\u0159\u00edjmov\u00fd \u00fa\u010det",
|
|
||||||
"create_new_liabilities": "Create new liability",
|
|
||||||
"half_year_budgets": "Pololetn\u00ed rozpo\u010dty",
|
|
||||||
"yearly_budgets": "Ro\u010dn\u00ed rozpo\u010dty",
|
|
||||||
"split_transaction_title": "Popis roz\u00fa\u010dtov\u00e1n\u00ed",
|
|
||||||
"errors_submission": "There was something wrong with your submission. Please check out the errors.",
|
|
||||||
"flash_error": "Chyba!",
|
|
||||||
"store_transaction": "Store transaction",
|
|
||||||
"flash_success": "\u00dasp\u011b\u0161n\u011b dokon\u010deno!",
|
|
||||||
"create_another": "After storing, return here to create another one.",
|
|
||||||
"update_transaction": "Aktualizovat transakci",
|
|
||||||
"after_update_create_another": "After updating, return here to continue editing.",
|
|
||||||
"transaction_updated_no_changes": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") did not receive any changes.",
|
|
||||||
"transaction_updated_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") has been updated.",
|
|
||||||
"spent_x_of_y": "Spent {amount} of {total}",
|
|
||||||
"search": "Hledat",
|
|
||||||
"create_new_asset": "Vytvo\u0159it nov\u00fd \u00fa\u010det aktiv",
|
|
||||||
"asset_accounts": "\u00da\u010dty aktiv",
|
|
||||||
"reset_after": "Reset form after submission",
|
|
||||||
"bill_paid_on": "Paid on {date}",
|
|
||||||
"first_split_decides": "The first split determines the value of this field",
|
|
||||||
"first_split_overrules_source": "The first split may overrule the source account",
|
|
||||||
"first_split_overrules_destination": "The first split may overrule the destination account",
|
|
||||||
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID} (\"{title}\")<\/a> has been stored.",
|
|
||||||
"custom_period": "Vlastn\u00ed obdob\u00ed",
|
|
||||||
"reset_to_current": "Obnovit aktu\u00e1ln\u00ed obdob\u00ed",
|
|
||||||
"select_period": "Vyberte obdob\u00ed",
|
|
||||||
"location": "Um\u00edst\u011bn\u00ed",
|
|
||||||
"other_budgets": "Custom timed budgets",
|
|
||||||
"journal_links": "Transaction links",
|
|
||||||
"go_to_withdrawals": "P\u0159ej\u00edt na v\u00fdb\u011bry",
|
|
||||||
"revenue_accounts": "P\u0159\u00edjmov\u00e9 \u00fa\u010dty",
|
|
||||||
"add_another_split": "P\u0159idat dal\u0161\u00ed roz\u00fa\u010dtov\u00e1n\u00ed",
|
|
||||||
"actions": "Akce",
|
|
||||||
"earned": "Vyd\u011bl\u00e1no",
|
|
||||||
"empty": "(pr\u00e1zdn\u00e9)",
|
|
||||||
"edit": "Upravit",
|
|
||||||
"never": "Nikdy",
|
|
||||||
"account_type_Loan": "P\u016fj\u010dka",
|
|
||||||
"account_type_Mortgage": "Hypot\u00e9ka",
|
|
||||||
"stored_new_account_js": "New account \"<a href=\"accounts\/show\/{ID}\">{name}<\/a>\" stored!",
|
|
||||||
"account_type_Debt": "Dluh",
|
|
||||||
"liability_direction_null_short": "Unknown",
|
|
||||||
"delete": "Odstranit",
|
|
||||||
"store_new_asset_account": "Ulo\u017eit nov\u00fd \u00fa\u010det aktiv",
|
|
||||||
"store_new_expense_account": "Ulo\u017eit nov\u00fd v\u00fddajov\u00fd \u00fa\u010det",
|
|
||||||
"store_new_liabilities_account": "Ulo\u017eit nov\u00fd z\u00e1vazek",
|
|
||||||
"store_new_revenue_account": "Ulo\u017eit nov\u00fd p\u0159\u00edjmov\u00fd \u00fa\u010det",
|
|
||||||
"mandatoryFields": "Povinn\u00e9 kolonky",
|
|
||||||
"optionalFields": "Voliteln\u00e9 kolonky",
|
|
||||||
"reconcile_this_account": "Vy\u00fa\u010dtovat tento \u00fa\u010det",
|
|
||||||
"interest_calc_weekly": "Per week",
|
|
||||||
"interest_calc_monthly": "Za m\u011bs\u00edc",
|
|
||||||
"interest_calc_quarterly": "Per quarter",
|
|
||||||
"interest_calc_half-year": "Per half year",
|
|
||||||
"interest_calc_yearly": "Za rok",
|
|
||||||
"liability_direction_credit": "I am owed this debt",
|
|
||||||
"liability_direction_debit": "I owe this debt to somebody else",
|
|
||||||
"liability_direction_credit_short": "Owed this debt",
|
|
||||||
"liability_direction_debit_short": "Owe this debt",
|
|
||||||
"account_type_debt": "Debt",
|
|
||||||
"account_type_loan": "Loan",
|
|
||||||
"left_in_debt": "Amount due",
|
|
||||||
"account_type_mortgage": "Mortgage",
|
|
||||||
"save_transactions_by_moving_js": "No transactions|Save this transaction by moving it to another account. |Save these transactions by moving them to another account.",
|
|
||||||
"none_in_select_list": "(\u017e\u00e1dn\u00e9)",
|
|
||||||
"transaction_expand_split": "Expand split",
|
|
||||||
"transaction_collapse_split": "Collapse split",
|
|
||||||
"default_group_title_name": "(neseskupeno)",
|
|
||||||
"bill_repeats_weekly": "Repeats weekly",
|
|
||||||
"bill_repeats_monthly": "Repeats monthly",
|
|
||||||
"bill_repeats_quarterly": "Repeats quarterly",
|
|
||||||
"bill_repeats_half-year": "Repeats every half year",
|
|
||||||
"bill_repeats_yearly": "Repeats yearly",
|
|
||||||
"bill_repeats_weekly_other": "Repeats every other week",
|
|
||||||
"bill_repeats_monthly_other": "Repeats every other month",
|
|
||||||
"bill_repeats_quarterly_other": "Repeats every other quarter",
|
|
||||||
"bill_repeats_half-year_other": "Repeats yearly",
|
|
||||||
"bill_repeats_yearly_other": "Repeats every other year",
|
|
||||||
"bill_repeats_weekly_skip": "Repeats every {skip} weeks",
|
|
||||||
"bill_repeats_monthly_skip": "Repeats every {skip} months",
|
|
||||||
"bill_repeats_quarterly_skip": "Repeats every {skip} quarters",
|
|
||||||
"bill_repeats_half-year_skip": "Repeats every {skip} half years",
|
|
||||||
"bill_repeats_yearly_skip": "Repeats every {skip} years",
|
|
||||||
"not_expected_period": "Not expected this period",
|
|
||||||
"subscriptions": "Subscriptions",
|
|
||||||
"bill_expected_date_js": "Expected {date}",
|
|
||||||
"inactive": "Neaktivn\u00ed",
|
|
||||||
"forever": "Forever",
|
|
||||||
"extension_date_is": "Extension date is {date}",
|
|
||||||
"create_new_bill": "Vytvo\u0159it novou fakturu",
|
|
||||||
"store_new_bill": "Ulo\u017eit novou \u00fa\u010dtenku",
|
|
||||||
"repeat_freq_yearly": "ro\u010dn\u011b",
|
|
||||||
"repeat_freq_half-year": "p\u016floro\u010dn\u011b",
|
|
||||||
"repeat_freq_quarterly": "\u010dtvrtletn\u011b",
|
|
||||||
"repeat_freq_monthly": "m\u011bs\u00ed\u010dn\u011b",
|
|
||||||
"repeat_freq_weekly": "t\u00fddn\u011b",
|
|
||||||
"credit_card_type_monthlyFull": "Full payment every month",
|
|
||||||
"update_liabilities_account": "Aktualizovat z\u00e1vazek",
|
|
||||||
"update_expense_account": "Aktualizovat v\u00fddajov\u00fd \u00fa\u010det",
|
|
||||||
"update_revenue_account": "Aktualizovat p\u0159\u00edjmov\u00fd \u00fa\u010det",
|
|
||||||
"update_undefined_account": "Update account",
|
|
||||||
"update_asset_account": "Aktualizovat v\u00fddajov\u00fd \u00fa\u010det",
|
|
||||||
"updated_account_js": "Updated account \"<a href=\"accounts\/show\/{ID}\">{title}<\/a>\"."
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"piggy_bank": "Pokladni\u010dka",
|
|
||||||
"percentage": "%",
|
|
||||||
"amount": "\u010c\u00e1stka",
|
|
||||||
"lastActivity": "Posledn\u00ed aktivita",
|
|
||||||
"name": "Jm\u00e9no",
|
|
||||||
"role": "Role",
|
|
||||||
"description": "Popis",
|
|
||||||
"date": "Datum",
|
|
||||||
"source_account": "Zdrojov\u00fd \u00fa\u010det",
|
|
||||||
"destination_account": "C\u00edlov\u00fd \u00fa\u010det",
|
|
||||||
"category": "Kategorie",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"interest": "\u00darok",
|
|
||||||
"interest_period": "\u00darokov\u00e9 obdob\u00ed",
|
|
||||||
"liability_type": "Typ z\u00e1vazku",
|
|
||||||
"liability_direction": "Sm\u011br z\u00e1vazku",
|
|
||||||
"currentBalance": "Aktu\u00e1ln\u00ed z\u016fstatek",
|
|
||||||
"next_expected_match": "Dal\u0161\u00ed o\u010dek\u00e1van\u00e1 shoda",
|
|
||||||
"expected_info": "Dal\u0161\u00ed o\u010dek\u00e1van\u00e1 transakce",
|
|
||||||
"start_date": "Datum zah\u00e1jen\u00ed",
|
|
||||||
"end_date": "Datum ukon\u010den\u00ed",
|
|
||||||
"payment_info": "Informace o platb\u011b"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"html_language": "cs",
|
|
||||||
"week_in_year_fns": "'t\u00fdden' w, yyyy",
|
|
||||||
"month_and_day_fns": "d MMMM, y",
|
|
||||||
"quarter_fns": "Q'Q, yyyy",
|
|
||||||
"half_year_fns": "'H{half}', yyyy"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"foreign_amount": "\u010c\u00e1stka v ciz\u00ed m\u011bn\u011b",
|
|
||||||
"interest_date": "\u00darokov\u00e9 datum",
|
|
||||||
"name": "N\u00e1zev",
|
|
||||||
"amount": "\u010c\u00e1stka",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"BIC": "BIC",
|
|
||||||
"notes": "Pozn\u00e1mky",
|
|
||||||
"location": "\u00dadaje o poloze",
|
|
||||||
"repeat_freq": "Opakuje se",
|
|
||||||
"skip": "P\u0159esko\u010dit",
|
|
||||||
"startdate": "Datum zah\u00e1jen\u00ed",
|
|
||||||
"enddate": "Datum ukon\u010den\u00ed",
|
|
||||||
"object_group": "Skupina",
|
|
||||||
"attachments": "P\u0159\u00edlohy",
|
|
||||||
"deletePermanently": "Nadobro smazat",
|
|
||||||
"active": "Aktivn\u00ed",
|
|
||||||
"include_net_worth": "Zahrnout do \u010dist\u00e9ho jm\u011bn\u00ed",
|
|
||||||
"cc_type": "Z\u00fa\u010dtovac\u00ed obdob\u00ed kreditn\u00ed karty",
|
|
||||||
"account_number": "\u010c\u00edslo \u00fa\u010dtu",
|
|
||||||
"cc_monthly_payment_date": "Datum m\u011bs\u00ed\u010dn\u00ed \u00fahrady kreditn\u00ed karty",
|
|
||||||
"virtual_balance": "Virtu\u00e1ln\u00ed z\u016fstatek",
|
|
||||||
"opening_balance": "Po\u010d\u00e1te\u010dn\u00ed z\u016fstatek",
|
|
||||||
"opening_balance_date": "Datum po\u010d\u00e1te\u010dn\u00edho z\u016fstatku",
|
|
||||||
"date": "Datum",
|
|
||||||
"interest": "\u00darok",
|
|
||||||
"interest_period": "\u00darokov\u00e9 obdob\u00ed",
|
|
||||||
"currency_id": "M\u011bna",
|
|
||||||
"liability_type": "Typ z\u00e1vazku",
|
|
||||||
"account_role": "Role \u00fa\u010dtu",
|
|
||||||
"liability_direction": "Sm\u011br z\u00e1vazku",
|
|
||||||
"book_date": "Datum rezervace",
|
|
||||||
"permDeleteWarning": "Odstran\u011bn\u00ed v\u011bc\u00ed z Firefly III je trval\u00e9 a nelze vr\u00e1tit zp\u011bt.",
|
|
||||||
"account_areYouSure_js": "Jste si jisti, \u017ee chcete odstranit \u00fa\u010det s n\u00e1zvem \"{name}\"?",
|
|
||||||
"also_delete_piggyBanks_js": "\u017d\u00e1dn\u00e9 pokladni\u010dky|Jedin\u00e1 pokladni\u010dka p\u0159ipojen\u00e1 k tomuto \u00fa\u010dtu bude tak\u00e9 odstran\u011bna. V\u0161ech {count} pokladni\u010dek, kter\u00e9 jsou p\u0159ipojeny k tomuto \u00fa\u010dtu, bude tak\u00e9 odstran\u011bno.",
|
|
||||||
"also_delete_transactions_js": "\u017d\u00e1dn\u00e9 transakce|Jedin\u00e1 transakce p\u0159ipojen\u00e1 k tomuto \u00fa\u010dtu bude tak\u00e9 smaz\u00e1na.|V\u0161ech {count} transakc\u00ed p\u0159ipojen\u00fdch k tomuto \u00fa\u010dtu bude tak\u00e9 odstran\u011bno.",
|
|
||||||
"process_date": "Datum zpracov\u00e1n\u00ed",
|
|
||||||
"due_date": "Datum splatnosti",
|
|
||||||
"payment_date": "Datum zaplacen\u00ed",
|
|
||||||
"invoice_date": "Datum vystaven\u00ed",
|
|
||||||
"amount_min": "Minim\u00e1ln\u00ed \u010d\u00e1stka",
|
|
||||||
"amount_max": "Maxim\u00e1ln\u00ed \u010d\u00e1stka",
|
|
||||||
"start_date": "Za\u010d\u00e1tek rozsahu",
|
|
||||||
"end_date": "Konec rozsahu",
|
|
||||||
"extension_date": "Datum roz\u0161\u00ed\u0159en\u00ed"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
{
|
|
||||||
"firefly": {
|
|
||||||
"Transfer": "Umbuchung",
|
|
||||||
"Withdrawal": "Ausgabe",
|
|
||||||
"Deposit": "Einnahme",
|
|
||||||
"date_and_time": "Datum und Uhrzeit",
|
|
||||||
"no_currency": "(ohne W\u00e4hrung)",
|
|
||||||
"date": "Datum",
|
|
||||||
"time": "Uhrzeit",
|
|
||||||
"no_budget": "(kein Budget)",
|
|
||||||
"destination_account": "Zielkonto",
|
|
||||||
"source_account": "Quellkonto",
|
|
||||||
"single_split": "Teil",
|
|
||||||
"create_new_transaction": "Neue Buchung erstellen",
|
|
||||||
"balance": "Kontostand",
|
|
||||||
"transaction_journal_extra": "Zus\u00e4tzliche Informationen",
|
|
||||||
"transaction_journal_meta": "Metainformationen",
|
|
||||||
"basic_journal_information": "Allgemeine Buchungsinformationen",
|
|
||||||
"bills_to_pay": "Unbezahlte Rechnungen",
|
|
||||||
"left_to_spend": "Verbleibend zum Ausgeben",
|
|
||||||
"attachments": "Anh\u00e4nge",
|
|
||||||
"net_worth": "Eigenkapital",
|
|
||||||
"bill": "Rechnung",
|
|
||||||
"no_bill": "(keine Belege)",
|
|
||||||
"tags": "Schlagw\u00f6rter",
|
|
||||||
"internal_reference": "Interner Verweis",
|
|
||||||
"external_url": "Externe URL",
|
|
||||||
"no_piggy_bank": "(kein Sparschwein)",
|
|
||||||
"paid": "Bezahlt",
|
|
||||||
"notes": "Notizen",
|
|
||||||
"yourAccounts": "Deine Konten",
|
|
||||||
"go_to_asset_accounts": "Bestandskonten anzeigen",
|
|
||||||
"delete_account": "Konto l\u00f6schen",
|
|
||||||
"transaction_table_description": "Eine Tabelle mit Ihren Buchungen",
|
|
||||||
"account": "Konto",
|
|
||||||
"description": "Beschreibung",
|
|
||||||
"amount": "Betrag",
|
|
||||||
"budget": "Budget",
|
|
||||||
"category": "Kategorie",
|
|
||||||
"opposing_account": "Gegenkonto",
|
|
||||||
"budgets": "Budgets",
|
|
||||||
"categories": "Kategorien",
|
|
||||||
"go_to_budgets": "Budgets anzeigen",
|
|
||||||
"income": "Einnahmen \/ Einkommen",
|
|
||||||
"go_to_deposits": "Einnahmen anzeigen",
|
|
||||||
"go_to_categories": "Kategorien anzeigen",
|
|
||||||
"expense_accounts": "Ausgabekonten",
|
|
||||||
"go_to_expenses": "Ausgaben anzeigen",
|
|
||||||
"go_to_bills": "Rechnungen anzeigen",
|
|
||||||
"bills": "Vertr\u00e4ge",
|
|
||||||
"last_thirty_days": "Letzte 30 Tage",
|
|
||||||
"last_seven_days": "Letzte sieben Tage",
|
|
||||||
"go_to_piggies": "Sparschweine anzeigen",
|
|
||||||
"saved": "Gespeichert",
|
|
||||||
"piggy_banks": "Sparschweine",
|
|
||||||
"piggy_bank": "Sparschwein",
|
|
||||||
"amounts": "Betr\u00e4ge",
|
|
||||||
"left": "\u00dcbrig",
|
|
||||||
"spent": "Ausgegeben",
|
|
||||||
"Default asset account": "Standard-Bestandskonto",
|
|
||||||
"search_results": "Suchergebnisse",
|
|
||||||
"include": "Inbegriffen?",
|
|
||||||
"transaction": "\u00dcberweisung",
|
|
||||||
"account_role_defaultAsset": "Standard-Bestandskonto",
|
|
||||||
"account_role_savingAsset": "Sparkonto",
|
|
||||||
"account_role_sharedAsset": "Gemeinsames Bestandskonto",
|
|
||||||
"clear_location": "Ort leeren",
|
|
||||||
"account_role_ccAsset": "Kreditkarte",
|
|
||||||
"account_role_cashWalletAsset": "Geldb\u00f6rse",
|
|
||||||
"daily_budgets": "Tagesbudgets",
|
|
||||||
"weekly_budgets": "Wochenbudgets",
|
|
||||||
"monthly_budgets": "Monatsbudgets",
|
|
||||||
"journals_in_period_for_account_js": "Alle Buchungen f\u00fcr Account {title} zwischen {start} und {end}",
|
|
||||||
"quarterly_budgets": "Quartalsbudgets",
|
|
||||||
"create_new_expense": "Neues Ausgabenkonto erstellen",
|
|
||||||
"create_new_revenue": "Neues Einnahmenkonto erstellen",
|
|
||||||
"create_new_liabilities": "Neue Verbindlichkeit anlegen",
|
|
||||||
"half_year_budgets": "Halbjahresbudgets",
|
|
||||||
"yearly_budgets": "Jahresbudgets",
|
|
||||||
"split_transaction_title": "Beschreibung der Splittbuchung",
|
|
||||||
"errors_submission": "Ihre \u00dcbermittlung ist fehlgeschlagen. Bitte \u00fcberpr\u00fcfen Sie die Fehler.",
|
|
||||||
"flash_error": "Fehler!",
|
|
||||||
"store_transaction": "Buchung speichern",
|
|
||||||
"flash_success": "Geschafft!",
|
|
||||||
"create_another": "Nach dem Speichern hierher zur\u00fcckkehren, um ein weiteres zu erstellen.",
|
|
||||||
"update_transaction": "Buchung aktualisieren",
|
|
||||||
"after_update_create_another": "Nach dem Aktualisieren hierher zur\u00fcckkehren, um weiter zu bearbeiten.",
|
|
||||||
"transaction_updated_no_changes": "<a href=\"transactions\/show\/{ID}\">Die Buchung #{ID}<\/a> (\"{title}\") wurde nicht ver\u00e4ndert.",
|
|
||||||
"transaction_updated_link": "<a href=\"transactions\/show\/{ID}\">Die Buchung #{ID}<\/a> (\"{title}\") wurde aktualisiert.",
|
|
||||||
"spent_x_of_y": "{amount} von {total} ausgegeben",
|
|
||||||
"search": "Suche",
|
|
||||||
"create_new_asset": "Neues Bestandskonto erstellen",
|
|
||||||
"asset_accounts": "Bestandskonten",
|
|
||||||
"reset_after": "Formular nach der \u00dcbermittlung zur\u00fccksetzen",
|
|
||||||
"bill_paid_on": "Bezahlt am {date}",
|
|
||||||
"first_split_decides": "Die erste Aufteilung bestimmt den Wert dieses Feldes",
|
|
||||||
"first_split_overrules_source": "Die erste Aufteilung k\u00f6nnte das Quellkonto \u00fcberschreiben",
|
|
||||||
"first_split_overrules_destination": "Die erste Aufteilung k\u00f6nnte das Zielkonto \u00fcberschreiben",
|
|
||||||
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Buchung #{ID} (\"{title}\")<\/a> wurde gespeichert.",
|
|
||||||
"custom_period": "Benutzerdefinierter Zeitraum",
|
|
||||||
"reset_to_current": "Auf aktuellen Zeitraum zur\u00fccksetzen",
|
|
||||||
"select_period": "Zeitraum ausw\u00e4hlen",
|
|
||||||
"location": "Standort",
|
|
||||||
"other_budgets": "Zeitlich befristete Budgets",
|
|
||||||
"journal_links": "Buchungsverkn\u00fcpfungen",
|
|
||||||
"go_to_withdrawals": "Ausgaben anzeigen",
|
|
||||||
"revenue_accounts": "Einnahmekonten",
|
|
||||||
"add_another_split": "Eine weitere Aufteilung hinzuf\u00fcgen",
|
|
||||||
"actions": "Aktionen",
|
|
||||||
"earned": "Eingenommen",
|
|
||||||
"empty": "(leer)",
|
|
||||||
"edit": "Bearbeiten",
|
|
||||||
"never": "Nie",
|
|
||||||
"account_type_Loan": "Darlehen",
|
|
||||||
"account_type_Mortgage": "Hypothek",
|
|
||||||
"stored_new_account_js": "Neues Konto \"<a href=\"accounts\/show\/{ID}\">\u201e{name}\u201d<\/a>\" gespeichert!",
|
|
||||||
"account_type_Debt": "Schuld",
|
|
||||||
"liability_direction_null_short": "Unbekannt",
|
|
||||||
"delete": "L\u00f6schen",
|
|
||||||
"store_new_asset_account": "Neues Bestandskonto speichern",
|
|
||||||
"store_new_expense_account": "Neues Ausgabenkonto speichern",
|
|
||||||
"store_new_liabilities_account": "Neue Verbindlichkeit speichern",
|
|
||||||
"store_new_revenue_account": "Neues Einnahmenkonto speichern",
|
|
||||||
"mandatoryFields": "Pflichtfelder",
|
|
||||||
"optionalFields": "Optionale Felder",
|
|
||||||
"reconcile_this_account": "Dieses Konto abgleichen",
|
|
||||||
"interest_calc_weekly": "Pro Woche",
|
|
||||||
"interest_calc_monthly": "Monatlich",
|
|
||||||
"interest_calc_quarterly": "Viertelj\u00e4hrlich",
|
|
||||||
"interest_calc_half-year": "Halbj\u00e4hrlich",
|
|
||||||
"interest_calc_yearly": "J\u00e4hrlich",
|
|
||||||
"liability_direction_credit": "Mir wird dies geschuldet",
|
|
||||||
"liability_direction_debit": "Ich schulde dies jemandem",
|
|
||||||
"liability_direction_credit_short": "Geschuldeter Betrag",
|
|
||||||
"liability_direction_debit_short": "Schuldiger Betrag",
|
|
||||||
"account_type_debt": "Schulden",
|
|
||||||
"account_type_loan": "Darlehen",
|
|
||||||
"left_in_debt": "F\u00e4lliger Betrag",
|
|
||||||
"account_type_mortgage": "Hypothek",
|
|
||||||
"save_transactions_by_moving_js": "Keine Buchungen|Speichern Sie diese Buchung, indem Sie sie auf ein anderes Konto verschieben. |Speichern Sie diese Buchungen, indem Sie sie auf ein anderes Konto verschieben.",
|
|
||||||
"none_in_select_list": "(Keine)",
|
|
||||||
"transaction_expand_split": "Aufteilung erweitern",
|
|
||||||
"transaction_collapse_split": "Aufteilung reduzieren",
|
|
||||||
"default_group_title_name": "(ohne Gruppierung)",
|
|
||||||
"bill_repeats_weekly": "Wiederholt sich w\u00f6chentlich",
|
|
||||||
"bill_repeats_monthly": "Wiederholt sich monatlich",
|
|
||||||
"bill_repeats_quarterly": "Wiederholt sich viertelj\u00e4hrlich",
|
|
||||||
"bill_repeats_half-year": "Wiederholt sich halbj\u00e4hrlich",
|
|
||||||
"bill_repeats_yearly": "Wiederholt sich j\u00e4hrlich",
|
|
||||||
"bill_repeats_weekly_other": "Wiederholt sich jede zweite Woche",
|
|
||||||
"bill_repeats_monthly_other": "Wiederholt sich jeden zweiten Monat",
|
|
||||||
"bill_repeats_quarterly_other": "Wiederholt sich jedes zweite Vierteljahr",
|
|
||||||
"bill_repeats_half-year_other": "Wiederholt sich j\u00e4hrlich",
|
|
||||||
"bill_repeats_yearly_other": "Wiederholt sich jedes zweite Jahr",
|
|
||||||
"bill_repeats_weekly_skip": "Wiederholt sich alle {skip} Wochen",
|
|
||||||
"bill_repeats_monthly_skip": "Wiederholt sich alle {skip} Monate",
|
|
||||||
"bill_repeats_quarterly_skip": "Wiederholt sich alle {skip} Vierteljahre",
|
|
||||||
"bill_repeats_half-year_skip": "Wiederholt sich alle {skip} Halbjahre",
|
|
||||||
"bill_repeats_yearly_skip": "Wiederholt sich alle {skip} Jahre",
|
|
||||||
"not_expected_period": "In diesem Zeitraum nicht erwartet",
|
|
||||||
"subscriptions": "Abonnements",
|
|
||||||
"bill_expected_date_js": "Erwartet {date}",
|
|
||||||
"inactive": "Inaktiv",
|
|
||||||
"forever": "Dauerhaft",
|
|
||||||
"extension_date_is": "Zeitpunkt der Verl\u00e4ngerung ist {date}",
|
|
||||||
"create_new_bill": "Eine neue Rechnung erstellen",
|
|
||||||
"store_new_bill": "Neue Rechnung speichern",
|
|
||||||
"repeat_freq_yearly": "J\u00e4hrlich",
|
|
||||||
"repeat_freq_half-year": "halbj\u00e4hrlich",
|
|
||||||
"repeat_freq_quarterly": "viertelj\u00e4hrlich",
|
|
||||||
"repeat_freq_monthly": "monatlich",
|
|
||||||
"repeat_freq_weekly": "w\u00f6chentlich",
|
|
||||||
"credit_card_type_monthlyFull": "Vollst\u00e4ndige Zahlung jeden Monat",
|
|
||||||
"update_liabilities_account": "Verbindlichkeit aktualisieren",
|
|
||||||
"update_expense_account": "Ausgabenkonto aktualisieren",
|
|
||||||
"update_revenue_account": "Einnahmenkonto aktualisieren",
|
|
||||||
"update_undefined_account": "Konto aktualisieren",
|
|
||||||
"update_asset_account": "Bestandskonto aktualisieren",
|
|
||||||
"updated_account_js": "Konto \"<a href=\"accounts\/show\/{ID}\">{title}<\/a>\" aktualisiert."
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"piggy_bank": "Sparschwein",
|
|
||||||
"percentage": "%",
|
|
||||||
"amount": "Betrag",
|
|
||||||
"lastActivity": "Letzte Aktivit\u00e4t",
|
|
||||||
"name": "Name",
|
|
||||||
"role": "Rolle",
|
|
||||||
"description": "Beschreibung",
|
|
||||||
"date": "Datum",
|
|
||||||
"source_account": "Quellkonto",
|
|
||||||
"destination_account": "Zielkonto",
|
|
||||||
"category": "Kategorie",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"interest": "Zinsen",
|
|
||||||
"interest_period": "Zinsperiode",
|
|
||||||
"liability_type": "Verbindlichkeitsart",
|
|
||||||
"liability_direction": "Verbindlichkeit ein\/aus",
|
|
||||||
"currentBalance": "Aktueller Kontostand",
|
|
||||||
"next_expected_match": "N\u00e4chste erwartete \u00dcbereinstimmung",
|
|
||||||
"expected_info": "N\u00e4chste erwartete Buchung",
|
|
||||||
"start_date": "Beginnt am",
|
|
||||||
"end_date": "Endet am",
|
|
||||||
"payment_info": "Zahlungsinformationen"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"html_language": "de",
|
|
||||||
"week_in_year_fns": "'Woche' ww\/yyyy",
|
|
||||||
"month_and_day_fns": "d. MMMM Y",
|
|
||||||
"quarter_fns": "'Q'QQQ, yyyy",
|
|
||||||
"half_year_fns": "'H{half}', yyyy"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"foreign_amount": "Ausl\u00e4ndischer Betrag",
|
|
||||||
"interest_date": "Zinstermin",
|
|
||||||
"name": "Name",
|
|
||||||
"amount": "Betrag",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"BIC": "BIC",
|
|
||||||
"notes": "Notizen",
|
|
||||||
"location": "Herkunft",
|
|
||||||
"repeat_freq": "Wiederholungen",
|
|
||||||
"skip": "\u00dcberspringen",
|
|
||||||
"startdate": "Startdatum",
|
|
||||||
"enddate": "Endet am",
|
|
||||||
"object_group": "Gruppe",
|
|
||||||
"attachments": "Anh\u00e4nge",
|
|
||||||
"deletePermanently": "Dauerhaft l\u00f6schen",
|
|
||||||
"active": "Aktiv",
|
|
||||||
"include_net_worth": "Im Eigenkapital enthalten",
|
|
||||||
"cc_type": "Kreditkartenzahlungsplan",
|
|
||||||
"account_number": "Kontonummer",
|
|
||||||
"cc_monthly_payment_date": "Monatlicher Kreditkartenzahlungsplan",
|
|
||||||
"virtual_balance": "Virtueller Kontostand",
|
|
||||||
"opening_balance": "Er\u00f6ffnungsbilanz",
|
|
||||||
"opening_balance_date": "Er\u00f6ffnungsbilanzdatum",
|
|
||||||
"date": "Datum",
|
|
||||||
"interest": "Zinsen",
|
|
||||||
"interest_period": "Verzinsungszeitraum",
|
|
||||||
"currency_id": "W\u00e4hrung",
|
|
||||||
"liability_type": "Art der Verbindlichkeit",
|
|
||||||
"account_role": "Kontenfunktion",
|
|
||||||
"liability_direction": "Verbindlichkeit Ein\/Aus",
|
|
||||||
"book_date": "Buchungsdatum",
|
|
||||||
"permDeleteWarning": "Das L\u00f6schen von Dingen in Firefly III ist dauerhaft und kann nicht r\u00fcckg\u00e4ngig gemacht werden.",
|
|
||||||
"account_areYouSure_js": "M\u00f6chten Sie das Konto \u201e{name}\u201d wirklich l\u00f6schen?",
|
|
||||||
"also_delete_piggyBanks_js": "Keine Sparschweine|Das einzige Sparschwein, welches mit diesem Konto verbunden ist, wird ebenfalls gel\u00f6scht.|Alle {count} Sparschweine, welche mit diesem Konto verbunden sind, werden ebenfalls gel\u00f6scht.",
|
|
||||||
"also_delete_transactions_js": "Keine Buchungen|Die einzige Buchung, die mit diesem Konto verbunden ist, wird ebenfalls gel\u00f6scht.|Alle {count} Buchungen, die mit diesem Konto verbunden sind, werden ebenfalls gel\u00f6scht.",
|
|
||||||
"process_date": "Bearbeitungsdatum",
|
|
||||||
"due_date": "F\u00e4lligkeitstermin",
|
|
||||||
"payment_date": "Zahlungsdatum",
|
|
||||||
"invoice_date": "Rechnungsdatum",
|
|
||||||
"amount_min": "Mindestbetrag",
|
|
||||||
"amount_max": "H\u00f6chstbetrag",
|
|
||||||
"start_date": "Anfang des Bereichs",
|
|
||||||
"end_date": "Ende des Bereichs",
|
|
||||||
"extension_date": "Verl\u00e4ngerungsdatum"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
{
|
|
||||||
"firefly": {
|
|
||||||
"Transfer": "\u039c\u03b5\u03c4\u03b1\u03c6\u03bf\u03c1\u03ac",
|
|
||||||
"Withdrawal": "\u0391\u03bd\u03ac\u03bb\u03b7\u03c8\u03b7",
|
|
||||||
"Deposit": "\u039a\u03b1\u03c4\u03ac\u03b8\u03b5\u03c3\u03b7",
|
|
||||||
"date_and_time": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03ba\u03b1\u03b9 \u03ce\u03c1\u03b1",
|
|
||||||
"no_currency": "(\u03c7\u03c9\u03c1\u03af\u03c2 \u03bd\u03cc\u03bc\u03b9\u03c3\u03bc\u03b1)",
|
|
||||||
"date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1",
|
|
||||||
"time": "\u038f\u03c1\u03b1",
|
|
||||||
"no_budget": "(\u03c7\u03c9\u03c1\u03af\u03c2 \u03c0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03cc)",
|
|
||||||
"destination_account": "\u039b\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03c0\u03c1\u03bf\u03bf\u03c1\u03b9\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"source_account": "\u039b\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03c0\u03c1\u03bf\u03ad\u03bb\u03b5\u03c5\u03c3\u03b7\u03c2",
|
|
||||||
"single_split": "\u0394\u03b9\u03b1\u03c7\u03c9\u03c1\u03b9\u03c3\u03bc\u03cc\u03c2",
|
|
||||||
"create_new_transaction": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03bc\u03b9\u03b1\u03c2 \u03bd\u03ad\u03b1\u03c2 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae\u03c2",
|
|
||||||
"balance": "\u0399\u03c3\u03bf\u03b6\u03cd\u03b3\u03b9\u03bf",
|
|
||||||
"transaction_journal_extra": "\u03a0\u03b5\u03c1\u03b9\u03c3\u03c3\u03cc\u03c4\u03b5\u03c1\u03b5\u03c2 \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2",
|
|
||||||
"transaction_journal_meta": "\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd",
|
|
||||||
"basic_journal_information": "\u0392\u03b1\u03c3\u03b9\u03ba\u03ad\u03c2 \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae\u03c2",
|
|
||||||
"bills_to_pay": "\u03a0\u03ac\u03b3\u03b9\u03b1 \u03ad\u03be\u03bf\u03b4\u03b1 \u03c0\u03c1\u03bf\u03c2 \u03c0\u03bb\u03b7\u03c1\u03c9\u03bc\u03ae",
|
|
||||||
"left_to_spend": "\u0394\u03b9\u03b1\u03b8\u03ad\u03c3\u03b9\u03bc\u03b1 \u03c0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03ce\u03bd",
|
|
||||||
"attachments": "\u03a3\u03c5\u03bd\u03b7\u03bc\u03bc\u03ad\u03bd\u03b1",
|
|
||||||
"net_worth": "\u039a\u03b1\u03b8\u03b1\u03c1\u03ae \u03b1\u03be\u03af\u03b1",
|
|
||||||
"bill": "\u03a0\u03ac\u03b3\u03b9\u03bf \u03ad\u03be\u03bf\u03b4\u03bf",
|
|
||||||
"no_bill": "(\u03c7\u03c9\u03c1\u03af\u03c2 \u03c0\u03ac\u03b3\u03b9\u03bf \u03ad\u03be\u03bf\u03b4\u03bf)",
|
|
||||||
"tags": "\u0395\u03c4\u03b9\u03ba\u03ad\u03c4\u03b5\u03c2",
|
|
||||||
"internal_reference": "\u0395\u03c3\u03c9\u03c4\u03b5\u03c1\u03b9\u03ba\u03ae \u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac",
|
|
||||||
"external_url": "\u0395\u03be\u03c9\u03c4\u03b5\u03c1\u03b9\u03ba\u03cc URL",
|
|
||||||
"no_piggy_bank": "(\u03c7\u03c9\u03c1\u03af\u03c2 \u03ba\u03bf\u03c5\u03bc\u03c0\u03b1\u03c1\u03ac)",
|
|
||||||
"paid": "\u03a0\u03bb\u03b7\u03c1\u03c9\u03bc\u03ad\u03bd\u03bf",
|
|
||||||
"notes": "\u03a3\u03b7\u03bc\u03b5\u03b9\u03ce\u03c3\u03b5\u03b9\u03c2",
|
|
||||||
"yourAccounts": "\u039f\u03b9 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03af \u03c3\u03b1\u03c2",
|
|
||||||
"go_to_asset_accounts": "\u0394\u03b5\u03af\u03c4\u03b5 \u03c4\u03bf\u03c5\u03c2 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd\u03c2 \u03ba\u03b5\u03c6\u03b1\u03bb\u03b1\u03af\u03bf\u03c5 \u03c3\u03b1\u03c2",
|
|
||||||
"delete_account": "\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"transaction_table_description": "\u0388\u03bd\u03b1\u03c2 \u03c0\u03af\u03bd\u03b1\u03ba\u03b1\u03c2 \u03bc\u03b5 \u03c4\u03b9\u03c2 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ad\u03c2 \u03c3\u03b1\u03c2",
|
|
||||||
"account": "\u039b\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2",
|
|
||||||
"description": "\u03a0\u03b5\u03c1\u03b9\u03b3\u03c1\u03b1\u03c6\u03ae",
|
|
||||||
"amount": "\u03a0\u03bf\u03c3\u03cc",
|
|
||||||
"budget": "\u03a0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03cc\u03c2",
|
|
||||||
"category": "\u039a\u03b1\u03c4\u03b7\u03b3\u03bf\u03c1\u03af\u03b1",
|
|
||||||
"opposing_account": "\u0388\u03bd\u03b1\u03bd\u03c4\u03b9 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2",
|
|
||||||
"budgets": "\u03a0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03bf\u03af",
|
|
||||||
"categories": "\u039a\u03b1\u03c4\u03b7\u03b3\u03bf\u03c1\u03af\u03b5\u03c2",
|
|
||||||
"go_to_budgets": "\u03a0\u03b7\u03b3\u03b1\u03af\u03bd\u03b5\u03c4\u03b5 \u03c3\u03c4\u03bf\u03c5\u03c2 \u03c0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03bf\u03cd\u03c2 \u03c3\u03b1\u03c2",
|
|
||||||
"income": "\u0388\u03c3\u03bf\u03b4\u03b1",
|
|
||||||
"go_to_deposits": "\u03a0\u03b7\u03b3\u03b1\u03af\u03bd\u03b5\u03c4\u03b5 \u03c3\u03c4\u03b9\u03c2 \u03ba\u03b1\u03c4\u03b1\u03b8\u03ad\u03c3\u03b5\u03b9\u03c2",
|
|
||||||
"go_to_categories": "\u03a0\u03b7\u03b3\u03b1\u03af\u03bd\u03b5\u03c4\u03b5 \u03c3\u03c4\u03b9\u03c2 \u03ba\u03b1\u03c4\u03b7\u03b3\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03b1\u03c2",
|
|
||||||
"expense_accounts": "\u0394\u03b1\u03c0\u03ac\u03bd\u03b5\u03c2",
|
|
||||||
"go_to_expenses": "\u03a0\u03b7\u03b3\u03b1\u03af\u03bd\u03b5\u03c4\u03b5 \u03c3\u03c4\u03b9\u03c2 \u03b4\u03b1\u03c0\u03ac\u03bd\u03b5\u03c2",
|
|
||||||
"go_to_bills": "\u03a0\u03b7\u03b3\u03b1\u03af\u03bd\u03b5\u03c4\u03b5 \u03c3\u03c4\u03b1 \u03c0\u03ac\u03b3\u03b9\u03b1 \u03ad\u03be\u03bf\u03b4\u03b1",
|
|
||||||
"bills": "\u03a0\u03ac\u03b3\u03b9\u03b1 \u03ad\u03be\u03bf\u03b4\u03b1",
|
|
||||||
"last_thirty_days": "\u03a4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03b5\u03c2 \u03c4\u03c1\u03b9\u03ac\u03bd\u03c4\u03b1 \u03b7\u03bc\u03ad\u03c1\u03b5\u03c2",
|
|
||||||
"last_seven_days": "\u03a4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03b5\u03c2 \u03b5\u03c0\u03c4\u03ac \u03b7\u03bc\u03ad\u03c1\u03b5\u03c2",
|
|
||||||
"go_to_piggies": "\u03a0\u03b7\u03b3\u03b1\u03af\u03bd\u03b5\u03c4\u03b5 \u03c3\u03c4\u03bf\u03c5\u03c2 \u03ba\u03bf\u03c5\u03bc\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03c2 \u03c3\u03b1\u03c2",
|
|
||||||
"saved": "\u0391\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c4\u03b7\u03ba\u03b5",
|
|
||||||
"piggy_banks": "\u039a\u03bf\u03c5\u03bc\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03c2",
|
|
||||||
"piggy_bank": "\u039a\u03bf\u03c5\u03bc\u03c0\u03b1\u03c1\u03ac\u03c2",
|
|
||||||
"amounts": "\u03a0\u03bf\u03c3\u03ac",
|
|
||||||
"left": "\u0391\u03c0\u03bf\u03bc\u03ad\u03bd\u03bf\u03c5\u03bd",
|
|
||||||
"spent": "\u0394\u03b1\u03c0\u03b1\u03bd\u03ae\u03b8\u03b7\u03ba\u03b1\u03bd",
|
|
||||||
"Default asset account": "\u0392\u03b1\u03c3\u03b9\u03ba\u03cc\u03c2 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03ba\u03b5\u03c6\u03b1\u03bb\u03b1\u03af\u03bf\u03c5",
|
|
||||||
"search_results": "\u0391\u03c0\u03bf\u03c4\u03b5\u03bb\u03ad\u03c3\u03bc\u03b1\u03c4\u03b1 \u03b1\u03bd\u03b1\u03b6\u03ae\u03c4\u03b7\u03c3\u03b7\u03c2",
|
|
||||||
"include": "\u03a0\u03b5\u03c1\u03b9\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9;",
|
|
||||||
"transaction": "\u03a3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae",
|
|
||||||
"account_role_defaultAsset": "\u0392\u03b1\u03c3\u03b9\u03ba\u03cc\u03c2 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03ba\u03b5\u03c6\u03b1\u03bb\u03b1\u03af\u03bf\u03c5",
|
|
||||||
"account_role_savingAsset": "\u039b\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03b1\u03c0\u03bf\u03c4\u03b1\u03bc\u03af\u03b5\u03c5\u03c3\u03b7\u03c2",
|
|
||||||
"account_role_sharedAsset": "\u039a\u03bf\u03b9\u03bd\u03cc\u03c2 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03ba\u03b5\u03c6\u03b1\u03bb\u03b1\u03af\u03bf\u03c5",
|
|
||||||
"clear_location": "\u0395\u03ba\u03ba\u03b1\u03b8\u03ac\u03c1\u03b9\u03c3\u03b7 \u03c4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1\u03c2",
|
|
||||||
"account_role_ccAsset": "\u03a0\u03b9\u03c3\u03c4\u03c9\u03c4\u03b9\u03ba\u03ae \u03ba\u03ac\u03c1\u03c4\u03b1",
|
|
||||||
"account_role_cashWalletAsset": "\u03a0\u03bf\u03c1\u03c4\u03bf\u03c6\u03cc\u03bb\u03b9 \u03bc\u03b5\u03c4\u03c1\u03b7\u03c4\u03ce\u03bd",
|
|
||||||
"daily_budgets": "\u0397\u03bc\u03b5\u03c1\u03ae\u03c3\u03b9\u03bf\u03b9 \u03c0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03bf\u03af",
|
|
||||||
"weekly_budgets": "\u0395\u03b2\u03b4\u03bf\u03bc\u03b1\u03b4\u03b9\u03b1\u03af\u03bf\u03b9 \u03c0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03bf\u03af",
|
|
||||||
"monthly_budgets": "\u039c\u03b7\u03bd\u03b9\u03b1\u03af\u03bf\u03b9 \u03c0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03bf\u03af",
|
|
||||||
"journals_in_period_for_account_js": "\u038c\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ad\u03c2 \u03b3\u03b9\u03b1 \u03c4\u03bf\u03bd \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc {title} \u03bc\u03b5\u03c4\u03b1\u03be\u03cd {start} \u03ba\u03b1\u03b9 {end}",
|
|
||||||
"quarterly_budgets": "\u03a4\u03c1\u03b9\u03bc\u03b7\u03bd\u03b9\u03b1\u03af\u03bf\u03b9 \u03c0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03bf\u03af",
|
|
||||||
"create_new_expense": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03bd\u03ad\u03bf\u03c5 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd \u03b4\u03b1\u03c0\u03b1\u03bd\u03ce\u03bd",
|
|
||||||
"create_new_revenue": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03bd\u03ad\u03bf\u03c5 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd \u03b5\u03c3\u03cc\u03b4\u03c9\u03bd",
|
|
||||||
"create_new_liabilities": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03bd\u03ad\u03b1\u03c2 \u03c5\u03c0\u03bf\u03c7\u03c1\u03ad\u03c9\u03c3\u03b7\u03c2",
|
|
||||||
"half_year_budgets": "\u0395\u03be\u03b1\u03bc\u03b7\u03bd\u03b9\u03b1\u03af\u03bf\u03b9 \u03c0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03bf\u03af",
|
|
||||||
"yearly_budgets": "\u0395\u03c4\u03ae\u03c3\u03b9\u03bf\u03b9 \u03c0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03bf\u03af",
|
|
||||||
"split_transaction_title": "\u03a0\u03b5\u03c1\u03b9\u03b3\u03c1\u03b1\u03c6\u03ae \u03c4\u03b7\u03c2 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae\u03c2 \u03bc\u03b5 \u03b4\u03b9\u03b1\u03c7\u03c9\u03c1\u03b9\u03c3\u03bc\u03cc",
|
|
||||||
"errors_submission": "\u03a5\u03c0\u03ae\u03c1\u03be\u03b5 \u03ba\u03ac\u03c0\u03bf\u03b9\u03bf \u03bb\u03ac\u03b8\u03bf\u03c2 \u03bc\u03b5 \u03c4\u03b7\u03bd \u03c5\u03c0\u03bf\u03b2\u03bf\u03bb\u03ae \u03c3\u03b1\u03c2. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce \u03b5\u03bb\u03ad\u03b3\u03be\u03c4\u03b5 \u03c4\u03b1 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1\u03c4\u03b1.",
|
|
||||||
"flash_error": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1!",
|
|
||||||
"store_transaction": "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae\u03c2",
|
|
||||||
"flash_success": "\u0395\u03c0\u03b9\u03c4\u03c5\u03c7\u03af\u03b1!",
|
|
||||||
"create_another": "\u039c\u03b5\u03c4\u03ac \u03c4\u03b7\u03bd \u03b1\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7, \u03b5\u03c0\u03b9\u03c3\u03c4\u03c1\u03ad\u03c8\u03c4\u03b5 \u03b5\u03b4\u03ce \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03b1\u03ba\u03cc\u03bc\u03b7 \u03ad\u03bd\u03b1.",
|
|
||||||
"update_transaction": "\u0395\u03bd\u03b7\u03bc\u03ad\u03c1\u03c9\u03c3\u03b7 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae\u03c2",
|
|
||||||
"after_update_create_another": "\u039c\u03b5\u03c4\u03ac \u03c4\u03b7\u03bd \u03b5\u03bd\u03b7\u03bc\u03ad\u03c1\u03c9\u03c3\u03b7, \u03b5\u03c0\u03b9\u03c3\u03c4\u03c1\u03ad\u03c8\u03c4\u03b5 \u03b5\u03b4\u03ce \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03c3\u03c5\u03bd\u03b5\u03c7\u03af\u03c3\u03b5\u03c4\u03b5 \u03c4\u03b7\u03bd \u03b5\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1.",
|
|
||||||
"transaction_updated_no_changes": "<a href=\"transactions\/show\/{ID}\">\u0397 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae #{ID}<\/a> (\"{title}\") \u03c0\u03b1\u03c1\u03ad\u03bc\u03b5\u03b9\u03bd\u03b5 \u03c7\u03c9\u03c1\u03af\u03c2 \u03ba\u03b1\u03bc\u03af\u03b1 \u03b1\u03bb\u03bb\u03b1\u03b3\u03ae.",
|
|
||||||
"transaction_updated_link": "<a href=\"transactions\/show\/{ID}\">\u0397 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae #{ID}<\/a> (\"{title}\") \u03ad\u03c7\u03b5\u03b9 \u03b5\u03bd\u03b7\u03bc\u03b5\u03c1\u03c9\u03b8\u03b5\u03af.",
|
|
||||||
"spent_x_of_y": "\u0394\u03b1\u03c0\u03b1\u03bd\u03ae\u03b8\u03b7\u03ba\u03b1\u03bd {amount} \u03b1\u03c0\u03cc {total}",
|
|
||||||
"search": "\u0391\u03bd\u03b1\u03b6\u03ae\u03c4\u03b7\u03c3\u03b7",
|
|
||||||
"create_new_asset": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03bd\u03ad\u03bf\u03c5 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd \u03ba\u03b5\u03c6\u03b1\u03bb\u03b1\u03af\u03bf\u03c5",
|
|
||||||
"asset_accounts": "\u039a\u03b5\u03c6\u03ac\u03bb\u03b1\u03b9\u03b1",
|
|
||||||
"reset_after": "\u0395\u03c0\u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac \u03c6\u03cc\u03c1\u03bc\u03b1\u03c2 \u03bc\u03b5\u03c4\u03ac \u03c4\u03b7\u03bd \u03c5\u03c0\u03bf\u03b2\u03bf\u03bb\u03ae",
|
|
||||||
"bill_paid_on": "\u03a0\u03bb\u03b7\u03c1\u03ce\u03b8\u03b7\u03ba\u03b5 \u03c3\u03c4\u03b9\u03c2 {date}",
|
|
||||||
"first_split_decides": "\u039f \u03c0\u03c1\u03ce\u03c4\u03bf\u03c2 \u03b4\u03b9\u03b1\u03c7\u03c9\u03c1\u03b9\u03c3\u03bc\u03cc\u03c2 \u03ba\u03b1\u03b8\u03bf\u03c1\u03af\u03b6\u03b5\u03b9 \u03c4\u03b7\u03bd \u03c4\u03b9\u03bc\u03ae \u03b1\u03c5\u03c4\u03bf\u03cd \u03c4\u03bf\u03c5 \u03c0\u03b5\u03b4\u03af\u03bf\u03c5",
|
|
||||||
"first_split_overrules_source": "\u039f \u03c0\u03c1\u03ce\u03c4\u03bf\u03c2 \u03b4\u03b9\u03b1\u03c7\u03c9\u03c1\u03b9\u03c3\u03bc\u03cc\u03c2 \u03b5\u03bd\u03b4\u03ad\u03c7\u03b5\u03c4\u03b1\u03b9 \u03bd\u03b1 \u03c0\u03b1\u03c1\u03b1\u03ba\u03ac\u03bc\u03c8\u03b5\u03b9 \u03c4\u03bf\u03bd \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03c0\u03c1\u03bf\u03ad\u03bb\u03b5\u03c5\u03c3\u03b7\u03c2",
|
|
||||||
"first_split_overrules_destination": "\u039f \u03c0\u03c1\u03ce\u03c4\u03bf\u03c2 \u03b4\u03b9\u03b1\u03c7\u03c9\u03c1\u03b9\u03c3\u03bc\u03cc\u03c2 \u03b5\u03bd\u03b4\u03ad\u03c7\u03b5\u03c4\u03b1\u03b9 \u03bd\u03b1 \u03c0\u03b1\u03c1\u03b1\u03ba\u03ac\u03bc\u03c8\u03b5\u03b9 \u03c4\u03bf\u03bd \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03c0\u03c1\u03bf\u03bf\u03c1\u03b9\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">\u0397 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae #{ID} (\"{title}\")<\/a> \u03ad\u03c7\u03b5\u03b9 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03c5\u03c4\u03b5\u03af.",
|
|
||||||
"custom_period": "\u03a0\u03c1\u03bf\u03c3\u03b1\u03c1\u03bc\u03bf\u03c3\u03bc\u03ad\u03bd\u03b7 \u03c0\u03b5\u03c1\u03af\u03bf\u03b4\u03bf\u03c2",
|
|
||||||
"reset_to_current": "\u0395\u03c0\u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac \u03c3\u03c4\u03b7\u03bd \u03c4\u03c1\u03ad\u03c7\u03bf\u03c5\u03c3\u03b1 \u03c0\u03b5\u03c1\u03af\u03bf\u03b4\u03bf",
|
|
||||||
"select_period": "\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03c0\u03b5\u03c1\u03af\u03bf\u03b4\u03bf",
|
|
||||||
"location": "\u03a4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1",
|
|
||||||
"other_budgets": "\u03a0\u03c1\u03bf\u03cb\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03bc\u03bf\u03af \u03bc\u03b5 \u03c7\u03c1\u03bf\u03bd\u03b9\u03ba\u03ae \u03c0\u03c1\u03bf\u03c3\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae",
|
|
||||||
"journal_links": "\u03a3\u03c5\u03bd\u03b4\u03ad\u03c3\u03b5\u03b9\u03c2 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ce\u03bd",
|
|
||||||
"go_to_withdrawals": "\u03a0\u03b7\u03b3\u03b1\u03af\u03bd\u03b5\u03c4\u03b5 \u03c3\u03c4\u03b9\u03c2 \u03b1\u03bd\u03b1\u03bb\u03ae\u03c8\u03b5\u03b9\u03c2 \u03c3\u03b1\u03c2",
|
|
||||||
"revenue_accounts": "\u0388\u03c3\u03bf\u03b4\u03b1",
|
|
||||||
"add_another_split": "\u03a0\u03c1\u03bf\u03c3\u03b8\u03ae\u03ba\u03b7 \u03b5\u03bd\u03cc\u03c2 \u03b1\u03ba\u03cc\u03bc\u03b1 \u03b4\u03b9\u03b1\u03c7\u03c9\u03c1\u03b9\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"actions": "\u0395\u03bd\u03ad\u03c1\u03b3\u03b5\u03b9\u03b5\u03c2",
|
|
||||||
"earned": "\u039a\u03b5\u03c1\u03b4\u03ae\u03b8\u03b7\u03ba\u03b1\u03bd",
|
|
||||||
"empty": "(\u03ba\u03b5\u03bd\u03cc)",
|
|
||||||
"edit": "\u0395\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1",
|
|
||||||
"never": "\u03a0\u03bf\u03c4\u03ad",
|
|
||||||
"account_type_Loan": "\u0394\u03ac\u03bd\u03b5\u03b9\u03bf",
|
|
||||||
"account_type_Mortgage": "\u03a5\u03c0\u03bf\u03b8\u03ae\u03ba\u03b7",
|
|
||||||
"stored_new_account_js": "\u039f \u03bd\u03ad\u03bf\u03c2 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \"<a href=\"accounts\/show\/{ID}\">{name}<\/a>\" \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c4\u03b7\u03ba\u03b5!",
|
|
||||||
"account_type_Debt": "\u03a7\u03c1\u03ad\u03bf\u03c2",
|
|
||||||
"liability_direction_null_short": "\u0386\u03b3\u03bd\u03c9\u03c3\u03c4\u03bf",
|
|
||||||
"delete": "\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae",
|
|
||||||
"store_new_asset_account": "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03bd\u03ad\u03bf\u03c5 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd \u03ba\u03b5\u03c6\u03b1\u03bb\u03b1\u03af\u03bf\u03c5",
|
|
||||||
"store_new_expense_account": "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03bd\u03ad\u03bf\u03c5 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd \u03b4\u03b1\u03c0\u03b1\u03bd\u03ce\u03bd",
|
|
||||||
"store_new_liabilities_account": "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03bd\u03ad\u03b1\u03c2 \u03c5\u03c0\u03bf\u03c7\u03c1\u03ad\u03c9\u03c3\u03b7\u03c2",
|
|
||||||
"store_new_revenue_account": "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03bd\u03ad\u03bf\u03c5 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd \u03b5\u03c3\u03cc\u03b4\u03c9\u03bd",
|
|
||||||
"mandatoryFields": "\u03a5\u03c0\u03bf\u03c7\u03c1\u03b5\u03c9\u03c4\u03b9\u03ba\u03ac \u03c0\u03b5\u03b4\u03af\u03b1",
|
|
||||||
"optionalFields": "\u03a0\u03c1\u03bf\u03b1\u03b9\u03c1\u03b5\u03c4\u03b9\u03ba\u03ac \u03c0\u03b5\u03b4\u03af\u03b1",
|
|
||||||
"reconcile_this_account": "\u03a4\u03b1\u03ba\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 \u03b1\u03c5\u03c4\u03bf\u03cd \u03c4\u03bf\u03c5 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"interest_calc_weekly": "\u0391\u03bd\u03ac \u03b5\u03b2\u03b4\u03bf\u03bc\u03ac\u03b4\u03b1",
|
|
||||||
"interest_calc_monthly": "\u0391\u03bd\u03ac \u03bc\u03ae\u03bd\u03b1",
|
|
||||||
"interest_calc_quarterly": "\u0391\u03bd\u03ac \u03c4\u03c1\u03af\u03bc\u03b7\u03bd\u03bf",
|
|
||||||
"interest_calc_half-year": "\u0391\u03bd\u03ac \u03b5\u03be\u03ac\u03bc\u03b7\u03bd\u03bf",
|
|
||||||
"interest_calc_yearly": "\u0391\u03bd\u03ac \u03ad\u03c4\u03bf\u03c2",
|
|
||||||
"liability_direction_credit": "\u039c\u03bf\u03c5 \u03bf\u03c6\u03b5\u03af\u03bb\u03bf\u03c5\u03bd \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c7\u03c1\u03ad\u03bf\u03c2 \u03c3\u03b5 \u03bc\u03ad\u03bd\u03b1",
|
|
||||||
"liability_direction_debit": "\u039f\u03c6\u03b5\u03af\u03bb\u03c9 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c7\u03c1\u03ad\u03bf\u03c2 \u03c3\u03b5 \u03ba\u03ac\u03c0\u03bf\u03b9\u03bf\u03bd \u03ac\u03bb\u03bb\u03bf",
|
|
||||||
"liability_direction_credit_short": "\u039c\u03bf\u03c5 \u03bf\u03c6\u03b5\u03af\u03bb\u03bf\u03c5\u03bd \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c7\u03c1\u03ad\u03bf\u03c2",
|
|
||||||
"liability_direction_debit_short": "\u039f\u03c6\u03b5\u03af\u03bb\u03c9 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c7\u03c1\u03ad\u03bf\u03c2",
|
|
||||||
"account_type_debt": "\u03a7\u03c1\u03ad\u03bf\u03c2",
|
|
||||||
"account_type_loan": "\u0394\u03ac\u03bd\u03b5\u03b9\u03bf",
|
|
||||||
"left_in_debt": "\u039f\u03c6\u03b5\u03b9\u03bb\u03cc\u03bc\u03b5\u03bd\u03bf \u03c0\u03bf\u03c3\u03cc",
|
|
||||||
"account_type_mortgage": "\u03a5\u03c0\u03bf\u03b8\u03ae\u03ba\u03b7",
|
|
||||||
"save_transactions_by_moving_js": "\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03c5\u03bd \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ad\u03c2|\u0391\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c3\u03c4\u03b5 \u03b1\u03c5\u03c4\u03ae \u03c4\u03b7 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae \u03bc\u03b5\u03c4\u03b1\u03ba\u03b9\u03bd\u03ce\u03bd\u03c4\u03b1\u03c2 \u03c4\u03b7\u03bd \u03c3\u03b5 \u03ac\u03bb\u03bb\u03bf \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc|\u0391\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c3\u03c4\u03b5 \u03b1\u03c5\u03c4\u03ad\u03c2 \u03c4\u03b9\u03c2 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ad\u03c2 \u03bc\u03b5\u03c4\u03b1\u03ba\u03b9\u03bd\u03ce\u03bd\u03c4\u03b1\u03c2 \u03c4\u03b9\u03c2 \u03c3\u03b5 \u03ac\u03bb\u03bb\u03bf \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc.",
|
|
||||||
"none_in_select_list": "(\u03c4\u03af\u03c0\u03bf\u03c4\u03b1)",
|
|
||||||
"transaction_expand_split": "\u0391\u03bd\u03ac\u03c0\u03c4\u03c5\u03be\u03b7 \u03b4\u03b9\u03b1\u03c7\u03c9\u03c1\u03b9\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"transaction_collapse_split": "\u03a3\u03cd\u03bc\u03c0\u03c4\u03c5\u03be\u03b7 \u03b4\u03b9\u03b1\u03c7\u03c9\u03c1\u03b9\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"default_group_title_name": "(\u03c7\u03c9\u03c1\u03af\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1)",
|
|
||||||
"bill_repeats_weekly": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03b5\u03b2\u03b4\u03bf\u03bc\u03b1\u03b4\u03b9\u03b1\u03af\u03c9\u03c2",
|
|
||||||
"bill_repeats_monthly": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03bc\u03b7\u03bd\u03b9\u03b1\u03af\u03c9\u03c2",
|
|
||||||
"bill_repeats_quarterly": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03b1\u03bd\u03ac \u03c4\u03c1\u03af\u03bc\u03b7\u03bd\u03bf",
|
|
||||||
"bill_repeats_half-year": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03ba\u03ac\u03b8\u03b5 \u03bc\u03b9\u03c3\u03cc \u03c7\u03c1\u03cc\u03bd\u03bf",
|
|
||||||
"bill_repeats_yearly": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03b5\u03c4\u03b7\u03c3\u03af\u03c9\u03c2",
|
|
||||||
"bill_repeats_weekly_other": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03ba\u03ac\u03b8\u03b5 \u03b4\u03b5\u03cd\u03c4\u03b5\u03c1\u03b7 \u03b5\u03b2\u03b4\u03bf\u03bc\u03ac\u03b4\u03b1",
|
|
||||||
"bill_repeats_monthly_other": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03ba\u03ac\u03b8\u03b5 \u03b4\u03b5\u03cd\u03c4\u03b5\u03c1\u03bf \u03bc\u03ae\u03bd\u03b1",
|
|
||||||
"bill_repeats_quarterly_other": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03ba\u03ac\u03b8\u03b5 \u03b4\u03b5\u03cd\u03c4\u03b5\u03c1\u03bf \u03c4\u03c1\u03af\u03bc\u03b7\u03bd\u03bf",
|
|
||||||
"bill_repeats_half-year_other": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03b5\u03c4\u03b7\u03c3\u03af\u03c9\u03c2",
|
|
||||||
"bill_repeats_yearly_other": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03ba\u03ac\u03b8\u03b5 \u03b4\u03b5\u03cd\u03c4\u03b5\u03c1\u03bf \u03c7\u03c1\u03cc\u03bd\u03bf",
|
|
||||||
"bill_repeats_weekly_skip": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03ba\u03ac\u03b8\u03b5 {skip} \u03b5\u03b2\u03b4\u03bf\u03bc\u03ac\u03b4\u03b5\u03c2",
|
|
||||||
"bill_repeats_monthly_skip": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03ba\u03ac\u03b8\u03b5 {skip} \u03bc\u03ae\u03bd\u03b5\u03c2",
|
|
||||||
"bill_repeats_quarterly_skip": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03ba\u03ac\u03b8\u03b5 {skip} \u03c4\u03c1\u03af\u03bc\u03b7\u03bd\u03b1",
|
|
||||||
"bill_repeats_half-year_skip": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03ba\u03ac\u03b8\u03b5 {skip} \u03b5\u03be\u03ac\u03bc\u03b7\u03bd\u03b1",
|
|
||||||
"bill_repeats_yearly_skip": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03b5\u03c4\u03b1\u03b9 \u03ba\u03ac\u03b8\u03b5 {skip} \u03ad\u03c4\u03b7",
|
|
||||||
"not_expected_period": "\u0394\u03b5\u03bd \u03b1\u03bd\u03b1\u03bc\u03ad\u03bd\u03b5\u03c4\u03b1\u03b9 \u03b1\u03c5\u03c4\u03ae \u03c4\u03b7\u03bd \u03c0\u03b5\u03c1\u03af\u03bf\u03b4\u03bf",
|
|
||||||
"subscriptions": "\u03a3\u03c5\u03bd\u03b4\u03c1\u03bf\u03bc\u03ad\u03c2",
|
|
||||||
"bill_expected_date_js": "\u0391\u03bd\u03b1\u03bc\u03ad\u03bd\u03b5\u03c4\u03b1\u03b9 {date}",
|
|
||||||
"inactive": "\u0391\u03bd\u03b5\u03bd\u03b5\u03c1\u03b3\u03cc",
|
|
||||||
"forever": "\u0393\u03b9\u03b1 \u03c0\u03ac\u03bd\u03c4\u03b1",
|
|
||||||
"extension_date_is": "\u0397 \u03b7\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03c0\u03b1\u03c1\u03ac\u03c4\u03b1\u03c3\u03b7\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 {date}",
|
|
||||||
"create_new_bill": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03bd\u03ad\u03bf\u03c5 \u03c0\u03ac\u03b3\u03b9\u03bf\u03c5 \u03ad\u03be\u03bf\u03b4\u03bf\u03c5",
|
|
||||||
"store_new_bill": "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03bd\u03ad\u03bf\u03c5 \u03c0\u03ac\u03b3\u03b9\u03bf\u03c5 \u03ad\u03be\u03bf\u03b4\u03bf\u03c5",
|
|
||||||
"repeat_freq_yearly": "\u03b5\u03c4\u03b7\u03c3\u03af\u03c9\u03c2",
|
|
||||||
"repeat_freq_half-year": "\u03b5\u03be\u03b1\u03bc\u03b7\u03bd\u03b9\u03b1\u03af\u03c9\u03c2",
|
|
||||||
"repeat_freq_quarterly": "\u03c4\u03c1\u03b9\u03bc\u03b7\u03bd\u03b9\u03b1\u03af\u03c9\u03c2",
|
|
||||||
"repeat_freq_monthly": "\u03bc\u03b7\u03bd\u03b9\u03b1\u03af\u03c9\u03c2",
|
|
||||||
"repeat_freq_weekly": "\u03b5\u03b2\u03b4\u03bf\u03bc\u03b1\u03b4\u03b9\u03b1\u03af\u03c9\u03c2",
|
|
||||||
"credit_card_type_monthlyFull": "\u0395\u03be\u03cc\u03c6\u03bb\u03b7\u03c3\u03b7 \u03ba\u03ac\u03b8\u03b5 \u03bc\u03ae\u03bd\u03b1",
|
|
||||||
"update_liabilities_account": "\u0395\u03bd\u03b7\u03bc\u03ad\u03c1\u03c9\u03c3\u03b7 \u03c5\u03c0\u03bf\u03c7\u03c1\u03ad\u03c9\u03c3\u03b7\u03c2",
|
|
||||||
"update_expense_account": "\u0395\u03bd\u03b7\u03bc\u03ad\u03c1\u03c9\u03c3\u03b7 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd \u03b4\u03b1\u03c0\u03b1\u03bd\u03ce\u03bd",
|
|
||||||
"update_revenue_account": "\u0395\u03bd\u03b7\u03bc\u03ad\u03c1\u03c9\u03c3\u03b7 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd \u03b5\u03c3\u03cc\u03b4\u03c9\u03bd",
|
|
||||||
"update_undefined_account": "\u0395\u03bd\u03b7\u03bc\u03ad\u03c1\u03c9\u03c3\u03b7 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"update_asset_account": "\u0395\u03bd\u03b7\u03bc\u03ad\u03c1\u03c9\u03c3\u03b7 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd \u03ba\u03b5\u03c6\u03b1\u03bb\u03b1\u03af\u03bf\u03c5",
|
|
||||||
"updated_account_js": "\u0395\u03bd\u03b7\u03bc\u03b5\u03c1\u03ce\u03b8\u03b7\u03ba\u03b5 \u03bf \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \"<a href=\"accounts\/show\/{ID}\">{title}<\/a>\"."
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"piggy_bank": "\u039a\u03bf\u03c5\u03bc\u03c0\u03b1\u03c1\u03ac\u03c2",
|
|
||||||
"percentage": "pct.",
|
|
||||||
"amount": "\u03a0\u03bf\u03c3\u03cc",
|
|
||||||
"lastActivity": "\u03a4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03b1 \u03b4\u03c1\u03b1\u03c3\u03c4\u03b7\u03c1\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1",
|
|
||||||
"name": "\u038c\u03bd\u03bf\u03bc\u03b1",
|
|
||||||
"role": "\u03a1\u03cc\u03bb\u03bf\u03c2",
|
|
||||||
"description": "\u03a0\u03b5\u03c1\u03b9\u03b3\u03c1\u03b1\u03c6\u03ae",
|
|
||||||
"date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1",
|
|
||||||
"source_account": "\u039b\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03c0\u03c1\u03bf\u03ad\u03bb\u03b5\u03c5\u03c3\u03b7\u03c2",
|
|
||||||
"destination_account": "\u039b\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03c0\u03c1\u03bf\u03bf\u03c1\u03b9\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"category": "\u039a\u03b1\u03c4\u03b7\u03b3\u03bf\u03c1\u03af\u03b1",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"interest": "\u03a4\u03cc\u03ba\u03bf\u03c2",
|
|
||||||
"interest_period": "\u03a4\u03bf\u03ba\u03b9\u03b6\u03cc\u03bc\u03b5\u03bd\u03b7 \u03c0\u03b5\u03c1\u03af\u03bf\u03b4\u03bf\u03c2",
|
|
||||||
"liability_type": "\u03a4\u03cd\u03c0\u03bf\u03c2 \u03c5\u03c0\u03bf\u03c7\u03c1\u03ad\u03c9\u03c3\u03b7\u03c2",
|
|
||||||
"liability_direction": "\u03a5\u03c0\u03bf\u03c7\u03c1\u03ad\u03c9\u03c3\u03b7 \u03b5\u03bd\u03c4\u03cc\u03c2\/\u03b5\u03ba\u03c4\u03cc\u03c2",
|
|
||||||
"currentBalance": "\u03a4\u03c1\u03ad\u03c7\u03bf\u03bd \u03c5\u03c0\u03cc\u03bb\u03bf\u03b9\u03c0\u03bf",
|
|
||||||
"next_expected_match": "\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03b7 \u03b1\u03bd\u03b1\u03bc\u03b5\u03bd\u03cc\u03bc\u03b5\u03bd\u03b7 \u03b1\u03bd\u03c4\u03b9\u03c3\u03c4\u03bf\u03af\u03c7\u03b9\u03c3\u03b7",
|
|
||||||
"expected_info": "\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03b7 \u03b1\u03bd\u03b1\u03bc\u03b5\u03bd\u03cc\u03bc\u03b5\u03bd\u03b7 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae",
|
|
||||||
"start_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03ad\u03bd\u03b1\u03c1\u03be\u03b7\u03c2",
|
|
||||||
"end_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03bb\u03ae\u03be\u03b7\u03c2",
|
|
||||||
"payment_info": "\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03a0\u03bb\u03b7\u03c1\u03c9\u03bc\u03ae\u03c2"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"html_language": "el",
|
|
||||||
"week_in_year_fns": "'\u0395\u03b2\u03b4\u03bf\u03bc\u03ac\u03b4\u03b1' w, yyyy",
|
|
||||||
"month_and_day_fns": "d MMMM y",
|
|
||||||
"quarter_fns": "'Q'Q, yyyy",
|
|
||||||
"half_year_fns": "'H{half}', yyyy"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"foreign_amount": "\u03a0\u03bf\u03c3\u03cc \u03c3\u03b5 \u03be\u03ad\u03bd\u03bf \u03bd\u03cc\u03bc\u03b9\u03c3\u03bc\u03b1",
|
|
||||||
"interest_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03c4\u03bf\u03ba\u03b9\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"name": "\u038c\u03bd\u03bf\u03bc\u03b1",
|
|
||||||
"amount": "\u03a0\u03bf\u03c3\u03cc",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"BIC": "BIC",
|
|
||||||
"notes": "\u03a3\u03b7\u03bc\u03b5\u03b9\u03ce\u03c3\u03b5\u03b9\u03c2",
|
|
||||||
"location": "\u03a4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1",
|
|
||||||
"repeat_freq": "\u0395\u03c0\u03b1\u03bd\u03b1\u03bb\u03ae\u03c8\u03b5\u03b9\u03c2",
|
|
||||||
"skip": "\u03a0\u03b1\u03c1\u03ac\u03bb\u03b5\u03b9\u03c8\u03b7",
|
|
||||||
"startdate": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u0388\u03bd\u03b1\u03c1\u03be\u03b7\u03c2",
|
|
||||||
"enddate": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03bb\u03ae\u03be\u03b7\u03c2",
|
|
||||||
"object_group": "\u039f\u03bc\u03ac\u03b4\u03b1",
|
|
||||||
"attachments": "\u03a3\u03c5\u03bd\u03b7\u03bc\u03bc\u03ad\u03bd\u03b1",
|
|
||||||
"deletePermanently": "\u039f\u03c1\u03b9\u03c3\u03c4\u03b9\u03ba\u03ae \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae",
|
|
||||||
"active": "\u0395\u03bd\u03b5\u03c1\u03b3\u03cc",
|
|
||||||
"include_net_worth": "\u0395\u03bd\u03c4\u03cc\u03c2 \u03ba\u03b1\u03b8\u03b1\u03c1\u03ae\u03c2 \u03b1\u03be\u03af\u03b1\u03c2",
|
|
||||||
"cc_type": "\u03a3\u03c7\u03ad\u03b4\u03b9\u03bf \u03c0\u03bb\u03b7\u03c1\u03c9\u03bc\u03ae\u03c2 \u03c0\u03b9\u03c3\u03c4\u03c9\u03c4\u03b9\u03ba\u03ae\u03c2 \u03ba\u03ac\u03c1\u03c4\u03b1\u03c2",
|
|
||||||
"account_number": "\u0391\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"cc_monthly_payment_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03bc\u03b7\u03bd\u03b9\u03b1\u03af\u03b1\u03c2 \u03c0\u03bb\u03b7\u03c1\u03c9\u03bc\u03ae\u03c2 \u03ba\u03ac\u03c1\u03c4\u03b1\u03c2",
|
|
||||||
"virtual_balance": "\u0395\u03b9\u03ba\u03bf\u03bd\u03b9\u03ba\u03cc \u03c5\u03c0\u03cc\u03bb\u03bf\u03b9\u03c0\u03bf",
|
|
||||||
"opening_balance": "\u03a5\u03c0\u03cc\u03bb\u03bf\u03b9\u03c0\u03bf \u03ad\u03bd\u03b1\u03c1\u03be\u03b7\u03c2",
|
|
||||||
"opening_balance_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03c5\u03c0\u03bf\u03bb\u03bf\u03af\u03c0\u03bf\u03c5 \u03ad\u03bd\u03b1\u03c1\u03be\u03b7\u03c2",
|
|
||||||
"date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1",
|
|
||||||
"interest": "\u03a4\u03cc\u03ba\u03bf\u03c2",
|
|
||||||
"interest_period": "\u03a4\u03bf\u03ba\u03b9\u03b6\u03cc\u03bc\u03b5\u03bd\u03b7 \u03c0\u03b5\u03c1\u03af\u03bf\u03b4\u03bf\u03c2",
|
|
||||||
"currency_id": "\u039d\u03cc\u03bc\u03b9\u03c3\u03bc\u03b1",
|
|
||||||
"liability_type": "\u03a4\u03cd\u03c0\u03bf\u03c2 \u03c5\u03c0\u03bf\u03c7\u03c1\u03ad\u03c9\u03c3\u03b7\u03c2",
|
|
||||||
"account_role": "\u03a1\u03cc\u03bb\u03bf\u03c2 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd",
|
|
||||||
"liability_direction": "\u03a5\u03c0\u03bf\u03c7\u03c1\u03ad\u03c9\u03c3\u03b7 \u03b5\u03bd\u03c4\u03cc\u03c2\/\u03b5\u03ba\u03c4\u03cc\u03c2",
|
|
||||||
"book_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03b5\u03b3\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2",
|
|
||||||
"permDeleteWarning": "\u0397 \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03c9\u03bd \u03b1\u03c0\u03cc \u03c4\u03bf Firefly III \u03b5\u03af\u03bd\u03b1\u03b9 \u03bc\u03cc\u03bd\u03b9\u03bc\u03b7 \u03ba\u03b1\u03b9 \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03b1\u03bd\u03b1\u03b9\u03c1\u03b5\u03b8\u03b5\u03af.",
|
|
||||||
"account_areYouSure_js": "\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03b9 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03c4\u03bf \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03bc\u03b5 \u03cc\u03bd\u03bf\u03bc\u03b1 \"{name}\";",
|
|
||||||
"also_delete_piggyBanks_js": "\u03a7\u03c9\u03c1\u03af\u03c2 \u03ba\u03bf\u03c5\u03bc\u03c0\u03b1\u03c1\u03ac | \u039f \u03bc\u03cc\u03bd\u03bf\u03c2 \u03ba\u03bf\u03c5\u03bc\u03c0\u03b1\u03c1\u03ac\u03c2 \u03c0\u03bf\u03c5 \u03b5\u03af\u03bd\u03b1\u03b9 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b4\u03b5\u03bc\u03ad\u03bd\u03bf\u03c2 \u03c3\u03b5 \u03b1\u03c5\u03c4\u03cc\u03bd \u03c4\u03bf\u03bd \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03b8\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03b5\u03af \u03b5\u03c0\u03af\u03c3\u03b7\u03c2. | \u038c\u03bb\u03bf\u03b9 \u03bf\u03b9 \u03ba\u03bf\u03c5\u03bc\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03c2 {count} \u03c0\u03bf\u03c5 \u03c3\u03c5\u03bd\u03b4\u03ad\u03bf\u03bd\u03c4\u03b1\u03b9 \u03bc\u03b5 \u03b1\u03c5\u03c4\u03cc\u03bd \u03c4\u03bf\u03bd \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03b8\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03bf\u03cd\u03bd \u03b5\u03c0\u03af\u03c3\u03b7\u03c2.",
|
|
||||||
"also_delete_transactions_js": "\u03a7\u03c9\u03c1\u03af\u03c2 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ad\u03c2 | \u0397 \u03bc\u03cc\u03bd\u03b7 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae \u03c0\u03bf\u03c5 \u03c3\u03c5\u03bd\u03b4\u03ad\u03b5\u03c4\u03b1\u03b9 \u03bc\u03b5 \u03b1\u03c5\u03c4\u03cc\u03bd \u03c4\u03bf\u03bd \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03b8\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03b5\u03af \u03b5\u03c0\u03af\u03c3\u03b7\u03c2. | \u038c\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ad\u03c2 {count} \u03c0\u03bf\u03c5 \u03c3\u03c5\u03bd\u03b4\u03ad\u03bf\u03bd\u03c4\u03b1\u03b9 \u03bc\u03b5 \u03b1\u03c5\u03c4\u03cc\u03bd \u03c4\u03bf\u03bd \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03b8\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03bf\u03cd\u03bd \u03b5\u03c0\u03af\u03c3\u03b7\u03c2.",
|
|
||||||
"process_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03b5\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1\u03c2",
|
|
||||||
"due_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03c0\u03c1\u03bf\u03b8\u03b5\u03c3\u03bc\u03af\u03b1\u03c2",
|
|
||||||
"payment_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03c0\u03bb\u03b7\u03c1\u03c9\u03bc\u03ae\u03c2",
|
|
||||||
"invoice_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03c4\u03b9\u03bc\u03bf\u03bb\u03cc\u03b3\u03b7\u03c3\u03b7\u03c2",
|
|
||||||
"amount_min": "\u0395\u03bb\u03ac\u03c7\u03b9\u03c3\u03c4\u03bf \u03c0\u03bf\u03c3\u03cc",
|
|
||||||
"amount_max": "\u039c\u03ad\u03b3\u03b9\u03c3\u03c4\u03bf \u03c0\u03bf\u03c3\u03cc",
|
|
||||||
"start_date": "\u0391\u03c1\u03c7\u03ae \u03c4\u03bf\u03c5 \u03b5\u03cd\u03c1\u03bf\u03c5\u03c2",
|
|
||||||
"end_date": "\u03a4\u03ad\u03bb\u03bf\u03c2 \u03c4\u03bf\u03c5 \u03b5\u03cd\u03c1\u03bf\u03c5\u03c2",
|
|
||||||
"extension_date": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03b5\u03c0\u03ad\u03ba\u03c4\u03b1\u03c3\u03b7\u03c2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
{
|
|
||||||
"firefly": {
|
|
||||||
"Transfer": "Transfer",
|
|
||||||
"Withdrawal": "Withdrawal",
|
|
||||||
"Deposit": "Deposit",
|
|
||||||
"date_and_time": "Date and time",
|
|
||||||
"no_currency": "(no currency)",
|
|
||||||
"date": "Date",
|
|
||||||
"time": "Time",
|
|
||||||
"no_budget": "(no budget)",
|
|
||||||
"destination_account": "Destination account",
|
|
||||||
"source_account": "Source account",
|
|
||||||
"single_split": "Split",
|
|
||||||
"create_new_transaction": "Create a new transaction",
|
|
||||||
"balance": "Balance",
|
|
||||||
"transaction_journal_extra": "Extra information",
|
|
||||||
"transaction_journal_meta": "Meta information",
|
|
||||||
"basic_journal_information": "Basic transaction information",
|
|
||||||
"bills_to_pay": "Bills to pay",
|
|
||||||
"left_to_spend": "Left to spend",
|
|
||||||
"attachments": "Attachments",
|
|
||||||
"net_worth": "Net worth",
|
|
||||||
"bill": "Bill",
|
|
||||||
"no_bill": "(no bill)",
|
|
||||||
"tags": "Tags",
|
|
||||||
"internal_reference": "Internal reference",
|
|
||||||
"external_url": "External URL",
|
|
||||||
"no_piggy_bank": "(no piggy bank)",
|
|
||||||
"paid": "Paid",
|
|
||||||
"notes": "Notes",
|
|
||||||
"yourAccounts": "Your accounts",
|
|
||||||
"go_to_asset_accounts": "View your asset accounts",
|
|
||||||
"delete_account": "Delete account",
|
|
||||||
"transaction_table_description": "A table containing your transactions",
|
|
||||||
"account": "Account",
|
|
||||||
"description": "Description",
|
|
||||||
"amount": "Amount",
|
|
||||||
"budget": "Budget",
|
|
||||||
"category": "Category",
|
|
||||||
"opposing_account": "Opposing account",
|
|
||||||
"budgets": "Budgets",
|
|
||||||
"categories": "Categories",
|
|
||||||
"go_to_budgets": "Go to your budgets",
|
|
||||||
"income": "Revenue \/ income",
|
|
||||||
"go_to_deposits": "Go to deposits",
|
|
||||||
"go_to_categories": "Go to your categories",
|
|
||||||
"expense_accounts": "Expense accounts",
|
|
||||||
"go_to_expenses": "Go to expenses",
|
|
||||||
"go_to_bills": "Go to your bills",
|
|
||||||
"bills": "Bills",
|
|
||||||
"last_thirty_days": "Last thirty days",
|
|
||||||
"last_seven_days": "Last seven days",
|
|
||||||
"go_to_piggies": "Go to your piggy banks",
|
|
||||||
"saved": "Saved",
|
|
||||||
"piggy_banks": "Piggy banks",
|
|
||||||
"piggy_bank": "Piggy bank",
|
|
||||||
"amounts": "Amounts",
|
|
||||||
"left": "Left",
|
|
||||||
"spent": "Spent",
|
|
||||||
"Default asset account": "Default asset account",
|
|
||||||
"search_results": "Search results",
|
|
||||||
"include": "Include?",
|
|
||||||
"transaction": "Transaction",
|
|
||||||
"account_role_defaultAsset": "Default asset account",
|
|
||||||
"account_role_savingAsset": "Savings account",
|
|
||||||
"account_role_sharedAsset": "Shared asset account",
|
|
||||||
"clear_location": "Clear location",
|
|
||||||
"account_role_ccAsset": "Credit card",
|
|
||||||
"account_role_cashWalletAsset": "Cash wallet",
|
|
||||||
"daily_budgets": "Daily budgets",
|
|
||||||
"weekly_budgets": "Weekly budgets",
|
|
||||||
"monthly_budgets": "Monthly budgets",
|
|
||||||
"journals_in_period_for_account_js": "All transactions for account {title} between {start} and {end}",
|
|
||||||
"quarterly_budgets": "Quarterly budgets",
|
|
||||||
"create_new_expense": "Create new expense account",
|
|
||||||
"create_new_revenue": "Create new revenue account",
|
|
||||||
"create_new_liabilities": "Create new liability",
|
|
||||||
"half_year_budgets": "Half-yearly budgets",
|
|
||||||
"yearly_budgets": "Yearly budgets",
|
|
||||||
"split_transaction_title": "Description of the split transaction",
|
|
||||||
"errors_submission": "There was something wrong with your submission. Please check out the errors.",
|
|
||||||
"flash_error": "Error!",
|
|
||||||
"store_transaction": "Store transaction",
|
|
||||||
"flash_success": "Success!",
|
|
||||||
"create_another": "After storing, return here to create another one.",
|
|
||||||
"update_transaction": "Update transaction",
|
|
||||||
"after_update_create_another": "After updating, return here to continue editing.",
|
|
||||||
"transaction_updated_no_changes": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") did not receive any changes.",
|
|
||||||
"transaction_updated_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") has been updated.",
|
|
||||||
"spent_x_of_y": "Spent {amount} of {total}",
|
|
||||||
"search": "Search",
|
|
||||||
"create_new_asset": "Create new asset account",
|
|
||||||
"asset_accounts": "Asset accounts",
|
|
||||||
"reset_after": "Reset form after submission",
|
|
||||||
"bill_paid_on": "Paid on {date}",
|
|
||||||
"first_split_decides": "The first split determines the value of this field",
|
|
||||||
"first_split_overrules_source": "The first split may overrule the source account",
|
|
||||||
"first_split_overrules_destination": "The first split may overrule the destination account",
|
|
||||||
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID} (\"{title}\")<\/a> has been stored.",
|
|
||||||
"custom_period": "Custom period",
|
|
||||||
"reset_to_current": "Reset to current period",
|
|
||||||
"select_period": "Select a period",
|
|
||||||
"location": "Location",
|
|
||||||
"other_budgets": "Custom timed budgets",
|
|
||||||
"journal_links": "Transaction links",
|
|
||||||
"go_to_withdrawals": "Go to your withdrawals",
|
|
||||||
"revenue_accounts": "Revenue accounts",
|
|
||||||
"add_another_split": "Add another split",
|
|
||||||
"actions": "Actions",
|
|
||||||
"earned": "Earned",
|
|
||||||
"empty": "(empty)",
|
|
||||||
"edit": "Edit",
|
|
||||||
"never": "Never",
|
|
||||||
"account_type_Loan": "Loan",
|
|
||||||
"account_type_Mortgage": "Mortgage",
|
|
||||||
"stored_new_account_js": "New account \"<a href=\"accounts\/show\/{ID}\">{name}<\/a>\" stored!",
|
|
||||||
"account_type_Debt": "Debt",
|
|
||||||
"liability_direction_null_short": "Unknown",
|
|
||||||
"delete": "Delete",
|
|
||||||
"store_new_asset_account": "Store new asset account",
|
|
||||||
"store_new_expense_account": "Store new expense account",
|
|
||||||
"store_new_liabilities_account": "Store new liability",
|
|
||||||
"store_new_revenue_account": "Store new revenue account",
|
|
||||||
"mandatoryFields": "Mandatory fields",
|
|
||||||
"optionalFields": "Optional fields",
|
|
||||||
"reconcile_this_account": "Reconcile this account",
|
|
||||||
"interest_calc_weekly": "Per week",
|
|
||||||
"interest_calc_monthly": "Per month",
|
|
||||||
"interest_calc_quarterly": "Per quarter",
|
|
||||||
"interest_calc_half-year": "Per half year",
|
|
||||||
"interest_calc_yearly": "Per year",
|
|
||||||
"liability_direction_credit": "I am owed this debt",
|
|
||||||
"liability_direction_debit": "I owe this debt to somebody else",
|
|
||||||
"liability_direction_credit_short": "Owed this debt",
|
|
||||||
"liability_direction_debit_short": "Owe this debt",
|
|
||||||
"account_type_debt": "Debt",
|
|
||||||
"account_type_loan": "Loan",
|
|
||||||
"left_in_debt": "Amount due",
|
|
||||||
"account_type_mortgage": "Mortgage",
|
|
||||||
"save_transactions_by_moving_js": "No transactions|Save this transaction by moving it to another account. |Save these transactions by moving them to another account.",
|
|
||||||
"none_in_select_list": "(none)",
|
|
||||||
"transaction_expand_split": "Expand split",
|
|
||||||
"transaction_collapse_split": "Collapse split",
|
|
||||||
"default_group_title_name": "(ungrouped)",
|
|
||||||
"bill_repeats_weekly": "Repeats weekly",
|
|
||||||
"bill_repeats_monthly": "Repeats monthly",
|
|
||||||
"bill_repeats_quarterly": "Repeats quarterly",
|
|
||||||
"bill_repeats_half-year": "Repeats every half year",
|
|
||||||
"bill_repeats_yearly": "Repeats yearly",
|
|
||||||
"bill_repeats_weekly_other": "Repeats every other week",
|
|
||||||
"bill_repeats_monthly_other": "Repeats every other month",
|
|
||||||
"bill_repeats_quarterly_other": "Repeats every other quarter",
|
|
||||||
"bill_repeats_half-year_other": "Repeats yearly",
|
|
||||||
"bill_repeats_yearly_other": "Repeats every other year",
|
|
||||||
"bill_repeats_weekly_skip": "Repeats every {skip} weeks",
|
|
||||||
"bill_repeats_monthly_skip": "Repeats every {skip} months",
|
|
||||||
"bill_repeats_quarterly_skip": "Repeats every {skip} quarters",
|
|
||||||
"bill_repeats_half-year_skip": "Repeats every {skip} half years",
|
|
||||||
"bill_repeats_yearly_skip": "Repeats every {skip} years",
|
|
||||||
"not_expected_period": "Not expected this period",
|
|
||||||
"subscriptions": "Subscriptions",
|
|
||||||
"bill_expected_date_js": "Expected {date}",
|
|
||||||
"inactive": "Inactive",
|
|
||||||
"forever": "Forever",
|
|
||||||
"extension_date_is": "Extension date is {date}",
|
|
||||||
"create_new_bill": "Create new bill",
|
|
||||||
"store_new_bill": "Store new bill",
|
|
||||||
"repeat_freq_yearly": "yearly",
|
|
||||||
"repeat_freq_half-year": "every half-year",
|
|
||||||
"repeat_freq_quarterly": "quarterly",
|
|
||||||
"repeat_freq_monthly": "monthly",
|
|
||||||
"repeat_freq_weekly": "weekly",
|
|
||||||
"credit_card_type_monthlyFull": "Full payment every month",
|
|
||||||
"update_liabilities_account": "Update liability",
|
|
||||||
"update_expense_account": "Update expense account",
|
|
||||||
"update_revenue_account": "Update revenue account",
|
|
||||||
"update_undefined_account": "Update account",
|
|
||||||
"update_asset_account": "Update asset account",
|
|
||||||
"updated_account_js": "Updated account \"<a href=\"accounts\/show\/{ID}\">{title}<\/a>\"."
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"piggy_bank": "Piggy bank",
|
|
||||||
"percentage": "pct.",
|
|
||||||
"amount": "Amount",
|
|
||||||
"lastActivity": "Last activity",
|
|
||||||
"name": "Name",
|
|
||||||
"role": "Role",
|
|
||||||
"description": "Description",
|
|
||||||
"date": "Date",
|
|
||||||
"source_account": "Source account",
|
|
||||||
"destination_account": "Destination account",
|
|
||||||
"category": "Category",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"interest": "Interest",
|
|
||||||
"interest_period": "Interest period",
|
|
||||||
"liability_type": "Type of liability",
|
|
||||||
"liability_direction": "Liability in\/out",
|
|
||||||
"currentBalance": "Current balance",
|
|
||||||
"next_expected_match": "Next expected match",
|
|
||||||
"expected_info": "Next expected transaction",
|
|
||||||
"start_date": "Start date",
|
|
||||||
"end_date": "End date",
|
|
||||||
"payment_info": "Payment information"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"html_language": "en-gb",
|
|
||||||
"week_in_year_fns": "'Week' w, yyyy",
|
|
||||||
"month_and_day_fns": "MMMM d, y",
|
|
||||||
"quarter_fns": "'Q'Q, yyyy",
|
|
||||||
"half_year_fns": "'H{half}', yyyy"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"foreign_amount": "Foreign amount",
|
|
||||||
"interest_date": "Interest date",
|
|
||||||
"name": "Name",
|
|
||||||
"amount": "Amount",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"BIC": "BIC",
|
|
||||||
"notes": "Notes",
|
|
||||||
"location": "Location",
|
|
||||||
"repeat_freq": "Repeats",
|
|
||||||
"skip": "Skip",
|
|
||||||
"startdate": "Start date",
|
|
||||||
"enddate": "End date",
|
|
||||||
"object_group": "Group",
|
|
||||||
"attachments": "Attachments",
|
|
||||||
"deletePermanently": "Delete permanently",
|
|
||||||
"active": "Active",
|
|
||||||
"include_net_worth": "Include in net worth",
|
|
||||||
"cc_type": "Credit card payment plan",
|
|
||||||
"account_number": "Account number",
|
|
||||||
"cc_monthly_payment_date": "Credit card monthly payment date",
|
|
||||||
"virtual_balance": "Virtual balance",
|
|
||||||
"opening_balance": "Opening balance",
|
|
||||||
"opening_balance_date": "Opening balance date",
|
|
||||||
"date": "Date",
|
|
||||||
"interest": "Interest",
|
|
||||||
"interest_period": "Interest period",
|
|
||||||
"currency_id": "Currency",
|
|
||||||
"liability_type": "Liability type",
|
|
||||||
"account_role": "Account role",
|
|
||||||
"liability_direction": "Liability in\/out",
|
|
||||||
"book_date": "Book date",
|
|
||||||
"permDeleteWarning": "Deleting stuff from Firefly III is permanent and cannot be undone.",
|
|
||||||
"account_areYouSure_js": "Are you sure you want to delete the account named \"{name}\"?",
|
|
||||||
"also_delete_piggyBanks_js": "No piggy banks|The only piggy bank connected to this account will be deleted as well.|All {count} piggy banks connected to this account will be deleted as well.",
|
|
||||||
"also_delete_transactions_js": "No transactions|The only transaction connected to this account will be deleted as well.|All {count} transactions connected to this account will be deleted as well.",
|
|
||||||
"process_date": "Processing date",
|
|
||||||
"due_date": "Due date",
|
|
||||||
"payment_date": "Payment date",
|
|
||||||
"invoice_date": "Invoice date",
|
|
||||||
"amount_min": "Minimum amount",
|
|
||||||
"amount_max": "Maximum amount",
|
|
||||||
"start_date": "Start of range",
|
|
||||||
"end_date": "End of range",
|
|
||||||
"extension_date": "Extension date"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
{
|
|
||||||
"firefly": {
|
|
||||||
"Transfer": "Transfer",
|
|
||||||
"Withdrawal": "Withdrawal",
|
|
||||||
"Deposit": "Deposit",
|
|
||||||
"date_and_time": "Date and time",
|
|
||||||
"no_currency": "(no currency)",
|
|
||||||
"date": "Date",
|
|
||||||
"time": "Time",
|
|
||||||
"no_budget": "(no budget)",
|
|
||||||
"destination_account": "Destination account",
|
|
||||||
"source_account": "Source account",
|
|
||||||
"single_split": "Split",
|
|
||||||
"create_new_transaction": "Create a new transaction",
|
|
||||||
"balance": "Balance",
|
|
||||||
"transaction_journal_extra": "Extra information",
|
|
||||||
"transaction_journal_meta": "Meta information",
|
|
||||||
"basic_journal_information": "Basic transaction information",
|
|
||||||
"bills_to_pay": "Bills to pay",
|
|
||||||
"left_to_spend": "Left to spend",
|
|
||||||
"attachments": "Attachments",
|
|
||||||
"net_worth": "Net worth",
|
|
||||||
"bill": "Bill",
|
|
||||||
"no_bill": "(no bill)",
|
|
||||||
"tags": "Tags",
|
|
||||||
"internal_reference": "Internal reference",
|
|
||||||
"external_url": "External URL",
|
|
||||||
"no_piggy_bank": "(no piggy bank)",
|
|
||||||
"paid": "Paid",
|
|
||||||
"notes": "Notes",
|
|
||||||
"yourAccounts": "Your accounts",
|
|
||||||
"go_to_asset_accounts": "View your asset accounts",
|
|
||||||
"delete_account": "Delete account",
|
|
||||||
"transaction_table_description": "A table containing your transactions",
|
|
||||||
"account": "Account",
|
|
||||||
"description": "Description",
|
|
||||||
"amount": "Amount",
|
|
||||||
"budget": "Budget",
|
|
||||||
"category": "Category",
|
|
||||||
"opposing_account": "Opposing account",
|
|
||||||
"budgets": "Budgets",
|
|
||||||
"categories": "Categories",
|
|
||||||
"go_to_budgets": "Go to your budgets",
|
|
||||||
"income": "Revenue \/ income",
|
|
||||||
"go_to_deposits": "Go to deposits",
|
|
||||||
"go_to_categories": "Go to your categories",
|
|
||||||
"expense_accounts": "Expense accounts",
|
|
||||||
"go_to_expenses": "Go to expenses",
|
|
||||||
"go_to_bills": "Go to your bills",
|
|
||||||
"bills": "Bills",
|
|
||||||
"last_thirty_days": "Last thirty days",
|
|
||||||
"last_seven_days": "Last seven days",
|
|
||||||
"go_to_piggies": "Go to your piggy banks",
|
|
||||||
"saved": "Saved",
|
|
||||||
"piggy_banks": "Piggy banks",
|
|
||||||
"piggy_bank": "Piggy bank",
|
|
||||||
"amounts": "Amounts",
|
|
||||||
"left": "Left",
|
|
||||||
"spent": "Spent",
|
|
||||||
"Default asset account": "Default asset account",
|
|
||||||
"search_results": "Search results",
|
|
||||||
"include": "Include?",
|
|
||||||
"transaction": "Transaction",
|
|
||||||
"account_role_defaultAsset": "Default asset account",
|
|
||||||
"account_role_savingAsset": "Savings account",
|
|
||||||
"account_role_sharedAsset": "Shared asset account",
|
|
||||||
"clear_location": "Clear location",
|
|
||||||
"account_role_ccAsset": "Credit card",
|
|
||||||
"account_role_cashWalletAsset": "Cash wallet",
|
|
||||||
"daily_budgets": "Daily budgets",
|
|
||||||
"weekly_budgets": "Weekly budgets",
|
|
||||||
"monthly_budgets": "Monthly budgets",
|
|
||||||
"journals_in_period_for_account_js": "All transactions for account {title} between {start} and {end}",
|
|
||||||
"quarterly_budgets": "Quarterly budgets",
|
|
||||||
"create_new_expense": "Create new expense account",
|
|
||||||
"create_new_revenue": "Create new revenue account",
|
|
||||||
"create_new_liabilities": "Create new liability",
|
|
||||||
"half_year_budgets": "Half-yearly budgets",
|
|
||||||
"yearly_budgets": "Yearly budgets",
|
|
||||||
"split_transaction_title": "Description of the split transaction",
|
|
||||||
"errors_submission": "There was something wrong with your submission. Please check out the errors.",
|
|
||||||
"flash_error": "Error!",
|
|
||||||
"store_transaction": "Store transaction",
|
|
||||||
"flash_success": "Success!",
|
|
||||||
"create_another": "After storing, return here to create another one.",
|
|
||||||
"update_transaction": "Update transaction",
|
|
||||||
"after_update_create_another": "After updating, return here to continue editing.",
|
|
||||||
"transaction_updated_no_changes": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") did not receive any changes.",
|
|
||||||
"transaction_updated_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") has been updated.",
|
|
||||||
"spent_x_of_y": "Spent {amount} of {total}",
|
|
||||||
"search": "Search",
|
|
||||||
"create_new_asset": "Create new asset account",
|
|
||||||
"asset_accounts": "Asset accounts",
|
|
||||||
"reset_after": "Reset form after submission",
|
|
||||||
"bill_paid_on": "Paid on {date}",
|
|
||||||
"first_split_decides": "The first split determines the value of this field",
|
|
||||||
"first_split_overrules_source": "The first split may overrule the source account",
|
|
||||||
"first_split_overrules_destination": "The first split may overrule the destination account",
|
|
||||||
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID} (\"{title}\")<\/a> has been stored.",
|
|
||||||
"custom_period": "Custom period",
|
|
||||||
"reset_to_current": "Reset to current period",
|
|
||||||
"select_period": "Select a period",
|
|
||||||
"location": "Location",
|
|
||||||
"other_budgets": "Custom timed budgets",
|
|
||||||
"journal_links": "Transaction links",
|
|
||||||
"go_to_withdrawals": "Go to your withdrawals",
|
|
||||||
"revenue_accounts": "Revenue accounts",
|
|
||||||
"add_another_split": "Add another split",
|
|
||||||
"actions": "Actions",
|
|
||||||
"earned": "Earned",
|
|
||||||
"empty": "(empty)",
|
|
||||||
"edit": "Edit",
|
|
||||||
"never": "Never",
|
|
||||||
"account_type_Loan": "Loan",
|
|
||||||
"account_type_Mortgage": "Mortgage",
|
|
||||||
"stored_new_account_js": "New account \"<a href=\"accounts\/show\/{ID}\">{name}<\/a>\" stored!",
|
|
||||||
"account_type_Debt": "Debt",
|
|
||||||
"liability_direction_null_short": "Unknown",
|
|
||||||
"delete": "Delete",
|
|
||||||
"store_new_asset_account": "Store new asset account",
|
|
||||||
"store_new_expense_account": "Store new expense account",
|
|
||||||
"store_new_liabilities_account": "Store new liability",
|
|
||||||
"store_new_revenue_account": "Store new revenue account",
|
|
||||||
"mandatoryFields": "Mandatory fields",
|
|
||||||
"optionalFields": "Optional fields",
|
|
||||||
"reconcile_this_account": "Reconcile this account",
|
|
||||||
"interest_calc_weekly": "Per week",
|
|
||||||
"interest_calc_monthly": "Per month",
|
|
||||||
"interest_calc_quarterly": "Per quarter",
|
|
||||||
"interest_calc_half-year": "Per half year",
|
|
||||||
"interest_calc_yearly": "Per year",
|
|
||||||
"liability_direction_credit": "I am owed this debt",
|
|
||||||
"liability_direction_debit": "I owe this debt to somebody else",
|
|
||||||
"liability_direction_credit_short": "Owed this debt",
|
|
||||||
"liability_direction_debit_short": "Owe this debt",
|
|
||||||
"account_type_debt": "Debt",
|
|
||||||
"account_type_loan": "Loan",
|
|
||||||
"left_in_debt": "Amount due",
|
|
||||||
"account_type_mortgage": "Mortgage",
|
|
||||||
"save_transactions_by_moving_js": "No transactions|Save this transaction by moving it to another account. |Save these transactions by moving them to another account.",
|
|
||||||
"none_in_select_list": "(none)",
|
|
||||||
"transaction_expand_split": "Expand split",
|
|
||||||
"transaction_collapse_split": "Collapse split",
|
|
||||||
"default_group_title_name": "(ungrouped)",
|
|
||||||
"bill_repeats_weekly": "Repeats weekly",
|
|
||||||
"bill_repeats_monthly": "Repeats monthly",
|
|
||||||
"bill_repeats_quarterly": "Repeats quarterly",
|
|
||||||
"bill_repeats_half-year": "Repeats every half year",
|
|
||||||
"bill_repeats_yearly": "Repeats yearly",
|
|
||||||
"bill_repeats_weekly_other": "Repeats every other week",
|
|
||||||
"bill_repeats_monthly_other": "Repeats every other month",
|
|
||||||
"bill_repeats_quarterly_other": "Repeats every other quarter",
|
|
||||||
"bill_repeats_half-year_other": "Repeats yearly",
|
|
||||||
"bill_repeats_yearly_other": "Repeats every other year",
|
|
||||||
"bill_repeats_weekly_skip": "Repeats every {skip} weeks",
|
|
||||||
"bill_repeats_monthly_skip": "Repeats every {skip} months",
|
|
||||||
"bill_repeats_quarterly_skip": "Repeats every {skip} quarters",
|
|
||||||
"bill_repeats_half-year_skip": "Repeats every {skip} half years",
|
|
||||||
"bill_repeats_yearly_skip": "Repeats every {skip} years",
|
|
||||||
"not_expected_period": "Not expected this period",
|
|
||||||
"subscriptions": "Subscriptions",
|
|
||||||
"bill_expected_date_js": "Expected {date}",
|
|
||||||
"inactive": "Inactive",
|
|
||||||
"forever": "Forever",
|
|
||||||
"extension_date_is": "Extension date is {date}",
|
|
||||||
"create_new_bill": "Create new bill",
|
|
||||||
"store_new_bill": "Store new bill",
|
|
||||||
"repeat_freq_yearly": "yearly",
|
|
||||||
"repeat_freq_half-year": "every half-year",
|
|
||||||
"repeat_freq_quarterly": "quarterly",
|
|
||||||
"repeat_freq_monthly": "monthly",
|
|
||||||
"repeat_freq_weekly": "weekly",
|
|
||||||
"credit_card_type_monthlyFull": "Full payment every month",
|
|
||||||
"update_liabilities_account": "Update liability",
|
|
||||||
"update_expense_account": "Update expense account",
|
|
||||||
"update_revenue_account": "Update revenue account",
|
|
||||||
"update_undefined_account": "Update account",
|
|
||||||
"update_asset_account": "Update asset account",
|
|
||||||
"updated_account_js": "Updated account \"<a href=\"accounts\/show\/{ID}\">{title}<\/a>\"."
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"piggy_bank": "Piggy bank",
|
|
||||||
"percentage": "pct.",
|
|
||||||
"amount": "Amount",
|
|
||||||
"lastActivity": "Last activity",
|
|
||||||
"name": "Name",
|
|
||||||
"role": "Role",
|
|
||||||
"description": "Description",
|
|
||||||
"date": "Date",
|
|
||||||
"source_account": "Source account",
|
|
||||||
"destination_account": "Destination account",
|
|
||||||
"category": "Category",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"interest": "Interest",
|
|
||||||
"interest_period": "Interest period",
|
|
||||||
"liability_type": "Type of liability",
|
|
||||||
"liability_direction": "Liability in\/out",
|
|
||||||
"currentBalance": "Current balance",
|
|
||||||
"next_expected_match": "Next expected match",
|
|
||||||
"expected_info": "Next expected transaction",
|
|
||||||
"start_date": "Start date",
|
|
||||||
"end_date": "End date",
|
|
||||||
"payment_info": "Payment information"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"html_language": "en",
|
|
||||||
"week_in_year_fns": "'Week' w, yyyy",
|
|
||||||
"month_and_day_fns": "MMMM d, y",
|
|
||||||
"quarter_fns": "'Q'Q, yyyy",
|
|
||||||
"half_year_fns": "'H{half}', yyyy"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"foreign_amount": "Foreign amount",
|
|
||||||
"interest_date": "Interest date",
|
|
||||||
"name": "Name",
|
|
||||||
"amount": "Amount",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"BIC": "BIC",
|
|
||||||
"notes": "Notes",
|
|
||||||
"location": "Location",
|
|
||||||
"repeat_freq": "Repeats",
|
|
||||||
"skip": "Skip",
|
|
||||||
"startdate": "Start date",
|
|
||||||
"enddate": "End date",
|
|
||||||
"object_group": "Group",
|
|
||||||
"attachments": "Attachments",
|
|
||||||
"deletePermanently": "Delete permanently",
|
|
||||||
"active": "Active",
|
|
||||||
"include_net_worth": "Include in net worth",
|
|
||||||
"cc_type": "Credit card payment plan",
|
|
||||||
"account_number": "Account number",
|
|
||||||
"cc_monthly_payment_date": "Credit card monthly payment date",
|
|
||||||
"virtual_balance": "Virtual balance",
|
|
||||||
"opening_balance": "Opening balance",
|
|
||||||
"opening_balance_date": "Opening balance date",
|
|
||||||
"date": "Date",
|
|
||||||
"interest": "Interest",
|
|
||||||
"interest_period": "Interest period",
|
|
||||||
"currency_id": "Currency",
|
|
||||||
"liability_type": "Liability type",
|
|
||||||
"account_role": "Account role",
|
|
||||||
"liability_direction": "Liability in\/out",
|
|
||||||
"book_date": "Book date",
|
|
||||||
"permDeleteWarning": "Deleting stuff from Firefly III is permanent and cannot be undone.",
|
|
||||||
"account_areYouSure_js": "Are you sure you want to delete the account named \"{name}\"?",
|
|
||||||
"also_delete_piggyBanks_js": "No piggy banks|The only piggy bank connected to this account will be deleted as well.|All {count} piggy banks connected to this account will be deleted as well.",
|
|
||||||
"also_delete_transactions_js": "No transactions|The only transaction connected to this account will be deleted as well.|All {count} transactions connected to this account will be deleted as well.",
|
|
||||||
"process_date": "Processing date",
|
|
||||||
"due_date": "Due date",
|
|
||||||
"payment_date": "Payment date",
|
|
||||||
"invoice_date": "Invoice date",
|
|
||||||
"amount_min": "Minimum amount",
|
|
||||||
"amount_max": "Maximum amount",
|
|
||||||
"start_date": "Start of range",
|
|
||||||
"end_date": "End of range",
|
|
||||||
"extension_date": "Extension date"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
{
|
|
||||||
"firefly": {
|
|
||||||
"Transfer": "Transferencia",
|
|
||||||
"Withdrawal": "Retiro",
|
|
||||||
"Deposit": "Dep\u00f3sito",
|
|
||||||
"date_and_time": "Fecha y hora",
|
|
||||||
"no_currency": "(sin moneda)",
|
|
||||||
"date": "Fecha",
|
|
||||||
"time": "Hora",
|
|
||||||
"no_budget": "(sin presupuesto)",
|
|
||||||
"destination_account": "Cuenta destino",
|
|
||||||
"source_account": "Cuenta origen",
|
|
||||||
"single_split": "Divisi\u00f3n",
|
|
||||||
"create_new_transaction": "Crear una nueva transacci\u00f3n",
|
|
||||||
"balance": "Balance",
|
|
||||||
"transaction_journal_extra": "Informaci\u00f3n adicional",
|
|
||||||
"transaction_journal_meta": "Informaci\u00f3n Meta",
|
|
||||||
"basic_journal_information": "Informaci\u00f3n b\u00e1sica de transacci\u00f3n",
|
|
||||||
"bills_to_pay": "Facturas por pagar",
|
|
||||||
"left_to_spend": "Disponible para gastar",
|
|
||||||
"attachments": "Archivos adjuntos",
|
|
||||||
"net_worth": "Valor Neto",
|
|
||||||
"bill": "Factura",
|
|
||||||
"no_bill": "(sin factura)",
|
|
||||||
"tags": "Etiquetas",
|
|
||||||
"internal_reference": "Referencia interna",
|
|
||||||
"external_url": "URL externa",
|
|
||||||
"no_piggy_bank": "(sin hucha)",
|
|
||||||
"paid": "Pagado",
|
|
||||||
"notes": "Notas",
|
|
||||||
"yourAccounts": "Tus cuentas",
|
|
||||||
"go_to_asset_accounts": "Ver tus cuentas de activos",
|
|
||||||
"delete_account": "Eliminar cuenta",
|
|
||||||
"transaction_table_description": "Una tabla que contiene sus transacciones",
|
|
||||||
"account": "Cuenta",
|
|
||||||
"description": "Descripci\u00f3n",
|
|
||||||
"amount": "Cantidad",
|
|
||||||
"budget": "Presupuesto",
|
|
||||||
"category": "Categoria",
|
|
||||||
"opposing_account": "Cuenta opuesta",
|
|
||||||
"budgets": "Presupuestos",
|
|
||||||
"categories": "Categor\u00edas",
|
|
||||||
"go_to_budgets": "Ir a tus presupuestos",
|
|
||||||
"income": "Ingresos \/ salarios",
|
|
||||||
"go_to_deposits": "Ir a dep\u00f3sitos",
|
|
||||||
"go_to_categories": "Ir a tus categor\u00edas",
|
|
||||||
"expense_accounts": "Cuentas de gastos",
|
|
||||||
"go_to_expenses": "Ir a gastos",
|
|
||||||
"go_to_bills": "Ir a tus cuentas",
|
|
||||||
"bills": "Facturas",
|
|
||||||
"last_thirty_days": "\u00daltimos treinta d\u00edas",
|
|
||||||
"last_seven_days": "\u00daltimos siete d\u00edas",
|
|
||||||
"go_to_piggies": "Ir a tu hucha",
|
|
||||||
"saved": "Guardado",
|
|
||||||
"piggy_banks": "Huchas",
|
|
||||||
"piggy_bank": "Hucha",
|
|
||||||
"amounts": "Importes",
|
|
||||||
"left": "Disponible",
|
|
||||||
"spent": "Gastado",
|
|
||||||
"Default asset account": "Cuenta de activos por defecto",
|
|
||||||
"search_results": "Buscar resultados",
|
|
||||||
"include": "\u00bfIncluir?",
|
|
||||||
"transaction": "Transaccion",
|
|
||||||
"account_role_defaultAsset": "Cuentas de ingresos por defecto",
|
|
||||||
"account_role_savingAsset": "Cuentas de ahorros",
|
|
||||||
"account_role_sharedAsset": "Cuenta de ingresos compartida",
|
|
||||||
"clear_location": "Eliminar ubicaci\u00f3n",
|
|
||||||
"account_role_ccAsset": "Tarjeta de Cr\u00e9dito",
|
|
||||||
"account_role_cashWalletAsset": "Billetera de efectivo",
|
|
||||||
"daily_budgets": "Presupuestos diarios",
|
|
||||||
"weekly_budgets": "Presupuestos semanales",
|
|
||||||
"monthly_budgets": "Presupuestos mensuales",
|
|
||||||
"journals_in_period_for_account_js": "Todas las transacciones de la cuenta {title} entre {start} y {end}",
|
|
||||||
"quarterly_budgets": "Presupuestos trimestrales",
|
|
||||||
"create_new_expense": "Crear nueva cuenta de gastos",
|
|
||||||
"create_new_revenue": "Crear nueva cuenta de ingresos",
|
|
||||||
"create_new_liabilities": "Crear nuevo pasivo",
|
|
||||||
"half_year_budgets": "Presupuestos semestrales",
|
|
||||||
"yearly_budgets": "Presupuestos anuales",
|
|
||||||
"split_transaction_title": "Descripci\u00f3n de la transacci\u00f3n dividida",
|
|
||||||
"errors_submission": "Hubo un problema con su env\u00edo. Por favor, compruebe los errores.",
|
|
||||||
"flash_error": "\u00a1Error!",
|
|
||||||
"store_transaction": "Guardar transacci\u00f3n",
|
|
||||||
"flash_success": "\u00a1Operaci\u00f3n correcta!",
|
|
||||||
"create_another": "Despu\u00e9s de guardar, vuelve aqu\u00ed para crear otro.",
|
|
||||||
"update_transaction": "Actualizar transacci\u00f3n",
|
|
||||||
"after_update_create_another": "Despu\u00e9s de actualizar, vuelve aqu\u00ed para continuar editando.",
|
|
||||||
"transaction_updated_no_changes": "<a href=\"transactions\/show\/{ID}\">La transacci\u00f3n #{ID}<\/a> (\"{title}\") no recibi\u00f3 ning\u00fan cambio.",
|
|
||||||
"transaction_updated_link": "<a href=\"transactions\/show\/{ID}\">La transacci\u00f3n #{ID}<\/a> (\"{title}\") ha sido actualizada.",
|
|
||||||
"spent_x_of_y": "{amount} gastado de {total}",
|
|
||||||
"search": "Buscar",
|
|
||||||
"create_new_asset": "Crear nueva cuenta de activos",
|
|
||||||
"asset_accounts": "Cuenta de activos",
|
|
||||||
"reset_after": "Restablecer formulario despu\u00e9s del env\u00edo",
|
|
||||||
"bill_paid_on": "Pagado el {date}",
|
|
||||||
"first_split_decides": "La primera divisi\u00f3n determina el valor de este campo",
|
|
||||||
"first_split_overrules_source": "La primera divisi\u00f3n puede anular la cuenta de origen",
|
|
||||||
"first_split_overrules_destination": "La primera divisi\u00f3n puede anular la cuenta de destino",
|
|
||||||
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">La transacci\u00f3n #{ID} (\"{title}\")<\/a> ha sido almacenada.",
|
|
||||||
"custom_period": "Per\u00edodo personalizado",
|
|
||||||
"reset_to_current": "Restablecer al per\u00edodo actual",
|
|
||||||
"select_period": "Seleccione un per\u00edodo",
|
|
||||||
"location": "Ubicaci\u00f3n",
|
|
||||||
"other_budgets": "Presupuestos de tiempo personalizado",
|
|
||||||
"journal_links": "Enlaces de transacciones",
|
|
||||||
"go_to_withdrawals": "Ir a tus retiradas",
|
|
||||||
"revenue_accounts": "Cuentas de ingresos",
|
|
||||||
"add_another_split": "A\u00f1adir otra divisi\u00f3n",
|
|
||||||
"actions": "Acciones",
|
|
||||||
"earned": "Ganado",
|
|
||||||
"empty": "(vac\u00edo)",
|
|
||||||
"edit": "Editar",
|
|
||||||
"never": "Nunca",
|
|
||||||
"account_type_Loan": "Pr\u00e9stamo",
|
|
||||||
"account_type_Mortgage": "Hipoteca",
|
|
||||||
"stored_new_account_js": "Nueva cuenta \"<a href=\"accounts\/show\/{ID}\">{name}<\/a>\" guardada!",
|
|
||||||
"account_type_Debt": "Deuda",
|
|
||||||
"liability_direction_null_short": "Desconocido",
|
|
||||||
"delete": "Eliminar",
|
|
||||||
"store_new_asset_account": "Crear cuenta de activos",
|
|
||||||
"store_new_expense_account": "Crear cuenta de gastos",
|
|
||||||
"store_new_liabilities_account": "Crear nuevo pasivo",
|
|
||||||
"store_new_revenue_account": "Crear cuenta de ingresos",
|
|
||||||
"mandatoryFields": "Campos obligatorios",
|
|
||||||
"optionalFields": "Campos opcionales",
|
|
||||||
"reconcile_this_account": "Reconciliar esta cuenta",
|
|
||||||
"interest_calc_weekly": "Por semana",
|
|
||||||
"interest_calc_monthly": "Por mes",
|
|
||||||
"interest_calc_quarterly": "Por trimestre",
|
|
||||||
"interest_calc_half-year": "Por semestre",
|
|
||||||
"interest_calc_yearly": "Por a\u00f1o",
|
|
||||||
"liability_direction_credit": "Se me debe esta deuda",
|
|
||||||
"liability_direction_debit": "Le debo esta deuda a otra persona",
|
|
||||||
"liability_direction_credit_short": "Ten\u00eda esta deuda",
|
|
||||||
"liability_direction_debit_short": "Tiene esta deuda",
|
|
||||||
"account_type_debt": "Deuda",
|
|
||||||
"account_type_loan": "Pr\u00e9stamo",
|
|
||||||
"left_in_debt": "Importe debido",
|
|
||||||
"account_type_mortgage": "Hipoteca",
|
|
||||||
"save_transactions_by_moving_js": "Ninguna transacci\u00f3n|Guardar esta transacci\u00f3n movi\u00e9ndola a otra cuenta. |Guardar estas transacciones movi\u00e9ndolas a otra cuenta.",
|
|
||||||
"none_in_select_list": "(ninguno)",
|
|
||||||
"transaction_expand_split": "Expandir divisi\u00f3n",
|
|
||||||
"transaction_collapse_split": "Colapsar divisi\u00f3n",
|
|
||||||
"default_group_title_name": "(sin agrupaci\u00f3n)",
|
|
||||||
"bill_repeats_weekly": "Repetir semanalmente",
|
|
||||||
"bill_repeats_monthly": "Repetir mensualmente",
|
|
||||||
"bill_repeats_quarterly": "Repite trimestralmente",
|
|
||||||
"bill_repeats_half-year": "Repetir cada 6 meses",
|
|
||||||
"bill_repeats_yearly": "Repetir anualmente",
|
|
||||||
"bill_repeats_weekly_other": "Repetir cada dos semanas",
|
|
||||||
"bill_repeats_monthly_other": "Repetir cada dos meses",
|
|
||||||
"bill_repeats_quarterly_other": "Repetir cada dos trimestres",
|
|
||||||
"bill_repeats_half-year_other": "Repetir anualmente",
|
|
||||||
"bill_repeats_yearly_other": "Repetir cada dos a\u00f1os",
|
|
||||||
"bill_repeats_weekly_skip": "Repetir cada {skip} semanas",
|
|
||||||
"bill_repeats_monthly_skip": "Repetir cada {skip} meses",
|
|
||||||
"bill_repeats_quarterly_skip": "Repetir cada {skip} trimestres",
|
|
||||||
"bill_repeats_half-year_skip": "Repetir cada {skip} medios a\u00f1os",
|
|
||||||
"bill_repeats_yearly_skip": "Repetir cada {skip} a\u00f1os",
|
|
||||||
"not_expected_period": "No se espera en este per\u00edodo",
|
|
||||||
"subscriptions": "Suscripciones",
|
|
||||||
"bill_expected_date_js": "Fecha prevista {date}",
|
|
||||||
"inactive": "Inactivo",
|
|
||||||
"forever": "Siempre",
|
|
||||||
"extension_date_is": "Fecha de extensi\u00f3n es {date}",
|
|
||||||
"create_new_bill": "Crear nueva factura",
|
|
||||||
"store_new_bill": "Crear factura",
|
|
||||||
"repeat_freq_yearly": "anualmente",
|
|
||||||
"repeat_freq_half-year": "cada medio a\u00f1o",
|
|
||||||
"repeat_freq_quarterly": "trimestralmente",
|
|
||||||
"repeat_freq_monthly": "mensualmente",
|
|
||||||
"repeat_freq_weekly": "semanalmente",
|
|
||||||
"credit_card_type_monthlyFull": "Pago completo cada mes",
|
|
||||||
"update_liabilities_account": "Actualizar pasivo",
|
|
||||||
"update_expense_account": "Actualizar cuenta de gastos",
|
|
||||||
"update_revenue_account": "Actualizar cuenta de ingresos",
|
|
||||||
"update_undefined_account": "Actualizar cuenta",
|
|
||||||
"update_asset_account": "Actualizar cuenta de activos",
|
|
||||||
"updated_account_js": "Cuenta actualizada \"<a href=\"accounts\/show\/{ID}\">{title}<\/a>\"."
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"piggy_bank": "Alcancilla",
|
|
||||||
"percentage": "pct.",
|
|
||||||
"amount": "Monto",
|
|
||||||
"lastActivity": "Actividad m\u00e1s reciente",
|
|
||||||
"name": "Nombre",
|
|
||||||
"role": "Rol",
|
|
||||||
"description": "Descripci\u00f3n",
|
|
||||||
"date": "Fecha",
|
|
||||||
"source_account": "Cuenta origen",
|
|
||||||
"destination_account": "Cuenta destino",
|
|
||||||
"category": "Categor\u00eda",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"interest": "Inter\u00e9s",
|
|
||||||
"interest_period": "Per\u00edodo de inter\u00e9s",
|
|
||||||
"liability_type": "Tipo de pasivo",
|
|
||||||
"liability_direction": "Pasivo entrada\/salida",
|
|
||||||
"currentBalance": "Balance actual",
|
|
||||||
"next_expected_match": "Pr\u00f3xima coincidencia esperada",
|
|
||||||
"expected_info": "Siguiente transacci\u00f3n esperada",
|
|
||||||
"start_date": "Fecha de inicio",
|
|
||||||
"end_date": "Fecha fin",
|
|
||||||
"payment_info": "Informaci\u00f3n del pago"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"html_language": "es",
|
|
||||||
"week_in_year_fns": "'Semana' w, yyyy",
|
|
||||||
"month_and_day_fns": "d MMMM y",
|
|
||||||
"quarter_fns": "'Trimestre' Q, yyyy",
|
|
||||||
"half_year_fns": "'H{half}', yyyy"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"foreign_amount": "Cantidad extranjera",
|
|
||||||
"interest_date": "Fecha de inter\u00e9s",
|
|
||||||
"name": "Nombre",
|
|
||||||
"amount": "Importe",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"BIC": "BIC",
|
|
||||||
"notes": "Notas",
|
|
||||||
"location": "Ubicaci\u00f3n",
|
|
||||||
"repeat_freq": "Repetici\u00f3n",
|
|
||||||
"skip": "Saltar",
|
|
||||||
"startdate": "Fecha de inicio",
|
|
||||||
"enddate": "Fecha fin",
|
|
||||||
"object_group": "Grupo",
|
|
||||||
"attachments": "Adjuntos",
|
|
||||||
"deletePermanently": "Borrar permanentemente",
|
|
||||||
"active": "Activo",
|
|
||||||
"include_net_worth": "Incluir en valor neto",
|
|
||||||
"cc_type": "Plan de pagos con tarjeta de cr\u00e9dito",
|
|
||||||
"account_number": "N\u00famero de cuenta",
|
|
||||||
"cc_monthly_payment_date": "Fecha de pago mensual de la tarjeta de cr\u00e9dito",
|
|
||||||
"virtual_balance": "Saldo virtual",
|
|
||||||
"opening_balance": "Saldo inicial",
|
|
||||||
"opening_balance_date": "Fecha del saldo inicial",
|
|
||||||
"date": "Fecha",
|
|
||||||
"interest": "Inter\u00e9s",
|
|
||||||
"interest_period": "Per\u00edodo de inter\u00e9s",
|
|
||||||
"currency_id": "Divisa",
|
|
||||||
"liability_type": "Tipo de pasivo",
|
|
||||||
"account_role": "Rol de cuenta",
|
|
||||||
"liability_direction": "Pasivo entrada\/salida",
|
|
||||||
"book_date": "Fecha de registro",
|
|
||||||
"permDeleteWarning": "Eliminar cosas de Firefly III es permanente y no se puede deshacer.",
|
|
||||||
"account_areYouSure_js": "\u00bfEst\u00e1 seguro que desea eliminar la cuenta llamada \"{name}\"?",
|
|
||||||
"also_delete_piggyBanks_js": "Ninguna alcanc\u00eda|La \u00fanica alcanc\u00eda conectada a esta cuenta tambi\u00e9n ser\u00e1 borrada. Tambi\u00e9n se eliminar\u00e1n todas {count} alcanc\u00edas conectados a esta cuenta.",
|
|
||||||
"also_delete_transactions_js": "Ninguna transacci\u00f3n|La \u00fanica transacci\u00f3n conectada a esta cuenta se eliminar\u00e1 tambi\u00e9n.|Todas las {count} transacciones conectadas a esta cuenta tambi\u00e9n se eliminar\u00e1n.",
|
|
||||||
"process_date": "Fecha de procesamiento",
|
|
||||||
"due_date": "Fecha de vencimiento",
|
|
||||||
"payment_date": "Fecha de pago",
|
|
||||||
"invoice_date": "Fecha de la factura",
|
|
||||||
"amount_min": "Importe m\u00ednimo",
|
|
||||||
"amount_max": "Importe m\u00e1ximo",
|
|
||||||
"start_date": "Inicio del rango",
|
|
||||||
"end_date": "Final del rango",
|
|
||||||
"extension_date": "Fecha de extensi\u00f3n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
{
|
|
||||||
"firefly": {
|
|
||||||
"Transfer": "Siirto",
|
|
||||||
"Withdrawal": "Nosto",
|
|
||||||
"Deposit": "Talletus",
|
|
||||||
"date_and_time": "Date and time",
|
|
||||||
"no_currency": "(ei valuuttaa)",
|
|
||||||
"date": "P\u00e4iv\u00e4m\u00e4\u00e4r\u00e4",
|
|
||||||
"time": "Time",
|
|
||||||
"no_budget": "(ei budjettia)",
|
|
||||||
"destination_account": "Kohdetili",
|
|
||||||
"source_account": "L\u00e4hdetili",
|
|
||||||
"single_split": "Split",
|
|
||||||
"create_new_transaction": "Create a new transaction",
|
|
||||||
"balance": "Saldo",
|
|
||||||
"transaction_journal_extra": "Extra information",
|
|
||||||
"transaction_journal_meta": "Metatiedot",
|
|
||||||
"basic_journal_information": "Basic transaction information",
|
|
||||||
"bills_to_pay": "Laskuja maksettavana",
|
|
||||||
"left_to_spend": "K\u00e4ytett\u00e4viss\u00e4",
|
|
||||||
"attachments": "Liitteet",
|
|
||||||
"net_worth": "Varallisuus",
|
|
||||||
"bill": "Lasku",
|
|
||||||
"no_bill": "(no bill)",
|
|
||||||
"tags": "T\u00e4git",
|
|
||||||
"internal_reference": "Internal reference",
|
|
||||||
"external_url": "External URL",
|
|
||||||
"no_piggy_bank": "(ei s\u00e4\u00e4st\u00f6possu)",
|
|
||||||
"paid": "Maksettu",
|
|
||||||
"notes": "Muistiinpanot",
|
|
||||||
"yourAccounts": "Omat tilisi",
|
|
||||||
"go_to_asset_accounts": "Tarkastele omaisuustilej\u00e4si",
|
|
||||||
"delete_account": "Poista k\u00e4ytt\u00e4j\u00e4tili",
|
|
||||||
"transaction_table_description": "A table containing your transactions",
|
|
||||||
"account": "Tili",
|
|
||||||
"description": "Kuvaus",
|
|
||||||
"amount": "Summa",
|
|
||||||
"budget": "Budjetti",
|
|
||||||
"category": "Kategoria",
|
|
||||||
"opposing_account": "Vastatili",
|
|
||||||
"budgets": "Budjetit",
|
|
||||||
"categories": "Kategoriat",
|
|
||||||
"go_to_budgets": "Avaa omat budjetit",
|
|
||||||
"income": "Tuotto \/ ansio",
|
|
||||||
"go_to_deposits": "Go to deposits",
|
|
||||||
"go_to_categories": "Avaa omat kategoriat",
|
|
||||||
"expense_accounts": "Kulutustilit",
|
|
||||||
"go_to_expenses": "Go to expenses",
|
|
||||||
"go_to_bills": "Avaa omat laskut",
|
|
||||||
"bills": "Laskut",
|
|
||||||
"last_thirty_days": "Viimeiset 30 p\u00e4iv\u00e4\u00e4",
|
|
||||||
"last_seven_days": "Viimeiset 7 p\u00e4iv\u00e4\u00e4",
|
|
||||||
"go_to_piggies": "Tarkastele s\u00e4\u00e4st\u00f6possujasi",
|
|
||||||
"saved": "Saved",
|
|
||||||
"piggy_banks": "S\u00e4\u00e4st\u00f6possut",
|
|
||||||
"piggy_bank": "S\u00e4\u00e4st\u00f6possu",
|
|
||||||
"amounts": "Amounts",
|
|
||||||
"left": "J\u00e4ljell\u00e4",
|
|
||||||
"spent": "K\u00e4ytetty",
|
|
||||||
"Default asset account": "Oletusomaisuustili",
|
|
||||||
"search_results": "Haun tulokset",
|
|
||||||
"include": "Include?",
|
|
||||||
"transaction": "Tapahtuma",
|
|
||||||
"account_role_defaultAsset": "Oletusk\u00e4ytt\u00f6tili",
|
|
||||||
"account_role_savingAsset": "S\u00e4\u00e4st\u00f6tili",
|
|
||||||
"account_role_sharedAsset": "Jaettu k\u00e4ytt\u00f6tili",
|
|
||||||
"clear_location": "Tyhjenn\u00e4 sijainti",
|
|
||||||
"account_role_ccAsset": "Luottokortti",
|
|
||||||
"account_role_cashWalletAsset": "K\u00e4teinen",
|
|
||||||
"daily_budgets": "Daily budgets",
|
|
||||||
"weekly_budgets": "Weekly budgets",
|
|
||||||
"monthly_budgets": "Monthly budgets",
|
|
||||||
"journals_in_period_for_account_js": "All transactions for account {title} between {start} and {end}",
|
|
||||||
"quarterly_budgets": "Quarterly budgets",
|
|
||||||
"create_new_expense": "Luo uusi maksutili",
|
|
||||||
"create_new_revenue": "Luo uusi tuottotili",
|
|
||||||
"create_new_liabilities": "Create new liability",
|
|
||||||
"half_year_budgets": "Half-yearly budgets",
|
|
||||||
"yearly_budgets": "Yearly budgets",
|
|
||||||
"split_transaction_title": "Jaetun tapahtuman kuvaus",
|
|
||||||
"errors_submission": "There was something wrong with your submission. Please check out the errors.",
|
|
||||||
"flash_error": "Virhe!",
|
|
||||||
"store_transaction": "Store transaction",
|
|
||||||
"flash_success": "Valmista tuli!",
|
|
||||||
"create_another": "Tallennuksen j\u00e4lkeen, palaa takaisin luomaan uusi tapahtuma.",
|
|
||||||
"update_transaction": "P\u00e4ivit\u00e4 tapahtuma",
|
|
||||||
"after_update_create_another": "P\u00e4ivityksen j\u00e4lkeen, palaa takaisin jatkamaan muokkausta.",
|
|
||||||
"transaction_updated_no_changes": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") did not receive any changes.",
|
|
||||||
"transaction_updated_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") has been updated.",
|
|
||||||
"spent_x_of_y": "Spent {amount} of {total}",
|
|
||||||
"search": "Hae",
|
|
||||||
"create_new_asset": "Luo uusi omaisuustili",
|
|
||||||
"asset_accounts": "K\u00e4ytt\u00f6tilit",
|
|
||||||
"reset_after": "Tyhjenn\u00e4 lomake l\u00e4hetyksen j\u00e4lkeen",
|
|
||||||
"bill_paid_on": "Paid on {date}",
|
|
||||||
"first_split_decides": "The first split determines the value of this field",
|
|
||||||
"first_split_overrules_source": "The first split may overrule the source account",
|
|
||||||
"first_split_overrules_destination": "The first split may overrule the destination account",
|
|
||||||
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID} (\"{title}\")<\/a> has been stored.",
|
|
||||||
"custom_period": "Custom period",
|
|
||||||
"reset_to_current": "Reset to current period",
|
|
||||||
"select_period": "Select a period",
|
|
||||||
"location": "Sijainti",
|
|
||||||
"other_budgets": "Custom timed budgets",
|
|
||||||
"journal_links": "Tapahtuman linkit",
|
|
||||||
"go_to_withdrawals": "Go to your withdrawals",
|
|
||||||
"revenue_accounts": "Tuottotilit",
|
|
||||||
"add_another_split": "Lis\u00e4\u00e4 tapahtumaan uusi osa",
|
|
||||||
"actions": "Toiminnot",
|
|
||||||
"earned": "Ansaittu",
|
|
||||||
"empty": "(tyhj\u00e4)",
|
|
||||||
"edit": "Muokkaa",
|
|
||||||
"never": "Ei koskaan",
|
|
||||||
"account_type_Loan": "Laina",
|
|
||||||
"account_type_Mortgage": "Kiinnelaina",
|
|
||||||
"stored_new_account_js": "New account \"<a href=\"accounts\/show\/{ID}\">{name}<\/a>\" stored!",
|
|
||||||
"account_type_Debt": "Velka",
|
|
||||||
"liability_direction_null_short": "Unknown",
|
|
||||||
"delete": "Poista",
|
|
||||||
"store_new_asset_account": "Tallenna uusi omaisuustili",
|
|
||||||
"store_new_expense_account": "Tallenna uusi kulutustili",
|
|
||||||
"store_new_liabilities_account": "Tallenna uusi vastuu",
|
|
||||||
"store_new_revenue_account": "Tallenna uusi tuottotili",
|
|
||||||
"mandatoryFields": "Pakolliset kent\u00e4t",
|
|
||||||
"optionalFields": "Valinnaiset kent\u00e4t",
|
|
||||||
"reconcile_this_account": "T\u00e4sm\u00e4yt\u00e4 t\u00e4m\u00e4 tili",
|
|
||||||
"interest_calc_weekly": "Per week",
|
|
||||||
"interest_calc_monthly": "Kuukaudessa",
|
|
||||||
"interest_calc_quarterly": "Per quarter",
|
|
||||||
"interest_calc_half-year": "Per half year",
|
|
||||||
"interest_calc_yearly": "Vuodessa",
|
|
||||||
"liability_direction_credit": "I am owed this debt",
|
|
||||||
"liability_direction_debit": "I owe this debt to somebody else",
|
|
||||||
"liability_direction_credit_short": "Owed this debt",
|
|
||||||
"liability_direction_debit_short": "Owe this debt",
|
|
||||||
"account_type_debt": "Debt",
|
|
||||||
"account_type_loan": "Loan",
|
|
||||||
"left_in_debt": "Amount due",
|
|
||||||
"account_type_mortgage": "Mortgage",
|
|
||||||
"save_transactions_by_moving_js": "No transactions|Save this transaction by moving it to another account. |Save these transactions by moving them to another account.",
|
|
||||||
"none_in_select_list": "(ei mit\u00e4\u00e4n)",
|
|
||||||
"transaction_expand_split": "Expand split",
|
|
||||||
"transaction_collapse_split": "Collapse split",
|
|
||||||
"default_group_title_name": "(ryhmittelem\u00e4tt\u00f6m\u00e4t)",
|
|
||||||
"bill_repeats_weekly": "Repeats weekly",
|
|
||||||
"bill_repeats_monthly": "Repeats monthly",
|
|
||||||
"bill_repeats_quarterly": "Repeats quarterly",
|
|
||||||
"bill_repeats_half-year": "Repeats every half year",
|
|
||||||
"bill_repeats_yearly": "Repeats yearly",
|
|
||||||
"bill_repeats_weekly_other": "Repeats every other week",
|
|
||||||
"bill_repeats_monthly_other": "Repeats every other month",
|
|
||||||
"bill_repeats_quarterly_other": "Repeats every other quarter",
|
|
||||||
"bill_repeats_half-year_other": "Repeats yearly",
|
|
||||||
"bill_repeats_yearly_other": "Repeats every other year",
|
|
||||||
"bill_repeats_weekly_skip": "Repeats every {skip} weeks",
|
|
||||||
"bill_repeats_monthly_skip": "Repeats every {skip} months",
|
|
||||||
"bill_repeats_quarterly_skip": "Repeats every {skip} quarters",
|
|
||||||
"bill_repeats_half-year_skip": "Repeats every {skip} half years",
|
|
||||||
"bill_repeats_yearly_skip": "Repeats every {skip} years",
|
|
||||||
"not_expected_period": "Ei odotettavissa t\u00e4ss\u00e4 jaksossa",
|
|
||||||
"subscriptions": "Subscriptions",
|
|
||||||
"bill_expected_date_js": "Expected {date}",
|
|
||||||
"inactive": "Ei aktiivinen",
|
|
||||||
"forever": "Forever",
|
|
||||||
"extension_date_is": "Extension date is {date}",
|
|
||||||
"create_new_bill": "Luo uusi lasku",
|
|
||||||
"store_new_bill": "Tallenna uusi lasku",
|
|
||||||
"repeat_freq_yearly": "vuosittain",
|
|
||||||
"repeat_freq_half-year": "puoli-vuosittain",
|
|
||||||
"repeat_freq_quarterly": "nelj\u00e4nnesvuosittain",
|
|
||||||
"repeat_freq_monthly": "kuukausittain",
|
|
||||||
"repeat_freq_weekly": "viikoittain",
|
|
||||||
"credit_card_type_monthlyFull": "Full payment every month",
|
|
||||||
"update_liabilities_account": "P\u00e4ivit\u00e4 vastuu",
|
|
||||||
"update_expense_account": "P\u00e4ivit\u00e4 kulutustili",
|
|
||||||
"update_revenue_account": "P\u00e4ivit\u00e4 tuottotili",
|
|
||||||
"update_undefined_account": "Update account",
|
|
||||||
"update_asset_account": "P\u00e4ivit\u00e4 omaisuustili",
|
|
||||||
"updated_account_js": "Updated account \"<a href=\"accounts\/show\/{ID}\">{title}<\/a>\"."
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"piggy_bank": "S\u00e4\u00e4st\u00f6possu",
|
|
||||||
"percentage": "pros.",
|
|
||||||
"amount": "Summa",
|
|
||||||
"lastActivity": "Viimeisin tapahtuma",
|
|
||||||
"name": "Nimi",
|
|
||||||
"role": "Rooli",
|
|
||||||
"description": "Kuvaus",
|
|
||||||
"date": "P\u00e4iv\u00e4m\u00e4\u00e4r\u00e4",
|
|
||||||
"source_account": "L\u00e4hdetili",
|
|
||||||
"destination_account": "Kohdetili",
|
|
||||||
"category": "Kategoria",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"interest": "Korko",
|
|
||||||
"interest_period": "Interest period",
|
|
||||||
"liability_type": "Vastuutyyppi",
|
|
||||||
"liability_direction": "Liability in\/out",
|
|
||||||
"currentBalance": "T\u00e4m\u00e4nhetkinen saldo",
|
|
||||||
"next_expected_match": "Seuraava lasku odotettavissa",
|
|
||||||
"expected_info": "Next expected transaction",
|
|
||||||
"start_date": "Start date",
|
|
||||||
"end_date": "End date",
|
|
||||||
"payment_info": "Payment information"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"html_language": "fi",
|
|
||||||
"week_in_year_fns": "'Week' w, yyyy",
|
|
||||||
"month_and_day_fns": "MMMM d, y",
|
|
||||||
"quarter_fns": "'Q'Q, yyyy",
|
|
||||||
"half_year_fns": "'H{half}', yyyy"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"foreign_amount": "Ulkomaan summa",
|
|
||||||
"interest_date": "Korkop\u00e4iv\u00e4",
|
|
||||||
"name": "Nimi",
|
|
||||||
"amount": "Summa",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"BIC": "BIC",
|
|
||||||
"notes": "Muistiinpanot",
|
|
||||||
"location": "Sijainti",
|
|
||||||
"repeat_freq": "Toistot",
|
|
||||||
"skip": "Ohita",
|
|
||||||
"startdate": "Aloitusp\u00e4iv\u00e4",
|
|
||||||
"enddate": "End date",
|
|
||||||
"object_group": "Ryhm\u00e4",
|
|
||||||
"attachments": "Liitteet",
|
|
||||||
"deletePermanently": "Poista pysyv\u00e4sti",
|
|
||||||
"active": "Aktiivinen",
|
|
||||||
"include_net_worth": "Sis\u00e4llyt\u00e4 varallisuuteen",
|
|
||||||
"cc_type": "Luottokortin maksusuunnitelma",
|
|
||||||
"account_number": "Tilinumero",
|
|
||||||
"cc_monthly_payment_date": "Luottokortin laskun er\u00e4p\u00e4iv\u00e4",
|
|
||||||
"virtual_balance": "Virtuaalinen saldo",
|
|
||||||
"opening_balance": "Alkusaldo",
|
|
||||||
"opening_balance_date": "Alkusaldon p\u00e4iv\u00e4m\u00e4\u00e4r\u00e4",
|
|
||||||
"date": "P\u00e4iv\u00e4m\u00e4\u00e4r\u00e4",
|
|
||||||
"interest": "Korko",
|
|
||||||
"interest_period": "Korkojakso",
|
|
||||||
"currency_id": "Valuutta",
|
|
||||||
"liability_type": "Liability type",
|
|
||||||
"account_role": "Tilin tyyppi",
|
|
||||||
"liability_direction": "Liability in\/out",
|
|
||||||
"book_date": "Kirjausp\u00e4iv\u00e4",
|
|
||||||
"permDeleteWarning": "Asioiden poistaminen Firefly III:sta on lopullista eik\u00e4 poistoa pysty perumaan.",
|
|
||||||
"account_areYouSure_js": "Are you sure you want to delete the account named \"{name}\"?",
|
|
||||||
"also_delete_piggyBanks_js": "No piggy banks|The only piggy bank connected to this account will be deleted as well.|All {count} piggy banks connected to this account will be deleted as well.",
|
|
||||||
"also_delete_transactions_js": "No transactions|The only transaction connected to this account will be deleted as well.|All {count} transactions connected to this account will be deleted as well.",
|
|
||||||
"process_date": "K\u00e4sittelyp\u00e4iv\u00e4",
|
|
||||||
"due_date": "Er\u00e4p\u00e4iv\u00e4",
|
|
||||||
"payment_date": "Maksup\u00e4iv\u00e4",
|
|
||||||
"invoice_date": "Laskun p\u00e4iv\u00e4m\u00e4\u00e4r\u00e4",
|
|
||||||
"amount_min": "V\u00e4himm\u00e4issumma",
|
|
||||||
"amount_max": "Enimm\u00e4issumma",
|
|
||||||
"start_date": "Valikoiman alku",
|
|
||||||
"end_date": "Valikoiman loppu",
|
|
||||||
"extension_date": "Extension date"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
{
|
|
||||||
"firefly": {
|
|
||||||
"Transfer": "Transfert",
|
|
||||||
"Withdrawal": "D\u00e9pense",
|
|
||||||
"Deposit": "D\u00e9p\u00f4t",
|
|
||||||
"date_and_time": "Date et heure",
|
|
||||||
"no_currency": "(pas de devise)",
|
|
||||||
"date": "Date",
|
|
||||||
"time": "Heure",
|
|
||||||
"no_budget": "(pas de budget)",
|
|
||||||
"destination_account": "Compte de destination",
|
|
||||||
"source_account": "Compte source",
|
|
||||||
"single_split": "Ventilation",
|
|
||||||
"create_new_transaction": "Cr\u00e9er une nouvelle op\u00e9ration",
|
|
||||||
"balance": "Solde",
|
|
||||||
"transaction_journal_extra": "Informations suppl\u00e9mentaires",
|
|
||||||
"transaction_journal_meta": "M\u00e9ta informations",
|
|
||||||
"basic_journal_information": "Informations de base sur l'op\u00e9ration",
|
|
||||||
"bills_to_pay": "Factures \u00e0 payer",
|
|
||||||
"left_to_spend": "Reste \u00e0 d\u00e9penser",
|
|
||||||
"attachments": "Pi\u00e8ces jointes",
|
|
||||||
"net_worth": "Avoir net",
|
|
||||||
"bill": "Facture",
|
|
||||||
"no_bill": "(aucune facture)",
|
|
||||||
"tags": "Tags",
|
|
||||||
"internal_reference": "R\u00e9f\u00e9rence interne",
|
|
||||||
"external_url": "URL externe",
|
|
||||||
"no_piggy_bank": "(aucune tirelire)",
|
|
||||||
"paid": "Pay\u00e9",
|
|
||||||
"notes": "Notes",
|
|
||||||
"yourAccounts": "Vos comptes",
|
|
||||||
"go_to_asset_accounts": "Afficher vos comptes d'actifs",
|
|
||||||
"delete_account": "Supprimer le compte",
|
|
||||||
"transaction_table_description": "Une table contenant vos op\u00e9rations",
|
|
||||||
"account": "Compte",
|
|
||||||
"description": "Description",
|
|
||||||
"amount": "Montant",
|
|
||||||
"budget": "Budget",
|
|
||||||
"category": "Cat\u00e9gorie",
|
|
||||||
"opposing_account": "Compte oppos\u00e9",
|
|
||||||
"budgets": "Budgets",
|
|
||||||
"categories": "Cat\u00e9gories",
|
|
||||||
"go_to_budgets": "G\u00e9rer vos budgets",
|
|
||||||
"income": "Recette \/ revenu",
|
|
||||||
"go_to_deposits": "Aller aux d\u00e9p\u00f4ts",
|
|
||||||
"go_to_categories": "G\u00e9rer vos cat\u00e9gories",
|
|
||||||
"expense_accounts": "Comptes de d\u00e9penses",
|
|
||||||
"go_to_expenses": "Aller aux d\u00e9penses",
|
|
||||||
"go_to_bills": "G\u00e9rer vos factures",
|
|
||||||
"bills": "Factures",
|
|
||||||
"last_thirty_days": "Trente derniers jours",
|
|
||||||
"last_seven_days": "7 Derniers Jours",
|
|
||||||
"go_to_piggies": "G\u00e9rer vos tirelires",
|
|
||||||
"saved": "Sauvegard\u00e9",
|
|
||||||
"piggy_banks": "Tirelires",
|
|
||||||
"piggy_bank": "Tirelire",
|
|
||||||
"amounts": "Montants",
|
|
||||||
"left": "Reste",
|
|
||||||
"spent": "D\u00e9pens\u00e9",
|
|
||||||
"Default asset account": "Compte d\u2019actif par d\u00e9faut",
|
|
||||||
"search_results": "R\u00e9sultats de la recherche",
|
|
||||||
"include": "Inclure ?",
|
|
||||||
"transaction": "Op\u00e9ration",
|
|
||||||
"account_role_defaultAsset": "Compte d'actif par d\u00e9faut",
|
|
||||||
"account_role_savingAsset": "Compte d\u2019\u00e9pargne",
|
|
||||||
"account_role_sharedAsset": "Compte d'actif partag\u00e9",
|
|
||||||
"clear_location": "Effacer la localisation",
|
|
||||||
"account_role_ccAsset": "Carte de cr\u00e9dit",
|
|
||||||
"account_role_cashWalletAsset": "Porte-monnaie",
|
|
||||||
"daily_budgets": "Budgets quotidiens",
|
|
||||||
"weekly_budgets": "Budgets hebdomadaires",
|
|
||||||
"monthly_budgets": "Budgets mensuels",
|
|
||||||
"journals_in_period_for_account_js": "Toutes les op\u00e9rations pour le compte {title} entre {start} et {end}",
|
|
||||||
"quarterly_budgets": "Budgets trimestriels",
|
|
||||||
"create_new_expense": "Cr\u00e9er nouveau compte de d\u00e9penses",
|
|
||||||
"create_new_revenue": "Cr\u00e9er nouveau compte de recettes",
|
|
||||||
"create_new_liabilities": "Cr\u00e9er un nouveau passif",
|
|
||||||
"half_year_budgets": "Budgets semestriels",
|
|
||||||
"yearly_budgets": "Budgets annuels",
|
|
||||||
"split_transaction_title": "Description de l'op\u00e9ration ventil\u00e9e",
|
|
||||||
"errors_submission": "Certaines informations ne sont pas correctes dans votre formulaire. Veuillez v\u00e9rifier les erreurs.",
|
|
||||||
"flash_error": "Erreur !",
|
|
||||||
"store_transaction": "Enregistrer l'op\u00e9ration",
|
|
||||||
"flash_success": "Super !",
|
|
||||||
"create_another": "Apr\u00e8s enregistrement, revenir ici pour en cr\u00e9er un nouveau.",
|
|
||||||
"update_transaction": "Mettre \u00e0 jour l'op\u00e9ration",
|
|
||||||
"after_update_create_another": "Apr\u00e8s la mise \u00e0 jour, revenir ici pour continuer l'\u00e9dition.",
|
|
||||||
"transaction_updated_no_changes": "<a href=\"transactions\/show\/{ID}\">L'op\u00e9ration n\u00b0{ID}<\/a> (\"{title}\") n'a pas \u00e9t\u00e9 modifi\u00e9e.",
|
|
||||||
"transaction_updated_link": "<a href=\"transactions\/show\/{ID}\">L'op\u00e9ration n\u00b0{ID}<\/a> (\"{title}\") a \u00e9t\u00e9 mise \u00e0 jour.",
|
|
||||||
"spent_x_of_y": "D\u00e9pens\u00e9 {amount} sur {total}",
|
|
||||||
"search": "Rechercher",
|
|
||||||
"create_new_asset": "Cr\u00e9er un nouveau compte d\u2019actif",
|
|
||||||
"asset_accounts": "Comptes d\u2019actif",
|
|
||||||
"reset_after": "R\u00e9initialiser le formulaire apr\u00e8s soumission",
|
|
||||||
"bill_paid_on": "Pay\u00e9 le {date}",
|
|
||||||
"first_split_decides": "La premi\u00e8re ventilation d\u00e9termine la valeur de ce champ",
|
|
||||||
"first_split_overrules_source": "La premi\u00e8re ventilation peut remplacer le compte source",
|
|
||||||
"first_split_overrules_destination": "La premi\u00e8re ventilation peut remplacer le compte de destination",
|
|
||||||
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">L'op\u00e9ration n\u00b0{ID} (\"{title}\")<\/a> a \u00e9t\u00e9 enregistr\u00e9e.",
|
|
||||||
"custom_period": "P\u00e9riode personnalis\u00e9e",
|
|
||||||
"reset_to_current": "R\u00e9initialiser \u00e0 la p\u00e9riode en cours",
|
|
||||||
"select_period": "S\u00e9lectionnez une p\u00e9riode",
|
|
||||||
"location": "Emplacement",
|
|
||||||
"other_budgets": "Budgets \u00e0 p\u00e9riode personnalis\u00e9e",
|
|
||||||
"journal_links": "Liens d'op\u00e9ration",
|
|
||||||
"go_to_withdrawals": "Acc\u00e9der \u00e0 vos retraits",
|
|
||||||
"revenue_accounts": "Comptes de recettes",
|
|
||||||
"add_another_split": "Ajouter une autre fraction",
|
|
||||||
"actions": "Actions",
|
|
||||||
"earned": "Gagn\u00e9",
|
|
||||||
"empty": "(vide)",
|
|
||||||
"edit": "Modifier",
|
|
||||||
"never": "Jamais",
|
|
||||||
"account_type_Loan": "Pr\u00eat",
|
|
||||||
"account_type_Mortgage": "Pr\u00eat hypoth\u00e9caire",
|
|
||||||
"stored_new_account_js": "Nouveau compte \"<a href=\"accounts\/show\/{ID}\">{name}<\/a>\" enregistr\u00e9 !",
|
|
||||||
"account_type_Debt": "Dette",
|
|
||||||
"liability_direction_null_short": "Inconnu",
|
|
||||||
"delete": "Supprimer",
|
|
||||||
"store_new_asset_account": "Cr\u00e9er un nouveau compte d\u2019actif",
|
|
||||||
"store_new_expense_account": "Cr\u00e9er un nouveau compte de d\u00e9penses",
|
|
||||||
"store_new_liabilities_account": "Enregistrer un nouveau passif",
|
|
||||||
"store_new_revenue_account": "Cr\u00e9er un compte de recettes",
|
|
||||||
"mandatoryFields": "Champs obligatoires",
|
|
||||||
"optionalFields": "Champs optionnels",
|
|
||||||
"reconcile_this_account": "Rapprocher ce compte",
|
|
||||||
"interest_calc_weekly": "Par semaine",
|
|
||||||
"interest_calc_monthly": "Par mois",
|
|
||||||
"interest_calc_quarterly": "Par trimestre",
|
|
||||||
"interest_calc_half-year": "Par semestre",
|
|
||||||
"interest_calc_yearly": "Par an",
|
|
||||||
"liability_direction_credit": "On me doit cette dette",
|
|
||||||
"liability_direction_debit": "Je dois cette dette \u00e0 quelqu'un d'autre",
|
|
||||||
"liability_direction_credit_short": "Emprunteur",
|
|
||||||
"liability_direction_debit_short": "Pr\u00eateur",
|
|
||||||
"account_type_debt": "Dette",
|
|
||||||
"account_type_loan": "Emprunt",
|
|
||||||
"left_in_debt": "Montant d\u00fb",
|
|
||||||
"account_type_mortgage": "Pr\u00eat immobilier",
|
|
||||||
"save_transactions_by_moving_js": "Aucune op\u00e9ration|Conserver cette op\u00e9ration en la d\u00e9pla\u00e7ant vers un autre compte. |Conserver ces op\u00e9rations en les d\u00e9pla\u00e7ant vers un autre compte.",
|
|
||||||
"none_in_select_list": "(aucun)",
|
|
||||||
"transaction_expand_split": "D\u00e9velopper la ventilation",
|
|
||||||
"transaction_collapse_split": "R\u00e9duire la ventilation",
|
|
||||||
"default_group_title_name": "(Sans groupement)",
|
|
||||||
"bill_repeats_weekly": "Se r\u00e9p\u00e8te toutes les semaines",
|
|
||||||
"bill_repeats_monthly": "Se r\u00e9p\u00e8te tous les mois",
|
|
||||||
"bill_repeats_quarterly": "Se r\u00e9p\u00e8te tous les trimestres",
|
|
||||||
"bill_repeats_half-year": "Se r\u00e9p\u00e8te tous les semestres",
|
|
||||||
"bill_repeats_yearly": "Se r\u00e9p\u00e8te tous les ans",
|
|
||||||
"bill_repeats_weekly_other": "Se r\u00e9p\u00e8te toutes les deux semaines",
|
|
||||||
"bill_repeats_monthly_other": "Se r\u00e9p\u00e8te tous les deux mois",
|
|
||||||
"bill_repeats_quarterly_other": "Se r\u00e9p\u00e8te tous les deux trimestres",
|
|
||||||
"bill_repeats_half-year_other": "Se r\u00e9p\u00e8te tous les ans",
|
|
||||||
"bill_repeats_yearly_other": "Se r\u00e9p\u00e8te tous les deux ans",
|
|
||||||
"bill_repeats_weekly_skip": "Se r\u00e9p\u00e8te toutes les {skip} semaines",
|
|
||||||
"bill_repeats_monthly_skip": "Se r\u00e9p\u00e8te tous les {skip} mois",
|
|
||||||
"bill_repeats_quarterly_skip": "Se r\u00e9p\u00e8te tous les {skip} trimestres",
|
|
||||||
"bill_repeats_half-year_skip": "Se r\u00e9p\u00e8te tous les {skip} semestres",
|
|
||||||
"bill_repeats_yearly_skip": "Se r\u00e9p\u00e8te tous les {skip} ans",
|
|
||||||
"not_expected_period": "Pas attendu cette p\u00e9riode",
|
|
||||||
"subscriptions": "Abonnements",
|
|
||||||
"bill_expected_date_js": "Attendu le {date}",
|
|
||||||
"inactive": "Inactif",
|
|
||||||
"forever": "Pour toujours",
|
|
||||||
"extension_date_is": "La date de l'extension est {date}",
|
|
||||||
"create_new_bill": "Cr\u00e9er une nouvelle facture",
|
|
||||||
"store_new_bill": "Cr\u00e9er une nouvelle facture",
|
|
||||||
"repeat_freq_yearly": "annuellement",
|
|
||||||
"repeat_freq_half-year": "semestriel",
|
|
||||||
"repeat_freq_quarterly": "trimestriel",
|
|
||||||
"repeat_freq_monthly": "mensuel",
|
|
||||||
"repeat_freq_weekly": "hebdomadaire",
|
|
||||||
"credit_card_type_monthlyFull": "Paiement complet tous les mois",
|
|
||||||
"update_liabilities_account": "Mettre \u00e0 jour le passif",
|
|
||||||
"update_expense_account": "Mettre \u00e0 jour le compte de d\u00e9penses",
|
|
||||||
"update_revenue_account": "Mettre \u00e0 jour le compte de recettes",
|
|
||||||
"update_undefined_account": "Mettre \u00e0 jour le compte",
|
|
||||||
"update_asset_account": "Mettre \u00e0 jour le compte d\u2019actif",
|
|
||||||
"updated_account_js": "Compte \"<a href=\"accounts\/show\/{ID}\">{title}<\/a>\" mis \u00e0 jour."
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"piggy_bank": "Tirelire",
|
|
||||||
"percentage": "pct.",
|
|
||||||
"amount": "Montant",
|
|
||||||
"lastActivity": "Activit\u00e9 r\u00e9cente",
|
|
||||||
"name": "Nom",
|
|
||||||
"role": "R\u00f4le",
|
|
||||||
"description": "Description",
|
|
||||||
"date": "Date",
|
|
||||||
"source_account": "Compte source",
|
|
||||||
"destination_account": "Compte destinataire",
|
|
||||||
"category": "Cat\u00e9gorie",
|
|
||||||
"iban": "Num\u00e9ro IBAN",
|
|
||||||
"interest": "Int\u00e9r\u00eat",
|
|
||||||
"interest_period": "P\u00e9riode d\u2019int\u00e9r\u00eat",
|
|
||||||
"liability_type": "Type de passif",
|
|
||||||
"liability_direction": "Sens du passif",
|
|
||||||
"currentBalance": "Solde courant",
|
|
||||||
"next_expected_match": "Prochaine association attendue",
|
|
||||||
"expected_info": "Prochaine op\u00e9ration attendue",
|
|
||||||
"start_date": "Date de d\u00e9but",
|
|
||||||
"end_date": "Date de fin",
|
|
||||||
"payment_info": "Informations sur le paiement"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"html_language": "fr",
|
|
||||||
"week_in_year_fns": "'Semaine' w, yyyy",
|
|
||||||
"month_and_day_fns": "d MMMM y",
|
|
||||||
"quarter_fns": "'Q'Q, yyyy",
|
|
||||||
"half_year_fns": "'H{half}', yyyy"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"foreign_amount": "Montant en devise \u00e9trang\u00e8re",
|
|
||||||
"interest_date": "Date de valeur (int\u00e9r\u00eats)",
|
|
||||||
"name": "Nom",
|
|
||||||
"amount": "Montant",
|
|
||||||
"iban": "Num\u00e9ro IBAN",
|
|
||||||
"BIC": "Code BIC",
|
|
||||||
"notes": "Notes",
|
|
||||||
"location": "Emplacement",
|
|
||||||
"repeat_freq": "R\u00e9p\u00e9titions",
|
|
||||||
"skip": "Ignorer",
|
|
||||||
"startdate": "Date de d\u00e9but",
|
|
||||||
"enddate": "Date de fin",
|
|
||||||
"object_group": "Groupe",
|
|
||||||
"attachments": "Documents joints",
|
|
||||||
"deletePermanently": "Supprimer d\u00e9finitivement",
|
|
||||||
"active": "Actif",
|
|
||||||
"include_net_worth": "Inclure dans l'avoir net",
|
|
||||||
"cc_type": "Plan de paiement de carte de cr\u00e9dit",
|
|
||||||
"account_number": "Num\u00e9ro de compte",
|
|
||||||
"cc_monthly_payment_date": "Date de paiement mensuelle de la carte de cr\u00e9dit",
|
|
||||||
"virtual_balance": "Solde virtuel",
|
|
||||||
"opening_balance": "Solde initial",
|
|
||||||
"opening_balance_date": "Date du solde initial",
|
|
||||||
"date": "Date",
|
|
||||||
"interest": "Int\u00e9r\u00eat",
|
|
||||||
"interest_period": "P\u00e9riode d\u2019int\u00e9r\u00eat",
|
|
||||||
"currency_id": "Devise",
|
|
||||||
"liability_type": "Type de passif",
|
|
||||||
"account_role": "R\u00f4le du compte",
|
|
||||||
"liability_direction": "Sens du passif",
|
|
||||||
"book_date": "Date de r\u00e9servation",
|
|
||||||
"permDeleteWarning": "Supprimer quelque chose dans Firefly est permanent et ne peut pas \u00eatre annul\u00e9.",
|
|
||||||
"account_areYouSure_js": "\u00cates-vous s\u00fbr de vouloir supprimer le compte nomm\u00e9 \"{name}\" ?",
|
|
||||||
"also_delete_piggyBanks_js": "Aucune tirelire|La seule tirelire li\u00e9e \u00e0 ce compte sera aussi supprim\u00e9e.|Les {count} tirelires li\u00e9es \u00e0 ce compte seront aussi supprim\u00e9es.",
|
|
||||||
"also_delete_transactions_js": "Aucune op\u00e9ration|La seule op\u00e9ration li\u00e9e \u00e0 ce compte sera aussi supprim\u00e9e.|Les {count} op\u00e9rations li\u00e9es \u00e0 ce compte seront aussi supprim\u00e9es.",
|
|
||||||
"process_date": "Date de traitement",
|
|
||||||
"due_date": "\u00c9ch\u00e9ance",
|
|
||||||
"payment_date": "Date de paiement",
|
|
||||||
"invoice_date": "Date de facturation",
|
|
||||||
"amount_min": "Montant minimum",
|
|
||||||
"amount_max": "Montant maximum",
|
|
||||||
"start_date": "D\u00e9but de l'\u00e9tendue",
|
|
||||||
"end_date": "Fin de l'\u00e9tendue",
|
|
||||||
"extension_date": "Date d'extension"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
{
|
|
||||||
"firefly": {
|
|
||||||
"Transfer": "\u00c1tvezet\u00e9s",
|
|
||||||
"Withdrawal": "K\u00f6lts\u00e9g",
|
|
||||||
"Deposit": "Bev\u00e9tel",
|
|
||||||
"date_and_time": "Date and time",
|
|
||||||
"no_currency": "(nincs p\u00e9nznem)",
|
|
||||||
"date": "D\u00e1tum",
|
|
||||||
"time": "Time",
|
|
||||||
"no_budget": "(nincs k\u00f6lts\u00e9gkeret)",
|
|
||||||
"destination_account": "C\u00e9lsz\u00e1mla",
|
|
||||||
"source_account": "Forr\u00e1s sz\u00e1mla",
|
|
||||||
"single_split": "Feloszt\u00e1s",
|
|
||||||
"create_new_transaction": "Create a new transaction",
|
|
||||||
"balance": "Egyenleg",
|
|
||||||
"transaction_journal_extra": "Extra information",
|
|
||||||
"transaction_journal_meta": "Meta-inform\u00e1ci\u00f3",
|
|
||||||
"basic_journal_information": "Basic transaction information",
|
|
||||||
"bills_to_pay": "Fizetend\u0151 sz\u00e1ml\u00e1k",
|
|
||||||
"left_to_spend": "Elk\u00f6lthet\u0151",
|
|
||||||
"attachments": "Mell\u00e9kletek",
|
|
||||||
"net_worth": "Nett\u00f3 \u00e9rt\u00e9k",
|
|
||||||
"bill": "Sz\u00e1mla",
|
|
||||||
"no_bill": "(no bill)",
|
|
||||||
"tags": "C\u00edmk\u00e9k",
|
|
||||||
"internal_reference": "Internal reference",
|
|
||||||
"external_url": "External URL",
|
|
||||||
"no_piggy_bank": "(nincs malacpersely)",
|
|
||||||
"paid": "Kifizetve",
|
|
||||||
"notes": "Megjegyz\u00e9sek",
|
|
||||||
"yourAccounts": "Banksz\u00e1ml\u00e1k",
|
|
||||||
"go_to_asset_accounts": "Eszk\u00f6zsz\u00e1ml\u00e1k megtekint\u00e9se",
|
|
||||||
"delete_account": "Fi\u00f3k t\u00f6rl\u00e9se",
|
|
||||||
"transaction_table_description": "Tranzakci\u00f3kat tartalmaz\u00f3 t\u00e1bl\u00e1zat",
|
|
||||||
"account": "Banksz\u00e1mla",
|
|
||||||
"description": "Le\u00edr\u00e1s",
|
|
||||||
"amount": "\u00d6sszeg",
|
|
||||||
"budget": "K\u00f6lts\u00e9gkeret",
|
|
||||||
"category": "Kateg\u00f3ria",
|
|
||||||
"opposing_account": "Ellenoldali sz\u00e1mla",
|
|
||||||
"budgets": "K\u00f6lts\u00e9gkeretek",
|
|
||||||
"categories": "Kateg\u00f3ri\u00e1k",
|
|
||||||
"go_to_budgets": "Ugr\u00e1s a k\u00f6lts\u00e9gkeretekhez",
|
|
||||||
"income": "J\u00f6vedelem \/ bev\u00e9tel",
|
|
||||||
"go_to_deposits": "Ugr\u00e1s a bev\u00e9telekre",
|
|
||||||
"go_to_categories": "Ugr\u00e1s a kateg\u00f3ri\u00e1khoz",
|
|
||||||
"expense_accounts": "K\u00f6lts\u00e9gsz\u00e1ml\u00e1k",
|
|
||||||
"go_to_expenses": "Ugr\u00e1s a kiad\u00e1sokra",
|
|
||||||
"go_to_bills": "Ugr\u00e1s a sz\u00e1ml\u00e1khoz",
|
|
||||||
"bills": "Sz\u00e1ml\u00e1k",
|
|
||||||
"last_thirty_days": "Elm\u00falt harminc nap",
|
|
||||||
"last_seven_days": "Utols\u00f3 h\u00e9t nap",
|
|
||||||
"go_to_piggies": "Ugr\u00e1s a malacperselyekhez",
|
|
||||||
"saved": "Mentve",
|
|
||||||
"piggy_banks": "Malacperselyek",
|
|
||||||
"piggy_bank": "Malacpersely",
|
|
||||||
"amounts": "Mennyis\u00e9gek",
|
|
||||||
"left": "Maradv\u00e1ny",
|
|
||||||
"spent": "Elk\u00f6lt\u00f6tt",
|
|
||||||
"Default asset account": "Alap\u00e9rtelmezett eszk\u00f6zsz\u00e1mla",
|
|
||||||
"search_results": "Keres\u00e9si eredm\u00e9nyek",
|
|
||||||
"include": "Include?",
|
|
||||||
"transaction": "Tranzakci\u00f3",
|
|
||||||
"account_role_defaultAsset": "Alap\u00e9rtelmezett eszk\u00f6zsz\u00e1mla",
|
|
||||||
"account_role_savingAsset": "Megtakar\u00edt\u00e1si sz\u00e1mla",
|
|
||||||
"account_role_sharedAsset": "Megosztott eszk\u00f6zsz\u00e1mla",
|
|
||||||
"clear_location": "Hely t\u00f6rl\u00e9se",
|
|
||||||
"account_role_ccAsset": "Hitelk\u00e1rtya",
|
|
||||||
"account_role_cashWalletAsset": "K\u00e9szp\u00e9nz",
|
|
||||||
"daily_budgets": "Daily budgets",
|
|
||||||
"weekly_budgets": "Weekly budgets",
|
|
||||||
"monthly_budgets": "Monthly budgets",
|
|
||||||
"journals_in_period_for_account_js": "All transactions for account {title} between {start} and {end}",
|
|
||||||
"quarterly_budgets": "Quarterly budgets",
|
|
||||||
"create_new_expense": "\u00daj k\u00f6lts\u00e9gsz\u00e1mla l\u00e9trehoz\u00e1sa",
|
|
||||||
"create_new_revenue": "\u00daj j\u00f6vedelemsz\u00e1mla l\u00e9trehoz\u00e1sa",
|
|
||||||
"create_new_liabilities": "Create new liability",
|
|
||||||
"half_year_budgets": "Half-yearly budgets",
|
|
||||||
"yearly_budgets": "Yearly budgets",
|
|
||||||
"split_transaction_title": "Felosztott tranzakci\u00f3 le\u00edr\u00e1sa",
|
|
||||||
"errors_submission": "There was something wrong with your submission. Please check out the errors.",
|
|
||||||
"flash_error": "Hiba!",
|
|
||||||
"store_transaction": "Store transaction",
|
|
||||||
"flash_success": "Siker!",
|
|
||||||
"create_another": "A t\u00e1rol\u00e1s ut\u00e1n t\u00e9rjen vissza ide \u00faj l\u00e9trehoz\u00e1s\u00e1hoz.",
|
|
||||||
"update_transaction": "Tranzakci\u00f3 friss\u00edt\u00e9se",
|
|
||||||
"after_update_create_another": "A friss\u00edt\u00e9s ut\u00e1n t\u00e9rjen vissza ide a szerkeszt\u00e9s folytat\u00e1s\u00e1hoz.",
|
|
||||||
"transaction_updated_no_changes": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") did not receive any changes.",
|
|
||||||
"transaction_updated_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") has been updated.",
|
|
||||||
"spent_x_of_y": "Spent {amount} of {total}",
|
|
||||||
"search": "Keres\u00e9s",
|
|
||||||
"create_new_asset": "\u00daj eszk\u00f6zsz\u00e1mla l\u00e9trehoz\u00e1sa",
|
|
||||||
"asset_accounts": "Eszk\u00f6zsz\u00e1ml\u00e1k",
|
|
||||||
"reset_after": "\u0170rlap t\u00f6rl\u00e9se a bek\u00fcld\u00e9s ut\u00e1n",
|
|
||||||
"bill_paid_on": "Paid on {date}",
|
|
||||||
"first_split_decides": "The first split determines the value of this field",
|
|
||||||
"first_split_overrules_source": "The first split may overrule the source account",
|
|
||||||
"first_split_overrules_destination": "The first split may overrule the destination account",
|
|
||||||
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID} (\"{title}\")<\/a> mentve.",
|
|
||||||
"custom_period": "Custom period",
|
|
||||||
"reset_to_current": "Reset to current period",
|
|
||||||
"select_period": "Select a period",
|
|
||||||
"location": "Hely",
|
|
||||||
"other_budgets": "Custom timed budgets",
|
|
||||||
"journal_links": "Tranzakci\u00f3 \u00f6sszekapcsol\u00e1sok",
|
|
||||||
"go_to_withdrawals": "Ugr\u00e1s a k\u00f6lts\u00e9gekhez",
|
|
||||||
"revenue_accounts": "J\u00f6vedelemsz\u00e1ml\u00e1k",
|
|
||||||
"add_another_split": "M\u00e1sik feloszt\u00e1s hozz\u00e1ad\u00e1sa",
|
|
||||||
"actions": "M\u0171veletek",
|
|
||||||
"earned": "Megkeresett",
|
|
||||||
"empty": "(\u00fcres)",
|
|
||||||
"edit": "Szerkeszt\u00e9s",
|
|
||||||
"never": "Soha",
|
|
||||||
"account_type_Loan": "Hitel",
|
|
||||||
"account_type_Mortgage": "Jelz\u00e1log",
|
|
||||||
"stored_new_account_js": "New account \"<a href=\"accounts\/show\/{ID}\">{name}<\/a>\" stored!",
|
|
||||||
"account_type_Debt": "Ad\u00f3ss\u00e1g",
|
|
||||||
"liability_direction_null_short": "Unknown",
|
|
||||||
"delete": "T\u00f6rl\u00e9s",
|
|
||||||
"store_new_asset_account": "\u00daj eszk\u00f6zsz\u00e1mla t\u00e1rol\u00e1sa",
|
|
||||||
"store_new_expense_account": "\u00daj k\u00f6lts\u00e9gsz\u00e1mla t\u00e1rol\u00e1sa",
|
|
||||||
"store_new_liabilities_account": "\u00daj k\u00f6telezetts\u00e9g elt\u00e1rol\u00e1sa",
|
|
||||||
"store_new_revenue_account": "\u00daj j\u00f6vedelemsz\u00e1mla l\u00e9trehoz\u00e1sa",
|
|
||||||
"mandatoryFields": "K\u00f6telez\u0151 mez\u0151k",
|
|
||||||
"optionalFields": "Nem k\u00f6telez\u0151 mez\u0151k",
|
|
||||||
"reconcile_this_account": "Sz\u00e1mla egyeztet\u00e9se",
|
|
||||||
"interest_calc_weekly": "Per week",
|
|
||||||
"interest_calc_monthly": "Havonta",
|
|
||||||
"interest_calc_quarterly": "Per quarter",
|
|
||||||
"interest_calc_half-year": "Per half year",
|
|
||||||
"interest_calc_yearly": "\u00c9vente",
|
|
||||||
"liability_direction_credit": "I am owed this debt",
|
|
||||||
"liability_direction_debit": "I owe this debt to somebody else",
|
|
||||||
"liability_direction_credit_short": "Owed this debt",
|
|
||||||
"liability_direction_debit_short": "Owe this debt",
|
|
||||||
"account_type_debt": "Debt",
|
|
||||||
"account_type_loan": "Loan",
|
|
||||||
"left_in_debt": "Amount due",
|
|
||||||
"account_type_mortgage": "Mortgage",
|
|
||||||
"save_transactions_by_moving_js": "No transactions|Save this transaction by moving it to another account. |Save these transactions by moving them to another account.",
|
|
||||||
"none_in_select_list": "(nincs)",
|
|
||||||
"transaction_expand_split": "Expand split",
|
|
||||||
"transaction_collapse_split": "Collapse split",
|
|
||||||
"default_group_title_name": "(nem csoportos\u00edtott)",
|
|
||||||
"bill_repeats_weekly": "Repeats weekly",
|
|
||||||
"bill_repeats_monthly": "Repeats monthly",
|
|
||||||
"bill_repeats_quarterly": "Repeats quarterly",
|
|
||||||
"bill_repeats_half-year": "Repeats every half year",
|
|
||||||
"bill_repeats_yearly": "Repeats yearly",
|
|
||||||
"bill_repeats_weekly_other": "Repeats every other week",
|
|
||||||
"bill_repeats_monthly_other": "Repeats every other month",
|
|
||||||
"bill_repeats_quarterly_other": "Repeats every other quarter",
|
|
||||||
"bill_repeats_half-year_other": "Repeats yearly",
|
|
||||||
"bill_repeats_yearly_other": "Repeats every other year",
|
|
||||||
"bill_repeats_weekly_skip": "Repeats every {skip} weeks",
|
|
||||||
"bill_repeats_monthly_skip": "Repeats every {skip} months",
|
|
||||||
"bill_repeats_quarterly_skip": "Repeats every {skip} quarters",
|
|
||||||
"bill_repeats_half-year_skip": "Repeats every {skip} half years",
|
|
||||||
"bill_repeats_yearly_skip": "Repeats every {skip} years",
|
|
||||||
"not_expected_period": "Nem v\u00e1rhat\u00f3 ebben az id\u0151szakban",
|
|
||||||
"subscriptions": "Subscriptions",
|
|
||||||
"bill_expected_date_js": "Expected {date}",
|
|
||||||
"inactive": "Inakt\u00edv",
|
|
||||||
"forever": "Forever",
|
|
||||||
"extension_date_is": "Extension date is {date}",
|
|
||||||
"create_new_bill": "\u00daj sz\u00e1mla l\u00e9trehoz\u00e1sa",
|
|
||||||
"store_new_bill": "\u00daj sz\u00e1mla t\u00e1rol\u00e1sa",
|
|
||||||
"repeat_freq_yearly": "\u00e9ves",
|
|
||||||
"repeat_freq_half-year": "f\u00e9l\u00e9vente",
|
|
||||||
"repeat_freq_quarterly": "negyed\u00e9ves",
|
|
||||||
"repeat_freq_monthly": "havi",
|
|
||||||
"repeat_freq_weekly": "heti",
|
|
||||||
"credit_card_type_monthlyFull": "Full payment every month",
|
|
||||||
"update_liabilities_account": "K\u00f6telezetts\u00e9g friss\u00edt\u00e9se",
|
|
||||||
"update_expense_account": "K\u00f6lts\u00e9gsz\u00e1mla friss\u00edt\u00e9se",
|
|
||||||
"update_revenue_account": "J\u00f6vedelemsz\u00e1mla friss\u00edt\u00e9se",
|
|
||||||
"update_undefined_account": "Update account",
|
|
||||||
"update_asset_account": "Eszk\u00f6zsz\u00e1mla friss\u00edt\u00e9se",
|
|
||||||
"updated_account_js": "Updated account \"<a href=\"accounts\/show\/{ID}\">{title}<\/a>\"."
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"piggy_bank": "Malacpersely",
|
|
||||||
"percentage": "%",
|
|
||||||
"amount": "\u00d6sszeg",
|
|
||||||
"lastActivity": "Utols\u00f3 aktivit\u00e1s",
|
|
||||||
"name": "N\u00e9v",
|
|
||||||
"role": "Szerepk\u00f6r",
|
|
||||||
"description": "Le\u00edr\u00e1s",
|
|
||||||
"date": "D\u00e1tum",
|
|
||||||
"source_account": "Forr\u00e1s banksz\u00e1mla",
|
|
||||||
"destination_account": "C\u00e9l banksz\u00e1mla",
|
|
||||||
"category": "Kateg\u00f3ria",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"interest": "Kamat",
|
|
||||||
"interest_period": "Interest period",
|
|
||||||
"liability_type": "A k\u00f6telezetts\u00e9g t\u00edpusa",
|
|
||||||
"liability_direction": "Liability in\/out",
|
|
||||||
"currentBalance": "Aktu\u00e1lis egyenleg",
|
|
||||||
"next_expected_match": "K\u00f6vetkez\u0151 v\u00e1rhat\u00f3 egyez\u00e9s",
|
|
||||||
"expected_info": "Next expected transaction",
|
|
||||||
"start_date": "Start date",
|
|
||||||
"end_date": "End date",
|
|
||||||
"payment_info": "Payment information"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"html_language": "hu",
|
|
||||||
"week_in_year_fns": "'Week' w, yyyy",
|
|
||||||
"month_and_day_fns": "MMMM d, y",
|
|
||||||
"quarter_fns": "'Q'Q, yyyy",
|
|
||||||
"half_year_fns": "'H{half}', yyyy"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"foreign_amount": "K\u00fclf\u00f6ldi \u00f6sszeg",
|
|
||||||
"interest_date": "Kamatfizet\u00e9si id\u0151pont",
|
|
||||||
"name": "N\u00e9v",
|
|
||||||
"amount": "\u00d6sszeg",
|
|
||||||
"iban": "IBAN",
|
|
||||||
"BIC": "BIC",
|
|
||||||
"notes": "Megjegyz\u00e9sek",
|
|
||||||
"location": "Hely",
|
|
||||||
"repeat_freq": "Ism\u00e9tl\u0151d\u00e9sek",
|
|
||||||
"skip": "Kihagy\u00e1s",
|
|
||||||
"startdate": "Kezd\u0151 d\u00e1tum",
|
|
||||||
"enddate": "End date",
|
|
||||||
"object_group": "Csoport",
|
|
||||||
"attachments": "Mell\u00e9kletek",
|
|
||||||
"deletePermanently": "V\u00e9gleges t\u00f6rl\u00e9s",
|
|
||||||
"active": "Akt\u00edv",
|
|
||||||
"include_net_worth": "Befoglalva a nett\u00f3 \u00e9rt\u00e9kbe",
|
|
||||||
"cc_type": "Hitelk\u00e1rtya fizet\u00e9si terv",
|
|
||||||
"account_number": "Sz\u00e1mlasz\u00e1m",
|
|
||||||
"cc_monthly_payment_date": "Hitelk\u00e1rtya havi fizet\u00e9s d\u00e1tuma",
|
|
||||||
"virtual_balance": "Virtu\u00e1lis egyenleg",
|
|
||||||
"opening_balance": "Nyit\u00f3 egyenleg",
|
|
||||||
"opening_balance_date": "Nyit\u00f3 egyenleg d\u00e1tuma",
|
|
||||||
"date": "D\u00e1tum",
|
|
||||||
"interest": "Kamat",
|
|
||||||
"interest_period": "Kamatperi\u00f3dus",
|
|
||||||
"currency_id": "P\u00e9nznem",
|
|
||||||
"liability_type": "Liability type",
|
|
||||||
"account_role": "Banksz\u00e1mla szerepk\u00f6re",
|
|
||||||
"liability_direction": "Liability in\/out",
|
|
||||||
"book_date": "K\u00f6nyvel\u00e9s d\u00e1tuma",
|
|
||||||
"permDeleteWarning": "A Firefly III-b\u00f3l t\u00f6rt\u00e9n\u0151 t\u00f6rl\u00e9s v\u00e9gleges \u00e9s nem vonhat\u00f3 vissza.",
|
|
||||||
"account_areYouSure_js": "Are you sure you want to delete the account named \"{name}\"?",
|
|
||||||
"also_delete_piggyBanks_js": "No piggy banks|The only piggy bank connected to this account will be deleted as well.|All {count} piggy banks connected to this account will be deleted as well.",
|
|
||||||
"also_delete_transactions_js": "No transactions|The only transaction connected to this account will be deleted as well.|All {count} transactions connected to this account will be deleted as well.",
|
|
||||||
"process_date": "Feldolgoz\u00e1s d\u00e1tuma",
|
|
||||||
"due_date": "Lej\u00e1rati id\u0151pont",
|
|
||||||
"payment_date": "Fizet\u00e9s d\u00e1tuma",
|
|
||||||
"invoice_date": "Sz\u00e1mla d\u00e1tuma",
|
|
||||||
"amount_min": "Minim\u00e1lis \u00f6sszeg",
|
|
||||||
"amount_max": "Maxim\u00e1lis \u00f6sszeg",
|
|
||||||
"start_date": "Tartom\u00e1ny kezdete",
|
|
||||||
"end_date": "Tartom\u00e1ny v\u00e9ge",
|
|
||||||
"extension_date": "Extension date"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user