mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Lots of new code for new transaction screen.
This commit is contained in:
parent
912fe99981
commit
d5c5fa4fad
@ -45,7 +45,7 @@ echo "Discover packages..."
|
|||||||
php artisan package:discover
|
php artisan package:discover
|
||||||
|
|
||||||
echo "Run various artisan commands..."
|
echo "Run various artisan commands..."
|
||||||
. $FIREFLY_PATH/.env
|
#. $FIREFLY_PATH/.env
|
||||||
if [[ -z "$DB_PORT" ]]; then
|
if [[ -z "$DB_PORT" ]]; then
|
||||||
if [[ $DB_CONNECTION == "pgsql" ]]; then
|
if [[ $DB_CONNECTION == "pgsql" ]]; then
|
||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
|
@ -519,22 +519,22 @@ return [
|
|||||||
],
|
],
|
||||||
|
|
||||||
|
|
||||||
'test-triggers' => [
|
'test-triggers' => [
|
||||||
'limit' => 10,
|
'limit' => 10,
|
||||||
'range' => 200,
|
'range' => 200,
|
||||||
],
|
],
|
||||||
'default_currency' => 'EUR',
|
'default_currency' => 'EUR',
|
||||||
'default_language' => 'en_US',
|
'default_language' => 'en_US',
|
||||||
'search_modifiers' => ['amount_is', 'amount', 'amount_max', 'amount_min', 'amount_less', 'amount_more', 'source', 'destination', 'category',
|
'search_modifiers' => ['amount_is', 'amount', 'amount_max', 'amount_min', 'amount_less', 'amount_more', 'source', 'destination', 'category',
|
||||||
'budget', 'bill', 'type', 'date', 'date_before', 'date_after', 'on', 'before', 'after'],
|
'budget', 'bill', 'type', 'date', 'date_before', 'date_after', 'on', 'before', 'after'],
|
||||||
// tag notes has_attachments
|
// tag notes has_attachments
|
||||||
'cer_providers' => [
|
'cer_providers' => [
|
||||||
'fixer' => FixerIOv2::class,
|
'fixer' => FixerIOv2::class,
|
||||||
'ratesapi' => RatesApiIOv1::class,
|
'ratesapi' => RatesApiIOv1::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
// expected source types for each transaction type, in order of preference.
|
// expected source types for each transaction type, in order of preference.
|
||||||
'expected_source_types' => [
|
'expected_source_types' => [
|
||||||
'source' => [
|
'source' => [
|
||||||
TransactionTypeModel::WITHDRAWAL => [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE],
|
TransactionTypeModel::WITHDRAWAL => [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE],
|
||||||
TransactionTypeModel::DEPOSIT => [AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE,
|
TransactionTypeModel::DEPOSIT => [AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE,
|
||||||
@ -543,6 +543,15 @@ return [
|
|||||||
TransactionTypeModel::OPENING_BALANCE => [AccountType::INITIAL_BALANCE, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT,
|
TransactionTypeModel::OPENING_BALANCE => [AccountType::INITIAL_BALANCE, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT,
|
||||||
AccountType::MORTGAGE],
|
AccountType::MORTGAGE],
|
||||||
TransactionTypeModel::RECONCILIATION => [AccountType::RECONCILIATION, AccountType::ASSET],
|
TransactionTypeModel::RECONCILIATION => [AccountType::RECONCILIATION, AccountType::ASSET],
|
||||||
|
// in case no transaction type is known yet, it could be anything.
|
||||||
|
'none' => [
|
||||||
|
AccountType::ASSET,
|
||||||
|
AccountType::EXPENSE,
|
||||||
|
AccountType::REVENUE,
|
||||||
|
AccountType::LOAN,
|
||||||
|
AccountType::DEBT,
|
||||||
|
AccountType::MORTGAGE,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
'destination' => [
|
'destination' => [
|
||||||
TransactionTypeModel::WITHDRAWAL => [AccountType::EXPENSE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT,
|
TransactionTypeModel::WITHDRAWAL => [AccountType::EXPENSE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT,
|
||||||
@ -554,9 +563,130 @@ return [
|
|||||||
TransactionTypeModel::RECONCILIATION => [AccountType::RECONCILIATION, AccountType::ASSET],
|
TransactionTypeModel::RECONCILIATION => [AccountType::RECONCILIATION, AccountType::ASSET],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
'allowed_opposing_types' => [
|
||||||
|
'source' => [
|
||||||
|
AccountType::ASSET => [AccountType::ASSET, AccountType::CASH, AccountType::DEBT, AccountType::EXPENSE, AccountType::INITIAL_BALANCE,
|
||||||
|
AccountType::LOAN, AccountType::RECONCILIATION],
|
||||||
|
AccountType::CASH => [AccountType::ASSET],
|
||||||
|
AccountType::DEBT => [AccountType::ASSET, AccountType::DEBT, AccountType::EXPENSE, AccountType::INITIAL_BALANCE, AccountType::LOAN,
|
||||||
|
AccountType::MORTGAGE],
|
||||||
|
AccountType::EXPENSE => [], // is not allowed as a source.
|
||||||
|
AccountType::INITIAL_BALANCE => [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE],
|
||||||
|
AccountType::LOAN => [AccountType::ASSET, AccountType::DEBT, AccountType::EXPENSE, AccountType::INITIAL_BALANCE, AccountType::LOAN,
|
||||||
|
AccountType::MORTGAGE],
|
||||||
|
AccountType::MORTGAGE => [AccountType::ASSET, AccountType::DEBT, AccountType::EXPENSE, AccountType::INITIAL_BALANCE, AccountType::LOAN,
|
||||||
|
AccountType::MORTGAGE],
|
||||||
|
AccountType::RECONCILIATION => [AccountType::ASSET],
|
||||||
|
AccountType::REVENUE => [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE],
|
||||||
|
|
||||||
|
],
|
||||||
|
'destination' => [
|
||||||
|
AccountType::ASSET => [AccountType::ASSET, AccountType::CASH, AccountType::DEBT, AccountType::INITIAL_BALANCE, AccountType::LOAN,
|
||||||
|
AccountType::MORTGAGE, AccountType::RECONCILIATION, AccountType::REVENUE],
|
||||||
|
AccountType::CASH => [AccountType::ASSET],
|
||||||
|
AccountType::DEBT => [AccountType::ASSET, AccountType::DEBT, AccountType::INITIAL_BALANCE, AccountType::LOAN, AccountType::MORTGAGE,
|
||||||
|
AccountType::REVENUE],
|
||||||
|
AccountType::EXPENSE => [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE],
|
||||||
|
AccountType::INITIAL_BALANCE => [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE],
|
||||||
|
AccountType::LOAN => [AccountType::ASSET, AccountType::DEBT, AccountType::INITIAL_BALANCE, AccountType::LOAN, AccountType::MORTGAGE,
|
||||||
|
AccountType::REVENUE],
|
||||||
|
AccountType::MORTGAGE => [AccountType::ASSET, AccountType::DEBT, AccountType::INITIAL_BALANCE, AccountType::LOAN, AccountType::MORTGAGE,
|
||||||
|
AccountType::REVENUE],
|
||||||
|
AccountType::RECONCILIATION => [AccountType::ASSET],
|
||||||
|
AccountType::REVENUE => [], // is not allowed as a destination
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// depending on the account type, return the allowed transaction types:
|
||||||
|
'allowed_transaction_types' => [
|
||||||
|
'source' => [
|
||||||
|
AccountType::ASSET => [TransactionTypeModel::WITHDRAWAL, TransactionTypeModel::TRANSFER, TransactionTypeModel::OPENING_BALANCE,
|
||||||
|
TransactionTypeModel::RECONCILIATION],
|
||||||
|
AccountType::EXPENSE => [], // is not allowed as a source.
|
||||||
|
AccountType::REVENUE => [TransactionTypeModel::DEPOSIT],
|
||||||
|
AccountType::LOAN => [TransactionTypeModel::WITHDRAWAL, TransactionTypeModel::DEPOSIT, TransactionTypeModel::TRANSFER,
|
||||||
|
TransactionTypeModel::OPENING_BALANCE],
|
||||||
|
AccountType::DEBT => [TransactionTypeModel::WITHDRAWAL, TransactionTypeModel::DEPOSIT, TransactionTypeModel::TRANSFER,
|
||||||
|
TransactionTypeModel::OPENING_BALANCE],
|
||||||
|
AccountType::MORTGAGE => [TransactionTypeModel::WITHDRAWAL, TransactionTypeModel::DEPOSIT, TransactionTypeModel::TRANSFER,
|
||||||
|
TransactionTypeModel::OPENING_BALANCE],
|
||||||
|
AccountType::INITIAL_BALANCE => [], // todo fill me in.
|
||||||
|
AccountType::RECONCILIATION => [], // todo fill me in.
|
||||||
|
],
|
||||||
|
'destination' => [
|
||||||
|
AccountType::ASSET => [TransactionTypeModel::DEPOSIT, TransactionTypeModel::TRANSFER, TransactionTypeModel::OPENING_BALANCE,
|
||||||
|
TransactionTypeModel::RECONCILIATION],
|
||||||
|
AccountType::EXPENSE => [TransactionTypeModel::WITHDRAWAL],
|
||||||
|
AccountType::REVENUE => [], // is not allowed as destination.
|
||||||
|
AccountType::LOAN => [TransactionTypeModel::WITHDRAWAL, TransactionTypeModel::DEPOSIT, TransactionTypeModel::TRANSFER,
|
||||||
|
TransactionTypeModel::OPENING_BALANCE],
|
||||||
|
AccountType::DEBT => [TransactionTypeModel::WITHDRAWAL, TransactionTypeModel::DEPOSIT, TransactionTypeModel::TRANSFER,
|
||||||
|
TransactionTypeModel::OPENING_BALANCE],
|
||||||
|
AccountType::MORTGAGE => [TransactionTypeModel::WITHDRAWAL, TransactionTypeModel::DEPOSIT, TransactionTypeModel::TRANSFER,
|
||||||
|
TransactionTypeModel::OPENING_BALANCE],
|
||||||
|
AccountType::INITIAL_BALANCE => [], // todo fill me in.
|
||||||
|
AccountType::RECONCILIATION => [], // todo fill me in.
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
// having the source + dest will tell you the transaction type.
|
||||||
|
'account_to_transaction' => [
|
||||||
|
AccountType::ASSET => [
|
||||||
|
AccountType::ASSET => TransactionTypeModel::TRANSFER,
|
||||||
|
AccountType::CASH => TransactionTypeModel::WITHDRAWAL,
|
||||||
|
AccountType::DEBT => TransactionTypeModel::WITHDRAWAL,
|
||||||
|
AccountType::EXPENSE => TransactionTypeModel::WITHDRAWAL,
|
||||||
|
AccountType::INITIAL_BALANCE => TransactionTypeModel::OPENING_BALANCE,
|
||||||
|
AccountType::LOAN => TransactionTypeModel::WITHDRAWAL,
|
||||||
|
AccountType::MORTGAGE => TransactionTypeModel::WITHDRAWAL,
|
||||||
|
AccountType::RECONCILIATION => TransactionTypeModel::RECONCILIATION,
|
||||||
|
],
|
||||||
|
AccountType::CASH => [
|
||||||
|
AccountType::ASSET => TransactionTypeModel::DEPOSIT,
|
||||||
|
],
|
||||||
|
AccountType::DEBT => [
|
||||||
|
AccountType::ASSET => TransactionTypeModel::DEPOSIT,
|
||||||
|
AccountType::DEBT => TransactionTypeModel::TRANSFER,
|
||||||
|
AccountType::EXPENSE => TransactionTypeModel::WITHDRAWAL,
|
||||||
|
AccountType::INITIAL_BALANCE => TransactionTypeModel::OPENING_BALANCE,
|
||||||
|
AccountType::LOAN => TransactionTypeModel::TRANSFER,
|
||||||
|
AccountType::MORTGAGE => TransactionTypeModel::TRANSFER,
|
||||||
|
],
|
||||||
|
AccountType::INITIAL_BALANCE => [
|
||||||
|
AccountType::ASSET => TransactionTypeModel::OPENING_BALANCE,
|
||||||
|
AccountType::DEBT => TransactionTypeModel::OPENING_BALANCE,
|
||||||
|
AccountType::LOAN => TransactionTypeModel::OPENING_BALANCE,
|
||||||
|
AccountType::MORTGAGE => TransactionTypeModel::OPENING_BALANCE,
|
||||||
|
],
|
||||||
|
AccountType::LOAN => [
|
||||||
|
AccountType::ASSET => TransactionTypeModel::DEPOSIT,
|
||||||
|
AccountType::DEBT => TransactionTypeModel::TRANSFER,
|
||||||
|
AccountType::EXPENSE => TransactionTypeModel::WITHDRAWAL,
|
||||||
|
AccountType::INITIAL_BALANCE => TransactionTypeModel::OPENING_BALANCE,
|
||||||
|
AccountType::LOAN => TransactionTypeModel::TRANSFER,
|
||||||
|
AccountType::MORTGAGE => TransactionTypeModel::TRANSFER,
|
||||||
|
],
|
||||||
|
AccountType::MORTGAGE => [
|
||||||
|
AccountType::ASSET => TransactionTypeModel::DEPOSIT,
|
||||||
|
AccountType::DEBT => TransactionTypeModel::TRANSFER,
|
||||||
|
AccountType::EXPENSE => TransactionTypeModel::WITHDRAWAL,
|
||||||
|
AccountType::INITIAL_BALANCE => TransactionTypeModel::OPENING_BALANCE,
|
||||||
|
AccountType::LOAN => TransactionTypeModel::TRANSFER,
|
||||||
|
AccountType::MORTGAGE => TransactionTypeModel::TRANSFER,
|
||||||
|
],
|
||||||
|
AccountType::RECONCILIATION => [
|
||||||
|
AccountType::ASSET => TransactionTypeModel::RECONCILIATION,
|
||||||
|
],
|
||||||
|
AccountType::REVENUE => [
|
||||||
|
AccountType::ASSET => TransactionTypeModel::DEPOSIT,
|
||||||
|
AccountType::DEBT => TransactionTypeModel::DEPOSIT,
|
||||||
|
AccountType::LOAN => TransactionTypeModel::DEPOSIT,
|
||||||
|
AccountType::MORTGAGE => TransactionTypeModel::DEPOSIT,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
// allowed source / destination accounts.
|
// allowed source / destination accounts.
|
||||||
'source_dests' => [
|
'source_dests' => [
|
||||||
TransactionTypeModel::WITHDRAWAL => [
|
TransactionTypeModel::WITHDRAWAL => [
|
||||||
AccountType::ASSET => [AccountType::EXPENSE, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE, AccountType::CASH],
|
AccountType::ASSET => [AccountType::EXPENSE, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE, AccountType::CASH],
|
||||||
AccountType::LOAN => [AccountType::EXPENSE],
|
AccountType::LOAN => [AccountType::EXPENSE],
|
||||||
|
@ -13,12 +13,14 @@
|
|||||||
"axios": "^0.17",
|
"axios": "^0.17",
|
||||||
"bootstrap-sass": "^3.3.7",
|
"bootstrap-sass": "^3.3.7",
|
||||||
"cross-env": "^5.1",
|
"cross-env": "^5.1",
|
||||||
"jquery": "^3.1.1",
|
|
||||||
"laravel-mix": "^1.0",
|
"laravel-mix": "^1.0",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
"vue": "^2.5.7"
|
"vue": "^2.5.7"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"font-awesome": "^4.7.0"
|
"@johmun/vue-tags-input": "^2.0.1",
|
||||||
|
"font-awesome": "^4.7.0",
|
||||||
|
"jquery": "^3.1.1",
|
||||||
|
"uiv": "^0.31.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
{
|
{
|
||||||
"/v2/js/index.js": "/v2/js/index.js",
|
"/v1/js/app.js": "/v1/js/app.js"
|
||||||
"/v2/js/manifest.js": "/v2/js/manifest.js",
|
}
|
||||||
"/v2/js/vendor.js": "/v2/js/vendor.js",
|
|
||||||
"/undefined.js": "/undefined.js",
|
|
||||||
"/v2/css/app.css": "/v2/css/app.css"
|
|
||||||
}
|
|
2
public/v1/css/app.css
vendored
Normal file
2
public/v1/css/app.css
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/* TODO REMOVE ME */
|
||||||
|
|
15
public/v1/css/firefly.css
vendored
15
public/v1/css/firefly.css
vendored
@ -18,6 +18,14 @@
|
|||||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
input.ti-new-tag-input {
|
||||||
|
font-size: 14px !important;
|
||||||
|
line-height: 1.42857143;
|
||||||
|
color: #555;
|
||||||
|
font-family:"Source Sans Pro", "Helvetica Neue",Helvetica,Arial,sans-serif !important;
|
||||||
|
}
|
||||||
|
|
||||||
.split_amount_input {
|
.split_amount_input {
|
||||||
width: 40%;
|
width: 40%;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
@ -36,6 +44,13 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.autocomplete-suggestions { border: 1px solid #999; background: #FFF; overflow: auto; }
|
||||||
|
.autocomplete-suggestion { padding: 2px 5px; white-space: nowrap; overflow: hidden; }
|
||||||
|
.autocomplete-selected { background: #F0F0F0; }
|
||||||
|
.autocomplete-suggestions strong { font-weight: normal; color: #3399FF; }
|
||||||
|
.autocomplete-group { padding: 2px 5px; font-weight: bold;}
|
||||||
|
.autocomplete-group strong { display: block; border-bottom: 1px solid #000; }
|
||||||
|
|
||||||
.split_amount_input:focus {
|
.split_amount_input:focus {
|
||||||
border-color: #98cbe8;
|
border-color: #98cbe8;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
|
53455
public/v1/js/app.js
vendored
53455
public/v1/js/app.js
vendored
File diff suppressed because one or more lines are too long
225
public/v1/js/ff/transactions/create.js
vendored
Normal file
225
public/v1/js/ff/transactions/create.js
vendored
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* create.js
|
||||||
|
* Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III.
|
||||||
|
*
|
||||||
|
* Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Firefly III 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** global: autoCompleteUri */
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
"use strict";
|
||||||
|
initPage();
|
||||||
|
|
||||||
|
});
|
||||||
|
function initPage() {
|
||||||
|
// recreate buttons and auto-complete things
|
||||||
|
autoComplete();
|
||||||
|
makeButtons();
|
||||||
|
runModernizer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset all click triggers.
|
||||||
|
*/
|
||||||
|
function makeButtons() {
|
||||||
|
$('.clearDestination').unbind('click').on('click', clearDestination);
|
||||||
|
$('.clearSource').unbind('click').on('click', clearSource);
|
||||||
|
$('#addSplitButton').unbind('click').on('click', addSplit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSplit() {
|
||||||
|
// clone the latest
|
||||||
|
var latest =$($('#transactions').children()[$('#transactions').children().length - 1]);
|
||||||
|
latest.clone(true).appendTo('#transactions');
|
||||||
|
|
||||||
|
initPage();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code to handle clearing the source account.
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
function clearSource(e) {
|
||||||
|
console.log('Now clearing source.');
|
||||||
|
var button = $(e.currentTarget);
|
||||||
|
// empty value.
|
||||||
|
$(button.parent().parent().find('input').get(0)).val('');
|
||||||
|
|
||||||
|
// reset source account
|
||||||
|
setSourceAccount(null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code to handle clearing the destination account.
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
function clearDestination(e) {
|
||||||
|
console.log('Now clearing destination.');
|
||||||
|
var button = $(e.currentTarget);
|
||||||
|
// empty value.
|
||||||
|
$(button.parent().parent().find('input').get(0)).val('');
|
||||||
|
|
||||||
|
// reset destination account
|
||||||
|
setDestinationAccount(null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the new source account (from a suggestion).
|
||||||
|
*
|
||||||
|
* @param newAccount
|
||||||
|
*/
|
||||||
|
function setSourceAccount(newAccount) {
|
||||||
|
if (null === newAccount) {
|
||||||
|
console.log('New source account is now null.');
|
||||||
|
sourceAccount = null;
|
||||||
|
setAllowedDestinationAccounts(newAccount);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('The new source account is now ' + newAccount.value + 'of type ' + newAccount.data.type);
|
||||||
|
setAllowedDestinationAccounts(newAccount);
|
||||||
|
|
||||||
|
sourceAccount = newAccount;
|
||||||
|
|
||||||
|
setTransactionType();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the new destination account (from a suggestion).
|
||||||
|
*
|
||||||
|
* @param newAccount
|
||||||
|
*/
|
||||||
|
function setDestinationAccount(newAccount) {
|
||||||
|
if (null === newAccount) {
|
||||||
|
console.log('New destination account is now null.');
|
||||||
|
destinationAccount = null;
|
||||||
|
setAllowedSourceAccounts(newAccount);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('The new destination account is now ' + newAccount.value + 'of type ' + newAccount.data.type);
|
||||||
|
setAllowedSourceAccounts(newAccount);
|
||||||
|
|
||||||
|
sourceAccount = newAccount;
|
||||||
|
|
||||||
|
setTransactionType();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a new limit on the allowed destination account.
|
||||||
|
*
|
||||||
|
* @param newAccount
|
||||||
|
*/
|
||||||
|
function setAllowedDestinationAccounts(newAccount) {
|
||||||
|
if (null === newAccount) {
|
||||||
|
console.log('Allowed type for destination account is anything.');
|
||||||
|
destAllowedAccountTypes = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
destAllowedAccountTypes = allowedOpposingTypes.source[newAccount.data.type];
|
||||||
|
console.log('The destination account must be of type: ', destAllowedAccountTypes);
|
||||||
|
|
||||||
|
// todo if the current destination account is not of this type, reset it.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a new limit on the allowed destination account.
|
||||||
|
*
|
||||||
|
* @param newAccount
|
||||||
|
*/
|
||||||
|
function setAllowedSourceAccounts(newAccount) {
|
||||||
|
if (null === newAccount) {
|
||||||
|
console.log('Allowed type for source account is anything.');
|
||||||
|
sourceAllowedAccountTypes = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sourceAllowedAccountTypes = allowedOpposingTypes.source[newAccount.data.type];
|
||||||
|
console.log('The source account must be of type: ', sourceAllowedAccountTypes);
|
||||||
|
|
||||||
|
// todo if the current destination account is not of this type, reset it.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create auto complete.
|
||||||
|
*/
|
||||||
|
function autoComplete() {
|
||||||
|
var options = {
|
||||||
|
serviceUrl: getSourceAutoCompleteURI,
|
||||||
|
groupBy: 'type',
|
||||||
|
onSelect: function (suggestion) {
|
||||||
|
setSourceAccount(suggestion);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$('.sourceAccountAC').autocomplete(options);
|
||||||
|
|
||||||
|
// also select destination account.
|
||||||
|
var destinationOptions = {
|
||||||
|
serviceUrl: getDestinationAutoCompleteURI,
|
||||||
|
groupBy: 'type',
|
||||||
|
onSelect: function (suggestion) {
|
||||||
|
setDestinationAccount(suggestion);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$('.destinationAccountAC').autocomplete(destinationOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTransactionType() {
|
||||||
|
if (sourceAccount === undefined || destinationAccount === undefined || sourceAccount === null || destinationAccount === null) {
|
||||||
|
$('.transactionTypeIndicator').text('');
|
||||||
|
$('.transactionTypeIndicatorBlock').hide();
|
||||||
|
console.warn('Not both accounts are known yet.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$('.transactionTypeIndicatorBlock').show();
|
||||||
|
var expectedType = accountToTypes[sourceAccount.data.type][destinationAccount.data.type];
|
||||||
|
$('.transactionTypeIndicator').html(creatingTypes[expectedType]);
|
||||||
|
console.log('Expected transaction type is ' + expectedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the auto complete URI for source accounts.
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getSourceAutoCompleteURI() {
|
||||||
|
console.log('Will filter source accounts', sourceAllowedAccountTypes);
|
||||||
|
return accountAutoCompleteURI + '?types=' + encodeURI(sourceAllowedAccountTypes.join(','));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the auto complete URI for destination accounts.
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getDestinationAutoCompleteURI() {
|
||||||
|
console.log('Will filter destination accounts', destAllowedAccountTypes);
|
||||||
|
return accountAutoCompleteURI + '?types=' + encodeURI(destAllowedAccountTypes.join(','));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give date a datepicker if not natively supported.
|
||||||
|
*/
|
||||||
|
function runModernizer() {
|
||||||
|
if (!Modernizr.inputtypes.date) {
|
||||||
|
$('input[type="date"]').datepicker(
|
||||||
|
{
|
||||||
|
dateFormat: 'yy-mm-dd'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
8
public/v1/js/lib/jquery.autocomplete.min.js
vendored
Executable file
8
public/v1/js/lib/jquery.autocomplete.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
19
resources/assets/js/app.js
vendored
19
resources/assets/js/app.js
vendored
@ -3,10 +3,26 @@
|
|||||||
* includes Vue and other libraries. It is a great starting point when
|
* includes Vue and other libraries. It is a great starting point when
|
||||||
* building robust, powerful web applications using Vue and Laravel.
|
* building robust, powerful web applications using Vue and Laravel.
|
||||||
*/
|
*/
|
||||||
/* TODO REMOVE ME */
|
|
||||||
|
|
||||||
require('./bootstrap');
|
require('./bootstrap');
|
||||||
window.Vue = require('vue');
|
window.Vue = require('vue');
|
||||||
|
import * as uiv from 'uiv';
|
||||||
|
|
||||||
|
Vue.use(uiv);
|
||||||
|
// components for create and edit transactions.
|
||||||
|
Vue.component('budget', require('./components/transactions/Budget.vue'));
|
||||||
|
Vue.component('custom-transaction-fields', require('./components/transactions/CustomTransactionFields.vue'));
|
||||||
|
Vue.component('piggy-bank', require('./components/transactions/PiggyBank.vue'));
|
||||||
|
Vue.component('tags', require('./components/transactions/Tags.vue'));
|
||||||
|
Vue.component('category', require('./components/transactions/Category.vue'));
|
||||||
|
Vue.component('amount', require('./components/transactions/Amount.vue'));
|
||||||
|
Vue.component('foreign-amount', require('./components/transactions/ForeignAmountSelect.vue'));
|
||||||
|
Vue.component('transaction-type', require('./components/transactions/TransactionType.vue'));
|
||||||
|
Vue.component('account-select', require('./components/transactions/AccountSelect.vue'));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Components for OAuth2 tokens.
|
* Components for OAuth2 tokens.
|
||||||
@ -14,6 +30,7 @@ window.Vue = require('vue');
|
|||||||
Vue.component('passport-clients', require('./components/passport/Clients.vue'));
|
Vue.component('passport-clients', require('./components/passport/Clients.vue'));
|
||||||
Vue.component('passport-authorized-clients', require('./components/passport/AuthorizedClients.vue'));
|
Vue.component('passport-authorized-clients', require('./components/passport/AuthorizedClients.vue'));
|
||||||
Vue.component('passport-personal-access-tokens', require('./components/passport/PersonalAccessTokens.vue'));
|
Vue.component('passport-personal-access-tokens', require('./components/passport/PersonalAccessTokens.vue'));
|
||||||
|
Vue.component('create-transaction', require('./components/transactions/CreateTransaction'));
|
||||||
|
|
||||||
|
|
||||||
const app = new Vue({
|
const app = new Vue({
|
||||||
|
160
resources/assets/js/components/transactions/AccountSelect.vue
Normal file
160
resources/assets/js/components/transactions/AccountSelect.vue
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
<!--
|
||||||
|
- AccountSelect.vue
|
||||||
|
- Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||||
|
-
|
||||||
|
- This file is part of Firefly III.
|
||||||
|
-
|
||||||
|
- Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
- it under the terms of the GNU General Public License as published by
|
||||||
|
- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
- (at your option) any later version.
|
||||||
|
-
|
||||||
|
- Firefly III 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 General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU General Public License
|
||||||
|
- along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
ref="input"
|
||||||
|
type="text"
|
||||||
|
:placeholder="title"
|
||||||
|
:data-index="index"
|
||||||
|
autocomplete="off"
|
||||||
|
data-role="input"
|
||||||
|
v-on:keypress="handleEnter"
|
||||||
|
:disabled="inputDisabled"
|
||||||
|
class="form-control"
|
||||||
|
v-on:submit.prevent
|
||||||
|
:name="inputName"
|
||||||
|
:title="title">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button
|
||||||
|
v-on:click="clearSource"
|
||||||
|
class="btn btn-default"
|
||||||
|
type="button"><i class="fa fa-trash-o"></i></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<typeahead
|
||||||
|
:open-on-empty=true
|
||||||
|
:open-on-focus=true
|
||||||
|
v-on:input="selectedItem"
|
||||||
|
:async-src="accountAutoCompleteURI"
|
||||||
|
v-model="name"
|
||||||
|
:target="target"
|
||||||
|
item-key="name"
|
||||||
|
></typeahead>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
inputName: String,
|
||||||
|
title: String,
|
||||||
|
index: Number,
|
||||||
|
transactionType: String,
|
||||||
|
accountName: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
accountTypeFilters: {
|
||||||
|
type: Array,
|
||||||
|
default: function () {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
accountAutoCompleteURI: null,
|
||||||
|
name: null,
|
||||||
|
trType: this.transactionType,
|
||||||
|
target: null,
|
||||||
|
inputDisabled: false,
|
||||||
|
allowedTypes: this.accountTypeFilters
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ready() {
|
||||||
|
this.name = this.accountName;
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.target = this.$refs.input;
|
||||||
|
let types = this.allowedTypes.join(',');
|
||||||
|
this.name = this.accountName;
|
||||||
|
this.accountAutoCompleteURI = document.getElementsByTagName('base')[0].href + "json/accounts?types=" + types + "&query=";
|
||||||
|
this.triggerTransactionType();
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
transactionType() {
|
||||||
|
this.triggerTransactionType();
|
||||||
|
},
|
||||||
|
accountTypeFilters() {
|
||||||
|
let types = this.accountTypeFilters.join(',');
|
||||||
|
console.log(this.inputName + '[' + this.index + '] is now searching for: ' + types);
|
||||||
|
this.accountAutoCompleteURI = document.getElementsByTagName('base')[0].href + "json/accounts?types=" + types + "&query=";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:
|
||||||
|
{
|
||||||
|
triggerTransactionType: function () {
|
||||||
|
if (null === this.transactionType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.inputDisabled = false;
|
||||||
|
if (this.transactionType.toString() !== '' && this.index > 0) {
|
||||||
|
if (this.transactionType.toString() === 'Transfer') {
|
||||||
|
this.inputDisabled = true;
|
||||||
|
// todo: needs to copy value from very first input
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.transactionType.toString() === 'Withdrawal' && this.inputName.substr(0, 6).toLowerCase() === 'source') {
|
||||||
|
// todo also clear value?
|
||||||
|
this.inputDisabled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.transactionType.toString() === 'Deposit' && this.inputName.substr(0, 11).toLowerCase() === 'destination') {
|
||||||
|
// todo also clear value?
|
||||||
|
this.inputDisabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectedItem: function (e) {
|
||||||
|
if (typeof this.name === 'undefined') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// emit the fact that the user selected a type of account
|
||||||
|
// (influencing the destination)
|
||||||
|
this.$emit('select:account', this.name);
|
||||||
|
},
|
||||||
|
clearSource: function (e) {
|
||||||
|
//props.value = '';
|
||||||
|
this.name = '';
|
||||||
|
// some event?
|
||||||
|
this.$emit('clear:value')
|
||||||
|
},
|
||||||
|
handleEnter: function (e) {
|
||||||
|
// todo feels sloppy
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
76
resources/assets/js/components/transactions/Amount.vue
Normal file
76
resources/assets/js/components/transactions/Amount.vue
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<!--
|
||||||
|
- Amount.vue
|
||||||
|
- Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||||
|
-
|
||||||
|
- This file is part of Firefly III.
|
||||||
|
-
|
||||||
|
- Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
- it under the terms of the GNU General Public License as published by
|
||||||
|
- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
- (at your option) any later version.
|
||||||
|
-
|
||||||
|
- Firefly III 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 General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU General Public License
|
||||||
|
- along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-4 control-label" ref="cur"></label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" step="any" class="form-control" name="amount[]"
|
||||||
|
title="amount" autocomplete="off" placeholder="Amount">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Amount",
|
||||||
|
props: ['source', 'destination', 'transactionType'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
sourceAccount: this.source,
|
||||||
|
destinationAccount: this.destination,
|
||||||
|
type: this.transactionType,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeData: function () {
|
||||||
|
if ('' === this.transactionType) {
|
||||||
|
$(this.$refs.cur).text(this.sourceAccount.currency_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.transactionType === 'Withdrawal' || this.transactionType === 'Transfer') {
|
||||||
|
$(this.$refs.cur).text(this.sourceAccount.currency_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.transactionType === 'Deposit') {
|
||||||
|
$(this.$refs.cur).text(this.destinationAccount.currency_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
source: function () {
|
||||||
|
this.changeData();
|
||||||
|
},
|
||||||
|
destination: function () {
|
||||||
|
this.changeData();
|
||||||
|
},
|
||||||
|
transactionType: function () {
|
||||||
|
this.changeData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.changeData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
66
resources/assets/js/components/transactions/Budget.vue
Normal file
66
resources/assets/js/components/transactions/Budget.vue
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<!--
|
||||||
|
- Budget.vue
|
||||||
|
- Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||||
|
-
|
||||||
|
- This file is part of Firefly III.
|
||||||
|
-
|
||||||
|
- Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
- it under the terms of the GNU General Public License as published by
|
||||||
|
- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
- (at your option) any later version.
|
||||||
|
-
|
||||||
|
- Firefly III 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 General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU General Public License
|
||||||
|
- along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="form-group" v-if="typeof this.transactionType !== 'undefined' && this.transactionType === 'Withdrawal'">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<select name="budget[]" class="form-control" v-if="this.budgets.length > 0">
|
||||||
|
<option v-for="budget in this.budgets">{{budget.name}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Budget",
|
||||||
|
props: ['transactionType'],
|
||||||
|
mounted() {
|
||||||
|
this.loadBudgets();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
budgets: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadBudgets: function () {
|
||||||
|
let URI = document.getElementsByTagName('base')[0].href + "json/budgets";
|
||||||
|
axios.get(URI, {}).then((res) => {
|
||||||
|
this.budgets = [
|
||||||
|
{
|
||||||
|
name: '(no budget)',
|
||||||
|
id: 0,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
for (const key in res.data) {
|
||||||
|
if (res.data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
||||||
|
this.budgets.push(res.data[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
108
resources/assets/js/components/transactions/Category.vue
Normal file
108
resources/assets/js/components/transactions/Category.vue
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<!--
|
||||||
|
- Category.vue
|
||||||
|
- Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||||
|
-
|
||||||
|
- This file is part of Firefly III.
|
||||||
|
-
|
||||||
|
- Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
- it under the terms of the GNU General Public License as published by
|
||||||
|
- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
- (at your option) any later version.
|
||||||
|
-
|
||||||
|
- Firefly III 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 General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU General Public License
|
||||||
|
- along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
ref="input"
|
||||||
|
type="text"
|
||||||
|
placeholder="Category"
|
||||||
|
autocomplete="off"
|
||||||
|
data-role="input"
|
||||||
|
v-on:keypress="handleEnter"
|
||||||
|
class="form-control"
|
||||||
|
v-on:submit.prevent
|
||||||
|
name="category[]"
|
||||||
|
title="Category">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button
|
||||||
|
v-on:click="clearCategory"
|
||||||
|
class="btn btn-default"
|
||||||
|
type="button"><i class="fa fa-trash-o"></i></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<typeahead
|
||||||
|
:open-on-empty=true
|
||||||
|
:open-on-focus=true
|
||||||
|
v-on:input="selectedItem"
|
||||||
|
:async-src="categoryAutoCompleteURI"
|
||||||
|
v-model="name"
|
||||||
|
:target="target"
|
||||||
|
item-key="name"
|
||||||
|
></typeahead>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Category",
|
||||||
|
props: {
|
||||||
|
inputName: String,
|
||||||
|
accountName: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
categoryAutoCompleteURI: null,
|
||||||
|
name: null,
|
||||||
|
target: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ready() {
|
||||||
|
this.name = this.accountName;
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.target = this.$refs.input;
|
||||||
|
this.categoryAutoCompleteURI = document.getElementsByTagName('base')[0].href + "json/categories?query=";
|
||||||
|
//this.triggerTransactionType();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
clearCategory: function () {
|
||||||
|
//props.value = '';
|
||||||
|
this.name = '';
|
||||||
|
// some event?
|
||||||
|
this.$emit('clear:category')
|
||||||
|
},
|
||||||
|
selectedItem: function (e) {
|
||||||
|
if (typeof this.name === 'undefined') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// emit the fact that the user selected a type of account
|
||||||
|
// (influencing the destination)
|
||||||
|
this.$emit('select:category', this.name);
|
||||||
|
},
|
||||||
|
handleEnter: function (e) {
|
||||||
|
// todo feels sloppy
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,301 @@
|
|||||||
|
<!--
|
||||||
|
- CreateTransaction.vue
|
||||||
|
- Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||||
|
-
|
||||||
|
- This file is part of Firefly III.
|
||||||
|
-
|
||||||
|
- Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
- it under the terms of the GNU General Public License as published by
|
||||||
|
- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
- (at your option) any later version.
|
||||||
|
-
|
||||||
|
- Firefly III 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 General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU General Public License
|
||||||
|
- along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<form method="POST" action="xxxx" accept-charset="UTF-8" class="form-horizontal" id="store" enctype="multipart/form-data">
|
||||||
|
<input name="_token" type="hidden" value="xxx">
|
||||||
|
|
||||||
|
<div class="row" v-if="transactions.transactions.length > 1">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">
|
||||||
|
Description of the split transaction
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<input type="text" class="form-control" name="group_title"
|
||||||
|
v-model="transactions.group_title"
|
||||||
|
title="Description of the split transaction" autocomplete="off" placeholder="Description of the split transaction">
|
||||||
|
|
||||||
|
|
||||||
|
<p class="help-block">
|
||||||
|
If you create a split transaction, there must be a global description for all splits of the transaction.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-for="(transaction, index) in transactions.transactions">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title splitTitle">
|
||||||
|
<span v-if="transactions.transactions.length > 1">Split {{ index+1 }} / {{ transactions.transactions.length }}</span>
|
||||||
|
<span v-if="transactions.transactions.length === 1">Transaction information</span>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<account-select
|
||||||
|
inputName="source[]"
|
||||||
|
title="Source account"
|
||||||
|
:accountName="transaction.source_account.name"
|
||||||
|
:accountTypeFilters="transaction.source_account.allowed_types"
|
||||||
|
:transactionType="transactionType"
|
||||||
|
:index="index"
|
||||||
|
v-on:clear:value="clearSource(index)"
|
||||||
|
v-on:select:account="selectedSourceAccount(index, $event)"
|
||||||
|
></account-select>
|
||||||
|
<account-select
|
||||||
|
inputName="destination[]"
|
||||||
|
title="Destination account"
|
||||||
|
:accountName="transaction.destination_account.name"
|
||||||
|
:accountTypeFilters="transaction.destination_account.allowed_types"
|
||||||
|
:transactionType="transactionType"
|
||||||
|
:index="index"
|
||||||
|
v-on:clear:value="clearDestination(index)"
|
||||||
|
v-on:select:account="selectedDestinationAccount(index, $event)"
|
||||||
|
></account-select>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<input type="text" class="form-control" name="description[]"
|
||||||
|
:value="transaction.description"
|
||||||
|
title="Description" autocomplete="off" placeholder="Description">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<input type="date" class="form-control" name="date[]"
|
||||||
|
title="Date" value="" autocomplete="off"
|
||||||
|
:value="transaction.date"
|
||||||
|
:disabled="index > 0"
|
||||||
|
placeholder="Date">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="index===0">
|
||||||
|
<transaction-type
|
||||||
|
:source="transaction.source_account.type"
|
||||||
|
:destination="transaction.destination_account.type"
|
||||||
|
v-on:set:transactionType="setTransactionType($event)"
|
||||||
|
v-on:act:limitSourceType="limitSourceType($event)"
|
||||||
|
v-on:act:limitDestinationType="limitDestinationType($event)"
|
||||||
|
></transaction-type>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<amount
|
||||||
|
:source="transaction.source_account"
|
||||||
|
:destination="transaction.destination_account"
|
||||||
|
:transactionType="transactionType"
|
||||||
|
></amount>
|
||||||
|
<foreign-amount
|
||||||
|
:source="transaction.source_account"
|
||||||
|
:destination="transaction.destination_account"
|
||||||
|
:transactionType="transactionType"
|
||||||
|
></foreign-amount>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<budget :transactionType="transactionType"></budget>
|
||||||
|
<category :transactionType="transactionType"></category>
|
||||||
|
<piggy-bank :transactionType="transactionType"></piggy-bank>
|
||||||
|
<tags></tags>
|
||||||
|
<!-- custom string fields -->
|
||||||
|
<custom-transaction-fields></custom-transaction-fields>
|
||||||
|
|
||||||
|
<!-- custom date fields -->
|
||||||
|
|
||||||
|
<!-- custom other fields -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<p>
|
||||||
|
<button class="btn btn-primary" v-on:click="addTransaction">Add another split</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "CreateTransaction",
|
||||||
|
components: {
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// not sure if something needs to happen here.
|
||||||
|
},
|
||||||
|
ready() {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addTransaction: function (e) {
|
||||||
|
let latest = this.transactions.transactions[this.transactions.transactions.length - 1];
|
||||||
|
this.transactions.transactions.push(latest);
|
||||||
|
e.preventDefault();
|
||||||
|
},
|
||||||
|
setTransactionType: function (type) {
|
||||||
|
this.transactionType = type;
|
||||||
|
},
|
||||||
|
limitSourceType: function (type) {
|
||||||
|
let i;
|
||||||
|
for (i = 0; i < this.transactions.transactions.length; i++) {
|
||||||
|
this.transactions.transactions[i].source_account.allowed_types = [type];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
limitDestinationType: function (type) {
|
||||||
|
let i;
|
||||||
|
for (i = 0; i < this.transactions.transactions.length; i++) {
|
||||||
|
this.transactions.transactions[i].destination_account.allowed_types = [type];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
selectedSourceAccount: function (index, model) {
|
||||||
|
if (typeof model === 'string') {
|
||||||
|
// cant change types, only name.
|
||||||
|
this.transactions.transactions[index].source_account.name = model;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// todo maybe replace the entire model?
|
||||||
|
this.transactions.transactions[index].source_account.id = model.id;
|
||||||
|
this.transactions.transactions[index].source_account.name = model.name;
|
||||||
|
this.transactions.transactions[index].source_account.type = model.type;
|
||||||
|
|
||||||
|
this.transactions.transactions[index].source_account.currency_id = model.currency_id;
|
||||||
|
this.transactions.transactions[index].source_account.currency_name = model.currency_name;
|
||||||
|
this.transactions.transactions[index].source_account.currency_code = model.currency_code;
|
||||||
|
this.transactions.transactions[index].source_account.currency_decimal_places = model.currency_decimal_places;
|
||||||
|
// force types on destination selector.
|
||||||
|
this.transactions.transactions[index].destination_account.allowed_types = window.allowedOpposingTypes.source[model.type];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectedDestinationAccount: function (index, model) {
|
||||||
|
if (typeof model === 'string') {
|
||||||
|
// cant change types, only name.
|
||||||
|
this.transactions.transactions[index].destination_account.name = model;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// todo maybe replace the entire model?
|
||||||
|
this.transactions.transactions[index].destination_account.id = model.id;
|
||||||
|
this.transactions.transactions[index].destination_account.name = model.name;
|
||||||
|
this.transactions.transactions[index].destination_account.type = model.type;
|
||||||
|
|
||||||
|
this.transactions.transactions[index].destination_account.currency_id = model.currency_id;
|
||||||
|
this.transactions.transactions[index].destination_account.currency_name = model.currency_name;
|
||||||
|
this.transactions.transactions[index].destination_account.currency_code = model.currency_code;
|
||||||
|
this.transactions.transactions[index].destination_account.currency_decimal_places = model.currency_decimal_places;
|
||||||
|
|
||||||
|
// force types on destination selector.
|
||||||
|
this.transactions.transactions[index].source_account.allowed_types = window.allowedOpposingTypes.destination[model.type];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clearSource: function (index) {
|
||||||
|
this.transactions.transactions[index].source_account.id = 0;
|
||||||
|
this.transactions.transactions[index].source_account.name = "";
|
||||||
|
this.transactions.transactions[index].source_account.type = "";
|
||||||
|
this.transactions.transactions[index].destination_account.allowed_types = [];
|
||||||
|
|
||||||
|
// if there is a destination model, reset the types of the source
|
||||||
|
// by pretending we selected it again.
|
||||||
|
if (this.transactions.transactions[index].destination_account) {
|
||||||
|
console.log('There is a destination account.');
|
||||||
|
this.selectedDestinationAccount(index, this.transactions.transactions[index].destination_account);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clearDestination: function (index) {
|
||||||
|
this.transactions.transactions[index].destination_account.id = 0;
|
||||||
|
this.transactions.transactions[index].destination_account.name = "";
|
||||||
|
this.transactions.transactions[index].destination_account.type = "";
|
||||||
|
this.transactions.transactions[index].source_account.allowed_types = [];
|
||||||
|
|
||||||
|
// if there is a source model, reset the types of the destination
|
||||||
|
// by pretending we selected it again.
|
||||||
|
if (this.transactions.transactions[index].source_account) {
|
||||||
|
console.log('There is a source account.');
|
||||||
|
this.selectedSourceAccount(index, this.transactions.transactions[index].source_account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The component's data.
|
||||||
|
*/
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
transactionType: null,
|
||||||
|
transactions: {
|
||||||
|
group_title: "",
|
||||||
|
transactions: [
|
||||||
|
{
|
||||||
|
description: "",
|
||||||
|
date: "",
|
||||||
|
amount: "",
|
||||||
|
foreign_amount: "",
|
||||||
|
source_account: {
|
||||||
|
id: 0,
|
||||||
|
name: "",
|
||||||
|
type: "",
|
||||||
|
//currency_id: window.defaultCurrency.id,
|
||||||
|
//currency_name: window.defaultCurrency.name,
|
||||||
|
//currency_code: window.defaultCurrency.code,
|
||||||
|
//currency_decimal_places: window.defaultCurrency.decimal_places,
|
||||||
|
currency_id: 0,
|
||||||
|
currency_name: '',
|
||||||
|
currency_code: '',
|
||||||
|
currency_decimal_places: 2,
|
||||||
|
allowed_types: []
|
||||||
|
},
|
||||||
|
destination_account: {
|
||||||
|
id: 0,
|
||||||
|
name: "",
|
||||||
|
type: "",
|
||||||
|
//currency_id: window.defaultCurrency.id,
|
||||||
|
//currency_name: window.defaultCurrency.name,
|
||||||
|
//currency_code: window.defaultCurrency.code,
|
||||||
|
//currency_decimal_places: window.defaultCurrency.decimal_places,
|
||||||
|
currency_id: 0,
|
||||||
|
currency_name: '',
|
||||||
|
currency_code: '',
|
||||||
|
currency_decimal_places: 2,
|
||||||
|
allowed_types: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
@ -0,0 +1,46 @@
|
|||||||
|
<!--
|
||||||
|
- CustomTransactionFields.vue
|
||||||
|
- Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||||
|
-
|
||||||
|
- This file is part of Firefly III.
|
||||||
|
-
|
||||||
|
- Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
- it under the terms of the GNU General Public License as published by
|
||||||
|
- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
- (at your option) any later version.
|
||||||
|
-
|
||||||
|
- Firefly III 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 General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU General Public License
|
||||||
|
- along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "CustomTransactionFields",
|
||||||
|
mounted() {
|
||||||
|
this.getPreference();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getPreference() {
|
||||||
|
|
||||||
|
const url = document.getElementsByTagName('base')[0].href + 'api/v1/preferences/transaction_journal_optional_fields';
|
||||||
|
|
||||||
|
axios.get(url).then(response => {
|
||||||
|
console.log(response.data.data.attributes);
|
||||||
|
}).catch(() => console.warn('Oh. Something went wrong'));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,127 @@
|
|||||||
|
<!--
|
||||||
|
- ForeignAmountSelect.vue
|
||||||
|
- Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||||
|
-
|
||||||
|
- This file is part of Firefly III.
|
||||||
|
-
|
||||||
|
- Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
- it under the terms of the GNU General Public License as published by
|
||||||
|
- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
- (at your option) any later version.
|
||||||
|
-
|
||||||
|
- Firefly III 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 General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU General Public License
|
||||||
|
- along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<select class="form-control" name="foreign_currency[]" v-if="this.enabledCurrencies.length > 0">
|
||||||
|
<option v-for="currency in this.enabledCurrencies" v-if="currency.enabled">{{ currency.name }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" step="any" class="form-control" name="foreign_amount[]" v-if="this.enabledCurrencies.length > 0"
|
||||||
|
title="Foreign amount" autocomplete="off" placeholder="Foreign amount">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "ForeignAmountSelect",
|
||||||
|
props: ['source', 'destination', 'transactionType'],
|
||||||
|
mounted() {
|
||||||
|
this.loadCurrencies();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
currencies: [],
|
||||||
|
enabledCurrencies: [],
|
||||||
|
exclude: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
source: function () {
|
||||||
|
this.changeData();
|
||||||
|
},
|
||||||
|
destination: function () {
|
||||||
|
this.changeData();
|
||||||
|
},
|
||||||
|
transactionType: function () {
|
||||||
|
this.changeData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeData: function () {
|
||||||
|
this.enabledCurrencies = [];
|
||||||
|
if (this.transactionType === 'Transfer') {
|
||||||
|
// lock source on currencyID of destination
|
||||||
|
for (const key in this.currencies) {
|
||||||
|
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
||||||
|
if (this.currencies[key].id === this.destination.currency_id) {
|
||||||
|
this.enabledCurrencies.push(this.currencies[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// if type is withdrawal, list all but skip the source account ID.
|
||||||
|
if (this.transactionType === 'Withdrawal' && this.source) {
|
||||||
|
for (const key in this.currencies) {
|
||||||
|
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
||||||
|
if (this.source.currency_id !== this.currencies[key].id) {
|
||||||
|
this.enabledCurrencies.push(this.currencies[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if type is deposit, list all but skip the source account ID.
|
||||||
|
if (this.transactionType === 'Deposit' && this.destination) {
|
||||||
|
for (const key in this.currencies) {
|
||||||
|
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
||||||
|
if (this.destination.currency_id !== this.currencies[key].id) {
|
||||||
|
this.enabledCurrencies.push(this.currencies[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const key in this.currencies) {
|
||||||
|
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
||||||
|
this.enabledCurrencies.push(this.currencies[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loadCurrencies: function () {
|
||||||
|
let URI = document.getElementsByTagName('base')[0].href + "json/currencies";
|
||||||
|
axios.get(URI, {}).then((res) => {
|
||||||
|
this.currencies = [
|
||||||
|
{
|
||||||
|
name: '(none)',
|
||||||
|
id: 0,
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
for (const key in res.data) {
|
||||||
|
if (res.data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
||||||
|
this.currencies.push(res.data[key]);
|
||||||
|
this.enabledCurrencies.push(res.data[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
66
resources/assets/js/components/transactions/PiggyBank.vue
Normal file
66
resources/assets/js/components/transactions/PiggyBank.vue
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<!--
|
||||||
|
- PiggyBank.vue
|
||||||
|
- Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||||
|
-
|
||||||
|
- This file is part of Firefly III.
|
||||||
|
-
|
||||||
|
- Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
- it under the terms of the GNU General Public License as published by
|
||||||
|
- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
- (at your option) any later version.
|
||||||
|
-
|
||||||
|
- Firefly III 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 General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU General Public License
|
||||||
|
- along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="form-group" v-if="typeof this.transactionType !== 'undefined' && this.transactionType === 'Transfer'">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<select name="piggy_bank[]" class="form-control" v-if="this.piggies.length > 0">
|
||||||
|
<option v-for="piggy in this.piggies">{{piggy.name}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "PiggyBank",
|
||||||
|
props: ['transactionType'],
|
||||||
|
mounted() {
|
||||||
|
this.loadPiggies();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
piggies: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadPiggies: function () {
|
||||||
|
let URI = document.getElementsByTagName('base')[0].href + "json/piggy-banks";
|
||||||
|
axios.get(URI, {}).then((res) => {
|
||||||
|
this.piggies = [
|
||||||
|
{
|
||||||
|
name: '(no piggy bank)',
|
||||||
|
id: 0,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
for (const key in res.data) {
|
||||||
|
if (res.data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
||||||
|
this.piggies.push(res.data[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
82
resources/assets/js/components/transactions/Tags.vue
Normal file
82
resources/assets/js/components/transactions/Tags.vue
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<!--
|
||||||
|
- Tags.vue
|
||||||
|
- Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||||
|
-
|
||||||
|
- This file is part of Firefly III.
|
||||||
|
-
|
||||||
|
- Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
- it under the terms of the GNU General Public License as published by
|
||||||
|
- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
- (at your option) any later version.
|
||||||
|
-
|
||||||
|
- Firefly III 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 General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU General Public License
|
||||||
|
- along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<vue-tags-input
|
||||||
|
v-model="tag"
|
||||||
|
:tags="tags"
|
||||||
|
classes="form-input"
|
||||||
|
:autocomplete-items="autocompleteItems"
|
||||||
|
:add-only-from-autocomplete="false"
|
||||||
|
@tags-changed="update"
|
||||||
|
placeholder="Tags"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios';
|
||||||
|
import VueTagsInput from '@johmun/vue-tags-input';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Tags",
|
||||||
|
components: {
|
||||||
|
VueTagsInput
|
||||||
|
}, data() {
|
||||||
|
return {
|
||||||
|
tag: '',
|
||||||
|
tags: [],
|
||||||
|
autocompleteItems: [],
|
||||||
|
debounce: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'tag': 'initItems',
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
update(newTags) {
|
||||||
|
this.autocompleteItems = [];
|
||||||
|
this.tags = newTags;
|
||||||
|
},
|
||||||
|
initItems() {
|
||||||
|
if (this.tag.length < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const url = document.getElementsByTagName('base')[0].href + `json/tags?query=${this.tag}`;
|
||||||
|
|
||||||
|
clearTimeout(this.debounce);
|
||||||
|
this.debounce = setTimeout(() => {
|
||||||
|
axios.get(url).then(response => {
|
||||||
|
this.autocompleteItems = response.data.map(a => {
|
||||||
|
return {text: a.tag};
|
||||||
|
});
|
||||||
|
}).catch(() => console.warn('Oh. Something went wrong'));
|
||||||
|
}, 600);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,90 @@
|
|||||||
|
<!--
|
||||||
|
- TransactionType.vue
|
||||||
|
- Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||||
|
-
|
||||||
|
- This file is part of Firefly III.
|
||||||
|
-
|
||||||
|
- Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
- it under the terms of the GNU General Public License as published by
|
||||||
|
- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
- (at your option) any later version.
|
||||||
|
-
|
||||||
|
- Firefly III 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 General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU General Public License
|
||||||
|
- along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<label v-if="sentence !== ''" class="control-label text-info">
|
||||||
|
{{ sentence }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
source: String,
|
||||||
|
destination: String,
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeValue: function () {
|
||||||
|
if (this.source && this.destination) {
|
||||||
|
let transactionType = '';
|
||||||
|
if (window.accountToTypes[this.source]) {
|
||||||
|
if (window.accountToTypes[this.source][this.destination]) {
|
||||||
|
transactionType = window.accountToTypes[this.source][this.destination];
|
||||||
|
} else {
|
||||||
|
console.warn('User selected an impossible destination.');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn('User selected an impossible source.');
|
||||||
|
}
|
||||||
|
if ('' !== transactionType) {
|
||||||
|
this.transactionType = transactionType;
|
||||||
|
this.sentence = 'You\'re creating a ' + this.transactionType;
|
||||||
|
|
||||||
|
// Must also emit a change to set ALL sources and destinations to this particular type.
|
||||||
|
this.$emit('act:limitSourceType', this.source);
|
||||||
|
this.$emit('act:limitDestinationType', this.destination);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.sentence = '';
|
||||||
|
this.transactionType = '';
|
||||||
|
}
|
||||||
|
// emit event how cool is that.
|
||||||
|
this.$emit('set:transactionType', this.transactionType);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
transactionType: this.type,
|
||||||
|
sentence: ''
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
source() {
|
||||||
|
this.changeValue();
|
||||||
|
},
|
||||||
|
destination() {
|
||||||
|
this.changeValue();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: "TransactionType"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -23,35 +23,36 @@
|
|||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'home' => 'Home',
|
'home' => 'Home',
|
||||||
'edit_currency' => 'Edit currency ":name"',
|
'edit_currency' => 'Edit currency ":name"',
|
||||||
'delete_currency' => 'Delete currency ":name"',
|
'delete_currency' => 'Delete currency ":name"',
|
||||||
'newPiggyBank' => 'Create a new piggy bank',
|
'newPiggyBank' => 'Create a new piggy bank',
|
||||||
'edit_piggyBank' => 'Edit piggy bank ":name"',
|
'edit_piggyBank' => 'Edit piggy bank ":name"',
|
||||||
'preferences' => 'Preferences',
|
'preferences' => 'Preferences',
|
||||||
'profile' => 'Profile',
|
'profile' => 'Profile',
|
||||||
'changePassword' => 'Change your password',
|
'changePassword' => 'Change your password',
|
||||||
'change_email' => 'Change your email address',
|
'change_email' => 'Change your email address',
|
||||||
'bills' => 'Bills',
|
'bills' => 'Bills',
|
||||||
'newBill' => 'New bill',
|
'newBill' => 'New bill',
|
||||||
'edit_bill' => 'Edit bill ":name"',
|
'edit_bill' => 'Edit bill ":name"',
|
||||||
'delete_bill' => 'Delete bill ":name"',
|
'delete_bill' => 'Delete bill ":name"',
|
||||||
'reports' => 'Reports',
|
'reports' => 'Reports',
|
||||||
'search_result' => 'Search results for ":query"',
|
'search_result' => 'Search results for ":query"',
|
||||||
'withdrawal_list' => 'Expenses',
|
'withdrawal_list' => 'Expenses',
|
||||||
'deposit_list' => 'Revenue, income and deposits',
|
'deposit_list' => 'Revenue, income and deposits',
|
||||||
'transfer_list' => 'Transfers',
|
'transfer_list' => 'Transfers',
|
||||||
'transfers_list' => 'Transfers',
|
'transfers_list' => 'Transfers',
|
||||||
'reconciliation_list' => 'Reconciliations',
|
'reconciliation_list' => 'Reconciliations',
|
||||||
'create_withdrawal' => 'Create new withdrawal',
|
'create_withdrawal' => 'Create new withdrawal',
|
||||||
'create_deposit' => 'Create new deposit',
|
'create_deposit' => 'Create new deposit',
|
||||||
'create_transfer' => 'Create new transfer',
|
'create_transfer' => 'Create new transfer',
|
||||||
'edit_journal' => 'Edit transaction ":description"',
|
'create_new_transaction' => 'Create a new transaction',
|
||||||
'edit_reconciliation' => 'Edit ":description"',
|
'edit_journal' => 'Edit transaction ":description"',
|
||||||
'delete_journal' => 'Delete transaction ":description"',
|
'edit_reconciliation' => 'Edit ":description"',
|
||||||
'tags' => 'Tags',
|
'delete_journal' => 'Delete transaction ":description"',
|
||||||
'createTag' => 'Create new tag',
|
'tags' => 'Tags',
|
||||||
'edit_tag' => 'Edit tag ":tag"',
|
'createTag' => 'Create new tag',
|
||||||
'delete_tag' => 'Delete tag ":tag"',
|
'edit_tag' => 'Edit tag ":tag"',
|
||||||
'delete_journal_link' => 'Delete link between transactions',
|
'delete_tag' => 'Delete tag ":tag"',
|
||||||
|
'delete_journal_link' => 'Delete link between transactions',
|
||||||
];
|
];
|
||||||
|
@ -1148,7 +1148,7 @@ return [
|
|||||||
'deleted_piggy_bank' => 'Deleted piggy bank ":name"',
|
'deleted_piggy_bank' => 'Deleted piggy bank ":name"',
|
||||||
'added_amount_to_piggy' => 'Added :amount to ":name"',
|
'added_amount_to_piggy' => 'Added :amount to ":name"',
|
||||||
'removed_amount_from_piggy' => 'Removed :amount from ":name"',
|
'removed_amount_from_piggy' => 'Removed :amount from ":name"',
|
||||||
'piggy_events' => 'Related piggy banks',
|
'piggy_events' => 'Related piggy banks',
|
||||||
|
|
||||||
// tags
|
// tags
|
||||||
'delete_tag' => 'Delete tag ":tag"',
|
'delete_tag' => 'Delete tag ":tag"',
|
||||||
@ -1158,49 +1158,57 @@ return [
|
|||||||
'updated_tag' => 'Updated tag ":tag"',
|
'updated_tag' => 'Updated tag ":tag"',
|
||||||
'created_tag' => 'Tag ":tag" has been created!',
|
'created_tag' => 'Tag ":tag" has been created!',
|
||||||
|
|
||||||
'transaction_journal_information' => 'Transaction information',
|
'transaction_journal_information' => 'Transaction information',
|
||||||
'transaction_journal_meta' => 'Meta information',
|
'transaction_journal_meta' => 'Meta information',
|
||||||
'transaction_journal_more' => 'More information',
|
'transaction_journal_more' => 'More information',
|
||||||
'att_part_of_journal' => 'Stored under ":journal"',
|
'att_part_of_journal' => 'Stored under ":journal"',
|
||||||
'total_amount' => 'Total amount',
|
'total_amount' => 'Total amount',
|
||||||
'number_of_decimals' => 'Number of decimals',
|
'number_of_decimals' => 'Number of decimals',
|
||||||
|
|
||||||
// administration
|
// administration
|
||||||
'administration' => 'Administration',
|
'administration' => 'Administration',
|
||||||
'user_administration' => 'User administration',
|
'user_administration' => 'User administration',
|
||||||
'list_all_users' => 'All users',
|
'list_all_users' => 'All users',
|
||||||
'all_users' => 'All users',
|
'all_users' => 'All users',
|
||||||
'instance_configuration' => 'Configuration',
|
'instance_configuration' => 'Configuration',
|
||||||
'firefly_instance_configuration' => 'Configuration options for Firefly III',
|
'firefly_instance_configuration' => 'Configuration options for Firefly III',
|
||||||
'setting_single_user_mode' => 'Single user mode',
|
'setting_single_user_mode' => 'Single user mode',
|
||||||
'setting_single_user_mode_explain' => 'By default, Firefly III only accepts one (1) registration: you. This is a security measure, preventing others from using your instance unless you allow them to. Future registrations are blocked. When you uncheck this box, others can use your instance as well, assuming they can reach it (when it is connected to the internet).',
|
'setting_single_user_mode_explain' => 'By default, Firefly III only accepts one (1) registration: you. This is a security measure, preventing others from using your instance unless you allow them to. Future registrations are blocked. When you uncheck this box, others can use your instance as well, assuming they can reach it (when it is connected to the internet).',
|
||||||
'store_configuration' => 'Store configuration',
|
'store_configuration' => 'Store configuration',
|
||||||
'single_user_administration' => 'User administration for :email',
|
'single_user_administration' => 'User administration for :email',
|
||||||
'edit_user' => 'Edit user :email',
|
'edit_user' => 'Edit user :email',
|
||||||
'hidden_fields_preferences' => 'Not all fields are visible right now. You must enable them in your <a href=":link">settings</a>.',
|
'hidden_fields_preferences' => 'You can enable more transaction options in your <a href=":link">settings</a>.',
|
||||||
'user_data_information' => 'User data',
|
'user_data_information' => 'User data',
|
||||||
'user_information' => 'User information',
|
'user_information' => 'User information',
|
||||||
'total_size' => 'total size',
|
'total_size' => 'total size',
|
||||||
'budget_or_budgets' => 'budget(s)',
|
'budget_or_budgets' => 'budget(s)',
|
||||||
'budgets_with_limits' => 'budget(s) with configured amount',
|
'budgets_with_limits' => 'budget(s) with configured amount',
|
||||||
'nr_of_rules_in_total_groups' => ':count_rules rule(s) in :count_groups rule group(s)',
|
'nr_of_rules_in_total_groups' => ':count_rules rule(s) in :count_groups rule group(s)',
|
||||||
'tag_or_tags' => 'tag(s)',
|
'tag_or_tags' => 'tag(s)',
|
||||||
'configuration_updated' => 'The configuration has been updated',
|
'configuration_updated' => 'The configuration has been updated',
|
||||||
'setting_is_demo_site' => 'Demo site',
|
'setting_is_demo_site' => 'Demo site',
|
||||||
'setting_is_demo_site_explain' => 'If you check this box, this installation will behave as if it is the demo site, which can have weird side effects.',
|
'setting_is_demo_site_explain' => 'If you check this box, this installation will behave as if it is the demo site, which can have weird side effects.',
|
||||||
'block_code_bounced' => 'Email message(s) bounced',
|
'block_code_bounced' => 'Email message(s) bounced',
|
||||||
'block_code_expired' => 'Demo account expired',
|
'block_code_expired' => 'Demo account expired',
|
||||||
'no_block_code' => 'No reason for block or user not blocked',
|
'no_block_code' => 'No reason for block or user not blocked',
|
||||||
'block_code_email_changed' => 'User has not yet confirmed new email address',
|
'block_code_email_changed' => 'User has not yet confirmed new email address',
|
||||||
'admin_update_email' => 'Contrary to the profile page, the user will NOT be notified their email address has changed!',
|
'admin_update_email' => 'Contrary to the profile page, the user will NOT be notified their email address has changed!',
|
||||||
'update_user' => 'Update user',
|
'update_user' => 'Update user',
|
||||||
'updated_user' => 'User data has been changed.',
|
'updated_user' => 'User data has been changed.',
|
||||||
'delete_user' => 'Delete user :email',
|
'delete_user' => 'Delete user :email',
|
||||||
'user_deleted' => 'The user has been deleted',
|
'user_deleted' => 'The user has been deleted',
|
||||||
'send_test_email' => 'Send test email message',
|
'send_test_email' => 'Send test email message',
|
||||||
'send_test_email_text' => 'To see if your installation is capable of sending email, please press this button. You will not see an error here (if any), <strong>the log files will reflect any errors</strong>. You can press this button as many times as you like. There is no spam control. The message will be sent to <code>:email</code> and should arrive shortly.',
|
'send_test_email_text' => 'To see if your installation is capable of sending email, please press this button. You will not see an error here (if any), <strong>the log files will reflect any errors</strong>. You can press this button as many times as you like. There is no spam control. The message will be sent to <code>:email</code> and should arrive shortly.',
|
||||||
'send_message' => 'Send message',
|
'send_message' => 'Send message',
|
||||||
'send_test_triggered' => 'Test was triggered. Check your inbox and the log files.',
|
'send_test_triggered' => 'Test was triggered. Check your inbox and the log files.',
|
||||||
|
|
||||||
|
'split_transaction_title' => 'Description of the split transaction',
|
||||||
|
'split_title_help' => 'If you create a split transaction, there must be a global description for all splits of the transaction.',
|
||||||
|
'transaction_information' => 'Transaction information',
|
||||||
|
'you_create_transfer' => 'You\'re creating a <strong>transfer</strong>.',
|
||||||
|
'you_create_withdrawal' => 'You\'re creating a <strong>withdrawal</strong>.',
|
||||||
|
'you_create_deposit' => 'You\'re creating a <strong>deposit</strong>.',
|
||||||
|
|
||||||
|
|
||||||
// links
|
// links
|
||||||
'journal_link_configuration' => 'Transaction links configuration',
|
'journal_link_configuration' => 'Transaction links configuration',
|
||||||
|
@ -57,6 +57,7 @@ return [
|
|||||||
'asset_source_account' => 'Source account',
|
'asset_source_account' => 'Source account',
|
||||||
'journal_description' => 'Description',
|
'journal_description' => 'Description',
|
||||||
'note' => 'Notes',
|
'note' => 'Notes',
|
||||||
|
'store_new_transaction' => 'Store new transaction',
|
||||||
'split_journal' => 'Split this transaction',
|
'split_journal' => 'Split this transaction',
|
||||||
'split_journal_explanation' => 'Split this transaction in multiple parts',
|
'split_journal_explanation' => 'Split this transaction in multiple parts',
|
||||||
'currency' => 'Currency',
|
'currency' => 'Currency',
|
||||||
|
@ -31,18 +31,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if type == 'create' and name == 'transaction' %}
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="{{ name }}_split" class="col-sm-4 control-label">
|
|
||||||
{{ trans('form.split_journal') }}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<div class="checkbox"><label>
|
|
||||||
{{ Form.checkbox('split_journal', '1', old('split_journal') == '1', {'id': name ~ 'split'}) }}
|
|
||||||
{{ trans('form.split_journal_explanation') }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
@ -193,8 +193,8 @@
|
|||||||
{% if not shownDemo %}
|
{% if not shownDemo %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var routeForTour = "{{ current_route_name }}";
|
var routeForTour = "{{ current_route_name }}";
|
||||||
var routeStepsUri = "{{ route('json.intro', [current_route_name, what|default("")]) }}";
|
var routeStepsUri = "{{ route('json.intro', [current_route_name, objectType|default("")]) }}";
|
||||||
var routeForFinishedTour = "{{ route('json.intro.finished', [current_route_name, what|default("")]) }}";
|
var routeForFinishedTour = "{{ route('json.intro.finished', [current_route_name, objectType|default("")]) }}";
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="v1/lib/intro/intro.min.js?v={{ FF_VERSION }}"></script>
|
<script type="text/javascript" src="v1/lib/intro/intro.min.js?v={{ FF_VERSION }}"></script>
|
||||||
<script type="text/javascript" src="v1/js/ff/intro/intro.js?v={{ FF_VERSION }}"></script>
|
<script type="text/javascript" src="v1/js/ff/intro/intro.js?v={{ FF_VERSION }}"></script>
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>X</th>
|
<th>
|
||||||
|
{{ groups.render }}
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
@ -12,22 +12,22 @@
|
|||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<ul class="treeview-menu">
|
<ul class="treeview-menu">
|
||||||
<li class="{{ activeRoutePartialWhat('accounts', 'asset') }}">
|
<li class="{{ activeRoutePartialObjectType('accounts', 'asset') }}">
|
||||||
<a href="{{ route('accounts.index','asset') }}">
|
<a href="{{ route('accounts.index','asset') }}">
|
||||||
<i class="fa fa-money fa-fw"></i> {{ 'asset_accounts'|_ }}
|
<i class="fa fa-money fa-fw"></i> {{ 'asset_accounts'|_ }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="{{ activeRoutePartialWhat('accounts', 'expense') }}">
|
<li class="{{ activeRoutePartialObjectType('accounts', 'expense') }}">
|
||||||
<a href="{{ route('accounts.index','expense') }}">
|
<a href="{{ route('accounts.index','expense') }}">
|
||||||
<i class="fa fa-shopping-cart fa-fw"></i> {{ 'expense_accounts'|_ }}
|
<i class="fa fa-shopping-cart fa-fw"></i> {{ 'expense_accounts'|_ }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="{{ activeRoutePartialWhat('accounts', 'revenue') }}">
|
<li class="{{ activeRoutePartialObjectType('accounts', 'revenue') }}">
|
||||||
<a href="{{ route('accounts.index','revenue') }}">
|
<a href="{{ route('accounts.index','revenue') }}">
|
||||||
<i class="fa fa-download fa-fw"></i> {{ 'revenue_accounts'|_ }}
|
<i class="fa fa-download fa-fw"></i> {{ 'revenue_accounts'|_ }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="{{ activeRoutePartialWhat('accounts', 'liabilities') }}">
|
<li class="{{ activeRoutePartialObjectType('accounts', 'liabilities') }}">
|
||||||
<a href="{{ route('accounts.index','liabilities') }}">
|
<a href="{{ route('accounts.index','liabilities') }}">
|
||||||
<i class="fa fa-ticket fa-fw"></i> {{ 'liabilities_accounts'|_ }}
|
<i class="fa fa-ticket fa-fw"></i> {{ 'liabilities_accounts'|_ }}
|
||||||
</a>
|
</a>
|
||||||
@ -67,15 +67,15 @@
|
|||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<ul class="treeview-menu">
|
<ul class="treeview-menu">
|
||||||
<li class="{{ activeRoutePartialWhat('transactions','withdrawal') }}">
|
<li class="{{ activeRoutePartialObjectType('transactions','withdrawal') }}">
|
||||||
<a href="{{ route('transactions.index','withdrawal') }}">
|
<a href="{{ route('transactions.index','withdrawal') }}">
|
||||||
<i class="fa fa-long-arrow-left fa-fw"></i> {{ 'expenses'|_ }}</a>
|
<i class="fa fa-long-arrow-left fa-fw"></i> {{ 'expenses'|_ }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="{{ activeRoutePartialWhat('transactions','deposit') }}">
|
<li class="{{ activeRoutePartialObjectType('transactions','deposit') }}">
|
||||||
<a href="{{ route('transactions.index','deposit') }}"><i
|
<a href="{{ route('transactions.index','deposit') }}"><i
|
||||||
class="fa fa-long-arrow-right fa-fw"></i> {{ 'income'|_ }}</a>
|
class="fa fa-long-arrow-right fa-fw"></i> {{ 'income'|_ }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="{{ activeRoutePartialWhat('transactions','transfers') }}">
|
<li class="{{ activeRoutePartialObjectType('transactions','transfers') }}">
|
||||||
<a href="{{ route('transactions.index','transfers') }}">
|
<a href="{{ route('transactions.index','transfers') }}">
|
||||||
<i class="fa fa-fw fa-exchange"></i> {{ 'transfers'|_ }}</a>
|
<i class="fa fa-fw fa-exchange"></i> {{ 'transfers'|_ }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
288
resources/views/v1/transactions/create.twig
Normal file
288
resources/views/v1/transactions/create.twig
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
{% extends "./layout/default" %}
|
||||||
|
|
||||||
|
{% block breadcrumbs %}
|
||||||
|
{{ Breadcrumbs.render(Route.getCurrentRoute.getName, objectType) }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<create-transaction></create-transaction>
|
||||||
|
|
||||||
|
|
||||||
|
{#
|
||||||
|
<form method="POST" action="{{ route('transactions.store') }}" accept-charset="UTF-8" class="form-horizontal" id="store" enctype="multipart/form-data">
|
||||||
|
<input name="_token" type="hidden" value="{{ csrf_token() }}">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">
|
||||||
|
{{ 'split_transaction_title'|_ }}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<input type="text" class="form-control" name="group_title"
|
||||||
|
title="{{ 'split_transaction_title'|_ }}" autocomplete="off" placeholder="{{ 'split_transaction_title'|_ }}">
|
||||||
|
<p class="help-block">
|
||||||
|
{{ 'split_title_help'|_ }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="transactions">
|
||||||
|
<div class="row transactionRow">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title splitTitle">
|
||||||
|
{{ 'transaction_information'|_ }}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<div class="form-group transactionTypeIndicatorBlock" style="display:none;">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<label class="control-label transactionTypeIndicator text-info"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" data-index="0" class="form-control indexField sourceAccountAC" name="source[]"
|
||||||
|
title="{{ trans('form.source_account') }}" autocomplete="off"
|
||||||
|
placeholder="{{ trans('form.source_account') }}">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-default clearSource" type="button"><i class="fa fa-trash-o"></i></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="input-group">
|
||||||
|
<input data-index="0" type="text" class="form-control indexField destinationAccountAC" name="destination[]"
|
||||||
|
title="{{ trans('form.destination_account') }}" autocomplete="off"
|
||||||
|
placeholder="{{ trans('form.destination_account') }}">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-default clearDestination" type="button"><i class="fa fa-trash-o"></i></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<input type="text" class="form-control" name="description[]"
|
||||||
|
title="{{ trans('form.description') }}" autocomplete="off" placeholder="{{ trans('form.description') }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<input type="date" class="form-control" name="date[]"
|
||||||
|
title="{{ trans('form.date') }}" value="{{ phpdate('Y-m-d') }}" autocomplete="off"
|
||||||
|
placeholder="{{ trans('form.date') }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">$</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="number" step="any" class="form-control" name="amount[]"
|
||||||
|
title="{{ trans('form.amount') }}" autocomplete="off" placeholder="{{ trans('form.amount') }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<select name="foreign_amount">
|
||||||
|
<option>none</option>
|
||||||
|
<option>USD</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="number" step="any" class="form-control" name="amount[]"
|
||||||
|
title="Foreign amount" autocomplete="off" placeholder="Foreign amount">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<select name="budget">
|
||||||
|
<option>budget</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<input type="text" class="form-control" name="category[]"
|
||||||
|
title="Category" autocomplete="off" placeholder="Category">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<input type="text" class="form-control" name="tags[]"
|
||||||
|
title="Tags" autocomplete="off" placeholder="Tags">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<select name="piggy">
|
||||||
|
<option>Piggy</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% if
|
||||||
|
optionalFields.interest_date or optionalFields.book_date or optionalFields.process_date
|
||||||
|
or optionalFields.due_date or optionalFields.payment_date
|
||||||
|
or optionalFields.invoice_date %}
|
||||||
|
{% for field in ['interest_date','book_date','process_date','due_date','payment_date','invoice_date'] %}
|
||||||
|
{% if optionalFields[field] %}
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<input type="text" class="form-control" name="{{ field }}[]"
|
||||||
|
title="{{ field }}" autocomplete="off" placeholder="{{ field }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if optionalFields.internal_reference or optionalFields.notes %}
|
||||||
|
|
||||||
|
{% if optionalFields.internal_reference %}
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<input type="text" class="form-control" name="internal_reference[]"
|
||||||
|
title="internal_reference" autocomplete="off" placeholder="internal_reference">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if optionalFields.notes %}
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<textarea></textarea>
|
||||||
|
<br>
|
||||||
|
{{ trans('firefly.field_supports_markdown')|raw }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if optionalFields.attachments %}
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
|
||||||
|
<input multiple="multiple" class="form-control"
|
||||||
|
autocomplete="off" placeholder="Attachments" name="attachments[]" type="file">
|
||||||
|
<p class="help-block">
|
||||||
|
{{ trans('firefly.upload_max_file_size', {'size': uploadSize|filesize}) }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if
|
||||||
|
not optionalFields.interest_date or
|
||||||
|
not optionalFields.book_date or
|
||||||
|
not optionalFields.process_date or
|
||||||
|
not optionalFields.due_date or
|
||||||
|
not optionalFields.payment_date or
|
||||||
|
not optionalFields.invoice_date or
|
||||||
|
not optionalFields.internal_reference or
|
||||||
|
not optionalFields.notes or
|
||||||
|
not optionalFields.attachments %}
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<p class="text-success"><i class="fa fa-info-circle"></i>
|
||||||
|
<em>{{ trans('firefly.hidden_fields_preferences', {link: route('preferences.index')})|raw }}</em></p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<p>
|
||||||
|
<button id="addSplitButton" class="btn btn-primary">Add another split</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{ 'options'|_ }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
{{ ExpandedForm.optionsList('create','transaction') }}
|
||||||
|
</div>
|
||||||
|
<div class="box-footer">
|
||||||
|
<button type="submit" class="transaction-btn btn btn-success pull-right">
|
||||||
|
{{ trans('form.store_new_transaction') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
#}
|
||||||
|
{% endblock %}
|
||||||
|
{% block scripts %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
var allowedOpposingTypes = {{ allowedOpposingTypes|json_encode|raw }};
|
||||||
|
var accountToTypes = {{ accountToTypes|json_encode|raw }};
|
||||||
|
var defaultCurrency = {{ defaultCurrency.toArray()|json_encode|raw }};
|
||||||
|
</script>
|
||||||
|
<!--
|
||||||
|
<script type="text/javascript">
|
||||||
|
var transactionType = 'none';
|
||||||
|
|
||||||
|
var accountToTypes = {{ accountToTypes|json_encode|raw }};
|
||||||
|
|
||||||
|
var creatingTypes = {
|
||||||
|
Transfer: "{{ 'you_create_transfer'|_ }}",
|
||||||
|
Withdrawal: "{{ 'you_create_withdrawal'|_ }}",
|
||||||
|
Deposit: "{{ 'you_create_deposit'|_ }}",
|
||||||
|
};
|
||||||
|
|
||||||
|
// options for source account selection.
|
||||||
|
var sourceAccount = null;
|
||||||
|
var sourceAllowedAccountTypes = [];
|
||||||
|
|
||||||
|
// options for destination account selection.
|
||||||
|
var destinationAccount = null;
|
||||||
|
var destAllowedAccountTypes = [];
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="v1/js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>
|
||||||
|
<script type="text/javascript" src="v1/js/lib/jquery.autocomplete.min.js?v={{ FF_VERSION }}"></script>
|
||||||
|
<script type="text/javascript" src="v1/js/ff/transactions/create.js?v={{ FF_VERSION }}"></script>
|
||||||
|
-->
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block styles %}
|
||||||
|
{% endblock %}
|
@ -31,7 +31,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{# actual list #}
|
{# actual list #}
|
||||||
{% include 'list.transactions' %}
|
{% include 'list.groups' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
{# links for other views #}
|
{# links for other views #}
|
||||||
|
@ -1022,9 +1022,9 @@ try {
|
|||||||
|
|
||||||
Breadcrumbs::register(
|
Breadcrumbs::register(
|
||||||
'transactions.create',
|
'transactions.create',
|
||||||
function (BreadcrumbsGenerator $breadcrumbs, string $what) {
|
function (BreadcrumbsGenerator $breadcrumbs, string $objectType) {
|
||||||
$breadcrumbs->parent('transactions.index', $what);
|
$breadcrumbs->parent('transactions.index', $objectType);
|
||||||
$breadcrumbs->push(trans('breadcrumbs.create_' . e($what)), route('transactions.create', [$what]));
|
$breadcrumbs->push(trans('breadcrumbs.create_new_transaction'), route('transactions.create', [$objectType]));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -546,14 +546,20 @@ Route::group(
|
|||||||
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'json', 'as' => 'json.'], function () {
|
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'json', 'as' => 'json.'], function () {
|
||||||
|
|
||||||
// for auto complete
|
// for auto complete
|
||||||
|
Route::get('accounts', ['uses' => 'Json\AutoCompleteController@accounts', 'as' => 'autocomplete.accounts']);
|
||||||
|
Route::get('currencies', ['uses' => 'Json\AutoCompleteController@currencies', 'as' => 'autocomplete.currencies']);
|
||||||
|
Route::get('budgets', ['uses' => 'Json\AutoCompleteController@budgets', 'as' => 'autocomplete.budgets']);
|
||||||
|
Route::get('categories', ['uses' => 'Json\AutoCompleteController@categories', 'as' => 'autocomplete.categories']);
|
||||||
|
Route::get('piggy-banks', ['uses' => 'Json\AutoCompleteController@piggyBanks', 'as' => 'autocomplete.piggy-banks']);
|
||||||
|
Route::get('tags', ['uses' => 'Json\AutoCompleteController@tags', 'as' => 'autocomplete.tags']);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO improve 3 routes:
|
// TODO improve 3 routes:
|
||||||
Route::get('transaction-journals/all', ['uses' => 'Json\AutoCompleteController@allTransactionJournals', 'as' => 'all-transaction-journals']);
|
//Route::get('transaction-journals/all', ['uses' => 'Json\AutoCompleteController@allTransactionJournals', 'as' => 'all-transaction-journals']);
|
||||||
Route::get('transaction-journals/with-id/{tj}', ['uses' => 'Json\AutoCompleteController@journalsWithId', 'as' => 'journals-with-id']);
|
//Route::get('transaction-journals/with-id/{tj}', ['uses' => 'Json\AutoCompleteController@journalsWithId', 'as' => 'journals-with-id']);
|
||||||
Route::get('transaction-journals/{what}', ['uses' => 'Json\AutoCompleteController@transactionJournals', 'as' => 'transaction-journals']);
|
//Route::get('transaction-journals/{what}', ['uses' => 'Json\AutoCompleteController@transactionJournals', 'as' => 'transaction-journals']);
|
||||||
// TODO end of improvement
|
// TODO end of improvement
|
||||||
|
|
||||||
Route::get('transaction-types', ['uses' => 'Json\AutoCompleteController@transactionTypes', 'as' => 'transaction-types']);
|
Route::get('transaction-types', ['uses' => 'Json\AutoCompleteController@transactionTypes', 'as' => 'transaction-types']);
|
||||||
|
|
||||||
// boxes
|
// boxes
|
||||||
@ -577,7 +583,7 @@ Route::group(
|
|||||||
Route::post('intro/enable/{route}/{specificPage?}', ['uses' => 'Json\IntroController@postEnable', 'as' => 'intro.enable']);
|
Route::post('intro/enable/{route}/{specificPage?}', ['uses' => 'Json\IntroController@postEnable', 'as' => 'intro.enable']);
|
||||||
Route::get('intro/{route}/{specificPage?}', ['uses' => 'Json\IntroController@getIntroSteps', 'as' => 'intro']);
|
Route::get('intro/{route}/{specificPage?}', ['uses' => 'Json\IntroController@getIntroSteps', 'as' => 'intro']);
|
||||||
|
|
||||||
Route::get('/{subject}', ['uses' => 'Json\AutoCompleteController@autoComplete', 'as' => 'autocomplete']);
|
//Route::get('/{subject}', ['uses' => 'Json\AutoCompleteController@autoComplete', 'as' => 'autocomplete']);
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -873,11 +879,13 @@ Route::group(
|
|||||||
Route::group(
|
Route::group(
|
||||||
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'transactions', 'as' => 'transactions.'], function () {
|
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'transactions', 'as' => 'transactions.'], function () {
|
||||||
|
|
||||||
|
// show groups:
|
||||||
Route::get('{what}/{start_date?}/{end_date?}', ['uses' => 'Transaction\IndexController@index', 'as' => 'index'])->where(
|
Route::get('{what}/{start_date?}/{end_date?}', ['uses' => 'Transaction\IndexController@index', 'as' => 'index'])->where(
|
||||||
['what' => 'withdrawal|deposit|transfers|transfer']
|
['what' => 'withdrawal|deposit|transfers|transfer']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// create group:
|
||||||
|
Route::get('create/{objectType}', ['uses' => 'Transaction\CreateController@create', 'as' => 'create'])->where(['objectType' => 'withdrawal|deposit|transfer']);
|
||||||
|
|
||||||
|
|
||||||
// TODO improve these routes
|
// TODO improve these routes
|
||||||
@ -903,7 +911,7 @@ Route::group(
|
|||||||
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers\Transaction', 'prefix' => 'transactions', 'as' => 'transactions.'],
|
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers\Transaction', 'prefix' => 'transactions', 'as' => 'transactions.'],
|
||||||
function () {
|
function () {
|
||||||
// TODO improve these routes
|
// TODO improve these routes
|
||||||
Route::get('create/{what}', ['uses' => 'SingleController@create', 'as' => 'create'])->where(['what' => 'withdrawal|deposit|transfer']);
|
|
||||||
Route::get('edit/{tj}', ['uses' => 'SingleController@edit', 'as' => 'edit']);
|
Route::get('edit/{tj}', ['uses' => 'SingleController@edit', 'as' => 'edit']);
|
||||||
Route::get('delete/{tj}', ['uses' => 'SingleController@delete', 'as' => 'delete']);
|
Route::get('delete/{tj}', ['uses' => 'SingleController@delete', 'as' => 'delete']);
|
||||||
Route::post('store', ['uses' => 'SingleController@store', 'as' => 'store'])->where(['what' => 'withdrawal|deposit|transfer']);
|
Route::post('store', ['uses' => 'SingleController@store', 'as' => 'store'])->where(['what' => 'withdrawal|deposit|transfer']);
|
||||||
|
2
webpack.mix.js
vendored
2
webpack.mix.js
vendored
@ -11,4 +11,4 @@ let mix = require('laravel-mix');
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mix.js('resources/assets/js/app.js', 'public/v1/js');
|
mix.js('resources/assets/js/app.js', 'public/v1/js');
|
24
yarn.lock
24
yarn.lock
@ -2,6 +2,13 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@johmun/vue-tags-input@^2.0.1":
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@johmun/vue-tags-input/-/vue-tags-input-2.0.1.tgz#5ca22a573858c8df6c05788e3ffabe92e1baa1df"
|
||||||
|
integrity sha512-1LUsINr6iBROfG31C05qf+XpoM4jLstpLzTmfu+57fxErgP2gGnVB41oz1qVxjKe1gdpOaAZSByhoAm2h0cO3w==
|
||||||
|
dependencies:
|
||||||
|
vue "^2.5.16"
|
||||||
|
|
||||||
"@types/q@^1.5.1":
|
"@types/q@^1.5.1":
|
||||||
version "1.5.1"
|
version "1.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18"
|
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18"
|
||||||
@ -7974,6 +7981,13 @@ uglifyjs-webpack-plugin@^1.0.0:
|
|||||||
webpack-sources "^1.1.0"
|
webpack-sources "^1.1.0"
|
||||||
worker-farm "^1.5.2"
|
worker-farm "^1.5.2"
|
||||||
|
|
||||||
|
uiv@^0.31.5:
|
||||||
|
version "0.31.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/uiv/-/uiv-0.31.5.tgz#bfb87833b9abb59d8f0bb4f630943449b053b733"
|
||||||
|
integrity sha512-VcizUxkJCr4XhnFJ3KWCuiVaDvU3H5yDLX4F1yhrmK5hz+2+OIuCShJd6Is366oJdJagoh42sjWQqZL74uMEmw==
|
||||||
|
dependencies:
|
||||||
|
vue-functional-data-merge "^2.0.3"
|
||||||
|
|
||||||
unbzip2-stream@^1.0.9:
|
unbzip2-stream@^1.0.9:
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz#7854da51622a7e63624221196357803b552966a1"
|
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz#7854da51622a7e63624221196357803b552966a1"
|
||||||
@ -8252,6 +8266,11 @@ vm-browserify@0.0.4:
|
|||||||
dependencies:
|
dependencies:
|
||||||
indexof "0.0.1"
|
indexof "0.0.1"
|
||||||
|
|
||||||
|
vue-functional-data-merge@^2.0.3:
|
||||||
|
version "2.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-functional-data-merge/-/vue-functional-data-merge-2.0.7.tgz#bdee655181eacdcb1f96ce95a4cc14e75313d1da"
|
||||||
|
integrity sha512-pvLc+H+x2prwBj/uSEIITyxjz/7ZUVVK8uYbrYMmhDvMXnzh9OvQvVEwcOSBQjsubd4Eq41/CSJaWzy4hemMNQ==
|
||||||
|
|
||||||
vue-hot-reload-api@^2.2.0:
|
vue-hot-reload-api@^2.2.0:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.1.tgz#b2d3d95402a811602380783ea4f566eb875569a2"
|
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.1.tgz#b2d3d95402a811602380783ea4f566eb875569a2"
|
||||||
@ -8297,6 +8316,11 @@ vue-template-es2015-compiler@^1.6.0:
|
|||||||
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18"
|
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18"
|
||||||
integrity sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg==
|
integrity sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg==
|
||||||
|
|
||||||
|
vue@^2.5.16:
|
||||||
|
version "2.6.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637"
|
||||||
|
integrity sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==
|
||||||
|
|
||||||
vue@^2.5.7:
|
vue@^2.5.7:
|
||||||
version "2.5.21"
|
version "2.5.21"
|
||||||
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.21.tgz#3d33dcd03bb813912ce894a8303ab553699c4a85"
|
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.21.tgz#3d33dcd03bb813912ce894a8303ab553699c4a85"
|
||||||
|
Loading…
Reference in New Issue
Block a user