mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-20 11:48: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
|
||||
|
||||
echo "Run various artisan commands..."
|
||||
. $FIREFLY_PATH/.env
|
||||
#. $FIREFLY_PATH/.env
|
||||
if [[ -z "$DB_PORT" ]]; then
|
||||
if [[ $DB_CONNECTION == "pgsql" ]]; then
|
||||
DB_PORT=5432
|
||||
|
@ -519,22 +519,22 @@ return [
|
||||
],
|
||||
|
||||
|
||||
'test-triggers' => [
|
||||
'test-triggers' => [
|
||||
'limit' => 10,
|
||||
'range' => 200,
|
||||
],
|
||||
'default_currency' => 'EUR',
|
||||
'default_language' => 'en_US',
|
||||
'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'],
|
||||
'default_currency' => 'EUR',
|
||||
'default_language' => 'en_US',
|
||||
'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'],
|
||||
// tag notes has_attachments
|
||||
'cer_providers' => [
|
||||
'cer_providers' => [
|
||||
'fixer' => FixerIOv2::class,
|
||||
'ratesapi' => RatesApiIOv1::class,
|
||||
],
|
||||
|
||||
// expected source types for each transaction type, in order of preference.
|
||||
'expected_source_types' => [
|
||||
'expected_source_types' => [
|
||||
'source' => [
|
||||
TransactionTypeModel::WITHDRAWAL => [AccountType::ASSET, 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,
|
||||
AccountType::MORTGAGE],
|
||||
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' => [
|
||||
TransactionTypeModel::WITHDRAWAL => [AccountType::EXPENSE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT,
|
||||
@ -554,9 +563,130 @@ return [
|
||||
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.
|
||||
'source_dests' => [
|
||||
'source_dests' => [
|
||||
TransactionTypeModel::WITHDRAWAL => [
|
||||
AccountType::ASSET => [AccountType::EXPENSE, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE, AccountType::CASH],
|
||||
AccountType::LOAN => [AccountType::EXPENSE],
|
||||
|
@ -13,12 +13,14 @@
|
||||
"axios": "^0.17",
|
||||
"bootstrap-sass": "^3.3.7",
|
||||
"cross-env": "^5.1",
|
||||
"jquery": "^3.1.1",
|
||||
"laravel-mix": "^1.0",
|
||||
"lodash": "^4.17.4",
|
||||
"vue": "^2.5.7"
|
||||
},
|
||||
"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",
|
||||
"/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"
|
||||
}
|
||||
"/v1/js/app.js": "/v1/js/app.js"
|
||||
}
|
2
public/v1/css/app.css
Normal file
2
public/v1/css/app.css
Normal file
@ -0,0 +1,2 @@
|
||||
/* TODO REMOVE ME */
|
||||
|
@ -18,6 +18,14 @@
|
||||
* 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 {
|
||||
width: 40%;
|
||||
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 {
|
||||
border-color: #98cbe8;
|
||||
outline: 0;
|
||||
|
53455
public/v1/js/app.js
53455
public/v1/js/app.js
File diff suppressed because one or more lines are too long
225
public/v1/js/ff/transactions/create.js
Normal file
225
public/v1/js/ff/transactions/create.js
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
@ -3,10 +3,26 @@
|
||||
* includes Vue and other libraries. It is a great starting point when
|
||||
* building robust, powerful web applications using Vue and Laravel.
|
||||
*/
|
||||
/* TODO REMOVE ME */
|
||||
|
||||
require('./bootstrap');
|
||||
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.
|
||||
@ -14,6 +30,7 @@ window.Vue = require('vue');
|
||||
Vue.component('passport-clients', require('./components/passport/Clients.vue'));
|
||||
Vue.component('passport-authorized-clients', require('./components/passport/AuthorizedClients.vue'));
|
||||
Vue.component('passport-personal-access-tokens', require('./components/passport/PersonalAccessTokens.vue'));
|
||||
Vue.component('create-transaction', require('./components/transactions/CreateTransaction'));
|
||||
|
||||
|
||||
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);
|
||||
|
||||
return [
|
||||
'home' => 'Home',
|
||||
'edit_currency' => 'Edit currency ":name"',
|
||||
'delete_currency' => 'Delete currency ":name"',
|
||||
'newPiggyBank' => 'Create a new piggy bank',
|
||||
'edit_piggyBank' => 'Edit piggy bank ":name"',
|
||||
'preferences' => 'Preferences',
|
||||
'profile' => 'Profile',
|
||||
'changePassword' => 'Change your password',
|
||||
'change_email' => 'Change your email address',
|
||||
'bills' => 'Bills',
|
||||
'newBill' => 'New bill',
|
||||
'edit_bill' => 'Edit bill ":name"',
|
||||
'delete_bill' => 'Delete bill ":name"',
|
||||
'reports' => 'Reports',
|
||||
'search_result' => 'Search results for ":query"',
|
||||
'withdrawal_list' => 'Expenses',
|
||||
'deposit_list' => 'Revenue, income and deposits',
|
||||
'transfer_list' => 'Transfers',
|
||||
'transfers_list' => 'Transfers',
|
||||
'reconciliation_list' => 'Reconciliations',
|
||||
'create_withdrawal' => 'Create new withdrawal',
|
||||
'create_deposit' => 'Create new deposit',
|
||||
'create_transfer' => 'Create new transfer',
|
||||
'edit_journal' => 'Edit transaction ":description"',
|
||||
'edit_reconciliation' => 'Edit ":description"',
|
||||
'delete_journal' => 'Delete transaction ":description"',
|
||||
'tags' => 'Tags',
|
||||
'createTag' => 'Create new tag',
|
||||
'edit_tag' => 'Edit tag ":tag"',
|
||||
'delete_tag' => 'Delete tag ":tag"',
|
||||
'delete_journal_link' => 'Delete link between transactions',
|
||||
'home' => 'Home',
|
||||
'edit_currency' => 'Edit currency ":name"',
|
||||
'delete_currency' => 'Delete currency ":name"',
|
||||
'newPiggyBank' => 'Create a new piggy bank',
|
||||
'edit_piggyBank' => 'Edit piggy bank ":name"',
|
||||
'preferences' => 'Preferences',
|
||||
'profile' => 'Profile',
|
||||
'changePassword' => 'Change your password',
|
||||
'change_email' => 'Change your email address',
|
||||
'bills' => 'Bills',
|
||||
'newBill' => 'New bill',
|
||||
'edit_bill' => 'Edit bill ":name"',
|
||||
'delete_bill' => 'Delete bill ":name"',
|
||||
'reports' => 'Reports',
|
||||
'search_result' => 'Search results for ":query"',
|
||||
'withdrawal_list' => 'Expenses',
|
||||
'deposit_list' => 'Revenue, income and deposits',
|
||||
'transfer_list' => 'Transfers',
|
||||
'transfers_list' => 'Transfers',
|
||||
'reconciliation_list' => 'Reconciliations',
|
||||
'create_withdrawal' => 'Create new withdrawal',
|
||||
'create_deposit' => 'Create new deposit',
|
||||
'create_transfer' => 'Create new transfer',
|
||||
'create_new_transaction' => 'Create a new transaction',
|
||||
'edit_journal' => 'Edit transaction ":description"',
|
||||
'edit_reconciliation' => 'Edit ":description"',
|
||||
'delete_journal' => 'Delete transaction ":description"',
|
||||
'tags' => 'Tags',
|
||||
'createTag' => 'Create new tag',
|
||||
'edit_tag' => 'Edit tag ":tag"',
|
||||
'delete_tag' => 'Delete tag ":tag"',
|
||||
'delete_journal_link' => 'Delete link between transactions',
|
||||
];
|
||||
|
@ -1148,7 +1148,7 @@ return [
|
||||
'deleted_piggy_bank' => 'Deleted piggy bank ":name"',
|
||||
'added_amount_to_piggy' => 'Added :amount to ":name"',
|
||||
'removed_amount_from_piggy' => 'Removed :amount from ":name"',
|
||||
'piggy_events' => 'Related piggy banks',
|
||||
'piggy_events' => 'Related piggy banks',
|
||||
|
||||
// tags
|
||||
'delete_tag' => 'Delete tag ":tag"',
|
||||
@ -1158,49 +1158,57 @@ return [
|
||||
'updated_tag' => 'Updated tag ":tag"',
|
||||
'created_tag' => 'Tag ":tag" has been created!',
|
||||
|
||||
'transaction_journal_information' => 'Transaction information',
|
||||
'transaction_journal_meta' => 'Meta information',
|
||||
'transaction_journal_more' => 'More information',
|
||||
'att_part_of_journal' => 'Stored under ":journal"',
|
||||
'total_amount' => 'Total amount',
|
||||
'number_of_decimals' => 'Number of decimals',
|
||||
'transaction_journal_information' => 'Transaction information',
|
||||
'transaction_journal_meta' => 'Meta information',
|
||||
'transaction_journal_more' => 'More information',
|
||||
'att_part_of_journal' => 'Stored under ":journal"',
|
||||
'total_amount' => 'Total amount',
|
||||
'number_of_decimals' => 'Number of decimals',
|
||||
|
||||
// administration
|
||||
'administration' => 'Administration',
|
||||
'user_administration' => 'User administration',
|
||||
'list_all_users' => 'All users',
|
||||
'all_users' => 'All users',
|
||||
'instance_configuration' => 'Configuration',
|
||||
'firefly_instance_configuration' => 'Configuration options for Firefly III',
|
||||
'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).',
|
||||
'store_configuration' => 'Store configuration',
|
||||
'single_user_administration' => 'User administration for :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>.',
|
||||
'user_data_information' => 'User data',
|
||||
'user_information' => 'User information',
|
||||
'total_size' => 'total size',
|
||||
'budget_or_budgets' => 'budget(s)',
|
||||
'budgets_with_limits' => 'budget(s) with configured amount',
|
||||
'nr_of_rules_in_total_groups' => ':count_rules rule(s) in :count_groups rule group(s)',
|
||||
'tag_or_tags' => 'tag(s)',
|
||||
'configuration_updated' => 'The configuration has been updated',
|
||||
'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.',
|
||||
'block_code_bounced' => 'Email message(s) bounced',
|
||||
'block_code_expired' => 'Demo account expired',
|
||||
'no_block_code' => 'No reason for block or user not blocked',
|
||||
'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!',
|
||||
'update_user' => 'Update user',
|
||||
'updated_user' => 'User data has been changed.',
|
||||
'delete_user' => 'Delete user :email',
|
||||
'user_deleted' => 'The user has been deleted',
|
||||
'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_message' => 'Send message',
|
||||
'send_test_triggered' => 'Test was triggered. Check your inbox and the log files.',
|
||||
'administration' => 'Administration',
|
||||
'user_administration' => 'User administration',
|
||||
'list_all_users' => 'All users',
|
||||
'all_users' => 'All users',
|
||||
'instance_configuration' => 'Configuration',
|
||||
'firefly_instance_configuration' => 'Configuration options for Firefly III',
|
||||
'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).',
|
||||
'store_configuration' => 'Store configuration',
|
||||
'single_user_administration' => 'User administration for :email',
|
||||
'edit_user' => 'Edit user :email',
|
||||
'hidden_fields_preferences' => 'You can enable more transaction options in your <a href=":link">settings</a>.',
|
||||
'user_data_information' => 'User data',
|
||||
'user_information' => 'User information',
|
||||
'total_size' => 'total size',
|
||||
'budget_or_budgets' => 'budget(s)',
|
||||
'budgets_with_limits' => 'budget(s) with configured amount',
|
||||
'nr_of_rules_in_total_groups' => ':count_rules rule(s) in :count_groups rule group(s)',
|
||||
'tag_or_tags' => 'tag(s)',
|
||||
'configuration_updated' => 'The configuration has been updated',
|
||||
'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.',
|
||||
'block_code_bounced' => 'Email message(s) bounced',
|
||||
'block_code_expired' => 'Demo account expired',
|
||||
'no_block_code' => 'No reason for block or user not blocked',
|
||||
'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!',
|
||||
'update_user' => 'Update user',
|
||||
'updated_user' => 'User data has been changed.',
|
||||
'delete_user' => 'Delete user :email',
|
||||
'user_deleted' => 'The user has been deleted',
|
||||
'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_message' => 'Send message',
|
||||
'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
|
||||
'journal_link_configuration' => 'Transaction links configuration',
|
||||
|
@ -57,6 +57,7 @@ return [
|
||||
'asset_source_account' => 'Source account',
|
||||
'journal_description' => 'Description',
|
||||
'note' => 'Notes',
|
||||
'store_new_transaction' => 'Store new transaction',
|
||||
'split_journal' => 'Split this transaction',
|
||||
'split_journal_explanation' => 'Split this transaction in multiple parts',
|
||||
'currency' => 'Currency',
|
||||
|
@ -31,18 +31,4 @@
|
||||
</div>
|
||||
</div>
|
||||
{% 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 %}
|
||||
<script type="text/javascript">
|
||||
var routeForTour = "{{ current_route_name }}";
|
||||
var routeStepsUri = "{{ route('json.intro', [current_route_name, what|default("")]) }}";
|
||||
var routeForFinishedTour = "{{ route('json.intro.finished', [current_route_name, what|default("")]) }}";
|
||||
var routeStepsUri = "{{ route('json.intro', [current_route_name, objectType|default("")]) }}";
|
||||
var routeForFinishedTour = "{{ route('json.intro.finished', [current_route_name, objectType|default("")]) }}";
|
||||
</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>
|
||||
|
@ -1,7 +1,9 @@
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>X</th>
|
||||
<th>
|
||||
{{ groups.render }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
@ -12,22 +12,22 @@
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li class="{{ activeRoutePartialWhat('accounts', 'asset') }}">
|
||||
<li class="{{ activeRoutePartialObjectType('accounts', 'asset') }}">
|
||||
<a href="{{ route('accounts.index','asset') }}">
|
||||
<i class="fa fa-money fa-fw"></i> {{ 'asset_accounts'|_ }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="{{ activeRoutePartialWhat('accounts', 'expense') }}">
|
||||
<li class="{{ activeRoutePartialObjectType('accounts', 'expense') }}">
|
||||
<a href="{{ route('accounts.index','expense') }}">
|
||||
<i class="fa fa-shopping-cart fa-fw"></i> {{ 'expense_accounts'|_ }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="{{ activeRoutePartialWhat('accounts', 'revenue') }}">
|
||||
<li class="{{ activeRoutePartialObjectType('accounts', 'revenue') }}">
|
||||
<a href="{{ route('accounts.index','revenue') }}">
|
||||
<i class="fa fa-download fa-fw"></i> {{ 'revenue_accounts'|_ }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="{{ activeRoutePartialWhat('accounts', 'liabilities') }}">
|
||||
<li class="{{ activeRoutePartialObjectType('accounts', 'liabilities') }}">
|
||||
<a href="{{ route('accounts.index','liabilities') }}">
|
||||
<i class="fa fa-ticket fa-fw"></i> {{ 'liabilities_accounts'|_ }}
|
||||
</a>
|
||||
@ -67,15 +67,15 @@
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li class="{{ activeRoutePartialWhat('transactions','withdrawal') }}">
|
||||
<li class="{{ activeRoutePartialObjectType('transactions','withdrawal') }}">
|
||||
<a href="{{ route('transactions.index','withdrawal') }}">
|
||||
<i class="fa fa-long-arrow-left fa-fw"></i> {{ 'expenses'|_ }}</a>
|
||||
</li>
|
||||
<li class="{{ activeRoutePartialWhat('transactions','deposit') }}">
|
||||
<li class="{{ activeRoutePartialObjectType('transactions','deposit') }}">
|
||||
<a href="{{ route('transactions.index','deposit') }}"><i
|
||||
class="fa fa-long-arrow-right fa-fw"></i> {{ 'income'|_ }}</a>
|
||||
</li>
|
||||
<li class="{{ activeRoutePartialWhat('transactions','transfers') }}">
|
||||
<li class="{{ activeRoutePartialObjectType('transactions','transfers') }}">
|
||||
<a href="{{ route('transactions.index','transfers') }}">
|
||||
<i class="fa fa-fw fa-exchange"></i> {{ 'transfers'|_ }}</a>
|
||||
</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 %}
|
||||
</div>
|
||||
{# actual list #}
|
||||
{% include 'list.transactions' %}
|
||||
{% include 'list.groups' %}
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{# links for other views #}
|
||||
|
@ -1022,9 +1022,9 @@ try {
|
||||
|
||||
Breadcrumbs::register(
|
||||
'transactions.create',
|
||||
function (BreadcrumbsGenerator $breadcrumbs, string $what) {
|
||||
$breadcrumbs->parent('transactions.index', $what);
|
||||
$breadcrumbs->push(trans('breadcrumbs.create_' . e($what)), route('transactions.create', [$what]));
|
||||
function (BreadcrumbsGenerator $breadcrumbs, string $objectType) {
|
||||
$breadcrumbs->parent('transactions.index', $objectType);
|
||||
$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 () {
|
||||
|
||||
// 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:
|
||||
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/{what}', ['uses' => 'Json\AutoCompleteController@transactionJournals', 'as' => '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/{what}', ['uses' => 'Json\AutoCompleteController@transactionJournals', 'as' => 'transaction-journals']);
|
||||
// TODO end of improvement
|
||||
|
||||
Route::get('transaction-types', ['uses' => 'Json\AutoCompleteController@transactionTypes', 'as' => 'transaction-types']);
|
||||
|
||||
// boxes
|
||||
@ -577,7 +583,7 @@ Route::group(
|
||||
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('/{subject}', ['uses' => 'Json\AutoCompleteController@autoComplete', 'as' => 'autocomplete']);
|
||||
//Route::get('/{subject}', ['uses' => 'Json\AutoCompleteController@autoComplete', 'as' => 'autocomplete']);
|
||||
|
||||
}
|
||||
);
|
||||
@ -873,11 +879,13 @@ Route::group(
|
||||
Route::group(
|
||||
['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(
|
||||
['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
|
||||
@ -903,7 +911,7 @@ Route::group(
|
||||
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers\Transaction', 'prefix' => 'transactions', 'as' => 'transactions.'],
|
||||
function () {
|
||||
// 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('delete/{tj}', ['uses' => 'SingleController@delete', 'as' => 'delete']);
|
||||
Route::post('store', ['uses' => 'SingleController@store', 'as' => 'store'])->where(['what' => 'withdrawal|deposit|transfer']);
|
||||
|
@ -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
|
||||
|
||||
|
||||
"@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":
|
||||
version "1.5.1"
|
||||
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"
|
||||
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:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz#7854da51622a7e63624221196357803b552966a1"
|
||||
@ -8252,6 +8266,11 @@ vm-browserify@0.0.4:
|
||||
dependencies:
|
||||
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:
|
||||
version "2.3.1"
|
||||
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"
|
||||
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:
|
||||
version "2.5.21"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.21.tgz#3d33dcd03bb813912ce894a8303ab553699c4a85"
|
||||
|
Loading…
Reference in New Issue
Block a user