mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'develop' of github.com:JC5/firefly-iii into develop
This commit is contained in:
commit
0a91a40c1b
@ -1,26 +1,50 @@
|
||||
# Save as .codeclimate.yml (note leading .) in project root directory
|
||||
languages:
|
||||
JavaScript: true
|
||||
PHP: true
|
||||
---
|
||||
engines:
|
||||
csslint:
|
||||
enabled: true
|
||||
duplication:
|
||||
enabled: true
|
||||
config:
|
||||
languages:
|
||||
- ruby
|
||||
- javascript
|
||||
- python
|
||||
- php
|
||||
eslint:
|
||||
enabled: true
|
||||
fixme:
|
||||
enabled: true
|
||||
phpmd:
|
||||
enabled: true
|
||||
ratings:
|
||||
paths:
|
||||
- "**.css"
|
||||
- "**.inc"
|
||||
- "**.js"
|
||||
- "**.jsx"
|
||||
- "**.module"
|
||||
- "**.php"
|
||||
- "**.py"
|
||||
- "**.rb"
|
||||
exclude_paths:
|
||||
- "gulpfile.js"
|
||||
- "public/packages/maximebf/php-debugbar/debugbar.js"
|
||||
- "public/packages/maximebf/php-debugbar/widgets.js"
|
||||
- "public/packages/maximebf/php-debugbar/openhandler.js"
|
||||
- "public/packages/maximebf/php-debugbar/widgets/sqlqueries/widget.js"
|
||||
- "public/js/bootstrap3-typeahead.min.js"
|
||||
- "public/js/bootstrap-sortable.js"
|
||||
- "public/js/bootstrap-tagsinput.min.js"
|
||||
- "public/js/bootstrap-tagsinput.min.js.map"
|
||||
- "public/js/daterangepicker.js"
|
||||
- "public/js/jquery-2.1.3.min.js"
|
||||
- "public/js/jquery-2.1.3.min.js.map"
|
||||
- "public/js/jquery-ui.min.js"
|
||||
- "public/js/metisMenu.js"
|
||||
- "public/js/moment.min.js"
|
||||
- "public/js/sb-admin-2.js"
|
||||
- "public/bootstrap/*"
|
||||
- "resources/lang/*"
|
||||
- "tests/*"
|
||||
- "database/*"
|
||||
- "storage/*"
|
||||
- gulpfile.js
|
||||
- public/packages/maximebf/php-debugbar/debugbar.js
|
||||
- public/packages/maximebf/php-debugbar/widgets.js
|
||||
- public/packages/maximebf/php-debugbar/openhandler.js
|
||||
- public/packages/maximebf/php-debugbar/widgets/sqlqueries/widget.js
|
||||
- public/js/bootstrap3-typeahead.min.js
|
||||
- public/js/bootstrap-sortable.js
|
||||
- public/js/bootstrap-tagsinput.min.js
|
||||
- public/js/bootstrap-tagsinput.min.js.map
|
||||
- public/js/daterangepicker.js
|
||||
- public/js/jquery-2.1.3.min.js
|
||||
- public/js/jquery-2.1.3.min.js.map
|
||||
- public/js/jquery-ui.min.js
|
||||
- public/js/metisMenu.js
|
||||
- public/js/moment.min.js
|
||||
- public/js/sb-admin-2.js
|
||||
- public/bootstrap/*
|
||||
- resources/lang/*
|
||||
- tests/*
|
||||
- database/*
|
||||
- storage/*
|
||||
|
2
.csslintrc
Normal file
2
.csslintrc
Normal file
@ -0,0 +1,2 @@
|
||||
--exclude-exts=.min.css
|
||||
--ignore=adjoining-classes,box-model,ids,order-alphabetical,unqualified-attributes
|
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@ -0,0 +1 @@
|
||||
**/*{.,-}min.js
|
213
.eslintrc
Normal file
213
.eslintrc
Normal file
@ -0,0 +1,213 @@
|
||||
ecmaFeatures:
|
||||
modules: true
|
||||
jsx: true
|
||||
|
||||
env:
|
||||
amd: true
|
||||
browser: true
|
||||
es6: true
|
||||
jquery: true
|
||||
node: true
|
||||
|
||||
# http://eslint.org/docs/rules/
|
||||
rules:
|
||||
# Possible Errors
|
||||
comma-dangle: [2, never]
|
||||
no-cond-assign: 2
|
||||
no-console: 0
|
||||
no-constant-condition: 2
|
||||
no-control-regex: 2
|
||||
no-debugger: 2
|
||||
no-dupe-args: 2
|
||||
no-dupe-keys: 2
|
||||
no-duplicate-case: 2
|
||||
no-empty: 2
|
||||
no-empty-character-class: 2
|
||||
no-ex-assign: 2
|
||||
no-extra-boolean-cast: 2
|
||||
no-extra-parens: 0
|
||||
no-extra-semi: 2
|
||||
no-func-assign: 2
|
||||
no-inner-declarations: [2, functions]
|
||||
no-invalid-regexp: 2
|
||||
no-irregular-whitespace: 2
|
||||
no-negated-in-lhs: 2
|
||||
no-obj-calls: 2
|
||||
no-regex-spaces: 2
|
||||
no-sparse-arrays: 2
|
||||
no-unexpected-multiline: 2
|
||||
no-unreachable: 2
|
||||
use-isnan: 2
|
||||
valid-jsdoc: 0
|
||||
valid-typeof: 2
|
||||
|
||||
# Best Practices
|
||||
accessor-pairs: 2
|
||||
block-scoped-var: 0
|
||||
complexity: [2, 6]
|
||||
consistent-return: 0
|
||||
curly: 0
|
||||
default-case: 0
|
||||
dot-location: 0
|
||||
dot-notation: 0
|
||||
eqeqeq: 2
|
||||
guard-for-in: 2
|
||||
no-alert: 2
|
||||
no-caller: 2
|
||||
no-case-declarations: 2
|
||||
no-div-regex: 2
|
||||
no-else-return: 0
|
||||
no-empty-label: 2
|
||||
no-empty-pattern: 2
|
||||
no-eq-null: 2
|
||||
no-eval: 2
|
||||
no-extend-native: 2
|
||||
no-extra-bind: 2
|
||||
no-fallthrough: 2
|
||||
no-floating-decimal: 0
|
||||
no-implicit-coercion: 0
|
||||
no-implied-eval: 2
|
||||
no-invalid-this: 0
|
||||
no-iterator: 2
|
||||
no-labels: 0
|
||||
no-lone-blocks: 2
|
||||
no-loop-func: 2
|
||||
no-magic-number: 0
|
||||
no-multi-spaces: 0
|
||||
no-multi-str: 0
|
||||
no-native-reassign: 2
|
||||
no-new-func: 2
|
||||
no-new-wrappers: 2
|
||||
no-new: 2
|
||||
no-octal-escape: 2
|
||||
no-octal: 2
|
||||
no-proto: 2
|
||||
no-redeclare: 2
|
||||
no-return-assign: 2
|
||||
no-script-url: 2
|
||||
no-self-compare: 2
|
||||
no-sequences: 0
|
||||
no-throw-literal: 0
|
||||
no-unused-expressions: 2
|
||||
no-useless-call: 2
|
||||
no-useless-concat: 2
|
||||
no-void: 2
|
||||
no-warning-comments: 0
|
||||
no-with: 2
|
||||
radix: 2
|
||||
vars-on-top: 0
|
||||
wrap-iife: 2
|
||||
yoda: 0
|
||||
|
||||
# Strict
|
||||
strict: 0
|
||||
|
||||
# Variables
|
||||
init-declarations: 0
|
||||
no-catch-shadow: 2
|
||||
no-delete-var: 2
|
||||
no-label-var: 2
|
||||
no-shadow-restricted-names: 2
|
||||
no-shadow: 0
|
||||
no-undef-init: 2
|
||||
no-undef: 0
|
||||
no-undefined: 0
|
||||
no-unused-vars: 0
|
||||
no-use-before-define: 0
|
||||
|
||||
# Node.js and CommonJS
|
||||
callback-return: 2
|
||||
global-require: 2
|
||||
handle-callback-err: 2
|
||||
no-mixed-requires: 0
|
||||
no-new-require: 0
|
||||
no-path-concat: 2
|
||||
no-process-exit: 2
|
||||
no-restricted-modules: 0
|
||||
no-sync: 0
|
||||
|
||||
# Stylistic Issues
|
||||
array-bracket-spacing: 0
|
||||
block-spacing: 0
|
||||
brace-style: 0
|
||||
camelcase: 0
|
||||
comma-spacing: 0
|
||||
comma-style: 0
|
||||
computed-property-spacing: 0
|
||||
consistent-this: 0
|
||||
eol-last: 0
|
||||
func-names: 0
|
||||
func-style: 0
|
||||
id-length: 0
|
||||
id-match: 0
|
||||
indent: 0
|
||||
jsx-quotes: 0
|
||||
key-spacing: 0
|
||||
linebreak-style: 0
|
||||
lines-around-comment: 0
|
||||
max-depth: 0
|
||||
max-len: 0
|
||||
max-nested-callbacks: 0
|
||||
max-params: 0
|
||||
max-statements: [2, 30]
|
||||
new-cap: 0
|
||||
new-parens: 0
|
||||
newline-after-var: 0
|
||||
no-array-constructor: 0
|
||||
no-bitwise: 0
|
||||
no-continue: 0
|
||||
no-inline-comments: 0
|
||||
no-lonely-if: 0
|
||||
no-mixed-spaces-and-tabs: 0
|
||||
no-multiple-empty-lines: 0
|
||||
no-negated-condition: 0
|
||||
no-nested-ternary: 0
|
||||
no-new-object: 0
|
||||
no-plusplus: 0
|
||||
no-restricted-syntax: 0
|
||||
no-spaced-func: 0
|
||||
no-ternary: 0
|
||||
no-trailing-spaces: 0
|
||||
no-underscore-dangle: 0
|
||||
no-unneeded-ternary: 0
|
||||
object-curly-spacing: 0
|
||||
one-var: 0
|
||||
operator-assignment: 0
|
||||
operator-linebreak: 0
|
||||
padded-blocks: 0
|
||||
quote-props: 0
|
||||
quotes: 0
|
||||
require-jsdoc: 0
|
||||
semi-spacing: 0
|
||||
semi: 0
|
||||
sort-vars: 0
|
||||
space-after-keywords: 0
|
||||
space-before-blocks: 0
|
||||
space-before-function-paren: 0
|
||||
space-before-keywords: 0
|
||||
space-in-parens: 0
|
||||
space-infix-ops: 0
|
||||
space-return-throw-case: 0
|
||||
space-unary-ops: 0
|
||||
spaced-comment: 0
|
||||
wrap-regex: 0
|
||||
|
||||
# ECMAScript 6
|
||||
arrow-body-style: 0
|
||||
arrow-parens: 0
|
||||
arrow-spacing: 0
|
||||
constructor-super: 0
|
||||
generator-star-spacing: 0
|
||||
no-arrow-condition: 0
|
||||
no-class-assign: 0
|
||||
no-const-assign: 0
|
||||
no-dupe-class-members: 0
|
||||
no-this-before-super: 0
|
||||
no-var: 0
|
||||
object-shorthand: 0
|
||||
prefer-arrow-callback: 0
|
||||
prefer-const: 0
|
||||
prefer-reflect: 0
|
||||
prefer-spread: 0
|
||||
prefer-template: 0
|
||||
require-yield: 0
|
@ -1,7 +1,6 @@
|
||||
# Firefly III
|
||||
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
|
||||
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/build-status/master)
|
||||
[](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102)
|
||||
|
@ -2,6 +2,7 @@
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
use Auth;
|
||||
use ErrorException;
|
||||
use Exception;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
@ -13,7 +14,7 @@ use Mail;
|
||||
use Request;
|
||||
use Swift_TransportException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Auth;
|
||||
|
||||
/**
|
||||
* Class Handler
|
||||
*
|
||||
@ -68,14 +69,11 @@ class Handler extends ExceptionHandler
|
||||
|
||||
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
|
||||
|
||||
// log
|
||||
Log::error($exception->getMessage());
|
||||
|
||||
// mail?
|
||||
try {
|
||||
$email = env('SITE_OWNER');
|
||||
$user = Auth::user();
|
||||
$args = [
|
||||
$user = Auth::user();
|
||||
$args = [
|
||||
'errorMessage' => $exception->getMessage(),
|
||||
'stacktrace' => $exception->getTraceAsString(),
|
||||
'file' => $exception->getFile(),
|
||||
@ -99,7 +97,6 @@ class Handler extends ExceptionHandler
|
||||
// could also not mail! :o
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
parent::report($exception);
|
||||
|
@ -20,7 +20,7 @@ class AmountComma extends BasicConverter implements ConverterInterface
|
||||
$value = str_replace(',', '.', $this->value);
|
||||
|
||||
if (is_numeric($value)) {
|
||||
return floatval($value);
|
||||
return $value;
|
||||
}
|
||||
|
||||
return '0';
|
||||
|
@ -3,8 +3,8 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
|
||||
/**
|
||||
* Class AssetAccountIban
|
||||
@ -27,20 +27,29 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface
|
||||
}
|
||||
if (strlen($this->value) > 0) {
|
||||
// find or create new account:
|
||||
$account = $this->findAccount();
|
||||
$accountType = AccountType::where('type', 'Asset account')->first();
|
||||
$account = $this->findAccount();
|
||||
|
||||
if (is_null($account)) {
|
||||
// create it if doesn't exist.
|
||||
$account = Account::firstOrCreateEncrypted( // TODO use repository
|
||||
[
|
||||
'name' => $this->value,
|
||||
'iban' => $this->value,
|
||||
'user_id' => Auth::user()->id,
|
||||
'account_type_id' => $accountType->id,
|
||||
'active' => 1,
|
||||
]
|
||||
);
|
||||
|
||||
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
|
||||
$accountData = [
|
||||
'name' => $this->value,
|
||||
'accountType' => 'asset',
|
||||
'virtualBalance' => 0,
|
||||
'virtualBalanceCurrency' => 1, // hard coded.
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'iban' => null,
|
||||
'accountNumber' => $this->value,
|
||||
'accountRole' => null,
|
||||
'openingBalance' => 0,
|
||||
'openingBalanceDate' => new Carbon,
|
||||
'openingBalanceCurrency' => 1, // hard coded.
|
||||
|
||||
];
|
||||
|
||||
$account = $repository->store($accountData);
|
||||
}
|
||||
|
||||
return $account;
|
||||
|
@ -3,6 +3,7 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
|
||||
@ -26,7 +27,6 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
|
||||
return $account;
|
||||
}
|
||||
// find or create new account:
|
||||
$accountType = AccountType::where('type', 'Asset account')->first();
|
||||
$set = Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->get();
|
||||
/** @var Account $entry */
|
||||
foreach ($set as $entry) {
|
||||
@ -36,15 +36,25 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
|
||||
}
|
||||
|
||||
// create it if doesnt exist.
|
||||
$account = Account::firstOrCreateEncrypted( // TODO use repository
|
||||
[
|
||||
'name' => $this->value,
|
||||
'iban' => '',
|
||||
'user_id' => Auth::user()->id,
|
||||
'account_type_id' => $accountType->id,
|
||||
'active' => 1,
|
||||
]
|
||||
);
|
||||
|
||||
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
|
||||
$accountData = [
|
||||
'name' => $this->value,
|
||||
'accountType' => 'asset',
|
||||
'virtualBalance' => 0,
|
||||
'virtualBalanceCurrency' => 1, // hard coded.
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'iban' => null,
|
||||
'accountNumber' => $this->value,
|
||||
'accountRole' => null,
|
||||
'openingBalance' => 0,
|
||||
'openingBalanceDate' => new Carbon,
|
||||
'openingBalanceCurrency' => 1, // hard coded.
|
||||
|
||||
];
|
||||
|
||||
$account = $repository->store($accountData);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
|
||||
'name' => $this->value,
|
||||
'accountType' => 'asset',
|
||||
'virtualBalance' => 0,
|
||||
'virtualBalanceCurrency' => 1, // TODO hard coded.
|
||||
'virtualBalanceCurrency' => 1, // hard coded.
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'iban' => null,
|
||||
@ -56,7 +56,7 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
|
||||
'accountRole' => null,
|
||||
'openingBalance' => 0,
|
||||
'openingBalanceDate' => new Carbon,
|
||||
'openingBalanceCurrency' => 1, // TODO hard coded.
|
||||
'openingBalanceCurrency' => 1, // hard coded.
|
||||
|
||||
];
|
||||
|
||||
|
@ -20,15 +20,10 @@ class BudgetName extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]);
|
||||
$budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]); // see issue #180
|
||||
} else {
|
||||
$budget = Budget::firstOrCreateEncrypted( // TODO use repository
|
||||
[
|
||||
'name' => $this->value,
|
||||
'user_id' => Auth::user()->id,
|
||||
'active' => true,
|
||||
]
|
||||
);
|
||||
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
|
||||
$budget = $repository->store(['name' => $this->value, 'user' => Auth::user()->id]);
|
||||
}
|
||||
|
||||
return $budget;
|
||||
|
@ -22,7 +22,7 @@ class CategoryName extends BasicConverter implements ConverterInterface
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$category = Auth::user()->categories()->find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$category = Category::firstOrCreateEncrypted( // TODO use repository
|
||||
$category = Category::firstOrCreateEncrypted( // See issue #180
|
||||
[
|
||||
'name' => $this->value,
|
||||
'user_id' => Auth::user()->id,
|
||||
|
@ -23,7 +23,7 @@ class TagsComma extends BasicConverter implements ConverterInterface
|
||||
|
||||
$strings = explode(',', $this->value);
|
||||
foreach ($strings as $string) {
|
||||
$tag = Tag::firstOrCreateEncrypted( // TODO use repository
|
||||
$tag = Tag::firstOrCreateEncrypted( // See issue #180
|
||||
[
|
||||
'tag' => $string,
|
||||
'tagMode' => 'nothing',
|
||||
|
@ -23,7 +23,7 @@ class TagsSpace extends BasicConverter implements ConverterInterface
|
||||
|
||||
$strings = explode(' ', $this->value);
|
||||
foreach ($strings as $string) {
|
||||
$tag = Tag::firstOrCreateEncrypted( // TODO use repository
|
||||
$tag = Tag::firstOrCreateEncrypted( // See issue #180
|
||||
[
|
||||
'tag' => $string,
|
||||
'tagMode' => 'nothing',
|
||||
|
@ -154,9 +154,9 @@ class AssetAccount implements PostProcessorInterface
|
||||
$name = $this->data['asset-account-name'] ?? '';
|
||||
$iban = $this->data['asset-account-iban'] ?? '';
|
||||
|
||||
// create if not exists: // TODO should be through repository.
|
||||
// create if not exists: // See issue #180
|
||||
$name = strlen($name) > 0 ? $name : $iban;
|
||||
$account = Account::firstOrCreateEncrypted( // TODO use repository
|
||||
$account = Account::firstOrCreateEncrypted(
|
||||
[
|
||||
'user_id' => Auth::user()->id,
|
||||
'account_type_id' => $accountType->id,
|
||||
@ -211,7 +211,8 @@ class AssetAccount implements PostProcessorInterface
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
// create if not exists: // TODO use repository
|
||||
// create if not exists:
|
||||
// See issue #180
|
||||
$account = Account::firstOrCreateEncrypted(
|
||||
[
|
||||
'user_id' => Auth::user()->id,
|
||||
@ -249,7 +250,7 @@ class AssetAccount implements PostProcessorInterface
|
||||
'name' => $accountNumber,
|
||||
'accountType' => 'asset',
|
||||
'virtualBalance' => 0,
|
||||
'virtualBalanceCurrency' => 1, // TODO hard coded.
|
||||
'virtualBalanceCurrency' => 1, // hard coded.
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'iban' => null,
|
||||
@ -257,7 +258,7 @@ class AssetAccount implements PostProcessorInterface
|
||||
'accountRole' => null,
|
||||
'openingBalance' => 0,
|
||||
'openingBalanceDate' => new Carbon,
|
||||
'openingBalanceCurrency' => 1, // TODO hard coded.
|
||||
'openingBalanceCurrency' => 1, // hard coded.
|
||||
];
|
||||
$account = $repository->store($accountData);
|
||||
|
||||
|
@ -125,7 +125,7 @@ class OpposingAccount implements PostProcessorInterface
|
||||
// create if not exists:
|
||||
$name = is_string($this->data['opposing-account-name']) && strlen($this->data['opposing-account-name']) > 0 ? $this->data['opposing-account-name']
|
||||
: $this->data['opposing-account-iban'];
|
||||
$account = Account::firstOrCreateEncrypted( // TODO use repository
|
||||
$account = Account::firstOrCreateEncrypted( // See issue #180
|
||||
[
|
||||
'user_id' => Auth::user()->id,
|
||||
'account_type_id' => $accountType->id,
|
||||
@ -195,7 +195,7 @@ class OpposingAccount implements PostProcessorInterface
|
||||
}
|
||||
}
|
||||
// create if not exists:
|
||||
$account = Account::firstOrCreateEncrypted( // TODO use repository
|
||||
$account = Account::firstOrCreateEncrypted( // See issue #180
|
||||
[
|
||||
'user_id' => Auth::user()->id,
|
||||
'account_type_id' => $accountType->id,
|
||||
|
@ -23,6 +23,10 @@ use stdClass;
|
||||
*/
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
const MAKE_POSITIVE = -1;
|
||||
const KEEP_POSITIVE = 1;
|
||||
|
||||
|
||||
/** @var \FireflyIII\Generator\Chart\Category\CategoryChartGeneratorInterface */
|
||||
protected $generator;
|
||||
|
||||
@ -134,32 +138,8 @@ class CategoryController extends Controller
|
||||
return $category->name;
|
||||
}
|
||||
);
|
||||
$entries = new Collection;
|
||||
|
||||
while ($start < $end) { // filter the set:
|
||||
$row = [clone $start];
|
||||
$currentSet = $set->filter( // get possibly relevant entries from the big $set
|
||||
function (Category $category) use ($start) {
|
||||
return $category->dateFormatted == $start->format('Y-m');
|
||||
}
|
||||
);
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) { // check for each category if its in the current set.
|
||||
$entry = $currentSet->filter( // if its in there, use the value.
|
||||
function (Category $cat) use ($category) {
|
||||
return ($cat->id == $category->id);
|
||||
}
|
||||
)->first();
|
||||
if (!is_null($entry)) {
|
||||
$row[] = round($entry->earned, 2);
|
||||
} else {
|
||||
$row[] = 0;
|
||||
}
|
||||
}
|
||||
$entries->push($row);
|
||||
$start->addMonth();
|
||||
}
|
||||
$data = $this->generator->earnedInPeriod($categories, $entries);
|
||||
$entries = $this->filterCollection($start, $end, $set, $categories);
|
||||
$data = $this->generator->earnedInPeriod($categories, $entries);
|
||||
$cache->store($data);
|
||||
|
||||
return $data;
|
||||
@ -340,42 +320,58 @@ class CategoryController extends Controller
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
|
||||
$set = $repository->spentForAccountsPerMonth($accounts, $start, $end);
|
||||
$categories = $set->unique('id')->sortBy(
|
||||
function (Category $category) {
|
||||
return $category->name;
|
||||
}
|
||||
);
|
||||
$entries = new Collection;
|
||||
|
||||
$entries = $this->filterCollection($start, $end, $set, $categories);
|
||||
$data = $this->generator->spentInPeriod($categories, $entries);
|
||||
$cache->store($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $set
|
||||
* @param Collection $categories
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
private function filterCollection(Carbon $start, Carbon $end, Collection $set, Collection $categories): Collection
|
||||
{
|
||||
$entries = new Collection;
|
||||
|
||||
while ($start < $end) { // filter the set:
|
||||
$row = [clone $start];
|
||||
$currentSet = $set->filter(// get possibly relevant entries from the big $set
|
||||
$currentSet = $set->filter( // get possibly relevant entries from the big $set
|
||||
function (Category $category) use ($start) {
|
||||
return $category->dateFormatted == $start->format('Y-m');
|
||||
}
|
||||
);
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {// check for each category if its in the current set.
|
||||
$entry = $currentSet->filter(// if its in there, use the value.
|
||||
foreach ($categories as $category) { // check for each category if its in the current set.
|
||||
$entry = $currentSet->filter( // if its in there, use the value.
|
||||
function (Category $cat) use ($category) {
|
||||
return ($cat->id == $category->id);
|
||||
}
|
||||
)->first();
|
||||
if (!is_null($entry)) {
|
||||
$row[] = round(($entry->spent * -1), 2);
|
||||
$row[] = round($entry->earned, 2);
|
||||
} else {
|
||||
$row[] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$entries->push($row);
|
||||
$start->addMonth();
|
||||
}
|
||||
$data = $this->generator->spentInPeriod($categories, $entries);
|
||||
$cache->store($data);
|
||||
|
||||
return $data;
|
||||
return $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -419,5 +415,4 @@ class CategoryController extends Controller
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -187,8 +187,8 @@ class PiggyBankController extends Controller
|
||||
'name' => $account->name,
|
||||
'balance' => Steam::balance($account, $end, true),
|
||||
'leftForPiggyBanks' => $repository->leftOnAccount($account, $end),
|
||||
'sumOfSaved' => $piggyBank->savedSoFar,
|
||||
'sumOfTargets' => round($piggyBank->targetamount, 2),
|
||||
'sumOfSaved' => strval($piggyBank->savedSoFar),
|
||||
'sumOfTargets' => strval(round($piggyBank->targetamount, 2)),
|
||||
'leftToSave' => $piggyBank->leftToSave,
|
||||
];
|
||||
} else {
|
||||
|
@ -4,7 +4,6 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Requests\TagFormRequest;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Models\Tag;
|
||||
@ -233,26 +232,7 @@ class TagController extends Controller
|
||||
*/
|
||||
public function store(TagFormRequest $request, TagRepositoryInterface $repository)
|
||||
{
|
||||
if (Input::get('setTag') == 'true') {
|
||||
$latitude = $request->get('latitude');
|
||||
$longitude = $request->get('longitude');
|
||||
$zoomLevel = $request->get('zoomLevel');
|
||||
} else {
|
||||
$latitude = null;
|
||||
$longitude = null;
|
||||
$zoomLevel = null;
|
||||
}
|
||||
$date = $request->get('date') ?? '';
|
||||
|
||||
$data = [
|
||||
'tag' => $request->get('tag'),
|
||||
'date' => strlen($date) > 0 ? new Carbon($date) : null,
|
||||
'description' => $request->get('description') ?? '',
|
||||
'latitude' => $latitude,
|
||||
'longitude' => $longitude,
|
||||
'zoomLevel' => $zoomLevel,
|
||||
'tagMode' => $request->get('tagMode'),
|
||||
];
|
||||
$data = $request->collectTagData();
|
||||
$repository->store($data);
|
||||
|
||||
Session::flash('success', 'The tag has been created!');
|
||||
@ -279,28 +259,7 @@ class TagController extends Controller
|
||||
*/
|
||||
public function update(TagFormRequest $request, TagRepositoryInterface $repository, Tag $tag)
|
||||
{
|
||||
if (Input::get('setTag') == 'true') {
|
||||
$latitude = $request->get('latitude');
|
||||
$longitude = $request->get('longitude');
|
||||
$zoomLevel = $request->get('zoomLevel');
|
||||
} else {
|
||||
$latitude = null;
|
||||
$longitude = null;
|
||||
$zoomLevel = null;
|
||||
}
|
||||
$date = $request->get('date') ?? '';
|
||||
|
||||
$data = [
|
||||
'tag' => $request->get('tag'),
|
||||
'date' => strlen($date) > 0 ? new Carbon($date) : null,
|
||||
'description' => $request->get('description') ?? '',
|
||||
'latitude' => $latitude,
|
||||
'longitude' => $longitude,
|
||||
'zoomLevel' => $zoomLevel,
|
||||
'tagMode' => $request->get('tagMode'),
|
||||
];
|
||||
|
||||
|
||||
$data = $request->collectTagData();
|
||||
$repository->update($tag, $data);
|
||||
|
||||
Session::flash('success', 'Tag "' . e($data['tag']) . '" updated.');
|
||||
|
@ -3,6 +3,7 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Tag;
|
||||
use Input;
|
||||
|
||||
@ -23,6 +24,37 @@ class TagFormRequest extends Request
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function collectTagData() :array
|
||||
{
|
||||
if (Input::get('setTag') == 'true') {
|
||||
$latitude = $this->get('latitude');
|
||||
$longitude = $this->get('longitude');
|
||||
$zoomLevel = $this->get('zoomLevel');
|
||||
} else {
|
||||
$latitude = null;
|
||||
$longitude = null;
|
||||
$zoomLevel = null;
|
||||
}
|
||||
$date = $this->get('date') ?? '';
|
||||
|
||||
$data = [
|
||||
'tag' => $this->get('tag'),
|
||||
'date' => strlen($date) > 0 ? new Carbon($date) : null,
|
||||
'description' => $this->get('description') ?? '',
|
||||
'latitude' => $latitude,
|
||||
'longitude' => $longitude,
|
||||
'zoomLevel' => $zoomLevel,
|
||||
'tagMode' => $this->get('tagMode'),
|
||||
];
|
||||
|
||||
return $data;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
use Zizaco\Entrust\EntrustPermission;
|
||||
|
||||
/**
|
||||
* FireflyIII\Models\Permission
|
||||
*
|
||||
* @property integer $id
|
||||
* @property string $name
|
||||
* @property string $display_name
|
||||
* @property string $description
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Role[] $roles
|
||||
*/
|
||||
class Permission extends EntrustPermission
|
||||
{
|
||||
}
|
@ -3,21 +3,19 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
|
||||
use Zizaco\Entrust\EntrustRole;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
/**
|
||||
* FireflyIII\Models\Role
|
||||
*
|
||||
* @property integer $id
|
||||
* @property string $name
|
||||
* @property string $display_name
|
||||
* @property string $description
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\User[] $users
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Permission[] $perms
|
||||
*/
|
||||
class Role extends EntrustRole
|
||||
|
||||
class Role extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function users(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany('FireflyIII\User');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
$balance = Steam::balance($account, $date, true);
|
||||
/** @var PiggyBank $p */
|
||||
foreach ($account->piggyBanks()->get() as $p) {
|
||||
$balance = bcsub($p->currentRelevantRep()->currentamount, $balance);
|
||||
$balance = bcsub($balance, $p->currentRelevantRep()->currentamount);
|
||||
}
|
||||
|
||||
return $balance;
|
||||
@ -544,7 +544,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
* @return bool
|
||||
*/
|
||||
private function storeMetadata(Account $account, array $data): bool
|
||||
{
|
||||
{
|
||||
foreach ($this->validFields as $field) {
|
||||
if (isset($data[$field])) {
|
||||
$metaData = new AccountMeta(
|
||||
|
@ -207,47 +207,10 @@ class RuleRepository implements RuleRepositoryInterface
|
||||
$rule->save();
|
||||
|
||||
// start storing triggers:
|
||||
$order = 1;
|
||||
$stopProcessing = false;
|
||||
|
||||
$triggerValues = [
|
||||
'action' => 'user_action',
|
||||
'value' => $data['trigger'],
|
||||
'stopProcessing' => $stopProcessing,
|
||||
'order' => $order,
|
||||
];
|
||||
|
||||
$this->storeTrigger($rule, $triggerValues);
|
||||
foreach ($data['rule-triggers'] as $index => $trigger) {
|
||||
$value = $data['rule-trigger-values'][$index];
|
||||
$stopProcessing = isset($data['rule-trigger-stop'][$index]) ? true : false;
|
||||
|
||||
$triggerValues = [
|
||||
'action' => $trigger,
|
||||
'value' => $value,
|
||||
'stopProcessing' => $stopProcessing,
|
||||
'order' => $order,
|
||||
];
|
||||
|
||||
$this->storeTrigger($rule, $triggerValues);
|
||||
$order++;
|
||||
}
|
||||
$this->storeTriggers($rule, $data);
|
||||
|
||||
// same for actions.
|
||||
$order = 1;
|
||||
foreach ($data['rule-actions'] as $index => $action) {
|
||||
$value = $data['rule-action-values'][$index];
|
||||
$stopProcessing = isset($data['rule-action-stop'][$index]) ? true : false;
|
||||
|
||||
$actionValues = [
|
||||
'action' => $action,
|
||||
'value' => $value,
|
||||
'stopProcessing' => $stopProcessing,
|
||||
'order' => $order,
|
||||
];
|
||||
|
||||
$this->storeAction($rule, $actionValues);
|
||||
}
|
||||
$this->storeActions($rule, $data);
|
||||
|
||||
return $rule;
|
||||
}
|
||||
@ -315,6 +278,44 @@ class RuleRepository implements RuleRepositoryInterface
|
||||
$rule->ruleActions()->delete();
|
||||
|
||||
// recreate triggers:
|
||||
$this->storeTriggers($rule, $data);
|
||||
|
||||
// recreate actions:
|
||||
$this->storeActions($rule, $data);
|
||||
|
||||
|
||||
return $rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
* @param array $data
|
||||
*/
|
||||
private function storeActions(Rule $rule, array $data)
|
||||
{
|
||||
$order = 1;
|
||||
foreach ($data['rule-actions'] as $index => $action) {
|
||||
$value = $data['rule-action-values'][$index];
|
||||
$stopProcessing = isset($data['rule-action-stop'][$index]) ? true : false;
|
||||
|
||||
$actionValues = [
|
||||
'action' => $action,
|
||||
'value' => $value,
|
||||
'stopProcessing' => $stopProcessing,
|
||||
'order' => $order,
|
||||
];
|
||||
|
||||
$this->storeAction($rule, $actionValues);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
* @param array $data
|
||||
*/
|
||||
private function storeTriggers(Rule $rule, array $data)
|
||||
{
|
||||
$order = 1;
|
||||
$stopProcessing = false;
|
||||
|
||||
@ -340,24 +341,5 @@ class RuleRepository implements RuleRepositoryInterface
|
||||
$this->storeTrigger($rule, $triggerValues);
|
||||
$order++;
|
||||
}
|
||||
|
||||
// recreate actions:
|
||||
$order = 1;
|
||||
foreach ($data['rule-actions'] as $index => $action) {
|
||||
$value = $data['rule-action-values'][$index];
|
||||
$stopProcessing = isset($data['rule-action-stop'][$index]) ? true : false;
|
||||
|
||||
$actionValues = [
|
||||
'action' => $action,
|
||||
'value' => $value,
|
||||
'stopProcessing' => $stopProcessing,
|
||||
'order' => $order,
|
||||
];
|
||||
|
||||
$this->storeAction($rule, $actionValues);
|
||||
}
|
||||
|
||||
|
||||
return $rule;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\User;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class TestData
|
||||
@ -90,20 +89,16 @@ class TestData
|
||||
public static function createAttachments(User $user, Carbon $start): TransactionJournal
|
||||
{
|
||||
|
||||
$toAccount = TestData::findAccount($user, 'TestData Checking Account');
|
||||
$fromAccount = TestData::findAccount($user, 'Job');
|
||||
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => 2,
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => 'Some journal for attachment',
|
||||
'completed' => 1,
|
||||
'date' => $start->format('Y-m-d'),
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, $fromAccount, $toAccount, '100');
|
||||
$args = [
|
||||
'user' => $user,
|
||||
'description' => 'Some journal for attachment',
|
||||
'date' => $start,
|
||||
'from' => 'Job',
|
||||
'to' => 'TestData Checking Account',
|
||||
'amount' => '100',
|
||||
'transaction_type' => 2,
|
||||
];
|
||||
$journal = self::createJournal($args);
|
||||
|
||||
// and now attachments
|
||||
$encrypted = Crypt::encrypt('I are secret');
|
||||
@ -245,45 +240,24 @@ class TestData
|
||||
public static function createCar(User $user, Carbon $date): TransactionJournal
|
||||
{
|
||||
// twice:
|
||||
$date = new Carbon($date->format('Y-m') . '-10'); // paid on 10th
|
||||
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
|
||||
$toAccount = TestData::findAccount($user, 'Shell');
|
||||
$category = Category::firstOrCreateEncrypted(['name' => 'Car', 'user_id' => $user->id]);
|
||||
$budget = Budget::firstOrCreateEncrypted(['name' => 'Car', 'user_id' => $user->id]);
|
||||
$amount = strval(rand(4000, 5000) / 100);
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => 1,
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => 'Bought gas',
|
||||
'completed' => 1,
|
||||
'date' => $date,
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
|
||||
$amount = strval(rand(4000, 5000) / 100);
|
||||
$args = [
|
||||
'user' => $user,
|
||||
'description' => 'Bought gas',
|
||||
'date' => new Carbon($date->format('Y-m') . '-10'),// paid on 10th
|
||||
'from' => 'TestData Checking Account',
|
||||
'to' => 'Shell',
|
||||
'amount' => $amount,
|
||||
'category' => 'Car',
|
||||
'budget' => 'Car',
|
||||
];
|
||||
self::createJournal($args);
|
||||
|
||||
$journal->categories()->save($category);
|
||||
$journal->budgets()->save($budget);
|
||||
|
||||
// and again!
|
||||
$date = new Carbon($date->format('Y-m') . '-20'); // paid on 20th
|
||||
$amount = rand(4000, 5000) / 100;
|
||||
|
||||
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => 1,
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => 'Gas for car',
|
||||
'completed' => 1,
|
||||
'date' => $date,
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, $fromAccount, $toAccount, strval($amount));
|
||||
|
||||
// and again!
|
||||
// again!
|
||||
$args['date'] = new Carbon($date->format('Y-m') . '-20'); // paid on 20th
|
||||
$args['amount'] = strval(rand(4000, 5000) / 100);
|
||||
$args['description'] = 'Gas for car';
|
||||
$journal = self::createJournal($args);
|
||||
|
||||
return $journal;
|
||||
}
|
||||
@ -322,28 +296,18 @@ class TestData
|
||||
// weekly drink:
|
||||
$thisDate = clone $current;
|
||||
$thisDate->addDay();
|
||||
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
|
||||
$toAccount = TestData::findAccount($user, 'Cafe Central');
|
||||
$category = Category::firstOrCreateEncrypted(['name' => 'Drinks', 'user_id' => $user->id]);
|
||||
$budget = Budget::firstOrCreateEncrypted(['name' => 'Going out', 'user_id' => $user->id]);
|
||||
$amount = strval(rand(1500, 3600) / 100);
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => 1,
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => 'Going out for drinks',
|
||||
'completed' => 1,
|
||||
'date' => $thisDate,
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
|
||||
|
||||
$journal->categories()->save($category);
|
||||
$journal->budgets()->save($budget);
|
||||
|
||||
// shopping at some (online) shop:
|
||||
|
||||
$amount = strval(rand(1500, 3600) / 100);
|
||||
$args = [
|
||||
'user' => $user,
|
||||
'description' => 'Going out for drinks',
|
||||
'date' => $thisDate,
|
||||
'from' => 'TestData Checking Account',
|
||||
'to' => 'Cafe Central',
|
||||
'amount' => $amount,
|
||||
'category' => 'Drinks',
|
||||
'budget' => 'Going out',
|
||||
];
|
||||
self::createJournal($args);
|
||||
|
||||
$current->addWeek();
|
||||
}
|
||||
@ -395,36 +359,25 @@ class TestData
|
||||
$start->startOfMonth();
|
||||
$end->endOfMonth();
|
||||
|
||||
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
|
||||
$stores = ['Albert Heijn', 'PLUS', 'Bakker'];
|
||||
$descriptions = ['Groceries', 'Bought some groceries', 'Got groceries'];
|
||||
$category = Category::firstOrCreateEncrypted(['name' => 'Daily groceries', 'user_id' => $user->id]);
|
||||
$budget = Budget::firstOrCreateEncrypted(['name' => 'Groceries', 'user_id' => $user->id]);
|
||||
|
||||
$current = clone $start;
|
||||
while ($current < $end && $current < $today) {
|
||||
// daily groceries:
|
||||
$toAccount = TestData::findAccount($user, $stores[rand(0, count($stores) - 1)]);
|
||||
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => 1,
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => $descriptions[rand(0, count($descriptions) - 1)],
|
||||
'completed' => 1,
|
||||
'date' => $current,
|
||||
]
|
||||
);
|
||||
if ($journal->id) {
|
||||
$number = (string)round((rand(1500, 2500) / 100), 2);
|
||||
$amount = $number;//'10';//strval((rand(1500, 2500) / 100));
|
||||
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
|
||||
$journal->categories()->save($category);
|
||||
$journal->budgets()->save($budget);
|
||||
}
|
||||
|
||||
$amount = (string)round((rand(1500, 2500) / 100), 2);
|
||||
|
||||
$args = [
|
||||
'user' => $user,
|
||||
'description' => $descriptions[rand(0, count($descriptions) - 1)],
|
||||
'date' => $current,
|
||||
'from' => 'TestData Checking Account',
|
||||
'to' => $stores[rand(0, count($stores) - 1)],
|
||||
'amount' => $amount,
|
||||
'category' => 'Daily groceries',
|
||||
'budget' => 'Groceries',
|
||||
];
|
||||
self::createJournal($args);
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
@ -446,28 +399,54 @@ class TestData
|
||||
if ($date >= $today) {
|
||||
return new TransactionJournal;
|
||||
}
|
||||
$toAccount = TestData::findAccount($user, 'TestData Checking Account');
|
||||
$fromAccount = TestData::findAccount($user, 'Job');
|
||||
$category = Category::firstOrCreateEncrypted(['name' => 'Salary', 'user_id' => $user->id]);
|
||||
// create journal:
|
||||
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => 2,
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => $description,
|
||||
'completed' => 1,
|
||||
'date' => $date,
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
|
||||
$journal->categories()->save($category);
|
||||
// create journal:
|
||||
$args = [
|
||||
'user' => $user,
|
||||
'description' => $description,
|
||||
'date' => $date,
|
||||
'from' => 'Job',
|
||||
'to' => 'TestData Checking Account',
|
||||
'amount' => $amount,
|
||||
'category' => 'Salary',
|
||||
'transaction_type' => 2,
|
||||
];
|
||||
$journal = self::createJournal($args);
|
||||
|
||||
return $journal;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $opt
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
public static function createJournal(array $opt): TransactionJournal
|
||||
{
|
||||
$type = $opt['transaction_type'] ?? 1;
|
||||
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $opt['user']->id,
|
||||
'transaction_type_id' => $type,
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => $opt['description'],
|
||||
'completed' => 1,
|
||||
'date' => $opt['date'],
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, self::findAccount($opt['user'], $opt['from']), self::findAccount($opt['user'], $opt['to']), $opt['amount']);
|
||||
if (isset($opt['category'])) {
|
||||
$journal->categories()->save(self::findCategory($opt['user'], $opt['category']));
|
||||
}
|
||||
if (isset($opt['budget'])) {
|
||||
$journal->budgets()->save(self::findBudget($opt['user'], $opt['budget']));
|
||||
}
|
||||
|
||||
return $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*
|
||||
@ -620,24 +599,17 @@ class TestData
|
||||
*/
|
||||
public static function createPower(User $user, string $description, Carbon $date, string $amount): TransactionJournal
|
||||
{
|
||||
$date = new Carbon($date->format('Y-m') . '-06'); // paid on 10th
|
||||
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
|
||||
$toAccount = TestData::findAccount($user, 'Greenchoice');
|
||||
$category = Category::firstOrCreateEncrypted(['name' => 'House', 'user_id' => $user->id]);
|
||||
$budget = Budget::firstOrCreateEncrypted(['name' => 'Bills', 'user_id' => $user->id]);
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => 1,
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => $description,
|
||||
'completed' => 1,
|
||||
'date' => $date,
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
|
||||
$journal->categories()->save($category);
|
||||
$journal->budgets()->save($budget);
|
||||
$args = [
|
||||
'user' => $user,
|
||||
'description' => $description,
|
||||
'date' => new Carbon($date->format('Y-m') . '-06'),// paid on 10th
|
||||
'from' => 'TestData Checking Account',
|
||||
'to' => 'Greenchoice',
|
||||
'amount' => $amount,
|
||||
'category' => 'House',
|
||||
'budget' => 'Bills',
|
||||
];
|
||||
$journal = self::createJournal($args);
|
||||
|
||||
return $journal;
|
||||
|
||||
@ -653,25 +625,17 @@ class TestData
|
||||
*/
|
||||
public static function createRent(User $user, string $description, Carbon $date, string $amount): TransactionJournal
|
||||
{
|
||||
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
|
||||
$toAccount = TestData::findAccount($user, 'Land lord');
|
||||
$category = Category::firstOrCreateEncrypted(['name' => 'Rent', 'user_id' => $user->id]);
|
||||
$budget = Budget::firstOrCreateEncrypted(['name' => 'Bills', 'user_id' => $user->id]);
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => 1,
|
||||
'transaction_currency_id' => 1,
|
||||
'bill_id' => 1,
|
||||
'description' => $description,
|
||||
'completed' => 1,
|
||||
'date' => $date,
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
|
||||
|
||||
$journal->categories()->save($category);
|
||||
$journal->budgets()->save($budget);
|
||||
$args = [
|
||||
'user' => $user,
|
||||
'description' => $description,
|
||||
'date' => $date,
|
||||
'from' => 'TestData Checking Account',
|
||||
'to' => 'Land lord',
|
||||
'amount' => $amount,
|
||||
'category' => 'Rent',
|
||||
'budget' => 'Bills',
|
||||
];
|
||||
$journal = self::createJournal($args);
|
||||
|
||||
return $journal;
|
||||
|
||||
@ -792,24 +756,17 @@ class TestData
|
||||
*/
|
||||
public static function createSavings(User $user, Carbon $date): TransactionJournal
|
||||
{
|
||||
$date = new Carbon($date->format('Y-m') . '-24'); // paid on 24th.
|
||||
$toAccount = TestData::findAccount($user, 'TestData Savings');
|
||||
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
|
||||
$category = Category::firstOrCreateEncrypted(['name' => 'Money management', 'user_id' => $user->id]);
|
||||
// create journal:
|
||||
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => 3,
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => 'Save money',
|
||||
'completed' => 1,
|
||||
'date' => $date,
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, $fromAccount, $toAccount, '150');
|
||||
$journal->categories()->save($category);
|
||||
$args = [
|
||||
'user' => $user,
|
||||
'description' => 'Save money',
|
||||
'date' => new Carbon($date->format('Y-m') . '-24'),// paid on 24th.
|
||||
'from' => 'TestData Checking Account',
|
||||
'to' => 'TestData Savings',
|
||||
'amount' => '150',
|
||||
'category' => 'Money management',
|
||||
'transaction_type' => 3,
|
||||
];
|
||||
$journal = self::createJournal($args);
|
||||
|
||||
return $journal;
|
||||
|
||||
@ -825,25 +782,17 @@ class TestData
|
||||
*/
|
||||
public static function createTV(User $user, string $description, Carbon $date, string $amount): TransactionJournal
|
||||
{
|
||||
$date = new Carbon($date->format('Y-m') . '-15'); // paid on 10th
|
||||
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
|
||||
$toAccount = TestData::findAccount($user, 'XS4All');
|
||||
$category = Category::firstOrCreateEncrypted(['name' => 'House', 'user_id' => $user->id]);
|
||||
$budget = Budget::firstOrCreateEncrypted(['name' => 'Bills', 'user_id' => $user->id]);
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => 1,
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => $description,
|
||||
'completed' => 1,
|
||||
'date' => $date,
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
|
||||
|
||||
$journal->categories()->save($category);
|
||||
$journal->budgets()->save($budget);
|
||||
$args = [
|
||||
'user' => $user,
|
||||
'description' => $description,
|
||||
'date' => new Carbon($date->format('Y-m') . '-15'),
|
||||
'from' => 'TestData Checking Account',
|
||||
'to' => 'XS4All',
|
||||
'amount' => $amount,
|
||||
'category' => 'House',
|
||||
'budget' => 'Bills',
|
||||
];
|
||||
$journal = self::createJournal($args);
|
||||
|
||||
return $journal;
|
||||
|
||||
@ -883,8 +832,6 @@ class TestData
|
||||
*/
|
||||
public static function createTransactions(TransactionJournal $journal, Account $from, Account $to, string $amount): bool
|
||||
{
|
||||
Log::debug('---- Transaction From: ' . bcmul($amount, '-1'));
|
||||
Log::debug('---- Transaction To : ' . $amount);
|
||||
Transaction::create(
|
||||
[
|
||||
'account_id' => $from->id,
|
||||
@ -931,24 +878,17 @@ class TestData
|
||||
*/
|
||||
public static function createWater(User $user, string $description, Carbon $date, string $amount): TransactionJournal
|
||||
{
|
||||
$date = new Carbon($date->format('Y-m') . '-10'); // paid on 10th
|
||||
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
|
||||
$toAccount = TestData::findAccount($user, 'Vitens');
|
||||
$category = Category::firstOrCreateEncrypted(['name' => 'House', 'user_id' => $user->id]);
|
||||
$budget = Budget::firstOrCreateEncrypted(['name' => 'Bills', 'user_id' => $user->id]);
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => 1,
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => $description,
|
||||
'completed' => 1,
|
||||
'date' => $date,
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
|
||||
$journal->categories()->save($category);
|
||||
$journal->budgets()->save($budget);
|
||||
$args = [
|
||||
'user' => $user,
|
||||
'description' => $description,
|
||||
'date' => new Carbon($date->format('Y-m') . '-10'), // paid on 10th
|
||||
'from' => 'TestData Checking Account',
|
||||
'to' => 'Vitens',
|
||||
'amount' => $amount,
|
||||
'category' => 'House',
|
||||
'budget' => 'Bills',
|
||||
];
|
||||
$journal = self::createJournal($args);
|
||||
|
||||
return $journal;
|
||||
|
||||
@ -987,7 +927,25 @@ class TestData
|
||||
}
|
||||
}
|
||||
|
||||
return new Budget;
|
||||
return Budget::firstOrCreateEncrypted(['name' => $name, 'user_id' => $user->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param $name
|
||||
*
|
||||
* @return Category
|
||||
*/
|
||||
public static function findCategory(User $user, string $name): Category
|
||||
{
|
||||
/** @var Category $category */
|
||||
foreach (Category::get() as $category) {
|
||||
if ($category->name == $name && $user->id == $category->user_id) {
|
||||
return $category;
|
||||
}
|
||||
}
|
||||
|
||||
return Category::firstOrCreateEncrypted(['name' => $name, 'user_id' => $user->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1023,6 +981,7 @@ class TestData
|
||||
]
|
||||
);
|
||||
self::createTransactions($journal, $opposing, $savings, '10000');
|
||||
|
||||
return $journal;
|
||||
|
||||
}
|
||||
|
75
app/User.php
75
app/User.php
@ -3,10 +3,10 @@ declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Zizaco\Entrust\Traits\EntrustUserTrait;
|
||||
|
||||
/**
|
||||
* Class User
|
||||
@ -32,11 +32,10 @@ use Zizaco\Entrust\Traits\EntrustUserTrait;
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Role[] $roles
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\RuleGroup[] $ruleGroups
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Rule[] $rules
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\ExportJob[] $exportjobs
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\ExportJob[] $exportjobs
|
||||
*/
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use EntrustUserTrait;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
@ -44,16 +43,12 @@ class User extends Authenticatable
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['email', 'password', 'blocked', 'blocked_code'];
|
||||
|
||||
|
||||
/**
|
||||
* The attributes excluded from the model's JSON form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = ['password', 'remember_token'];
|
||||
|
||||
|
||||
/**
|
||||
* The database table used by the model.
|
||||
*
|
||||
@ -69,6 +64,26 @@ class User extends Authenticatable
|
||||
return $this->hasMany('FireflyIII\Models\Account');
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias to eloquent many-to-many relation's attach() method.
|
||||
*
|
||||
* Full credit goes to: https://github.com/Zizaco/entrust
|
||||
*
|
||||
* @param mixed $role
|
||||
*/
|
||||
public function attachRole($role)
|
||||
{
|
||||
if (is_object($role)) {
|
||||
$role = $role->getKey();
|
||||
}
|
||||
|
||||
if (is_array($role)) {
|
||||
$role = $role['id'];
|
||||
}
|
||||
|
||||
$this->roles()->attach($role);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany
|
||||
*/
|
||||
@ -109,6 +124,44 @@ class User extends Authenticatable
|
||||
return $this->hasMany('FireflyIII\Models\ExportJob');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user has a role by its name.
|
||||
*
|
||||
* Full credit goes to: https://github.com/Zizaco/entrust
|
||||
*
|
||||
* @param string|array $name Role name or array of role names.
|
||||
* @param bool $requireAll All roles in the array are required.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRole($name, $requireAll = false)
|
||||
{
|
||||
if (is_array($name)) {
|
||||
foreach ($name as $roleName) {
|
||||
$hasRole = $this->hasRole($roleName);
|
||||
|
||||
if ($hasRole && !$requireAll) {
|
||||
return true;
|
||||
} elseif (!$hasRole && $requireAll) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If we've made it this far and $requireAll is FALSE, then NONE of the roles were found
|
||||
// If we've made it this far and $requireAll is TRUE, then ALL of the roles were found.
|
||||
// Return the value of $requireAll;
|
||||
return $requireAll;
|
||||
} else {
|
||||
foreach ($this->roles as $role) {
|
||||
if ($role->name == $name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasManyThrough
|
||||
*/
|
||||
@ -125,6 +178,14 @@ class User extends Authenticatable
|
||||
return $this->hasMany('FireflyIII\Models\Preference');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function roles(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany('FireflyIII\Models\Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany
|
||||
*/
|
||||
|
@ -199,6 +199,13 @@ class FireflyValidator extends Validator
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attribute
|
||||
* @param $value
|
||||
* @param $parameters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateUniqueAccountNumberForUser($attribute, $value, $parameters): bool
|
||||
{
|
||||
$accountId = $this->data['id'] ?? 0;
|
||||
|
@ -20,7 +20,6 @@
|
||||
"doctrine/dbal": "~2.5",
|
||||
"league/commonmark": "~0.7",
|
||||
"rcrowe/twigbridge": "~0.9",
|
||||
"zizaco/entrust": "dev-laravel-5",
|
||||
"league/csv": "^7.1",
|
||||
"laravelcollective/html": "^5.2"
|
||||
},
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
@ -29,7 +30,7 @@ class CreateSessionTable extends Migration
|
||||
public function up()
|
||||
{
|
||||
Schema::create(
|
||||
'sessions', function ($table) {
|
||||
'sessions', function (Blueprint $table) {
|
||||
$table->string('id')->unique();
|
||||
$table->integer('user_id')->nullable();
|
||||
$table->string('ip_address', 45)->nullable();
|
||||
|
0
gulpfile.js
Executable file → Normal file
0
gulpfile.js
Executable file → Normal file
@ -79,7 +79,7 @@ function sortStop(event, ui) {
|
||||
});
|
||||
|
||||
// do extra animation when done?
|
||||
$.post('/transaction/reorder', {items: submit, date: thisDate, _token: token});
|
||||
$.post('transaction/reorder', {items: submit, date: thisDate, _token: token});
|
||||
|
||||
current.animate({backgroundColor: "#5cb85c"}, 200, function () {
|
||||
$(this).animate({backgroundColor: originalBG}, 200);
|
||||
|
@ -79,7 +79,7 @@ function stopSorting() {
|
||||
var id = holder.data('id');
|
||||
order.push(id);
|
||||
});
|
||||
$.post('/piggy-banks/sort', {_token: token, order: order}).done(function () {
|
||||
$.post('piggy-banks/sort', {_token: token, order: order}).done(function () {
|
||||
$('.loadSpin').removeClass('fa fa-refresh fa-spin');
|
||||
});
|
||||
}
|
@ -1,41 +1,46 @@
|
||||
{
|
||||
"name": "geld.nder.be",
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/android-chrome-36x36.png?v=Lb54KlrQnz",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "\/android-chrome-48x48.png?v=Lb54KlrQnz",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-chrome-72x72.png?v=Lb54KlrQnz",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "\/android-chrome-96x96.png?v=Lb54KlrQnz",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-chrome-144x144.png?v=Lb54KlrQnz",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-chrome-192x192.png?v=Lb54KlrQnz",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
"name": "Firefly III",
|
||||
"short_name": "Firefly III",
|
||||
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/android-chrome-36x36.png?v=Lb54KlrQnz",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "\/android-chrome-48x48.png?v=Lb54KlrQnz",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-chrome-72x72.png?v=Lb54KlrQnz",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "\/android-chrome-96x96.png?v=Lb54KlrQnz",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-chrome-144x144.png?v=Lb54KlrQnz",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-chrome-192x192.png?v=Lb54KlrQnz",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"orientation": "portrait"
|
||||
}
|
||||
|
@ -13,10 +13,6 @@
|
||||
Welkome to <a style="color:#337ab7" href="{{ address }}">
|
||||
<span itemprop="name">Firefly III</span></a>. Your registration has made it, and this email is here to confirm it. Yay!
|
||||
</p>
|
||||
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:13px;">
|
||||
You can now continue on <span itemprop="url"><a href="{{ address }}">{{ address }}</a></span>, if you weren't there already.
|
||||
</p>
|
||||
|
||||
|
||||
<ul>
|
||||
<li style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:13px;">
|
||||
|
@ -15,7 +15,11 @@
|
||||
<a href="{{ route('accounts.show',income.id) }}" title="{{ income.name }}">{{ income.name }}</a>
|
||||
{% if income.count > 1 %}
|
||||
<br/>
|
||||
<small>{{ income.count }} {{ 'transactions'|_|lower }}</small>
|
||||
<small>
|
||||
{{ income.count }} {{ 'transactions'|_|lower }}
|
||||
<i class="fa fa-fw text-muted fa-info-circle"></i>
|
||||
</small>
|
||||
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ income.amount|formatAmount }}</td>
|
||||
|
Loading…
Reference in New Issue
Block a user