Compare commits

..

127 Commits
4.3.2 ... 4.3.3

Author SHA1 Message Date
James Cole
0f929faa16 Merge branch 'release/4.3.3' 2017-01-30 11:18:29 +01:00
James Cole
7a40c34cf0 New change log. 2017-01-30 11:18:02 +01:00
James Cole
462d987de9 Merge pull request #532 from firefly-iii/l10n_develop
New Crowdin translations
2017-01-30 11:11:36 +01:00
James Cole
f64e8d8973 Composer update. [skip ci] 2017-01-30 11:10:34 +01:00
James Cole
21222eb697 Mention new version. 2017-01-30 10:33:44 +01:00
James Cole
e47d6fb3ac Move default option to bottom. 2017-01-30 10:33:18 +01:00
James Cole
c7fc10ac89 Remove debug statements. 2017-01-30 08:32:16 +01:00
James Cole
e8b528f520 New translations 2017-01-29 22:05:43 +01:00
James Cole
b22de7bf70 New translations 2017-01-29 22:05:38 +01:00
James Cole
ec119c8f6e Translated 2017-01-29 21:55:32 +01:00
James Cole
a20b38598e New translations 2017-01-29 21:45:32 +01:00
James Cole
aa0eb47205 New translations 2017-01-29 21:35:31 +01:00
James Cole
723db9d71e New translations 2017-01-29 13:36:21 +01:00
James Cole
1d8dc3d65d Approved. Step name: Proofread 2017-01-24 16:17:57 +01:00
James Cole
fe2716876a New translations 2017-01-24 15:44:55 +01:00
James Cole
fac0e97e5d New translations 2017-01-24 15:44:27 +01:00
James Cole
449d009c28 New translations 2017-01-24 15:43:49 +01:00
James Cole
55b2e6fe25 New translations 2017-01-24 15:43:36 +01:00
James Cole
9989b3b9da New translations 2017-01-24 15:43:27 +01:00
James Cole
7ab1cbfc1f New translations 2017-01-24 15:43:13 +01:00
James Cole
62d19c3902 New translations 2017-01-24 15:42:34 +01:00
James Cole
19700e7ee3 New translations 2017-01-24 15:42:08 +01:00
James Cole
de3e8edd6d New translations 2017-01-24 15:41:44 +01:00
James Cole
deda48af4a New translations 2017-01-24 15:41:32 +01:00
James Cole
7688d7c619 Include trigger that responds to tags 2017-01-24 15:38:41 +01:00
James Cole
76328b5c45 New translations 2017-01-24 15:11:51 +01:00
James Cole
1de17bf06f New translations 2017-01-24 15:11:31 +01:00
James Cole
6724daf995 New translations 2017-01-24 15:11:11 +01:00
James Cole
7caca053a1 New translations 2017-01-24 15:10:54 +01:00
James Cole
ae1bf8c017 New translations 2017-01-24 15:10:33 +01:00
James Cole
d20b0da438 Approved. Step name: Proofread 2017-01-24 15:10:11 +01:00
James Cole
a0218d7df1 New translations 2017-01-24 15:09:55 +01:00
James Cole
5ae5d67b91 New translations 2017-01-24 15:09:39 +01:00
James Cole
8493ed7603 New translations 2017-01-24 15:09:28 +01:00
James Cole
804b681d40 New translations 2017-01-24 15:09:18 +01:00
James Cole
e8303bd059 Expand the multi-select to various other fields. 2017-01-24 15:07:01 +01:00
James Cole
ac6c5d4e32 New translations 2017-01-24 13:57:08 +01:00
James Cole
90b0d0d52c New translations 2017-01-24 13:37:12 +01:00
James Cole
4093bdbd3e New translations 2017-01-24 13:37:08 +01:00
James Cole
a2097cf981 New translations 2017-01-24 13:27:14 +01:00
James Cole
6a33d0c9dc New translations 2017-01-24 13:27:07 +01:00
James Cole
525d5fb427 New translations 2017-01-24 13:17:40 +01:00
James Cole
e4946b8cd5 New translations 2017-01-24 13:17:35 +01:00
James Cole
76b32df622 Remove nightly. 2017-01-24 12:33:16 +01:00
James Cole
bc1079364d This should fix the nightly. No more hhvm. 2017-01-24 12:24:02 +01:00
James Cole
8602febe9d If/then thing for HHVM 2017-01-24 12:15:52 +01:00
James Cole
d55dfe27dc Updated test script 2017-01-24 12:08:06 +01:00
James Cole
90c16e2a07 Update travis.yml. 2017-01-24 11:49:05 +01:00
James Cole
149c1cd9b1 Approved. Step name: Proofread 2017-01-24 08:17:31 +01:00
James Cole
20f1a43369 Approved. Step name: Proofread 2017-01-24 08:17:20 +01:00
James Cole
e8fb8f993d Approved. Step name: Proofread 2017-01-24 08:07:14 +01:00
James Cole
f0c782dc01 New translations 2017-01-24 08:03:02 +01:00
James Cole
50c13e6d20 New translations 2017-01-24 08:02:44 +01:00
James Cole
69bedd035f New translations 2017-01-24 08:02:30 +01:00
James Cole
85337f0a31 New translations 2017-01-24 08:02:22 +01:00
James Cole
f8a7e2f98e New translations 2017-01-24 08:02:15 +01:00
James Cole
ec90a49d43 New translations 2017-01-24 08:02:07 +01:00
James Cole
5812b150c6 New translations 2017-01-24 08:01:45 +01:00
James Cole
c7ebc7273f Translated 2017-01-24 08:01:36 +01:00
James Cole
5226c87304 Translated 2017-01-24 08:01:35 +01:00
James Cole
25dd1c5d35 New translations 2017-01-24 08:01:31 +01:00
James Cole
c5a9e5e56d New translations 2017-01-24 08:01:26 +01:00
James Cole
47ed70d671 New translations 2017-01-24 08:01:20 +01:00
James Cole
cb5526f469 New translations 2017-01-24 08:01:14 +01:00
James Cole
a4f128077f New translations 2017-01-24 08:01:10 +01:00
James Cole
7140ba76d5 Small language things [skip ci] 2017-01-24 07:53:46 +01:00
James Cole
872e8f2de6 Hip new multi select. 2017-01-24 07:37:29 +01:00
James Cole
6c14e9d083 No sleep for the wicked [skip ci] 2017-01-24 07:26:06 +01:00
James Cole
e4b1812b46 Fix small layout thing [skip ci] 2017-01-23 18:03:17 +01:00
James Cole
1c2c6bb1d0 Various small changes. 2017-01-22 11:23:56 +01:00
James Cole
baefd4f93b Two new rule triggers 2017-01-22 11:23:40 +01:00
James Cole
4270fe07ab Rules now have auto-complete. 2017-01-22 09:15:53 +01:00
James Cole
e4ae925d2b Include typeahead [skip ci] 2017-01-21 13:34:41 +01:00
James Cole
dc599361a4 Removed unused method. 2017-01-21 09:15:33 +01:00
James Cole
738a311f49 Various code cleanup. 2017-01-21 09:07:10 +01:00
James Cole
71f6ba3418 Make request code more uniform. 2017-01-21 08:32:23 +01:00
James Cole
d1d573c408 Fix some tests. 2017-01-20 19:50:32 +01:00
James Cole
50e39a4a75 Update rule controller to have some auto complete functionality. 2017-01-20 19:50:22 +01:00
James Cole
8635fe7ebb Update requests to use uniform methods. 2017-01-20 19:49:35 +01:00
James Cole
6b57d4397a Try with “true” instead of “1”. 2017-01-20 16:27:30 +01:00
James Cole
8f2b898b2b Update some tests. 2017-01-20 16:22:19 +01:00
James Cole
0d1d360d18 Can now clone transaction #538. Wasn’t that difficult. 2017-01-20 12:23:52 +01:00
James Cole
def3b3a155 Fix for #539 2017-01-20 12:23:09 +01:00
James Cole
d344512743 Update update and installation instructions. 2017-01-20 10:08:38 +01:00
James Cole
19eef71133 Make sure all date fields have a fallback. 2017-01-20 08:18:52 +01:00
James Cole
61d58a354e Various code cleanup. 2017-01-20 08:03:26 +01:00
James Cole
be868d37f2 Fixed some issues with the monthly report and missing amounts. 2017-01-19 21:54:27 +01:00
James Cole
20bb151cf3 Add updated_at value. 2017-01-18 07:28:49 +01:00
James Cole
77f889aba6 Include a batch of naughty strings to see what happens to Firefly. 2017-01-16 20:10:47 +01:00
James Cole
1e69a54972 Small JS issue. [skip ci] 2017-01-15 20:18:32 +01:00
James Cole
6b7a47ca28 Clean up JS. 2017-01-15 20:10:34 +01:00
James Cole
c3fdd3b5f7 Allow date picker for browsers that do not support it natively. See issue #535 2017-01-15 20:05:40 +01:00
James Cole
e9f2121667 Fix menu in Firefox. 2017-01-15 19:45:57 +01:00
James Cole
161e9e1e11 Final JS cleanup. 2017-01-15 19:28:54 +01:00
James Cole
e336a45f79 Edit JS file for split transaction 2017-01-15 19:16:46 +01:00
James Cole
9c09f93908 Update views and JS for delete (single) transaction. 2017-01-15 19:08:16 +01:00
James Cole
582398e7f6 Update views and JS for create (single) transaction. 2017-01-15 19:07:31 +01:00
James Cole
b118635abd Update views and JS for edit single transaction. 2017-01-15 19:00:06 +01:00
James Cole
ac0d4a75b5 Removed forgotten twig comment [skip ci] 2017-01-15 15:46:58 +01:00
James Cole
c212d5c5ea Order by date does not matter in this context. 2017-01-14 21:00:43 +01:00
James Cole
08ac27cccf Fix some scrutiniser issues. 2017-01-14 19:43:33 +01:00
James Cole
0b5cab99cf Fix some scrutiniser issues. 2017-01-14 18:52:52 +01:00
James Cole
cc0057cc56 Rename command [skip ci] 2017-01-14 17:24:30 +01:00
James Cole
1ce49b814b Fix rounding. [skip ci] 2017-01-14 17:23:47 +01:00
James Cole
5bbaaece38 Encryption is optional (but on by default) and a command to switch from one to the other 2017-01-14 17:13:57 +01:00
James Cole
30bc4ccfa7 More date fixes [skip ci] 2017-01-13 21:16:54 +01:00
James Cole
4f64f1d754 Force order by. [skip ci] 2017-01-13 21:14:46 +01:00
James Cole
c0e578dd47 Fix bug found by persistent user who kept mailing me about broken charts. Which turned out to be broken indeed! 2017-01-13 21:12:59 +01:00
James Cole
2b82fca2cf Small various bugs. 2017-01-13 20:48:51 +01:00
James Cole
f0028b33e9 Double check that deleted transaction journals are not included. 2017-01-13 16:12:09 +01:00
James Cole
7ddea23375 Merge branch 'master' into develop
* master:
  add firefly locales to Dockerfile fixes #521 for docker environment
  Code for 4.1.6
2017-01-12 20:58:06 +01:00
James Cole
83edccacc6 Delete CONTRIBUTING 2017-01-12 09:40:12 +01:00
James Cole
75e95d6452 With markdown 2017-01-12 09:39:53 +01:00
James Cole
423bb4bbcd Better layout 2017-01-12 09:37:12 +01:00
James Cole
43585c563c Merge pull request #534 from elohmeier/master
add firefly locales to Dockerfile
2017-01-12 08:48:58 +01:00
Enno Lohmeier
2564a41d05 add firefly locales to Dockerfile
fixes #521 for docker environment
2017-01-12 00:30:33 +01:00
James Cole
a0bb1e3625 CSS fix for #533 2017-01-10 19:55:52 +01:00
James Cole
9b4fd57f51 Optimize new JS code. 2017-01-10 18:35:00 +01:00
James Cole
e67709e339 Make index significantly simpler. 2017-01-10 18:25:03 +01:00
James Cole
0c4e913f30 New translations 2017-01-10 13:06:37 +01:00
James Cole
c6de0e51c7 New translations 2017-01-10 13:06:29 +01:00
James Cole
69e85adadf New translations 2017-01-10 12:54:39 +01:00
James Cole
b34068207f New translations 2017-01-10 12:54:32 +01:00
James Cole
68b7b4b3a4 New translations 2017-01-10 12:45:24 +01:00
James Cole
5e3ee30e66 New translations 2017-01-10 12:45:15 +01:00
James Cole
aaf7d12b46 New translations 2017-01-10 12:45:12 +01:00
James Cole
729a348657 New translations 2017-01-10 12:36:17 +01:00
165 changed files with 4886 additions and 1374 deletions

View File

@@ -43,6 +43,7 @@ CACHE_PREFIX=firefly
GOOGLE_MAPS_API_KEY=
ANALYTICS_ID=
SITE_OWNER=mail@example.com
USE_ENCRYPTION=true
PUSHER_KEY=
PUSHER_SECRET=

View File

@@ -1 +0,0 @@
If you are requesting a new feature, please check out the list of [often requested features](https://firefly-iii.github.io/requested-features/) first. Thanks!

7
.github/CONTRIBUTING.md vendored Normal file
View File

@@ -0,0 +1,7 @@
## Hi there!
Thank you for taking the time to report an issue or requesting a new feature.
Please take note that there are NO rules or regulations when you submit an issue.
If you are requesting a new feature, please check out the list of [often requested features](https://firefly-iii.github.io/requested-features/).

View File

@@ -1,12 +1,18 @@
language: php
sudo: false
php:
- '7.0'
- 7.0
- 7.1
cache:
directories:
- vendor
- $HOME/.composer/cache
install:
- phpenv config-rm xdebug.ini
- if [[ "$(php -v | grep 'PHP 7')" ]]; then phpenv config-rm xdebug.ini; fi
- rm composer.lock
- composer update --no-scripts
- cp .env.testing .env
- php artisan clear-compiled
- php artisan optimize
- php artisan env

View File

@@ -2,6 +2,28 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [4.3.3] - 2017-01-30
_The 100th release of Firefly!_
### Added
- Add locales to Docker (#534) by @elohmeier.
- Optional database encryption. On by default.
- Datepicker for Firefox and other browsers.
- New instruction block for updating and installing.
- Ability to clone transactions.
- Use multi-select Bootstrap thing instead of massive lists of checkboxes.
### Removed
- Lots of old Javascript
### Fixed
- Missing sort broke various charts
- Bug in reports that made amounts behave weird
- Various bug fixes
### Security
- Tested FF against the naughty string list.
## [4.3.2] - 2017-01-09

View File

@@ -11,12 +11,16 @@ RUN apt-get update -y && \
libtidy-dev \
libxml2-dev \
libsqlite3-dev \
libbz2-dev && \
libbz2-dev \
locales && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-install -j$(nproc) curl gd intl json mcrypt readline tidy zip bcmath xml mbstring pdo_sqlite pdo_mysql bz2
# Generate locales supported by firefly
RUN echo "en_US.UTF-8 UTF-8\nde_DE.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npt_BR.UTF-8 UTF-8" > /etc/locale.gen && locale-gen
# Enable apache mod rewrite..
RUN a2enmod rewrite

View File

@@ -35,7 +35,7 @@ class EncryptFile extends Command
*
* @var string
*/
protected $signature = 'firefly:encrypt {file} {key}';
protected $signature = 'firefly:encrypt-file {file} {key}';
/**
* Create a new command instance.

View File

@@ -33,7 +33,7 @@ class UpgradeFireflyInstructions extends Command
*
* @var string
*/
protected $signature = 'firefly:upgrade-instructions';
protected $signature = 'firefly:instructions {task}';
/**
* Create a new command instance.
@@ -49,11 +49,60 @@ class UpgradeFireflyInstructions extends Command
*/
public function handle()
{
//
if ($this->argument('task') == 'update') {
$this->updateInstructions();
}
if ($this->argument('task') == 'install') {
$this->installInstructions();
}
}
/**
* Show a nice box
*
* @param string $text
*/
private function boxed(string $text)
{
$parts = explode("\n", wordwrap($text));
foreach ($parts as $string) {
$this->line('| ' . sprintf('%-77s', $string) . '|');
}
}
/**
* Show a nice info box
*
* @param string $text
*/
private function boxedInfo(string $text)
{
$parts = explode("\n", wordwrap($text));
foreach ($parts as $string) {
$this->info('| ' . sprintf('%-77s', $string) . '|');
}
}
/**
* Show a line
*/
private function showLine()
{
$line = '+';
for ($i = 0; $i < 78; $i++) {
$line .= '-';
}
$line .= '+';
$this->line($line);
}
private function installInstructions() {
/** @var string $version */
$version = config('firefly.version');
$config = config('upgrade.text');
$text = null;
$config = config('upgrade.text.install');
$text = '';
foreach (array_keys($config) as $compare) {
// if string starts with:
$len = strlen($compare);
@@ -62,22 +111,53 @@ class UpgradeFireflyInstructions extends Command
}
}
$this->showLine();
$this->boxed('');
if (is_null($text)) {
$this->line(sprintf('Thank you for installing Firefly III, v%s', $version));
$this->info('There are no extra upgrade instructions.');
$this->line('Firefly III should be ready for use.');
$this->boxed(sprintf('Thank you for installin Firefly III, v%s!', $version));
$this->boxedInfo('There are no extra installation instructions.');
$this->boxed('Firefly III should be ready for use.');
$this->boxed('');
$this->showLine();
return;
}
$this->line('+------------------------------------------------------------------------------+');
$this->line('');
$this->line(sprintf('Thank you for installing Firefly III, v%s', $version));
$this->info(wordwrap($text));
$this->line('');
$this->line('+------------------------------------------------------------------------------+');
$this->boxed(sprintf('Thank you for installing Firefly III, v%s!', $version));
$this->boxedInfo($text);
$this->boxed('');
$this->showLine();
}
private function updateInstructions()
{
/** @var string $version */
$version = config('firefly.version');
$config = config('upgrade.text.upgrade');
$text = '';
foreach (array_keys($config) as $compare) {
// if string starts with:
$len = strlen($compare);
if (substr($version, 0, $len) === $compare) {
$text = $config[$compare];
}
}
$this->showLine();
$this->boxed('');
if (is_null($text)) {
$this->boxed(sprintf('Thank you for updating to Firefly III, v%s', $version));
$this->boxedInfo('There are no extra upgrade instructions.');
$this->boxed('Firefly III should be ready for use.');
$this->boxed('');
$this->showLine();
return;
}
$this->boxed(sprintf('Thank you for updating to Firefly III, v%s!', $version));
$this->boxedInfo($text);
$this->boxed('');
$this->showLine();
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace FireflyIII\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
class UseEncryption extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'This command will make sure that entries in the database will be encrypted (or not) according to the settings in .env';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly:use-encryption';
/**
* Create a new command instance.
*
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
{
//
$this->handleObjects('Account', 'name', 'encrypted');
$this->handleObjects('Bill', 'name', 'name_encrypted');
$this->handleObjects('Bill', 'match', 'match_encrypted');
$this->handleObjects('Budget', 'name', 'encrypted');
$this->handleObjects('Category', 'name', 'encrypted');
$this->handleObjects('PiggyBank', 'name', 'encrypted');
$this->handleObjects('TransactionJournal', 'description', 'encrypted');
}
/**
* @param string $class
* @param string $field
* @param string $indicator
*/
public function handleObjects(string $class, string $field, string $indicator)
{
$fqn = sprintf('FireflyIII\Models\%s', $class);
$encrypt = config('firefly.encryption') ? 0 : 1;
$set = $fqn::where($indicator, $encrypt)->get();
foreach ($set as $entry) {
$newName = $entry->$field;
$entry->$field = $newName;
$entry->save();
}
$this->line(sprintf('Updated %d %s.', $set->count(), strtolower(Str::plural($class))));
}
}

View File

@@ -16,10 +16,10 @@ namespace FireflyIII\Console;
use FireflyIII\Console\Commands\CreateImport;
use FireflyIII\Console\Commands\EncryptFile;
use FireflyIII\Console\Commands\Import;
use FireflyIII\Console\Commands\MoveRepository;
use FireflyIII\Console\Commands\ScanAttachments;
use FireflyIII\Console\Commands\UpgradeDatabase;
use FireflyIII\Console\Commands\UpgradeFireflyInstructions;
use FireflyIII\Console\Commands\UseEncryption;
use FireflyIII\Console\Commands\VerifyDatabase;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
@@ -63,6 +63,7 @@ class Kernel extends ConsoleKernel
EncryptFile::class,
ScanAttachments::class,
UpgradeDatabase::class,
UseEncryption::class,
];
/**

View File

@@ -111,9 +111,9 @@ class Handler extends ExceptionHandler
/**
* Convert an authentication exception into an unauthenticated response.
*
* @param \Illuminate\Http\Request $request
* @param $request
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
*/
protected function unauthenticated($request)
{

View File

@@ -51,7 +51,6 @@ final class Entry
public $destination_account_id;
public $destination_account_name;
public $budget_id;
public $budget_name;
public $category_id;
@@ -74,15 +73,15 @@ final class Entry
{
$entry = new self;
$entry->journal_id = $object->transaction_journal_id;
$entry->description = self::decrypt($object->journal_encrypted, $object->journal_description);
$entry->description = self::decrypt(intval($object->journal_encrypted), $object->journal_description);
$entry->amount = $object->amount;
$entry->date = $object->date;
$entry->transaction_type = $object->transaction_type;
$entry->currency_code = $object->transaction_currency_code;
$entry->source_account_id = $object->account_id;
$entry->source_account_name = self::decrypt($object->account_name_encrypted, $object->account_name);
$entry->source_account_name = self::decrypt(intval($object->account_name_encrypted), $object->account_name);
$entry->destination_account_id = $object->opposing_account_id;
$entry->destination_account_name = self::decrypt($object->opposing_account_encrypted, $object->opposing_account_name);
$entry->destination_account_name = self::decrypt(intval($object->opposing_account_encrypted), $object->opposing_account_name);
$entry->category_id = $object->category_id ?? '';
$entry->category_name = $object->category_name ?? '';
$entry->budget_id = $object->budget_id ?? '';

View File

@@ -32,9 +32,9 @@ class AttachmentHelper implements AttachmentHelperInterface
/** @var MessageBag */
public $messages;
/** @var array */
protected $allowedMimes;
protected $allowedMimes = [];
/** @var int */
protected $maxUploadSize;
protected $maxUploadSize = 0;
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
protected $uploadDisk;
@@ -44,8 +44,8 @@ class AttachmentHelper implements AttachmentHelperInterface
*/
public function __construct()
{
$this->maxUploadSize = config('firefly.maxUploadSize');
$this->allowedMimes = config('firefly.allowedMimes');
$this->maxUploadSize = intval(config('firefly.maxUploadSize'));
$this->allowedMimes = (array) config('firefly.allowedMimes');
$this->errors = new MessageBag;
$this->messages = new MessageBag;
$this->uploadDisk = Storage::disk('upload');

View File

@@ -1,107 +0,0 @@
<?php
/**
* Account.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use Illuminate\Support\Collection;
/**
* Class Account
*
* @package FireflyIII\Helpers\Collection
*/
class Account
{
/** @var Collection */
protected $accounts;
/** @var string */
protected $difference = '';
/** @var string */
protected $end = '';
/** @var string */
protected $start = '';
/**
* Account constructor.
*/
public function __construct()
{
$this->accounts = new Collection;
}
/**
* @return Collection
*/
public function getAccounts(): Collection
{
return $this->accounts;
}
/**
* @param Collection $accounts
*/
public function setAccounts(Collection $accounts)
{
$this->accounts = $accounts;
}
/**
* @return string
*/
public function getDifference(): string
{
return $this->difference;
}
/**
* @param string $difference
*/
public function setDifference(string $difference)
{
$this->difference = $difference;
}
/**
* @return string
*/
public function getEnd(): string
{
return $this->end;
}
/**
* @param string $end
*/
public function setEnd(string $end)
{
$this->end = $end;
}
/**
* @return string
*/
public function getStart(): string
{
return $this->start;
}
/**
* @param string $start
*/
public function setStart(string $start)
{
$this->start = $start;
}
}

View File

@@ -167,6 +167,7 @@ class JournalCollector implements JournalCollectorInterface
public function getJournals(): Collection
{
$this->run = true;
/** @var Collection $set */
$set = $this->query->get(array_values($this->fields));
Log::debug(sprintf('Count of set is %d', $set->count()));
$set = $this->filterTransfers($set);

View File

@@ -75,6 +75,11 @@ class AccountController extends Controller
$defaultCurrency = Amount::getDefaultCurrency();
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
$subTitle = trans('firefly.make_new_' . $what . '_account');
$roles = [];
foreach (config('firefly.accountRoles') as $role) {
$roles[$role] = strval(trans('firefly.account_role_' . $role));
}
// pre fill some data
Session::flash('preFilled', ['currency_id' => $defaultCurrency->id,]);
@@ -87,7 +92,7 @@ class AccountController extends Controller
Session::flash('gaEventCategory', 'accounts');
Session::flash('gaEventAction', 'create-' . $what);
return view('accounts.create', compact('subTitleIcon', 'what', 'subTitle', 'currencies'));
return view('accounts.create', compact('subTitleIcon', 'what', 'subTitle', 'currencies', 'roles'));
}
@@ -155,6 +160,11 @@ class AccountController extends Controller
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$currencies = ExpandedForm::makeSelectList($repository->get());
$roles = [];
foreach (config('firefly.accountRoles') as $role) {
$roles[$role] = strval(trans('firefly.account_role_' . $role));
}
// put previous url in session if not redirect from store (not "return_to_edit").
if (session('accounts.edit.fromUpdate') !== true) {
@@ -185,7 +195,7 @@ class AccountController extends Controller
Session::flash('gaEventCategory', 'accounts');
Session::flash('gaEventAction', 'edit-' . $what);
return view('accounts.edit', compact('currencies', 'account', 'subTitle', 'subTitleIcon', 'openingBalance', 'what'));
return view('accounts.edit', compact('currencies', 'account', 'subTitle', 'subTitleIcon', 'openingBalance', 'what', 'roles'));
}
/**

View File

@@ -18,6 +18,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Requests\AttachmentFormRequest;
use FireflyIII\Models\Attachment;
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use Illuminate\Http\Response as LaravelResponse;
use Preferences;
use Response;
use Session;
@@ -100,7 +101,9 @@ class AttachmentController extends Controller
$content = $repository->getContent($attachment);
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
return response($content, 200)
/** @var LaravelResponse $response */
$response = response($content, 200);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename=' . $quoted)
@@ -110,6 +113,8 @@ class AttachmentController extends Controller
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', strlen($content));
return $response;
}
throw new FireflyException('Could not find the indicated attachment. The file is no longer there.');
}

View File

@@ -278,8 +278,6 @@ class BudgetController extends Controller
throw new FireflyException('This budget limit is not part of this budget.');
}
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
$page = intval($request->get('page')) == 0 ? 1 : intval($request->get('page'));
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
$subTitle = trans(
@@ -289,7 +287,6 @@ class BudgetController extends Controller
'end' => $budgetLimit->end_date->formatLocalized($this->monthAndDayFormat),
]
);
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::CASH]);
// collector:
/** @var JournalCollectorInterface $collector */

View File

@@ -24,6 +24,7 @@ use FireflyIII\Models\ExportJob;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface;
use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface as EJRI;
use Illuminate\Http\Response as LaravelResponse;
use Preferences;
use Response;
use View;
@@ -73,8 +74,9 @@ class ExportController extends Controller
$job->change('export_downloaded');
return response($content, 200)
/** @var LaravelResponse $response */
$response = response($content, 200);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename=' . $quoted)
@@ -85,6 +87,8 @@ class ExportController extends Controller
->header('Pragma', 'public')
->header('Content-Length', strlen($content));
return $response;
}
/**
@@ -128,8 +132,7 @@ class ExportController extends Controller
* @param AccountRepositoryInterface $repository
* @param EJRI $jobs
*
* @return string
*
* @return \Illuminate\Http\JsonResponse
*/
public function postIndex(ExportFormRequest $request, AccountRepositoryInterface $repository, EJRI $jobs)
{

View File

@@ -21,6 +21,7 @@ use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Http\Request;
use Illuminate\Http\Response as LaravelResponse;
use Log;
use Response;
use Session;
@@ -120,15 +121,18 @@ class ImportController extends Controller
$result = json_encode($config, JSON_PRETTY_PRINT);
$name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\'));
return response($result, 200)
->header('Content-disposition', 'attachment; filename=' . $name)
->header('Content-Type', 'application/json')
->header('Content-Description', 'File Transfer')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', strlen($result));
/** @var LaravelResponse $response */
$response = response($result, 200);
$response->header('Content-disposition', 'attachment; filename=' . $name)
->header('Content-Type', 'application/json')
->header('Content-Description', 'File Transfer')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', strlen($result));
return $response;
}

View File

@@ -0,0 +1,132 @@
<?php
/**
* JavascriptController.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Amount;
use FireflyIII\Exceptions\FireflyException;
use Navigation;
use Preferences;
use Session;
/**
* Class JavascriptController
*
* @package FireflyIII\Http\Controllers
*/
class JavascriptController extends Controller
{
/**
*
*/
public function variables()
{
$picker = $this->getDateRangePicker();
$start = Session::get('start');
$end = Session::get('end');
$linkTitle = sprintf('%s - %s', $start->formatLocalized($this->monthAndDayFormat), $end->formatLocalized($this->monthAndDayFormat));
$firstDate = session('first')->format('Y-m-d');
$localeconv = localeconv();
$accounting = Amount::getJsConfig($localeconv);
$localeconv = localeconv();
$defaultCurrency = Amount::getDefaultCurrency();
$localeconv['frac_digits'] = $defaultCurrency->decimal_places;
$pref = Preferences::get('language', config('firefly.default_language', 'en_US'));
$lang = $pref->data;
$data = [
'picker' => $picker,
'linkTitle' => $linkTitle,
'firstDate' => $firstDate,
'currencyCode' => Amount::getCurrencyCode(),
'currencySymbol' => Amount::getCurrencySymbol(),
'accounting' => $accounting,
'localeconv' => $localeconv,
'language' => $lang,
];
return response()
->view('javascript.variables', $data, 200)
->header('Content-Type', 'text/javascript');
}
/**
* @return array
* @throws FireflyException
*/
private function getDateRangePicker(): array
{
$viewRange = Preferences::get('viewRange', '1M')->data;
$start = Session::get('start');
$end = Session::get('end');
$prevStart = clone $start;
$prevEnd = clone $start;
$nextStart = clone $end;
$nextEnd = clone $end;
if ($viewRange === 'custom') {
$days = $start->diffInDays($end);
$prevStart->subDays($days);
$nextEnd->addDays($days);
unset($days);
}
if ($viewRange !== 'custom') {
$prevStart = Navigation::subtractPeriod($start, $viewRange);// subtract for previous period
$prevEnd = Navigation::endOfPeriod($prevStart, $viewRange);
$nextStart = Navigation::addPeriod($start, $viewRange, 0); // add for previous period
$nextEnd = Navigation::endOfPeriod($nextStart, $viewRange);
}
$ranges = [];
$ranges['current'] = [$start->format('Y-m-d'), $end->format('Y-m-d')];
$ranges['previous'] = [$prevStart->format('Y-m-d'), $prevEnd->format('Y-m-d')];
$ranges['next'] = [$nextStart->format('Y-m-d'), $nextEnd->format('Y-m-d')];
switch ($viewRange) {
default:
throw new FireflyException('The date picker does not yet support "' . $viewRange . '".');
case '1D':
case 'custom':
$format = (string)trans('config.month_and_day');
break;
case '3M':
$format = (string)trans('config.quarter_in_year');
break;
case '6M':
$format = (string)trans('config.half_year');
break;
case '1Y':
$format = (string)trans('config.year');
break;
case '1M':
$format = (string)trans('config.month');
break;
case '1W':
$format = (string)trans('config.week_in_year');
break;
}
$current = $start->formatLocalized($format);
$next = $nextStart->formatLocalized($format);
$prev = $prevStart->formatLocalized($format);
return [
'start' => $start->format('Y-m-d'),
'end' => $end->format('Y-m-d'),
'current' => $current,
'previous' => $prev,
'next' => $next,
'ranges' => $ranges,
];
}
}

View File

@@ -20,7 +20,9 @@ use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Account\AccountTaskerInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Http\Request;
@@ -61,6 +63,43 @@ class JsonController extends Controller
return Response::json(['html' => $view]);
}
/**
* Returns a JSON list of all accounts.
*
* @param AccountRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*
*/
public function allAccounts(AccountRepositoryInterface $repository)
{
$return = array_unique(
$repository->getAccountsByType(
[AccountType::REVENUE, AccountType::EXPENSE, AccountType::BENEFICIARY, AccountType::DEFAULT, AccountType::ASSET]
)->pluck('name')->toArray()
);
sort($return);
return Response::json($return);
}
/**
* @param JournalCollectorInterface $collector
*
* @return \Illuminate\Http\JsonResponse
*/
public function allTransactionJournals(JournalCollectorInterface $collector)
{
$collector->setLimit(100)->setPage(1);
$return = array_unique($collector->getJournals()->pluck('description')->toArray());
sort($return);
return Response::json($return);
}
/**
* @param BillRepositoryInterface $repository
*
@@ -158,19 +197,29 @@ class JsonController extends Controller
}
/**
* Returns a list of categories.
*
* @param CRI $repository
* @param BudgetRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*/
public function categories(CRI $repository)
public function budgets(BudgetRepositoryInterface $repository)
{
$list = $repository->getCategories();
$return = [];
foreach ($list as $entry) {
$return[] = $entry->name;
}
$return = array_unique($repository->getBudgets()->pluck('name')->toArray());
sort($return);
return Response::json($return);
}
/**
* Returns a list of categories.
*
* @param CategoryRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*/
public function categories(CategoryRepositoryInterface $repository)
{
$return = array_unique($repository->getCategories()->pluck('name')->toArray());
sort($return);
return Response::json($return);
}
@@ -195,14 +244,10 @@ class JsonController extends Controller
*/
public function expenseAccounts(AccountRepositoryInterface $repository)
{
$list = $repository->getAccountsByType([AccountType::EXPENSE, AccountType::BENEFICIARY]);
$return = [];
foreach ($list as $entry) {
$return[] = $entry->name;
}
$return = array_unique($repository->getAccountsByType([AccountType::EXPENSE, AccountType::BENEFICIARY])->pluck('name')->toArray());
sort($return);
return Response::json($return);
}
/**
@@ -213,14 +258,10 @@ class JsonController extends Controller
*/
public function revenueAccounts(AccountRepositoryInterface $repository)
{
$list = $repository->getAccountsByType([AccountType::REVENUE]);
$return = [];
foreach ($list as $entry) {
$return[] = $entry->name;
}
$return = array_unique($repository->getAccountsByType([AccountType::REVENUE])->pluck('name')->toArray());
sort($return);
return Response::json($return);
}
/**
@@ -232,11 +273,8 @@ class JsonController extends Controller
*/
public function tags(TagRepositoryInterface $tagRepository)
{
$list = $tagRepository->get();
$return = [];
foreach ($list as $entry) {
$return[] = $entry->tag;
}
$return = array_unique($tagRepository->get()->pluck('tag')->toArray());
sort($return);
return Response::json($return);
@@ -278,25 +316,29 @@ class JsonController extends Controller
*/
public function transactionJournals(JournalCollectorInterface $collector, string $what)
{
$descriptions = [];
$type = config('firefly.transactionTypesByWhat.' . $what);
$types = [$type];
$type = config('firefly.transactionTypesByWhat.' . $what);
$types = [$type];
// use journal collector instead:
$collector->setTypes($types)->setLimit(100)->setPage(1);
$journals = $collector->getJournals();
foreach ($journals as $j) {
$descriptions[] = $j->description;
}
$return = array_unique($collector->getJournals()->pluck('description')->toArray());
sort($return);
$descriptions = array_unique($descriptions);
sort($descriptions);
return Response::json($descriptions);
return Response::json($return);
}
/**
*
*/
public function transactionTypes(JournalRepositoryInterface $repository)
{
$return = array_unique($repository->getTransactionTypes()->pluck('type')->toArray());
sort($return);
return Response::json($return);
}
/**
* @param Request $request
*

View File

@@ -230,6 +230,8 @@ class TagController extends Controller
public function show(Request $request, JournalCollectorInterface $collector, Tag $tag, string $moment = '')
{
$range = Preferences::get('viewRange', '1M')->data;
$start = new Carbon;
$end = new Carbon;
if (strlen($moment) > 0) {
try {

View File

@@ -163,11 +163,11 @@ class MassController extends Controller
$journal->transaction_count = $journal->transactions()->count();
if (!is_null($sources->first())) {
$journal->source_account_id = $sources->first()->id;
$journal->source_account_name = $sources->first()->name;
$journal->source_account_name = $sources->first()->editname;
}
if (!is_null($destinations->first())) {
$journal->destination_account_id = $destinations->first()->id;
$journal->destination_account_name = $destinations->first()->name;
$journal->destination_account_name = $destinations->first()->editname;
}
}
);
@@ -178,7 +178,7 @@ class MassController extends Controller
$journals = $filtered;
return view('transactions.mass-edit', compact('journals', 'subTitle', 'accountList'));
return view('transactions.mass.edit', compact('journals', 'subTitle', 'accountList'));
}
/**

View File

@@ -82,6 +82,42 @@ class SingleController extends Controller
}
public function cloneTransaction(TransactionJournal $journal)
{
$source = TransactionJournal::sourceAccountList($journal)->first();
$destination = TransactionJournal::destinationAccountList($journal)->first();
$budget = $journal->budgets()->first();
$budgetId = is_null($budget) ? 0 : $budget->id;
$category = $journal->categories()->first();
$categoryName = is_null($category) ? '' : $category->name;
$tags = join(',', $journal->tags()->get()->pluck('tag')->toArray());
$preFilled = [
'description' => $journal->description,
'source_account_id' => $source->id,
'source_account_name' => $source->name,
'destination_account_id' => $destination->id,
'destination_account_name' => $destination->name,
'amount' => TransactionJournal::amountPositive($journal),
'date' => $journal->date->format('Y-m-d'),
'budget_id' => $budgetId,
'category' => $categoryName,
'tags' => $tags,
'interest_date' => $journal->getMeta('interest_date'),
'book_date' => $journal->getMeta('book_date'),
'process_date' => $journal->getMeta('process_date'),
'due_date' => $journal->getMeta('due_date'),
'payment_date' => $journal->getMeta('payment_date'),
'invoice_date' => $journal->getMeta('invoice_date'),
'internal_reference' => $journal->getMeta('internal_reference'),
'notes' => $journal->getMeta('notes'),
];
Session::flash('preFilled', $preFilled);
return redirect(route('transactions.create', [strtolower($journal->transactionType->type)]));
}
/**
* @param string $what
*
@@ -113,7 +149,10 @@ class SingleController extends Controller
asort($piggies);
return view('transactions.create', compact('assetAccounts', 'subTitleIcon', 'uploadSize', 'budgets', 'what', 'piggies', 'subTitle', 'optionalFields'));
return view(
'transactions.single.create',
compact('assetAccounts', 'subTitleIcon', 'uploadSize', 'budgets', 'what', 'piggies', 'subTitle', 'optionalFields', 'preFilled')
);
}
/**
@@ -137,7 +176,7 @@ class SingleController extends Controller
Session::flash('gaEventCategory', 'transactions');
Session::flash('gaEventAction', 'delete-' . $what);
return view('transactions.delete', compact('journal', 'subTitle', 'what'));
return view('transactions.single.delete', compact('journal', 'subTitle', 'what'));
}
@@ -241,7 +280,7 @@ class SingleController extends Controller
Session::forget('transactions.edit.fromUpdate');
return view(
'transactions.edit',
'transactions.single.edit',
compact('journal', 'optionalFields', 'assetAccounts', 'what', 'budgetList', 'subTitle')
)->with('data', $preFilled);
}
@@ -265,6 +304,7 @@ class SingleController extends Controller
return redirect(route('transactions.create', [$request->input('what')]))->withInput();
}
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
$this->attachments->saveAttachmentsForModel($journal, $files);
@@ -315,7 +355,8 @@ class SingleController extends Controller
$data = $request->getJournalData();
$journal = $repository->update($journal, $data);
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
$this->attachments->saveAttachmentsForModel($journal, $files);
// flash errors

View File

@@ -112,7 +112,7 @@ class SplitController extends Controller
Session::forget('transactions.edit-split.fromUpdate');
return view(
'transactions.edit-split',
'transactions.split.edit',
compact(
'subTitleIcon', 'currencies', 'optionalFields',
'preFilled', 'subTitle', 'amount', 'sourceAccounts', 'uploadSize', 'destinationAccounts', 'assetAccounts',
@@ -138,6 +138,7 @@ class SplitController extends Controller
$data = $this->arrayFromInput($request);
$journal = $repository->updateSplitJournal($journal, $data);
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
// save attachments:
$this->attachments->saveAttachmentsForModel($journal, $files);

View File

@@ -72,9 +72,6 @@ class Range
// set view variables.
$this->configureView();
// get variables for date range:
$this->datePicker();
// set more view variables:
$this->configureList();
}
@@ -96,7 +93,6 @@ class Range
{
$pref = Preferences::get('language', config('firefly.default_language', 'en_US'));
$lang = $pref->data;
App::setLocale($lang);
Carbon::setLocale(substr($lang, 0, 2));
$locale = explode(',', trans('config.locale'));
@@ -105,94 +101,15 @@ class Range
setlocale(LC_TIME, $locale);
setlocale(LC_MONETARY, $locale);
// save some formats:
$monthFormat = (string)trans('config.month');
$monthAndDayFormat = (string)trans('config.month_and_day');
$dateTimeFormat = (string)trans('config.date_time');
$defaultCurrency = Amount::getDefaultCurrency();
$localeconv = localeconv();
$accounting = Amount::getJsConfig($localeconv);
// decimal places is overruled by TransactionCurrency
$localeconv['frac_digits'] = $defaultCurrency->decimal_places;
View::share('monthFormat', $monthFormat);
View::share('monthAndDayFormat', $monthAndDayFormat);
View::share('dateTimeFormat', $dateTimeFormat);
View::share('language', $lang);
View::share('localeconv', $localeconv);
View::share('defaultCurrency', $defaultCurrency);
View::share('accountingConfig', $accounting);
}
/**
* @throws FireflyException
*/
private function datePicker()
{
$viewRange = Preferences::get('viewRange', '1M')->data;
/** @var Carbon $start */
$start = Session::get('start');
/** @var Carbon $end */
$end = Session::get('end');
$prevStart = clone $start;
$prevEnd = clone $start;
$nextStart = clone $end;
$nextEnd = clone $end;
if ($viewRange === 'custom') {
$days = $start->diffInDays($end);
$prevStart->subDays($days);
$nextEnd->addDays($days);
unset($days);
}
if ($viewRange !== 'custom') {
$prevStart = Navigation::subtractPeriod($start, $viewRange);// subtract for previous period
$prevEnd = Navigation::endOfPeriod($prevStart, $viewRange);
$nextStart = Navigation::addPeriod($start, $viewRange, 0); // add for previous period
$nextEnd = Navigation::endOfPeriod($nextStart, $viewRange);
}
$ranges = [];
$ranges['current'] = [$start->format('Y-m-d'), $end->format('Y-m-d')];
$ranges['previous'] = [$prevStart->format('Y-m-d'), $prevEnd->format('Y-m-d')];
$ranges['next'] = [$nextStart->format('Y-m-d'), $nextEnd->format('Y-m-d')];
switch ($viewRange) {
default:
throw new FireflyException('The date picker does not yet support "' . $viewRange . '".');
case '1D':
case 'custom':
$format = (string)trans('config.month_and_day');
break;
case '3M':
$format = (string)trans('config.quarter_in_year');
break;
case '6M':
$format = (string)trans('config.half_year');
break;
case '1Y':
$format = (string)trans('config.year');
break;
case '1M':
$format = (string)trans('config.month');
break;
case '1W':
$format = (string)trans('config.week_in_year');
break;
}
$current = $start->formatLocalized($format);
$next = $nextStart->formatLocalized($format);
$prev = $prevStart->formatLocalized($format);
View::share('dpStart', $start->format('Y-m-d'));
View::share('dpEnd', $end->format('Y-m-d'));
View::share('dpCurrent', $current);
View::share('dpPrevious', $prev);
View::share('dpNext', $next);
View::share('dpRanges', $ranges);
}
/**

View File

@@ -13,7 +13,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Carbon\Carbon;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
@@ -39,21 +38,21 @@ class AccountFormRequest extends Request
public function getAccountData(): array
{
return [
'name' => trim(strval($this->input('name'))),
'active' => intval($this->input('active')) === 1,
'accountType' => $this->input('what'),
'currency_id' => intval($this->input('currency_id')),
'virtualBalance' => round($this->input('virtualBalance'), 12),
'virtualBalanceCurrency' => intval($this->input('amount_currency_id_virtualBalance')),
'iban' => trim(strval($this->input('iban'))),
'BIC' => trim(strval($this->input('BIC'))),
'accountNumber' => trim(strval($this->input('accountNumber'))),
'accountRole' => $this->input('accountRole'),
'openingBalance' => round($this->input('openingBalance'), 12),
'openingBalanceDate' => new Carbon((string)$this->input('openingBalanceDate')),
'openingBalanceCurrency' => intval($this->input('amount_currency_id_openingBalance')),
'ccType' => $this->input('ccType'),
'ccMonthlyPaymentDate' => $this->input('ccMonthlyPaymentDate'),
'name' => $this->string('name'),
'active' => $this->boolean('active'),
'accountType' => $this->string('what'),
'currency_id' => $this->integer('currency_id'),
'virtualBalance' => $this->float('virtualBalance'),
'virtualBalanceCurrency' => $this->integer('amount_currency_id_virtualBalance'),
'iban' => $this->string('iban'),
'BIC' => $this->string('BIC'),
'accountNumber' => $this->string('accountNumber'),
'accountRole' => $this->string('accountRole'),
'openingBalance' => $this->float('openingBalance'),
'openingBalanceDate' => $this->date('openingBalanceDate'),
'openingBalanceCurrency' => $this->integer('amount_currency_id_openingBalance'),
'ccType' => $this->string('ccType'),
'ccMonthlyPaymentDate' => $this->string('ccMonthlyPaymentDate'),
];
}
@@ -72,7 +71,7 @@ class AccountFormRequest extends Request
$idRule = '';
if (!is_null($repository->find(intval($this->get('id')))->id)) {
$idRule = 'belongsToUser:accounts';
$nameRule = 'required|min:1|uniqueAccountForUser:' . $this->get('id');
$nameRule = 'required|min:1|uniqueAccountForUser:' . intval($this->get('id'));
}
return [

View File

@@ -36,9 +36,9 @@ class AttachmentFormRequest extends Request
public function getAttachmentData(): array
{
return [
'title' => trim($this->input('title')),
'description' => trim($this->input('description')),
'notes' => trim($this->input('notes')),
'title' => $this->string('title'),
'description' => $this->string('description'),
'notes' => $this->string('notes'),
];
}

View File

@@ -13,8 +13,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Carbon\Carbon;
/**
* Class BillFormRequest
*
@@ -38,17 +36,17 @@ class BillFormRequest extends Request
public function getBillData()
{
return [
'name' => $this->get('name'),
'match' => $this->get('match'),
'amount_min' => round($this->get('amount_min'), 12),
'amount_currency_id_amount_min' => intval($this->get('amount_currency_id_amount_min')),
'amount_currency_id_amount_max' => intval($this->get('amount_currency_id_amount_max')),
'amount_max' => round($this->get('amount_max'), 12),
'date' => new Carbon($this->get('date')),
'repeat_freq' => $this->get('repeat_freq'),
'skip' => intval($this->get('skip')),
'automatch' => intval($this->get('automatch')) === 1,
'active' => intval($this->get('active')) === 1,
'name' => $this->string('name'),
'match' => $this->string('match'),
'amount_min' => $this->float('amount_min'),
'amount_currency_id_amount_min' => $this->integer('amount_currency_id_amount_min'),
'amount_currency_id_amount_max' => $this->integer('amount_currency_id_amount_max'),
'amount_max' => $this->float('amount_max'),
'date' => $this->date('date'),
'repeat_freq' => $this->string('repeat_freq'),
'skip' => $this->integer('skip'),
'automatch' => $this->boolean('automatch'),
'active' => $this->boolean('active'),
];
}

View File

@@ -37,8 +37,8 @@ class BudgetFormRequest extends Request
public function getBudgetData(): array
{
return [
'name' => trim($this->input('name')),
'active' => intval($this->input('active')) == 1,
'name' => $this->string('name'),
'active' => $this->boolean('active'),
];
}

View File

@@ -38,7 +38,7 @@ class CategoryFormRequest extends Request
public function getCategoryData(): array
{
return [
'name' => trim($this->input('name')),
'name' => $this->string('name'),
];
}

View File

@@ -36,8 +36,8 @@ class ConfigurationRequest extends Request
public function getConfigurationData(): array
{
return [
'single_user_mode' => intval($this->get('single_user_mode')) === 1,
'is_demo_site' => intval($this->get('is_demo_site')) === 1,
'single_user_mode' => $this->boolean('single_user_mode'),
'is_demo_site' => $this->boolean('is_demo_site'),
];
}

View File

@@ -36,10 +36,10 @@ class CurrencyFormRequest extends Request
public function getCurrencyData()
{
return [
'name' => $this->get('name'),
'code' => $this->get('code'),
'symbol' => $this->get('symbol'),
'decimal_places' => intval($this->get('decimal_places')),
'name' => $this->string('name'),
'code' => $this->string('code'),
'symbol' => $this->string('symbol'),
'decimal_places' => $this->integer('decimal_places'),
];
}

View File

@@ -13,7 +13,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionType;
@@ -43,30 +42,30 @@ class JournalFormRequest extends Request
{
$data = [
'what' => $this->get('what'), // type. can be 'deposit', 'withdrawal' or 'transfer'
'date' => new Carbon($this->get('date')),
'tags' => explode(',', $this->getFieldOrEmptyString('tags')),
'currency_id' => intval($this->get('amount_currency_id_amount')),
'date' => $this->date('date'),
'tags' => explode(',', $this->string('tags')),
'currency_id' => $this->integer('amount_currency_id_amount'),
// all custom fields:
'interest_date' => $this->getDateOrNull('interest_date'),
'book_date' => $this->getDateOrNull('book_date'),
'process_date' => $this->getDateOrNull('process_date'),
'due_date' => $this->getDateOrNull('due_date'),
'payment_date' => $this->getDateOrNull('payment_date'),
'invoice_date' => $this->getDateOrNull('invoice_date'),
'internal_reference' => trim(strval($this->get('internal_reference'))),
'notes' => trim(strval($this->get('notes'))),
'interest_date' => $this->date('interest_date'),
'book_date' => $this->date('book_date'),
'process_date' => $this->date('process_date'),
'due_date' => $this->date('due_date'),
'payment_date' => $this->date('payment_date'),
'invoice_date' => $this->date('invoice_date'),
'internal_reference' => $this->string('internal_reference'),
'notes' => $this->string('notes'),
// transaction / journal data:
'description' => $this->getFieldOrEmptyString('description'),
'amount' => round($this->get('amount'), 12),
'budget_id' => intval($this->get('budget_id')),
'category' => $this->getFieldOrEmptyString('category'),
'source_account_id' => intval($this->get('source_account_id')),
'source_account_name' => $this->getFieldOrEmptyString('source_account_name'),
'destination_account_id' => $this->getFieldOrEmptyString('destination_account_id'),
'destination_account_name' => $this->getFieldOrEmptyString('destination_account_name'),
'piggy_bank_id' => intval($this->get('piggy_bank_id')),
'description' => $this->string('description'),
'amount' => $this->float('amount'),
'budget_id' => $this->integer('budget_id'),
'category' => $this->string('category'),
'source_account_id' => $this->integer('source_account_id'),
'source_account_name' => $this->string('source_account_name'),
'destination_account_id' => $this->string('destination_account_id'),
'destination_account_name' => $this->string('destination_account_name'),
'piggy_bank_id' => $this->integer('piggy_bank_id'),
];
@@ -142,26 +141,4 @@ class JournalFormRequest extends Request
return $rules;
}
/**
* @param string $field
*
* @return Carbon|null
*/
private function getDateOrNull(string $field)
{
return $this->get($field) ? new Carbon($this->get($field)) : null;
}
/**
* @param string $field
*
* @return string
*/
private function getFieldOrEmptyString(string $field): string
{
$string = $this->get($field) ?? '';
return trim($string);
}
}

View File

@@ -38,12 +38,12 @@ class PiggyBankFormRequest extends Request
public function getPiggyBankData(): array
{
return [
'name' => trim($this->get('name')),
'name' => $this->string('name'),
'startdate' => new Carbon,
'account_id' => intval($this->get('account_id')),
'targetamount' => round($this->get('targetamount'), 12),
'targetdate' => strlen(strval($this->get('targetdate'))) > 0 ? new Carbon($this->get('targetdate')) : null,
'note' => trim(strval($this->get('note'))),
'account_id' => $this->integer('account_id'),
'targetamount' => $this->float('targetamount'),
'targetdate' => $this->date('targetdate'),
'note' => $this->string('note'),
];
}

View File

@@ -13,6 +13,7 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Carbon\Carbon;
use Illuminate\Foundation\Http\FormRequest;
/**
@@ -20,7 +21,123 @@ use Illuminate\Foundation\Http\FormRequest;
*
* @package FireflyIII\Http\Requests
*/
abstract class Request extends FormRequest
class Request extends FormRequest
{
//
/**
* @param string $field
*
* @return bool
*/
protected function boolean(string $field): bool
{
return intval($this->input($field)) === 1;
}
/**
* @param string $field
*
* @return Carbon|null
*/
protected function date(string $field)
{
return $this->get($field) ? new Carbon($this->get($field)) : null;
}
/**
* @param string $field
*
* @return float
*/
protected function float(string $field): float
{
return round($this->input($field), 12);
}
/**
* @param string $field
* @param string $type
*
* @return array
*/
protected function getArray(string $field, string $type): array
{
$original = $this->get($field);
$return = [];
foreach ($original as $index => $value) {
$return[$index] = $this->$type($value);
}
return $return;
}
/**
* @param string $field
*
* @return int
*/
protected function integer(string $field): int
{
return intval($this->get($field));
}
/**
* @param string $field
*
* @return string
*/
protected function string(string $field): string
{
$string = $this->get($field) ?? '';
$search = [
"\u{0001}", // start of heading
"\u{0002}", // start of text
"\u{0003}", // end of text
"\u{0004}", // end of transmission
"\u{0005}", // enquiry
"\u{0006}", // ACK
"\u{0007}", // BEL
"\u{0008}", // backspace
"\u{000E}", // shift out
"\u{000F}", // shift in
"\u{0010}", // data link escape
"\u{0011}", // DC1
"\u{0012}", // DC2
"\u{0013}", // DC3
"\u{0014}", // DC4
"\u{0015}", // NAK
"\u{0016}", // SYN
"\u{0017}", // ETB
"\u{0018}", // CAN
"\u{0019}", // EM
"\u{001A}", // SUB
"\u{001B}", // escape
"\u{001C}", // file separator
"\u{001D}", // group separator
"\u{001E}", // record separator
"\u{001F}", // unit separator
"\u{007F}", // DEL
"\u{00A0}", // non-breaking space
"\u{1680}", // ogham space mark
"\u{180E}", // mongolian vowel separator
"\u{2000}", // en quad
"\u{2001}", // em quad
"\u{2002}", // en space
"\u{2003}", // em space
"\u{2004}", // three-per-em space
"\u{2005}", // four-per-em space
"\u{2006}", // six-per-em space
"\u{2007}", // figure space
"\u{2008}", // punctuation space
"\u{2009}", // thin space
"\u{200A}", // hair space
"\u{200B}", // zero width space
"\u{202F}", // narrow no-break space
"\u{3000}", // ideographic space
"\u{FEFF}", // zero width no -break space
];
$replace = "\x20"; // plain old normal space
$string = str_replace($search, $replace, $string);
return trim($string);
}
}

View File

@@ -38,17 +38,17 @@ class RuleFormRequest extends Request
public function getRuleData(): array
{
return [
'title' => trim($this->get('title')),
'active' => intval($this->get('active')) == 1,
'trigger' => trim($this->get('trigger')),
'description' => trim($this->get('description')),
'title' => $this->string('title'),
'active' => $this->boolean('active'),
'trigger' => $this->string('trigger'),
'description' => $this->string('description'),
'rule-triggers' => $this->get('rule-trigger'),
'rule-trigger-values' => $this->get('rule-trigger-value'),
'rule-trigger-stop' => $this->get('rule-trigger-stop'),
'rule-actions' => $this->get('rule-action'),
'rule-action-values' => $this->get('rule-action-value'),
'rule-action-stop' => $this->get('rule-action-stop'),
'stop_processing' => intval($this->get('stop_processing')) === 1,
'stop_processing' => $this->boolean('stop_processing'),
];
}

View File

@@ -38,8 +38,8 @@ class RuleGroupFormRequest extends Request
public function getRuleGroupData(): array
{
return [
'title' => trim($this->input('title')),
'description' => trim($this->input('description')),
'title' => $this->string('title'),
'description' => $this->string('description'),
];
}

View File

@@ -13,8 +13,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Carbon\Carbon;
/**
* Class SplitJournalFormRequest
@@ -38,18 +36,18 @@ class SplitJournalFormRequest extends Request
public function getSplitData(): array
{
$data = [
'id' => $this->get('id') ?? 0,
'journal_description' => $this->get('journal_description'),
'journal_currency_id' => intval($this->get('journal_currency_id')),
'journal_source_account_id' => intval($this->get('journal_source_account_id')),
'journal_source_account_name' => $this->get('journal_source_account_name'),
'journal_destination_account_id' => intval($this->get('journal_destination_account_id')),
'journal_destination_account_name' => $this->get('journal_source_destination_name'),
'date' => new Carbon($this->get('date')),
'what' => $this->get('what'),
'interest_date' => $this->get('interest_date') ? new Carbon($this->get('interest_date')) : null,
'book_date' => $this->get('book_date') ? new Carbon($this->get('book_date')) : null,
'process_date' => $this->get('process_date') ? new Carbon($this->get('process_date')) : null,
'id' => $this->integer('id'),
'journal_description' => $this->string('journal_description'),
'journal_currency_id' => $this->integer('journal_currency_id'),
'journal_source_account_id' => $this->integer('journal_source_account_id'),
'journal_source_account_name' => $this->string('journal_source_account_name'),
'journal_destination_account_id' => $this->integer('journal_destination_account_id'),
'journal_destination_account_name' => $this->string('journal_source_destination_name'),
'date' => $this->date('date'),
'what' => $this->string('what'),
'interest_date' => $this->date('interest_date'),
'book_date' => $this->date('book_date'),
'process_date' => $this->date('process_date'),
'transactions' => $this->getTransactionData(),
];
@@ -87,28 +85,30 @@ class SplitJournalFormRequest extends Request
*/
private function getTransactionData(): array
{
$descriptions = $this->getArray('description', 'string');
$categories = $this->getArray('category', 'string');
$amounts = $this->getArray('amount', 'float');
$budgets = $this->getArray('amount', 'integer');
$srcAccountIds = $this->getArray('source_account_id', 'integer');
$srcAccountNames = $this->getArray('source_account_name', 'string');
$dstAccountIds = $this->getArray('destination_account_id', 'integer');
$dstAccountNames = $this->getArray('destination_account_name', 'string');
$piggyBankIds = $this->getArray('piggy_bank_id', 'integer');
$return = [];
// description is leading because it is one of the mandatory fields.
foreach ($this->get('description') as $index => $description) {
$category = $this->get('category')[$index] ?? '';
foreach ($descriptions as $index => $description) {
$category = $categories[$index] ?? '';
$transaction = [
'description' => $description,
'amount' => round($this->get('amount')[$index], 12),
'budget_id' => $this->get('budget_id')[$index] ? intval($this->get('budget_id')[$index]) : 0,
'category' => trim($category),
'source_account_id' => isset($this->get('source_account_id')[$index])
? intval($this->get('source_account_id')[$index])
: intval(
$this->get('journal_source_account_id')
),
'source_account_name' => $this->get('source_account_name')[$index] ?? '',
'piggy_bank_id' => isset($this->get('piggy_bank_id')[$index]) ? intval($this->get('piggy_bank_id')[$index]) : 0,
'destination_account_id' => isset($this->get('destination_account_id')[$index])
? intval($this->get('destination_account_id')[$index])
: intval(
$this->get('journal_destination_account_id')
),
'destination_account_name' => $this->get('destination_account_name')[$index] ?? '',
'amount' => $amounts[$index],
'budget_id' => $budgets[$index] ?? 0,
'category' => $category,
'source_account_id' => $srcAccountIds[$index] ?? $this->get('journal_source_account_id'),
'source_account_name' => $srcAccountNames[$index] ?? '',
'piggy_bank_id' => $piggyBankIds[$index] ?? 0,
'destination_account_id' => $dstAccountIds[$index] ?? $this->get('journal_destination_account_id'),
'destination_account_name' => $dstAccountNames[$index] ?? '',
];
$return[] = $transaction;
}

View File

@@ -38,9 +38,9 @@ class TagFormRequest extends Request
public function collectTagData(): array
{
if ($this->get('setTag') == 'true') {
$latitude = $this->get('latitude');
$longitude = $this->get('longitude');
$zoomLevel = $this->get('zoomLevel');
$latitude = $this->string('latitude');
$longitude = $this->string('longitude');
$zoomLevel = $this->integer('zoomLevel');
} else {
$latitude = null;
$longitude = null;
@@ -49,13 +49,13 @@ class TagFormRequest extends Request
$date = $this->get('date') ?? '';
$data = [
'tag' => $this->get('tag'),
'date' => strlen($date) > 0 ? new Carbon($date) : null,
'description' => $this->get('description') ?? '',
'tag' => $this->string('tag'),
'date' => $this->date($date),
'description' => $this->string('description'),
'latitude' => $latitude,
'longitude' => $longitude,
'zoomLevel' => $zoomLevel,
'tagMode' => $this->get('tagMode'),
'tagMode' => $this->string('tagMode'),
];
return $data;

View File

@@ -36,11 +36,10 @@ class UserFormRequest extends Request
public function getUserData(): array
{
return [
'email' => trim($this->get('email')),
'blocked' => intval($this->get('blocked')),
'blocked_code' => trim($this->get('blocked_code')),
'password' => trim($this->get('password')),
'email' => $this->string('email'),
'blocked' => $this->integer('blocked'),
'blocked_code' => $this->string('blocked_code'),
'password' => $this->string('password'),
];
}

View File

@@ -85,7 +85,7 @@ class Account extends Model
foreach ($search as $name => $value) {
$query->where($name, $value);
}
$set = $query->get(['accounts.*']);
$set = $query->get(['accounts.*']);
// account must have a name. If not set, use IBAN.
if (!isset($fields['name'])) {
@@ -93,7 +93,6 @@ class Account extends Model
}
/** @var Account $account */
foreach ($set as $account) {
if ($account->name == $fields['name']) {
@@ -316,8 +315,9 @@ class Account extends Model
*/
public function setNameAttribute($value)
{
$this->attributes['name'] = $value;
$this->attributes['encrypted'] = false;
$encrypt = config('firefly.encryption');
$this->attributes['name'] = $encrypt ? Crypt::encrypt($value) : $value;
$this->attributes['encrypted'] = $encrypt;
}
/**

View File

@@ -35,7 +35,7 @@ class Bill extends Model
* @var array
*/
protected $casts
= [
= [
'created_at' => 'date',
'updated_at' => 'date',
'deleted_at' => 'date',
@@ -47,7 +47,7 @@ class Bill extends Model
'match_encrypted' => 'boolean',
];
/** @var array */
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
protected $fillable
= ['name', 'match', 'amount_min', 'match_encrypted', 'name_encrypted', 'user_id', 'amount_max', 'date', 'repeat_freq', 'skip',
'automatch', 'active',];
@@ -120,8 +120,9 @@ class Bill extends Model
*/
public function setMatchAttribute($value)
{
$this->attributes['match'] = Crypt::encrypt($value);
$this->attributes['match_encrypted'] = true;
$encrypt = config('firefly.encryption');
$this->attributes['match'] = $encrypt ? Crypt::encrypt($value) : $value;
$this->attributes['match_encrypted'] = $encrypt;
}
/**
@@ -129,8 +130,9 @@ class Bill extends Model
*/
public function setNameAttribute($value)
{
$this->attributes['name'] = Crypt::encrypt($value);
$this->attributes['name_encrypted'] = true;
$encrypt = config('firefly.encryption');
$this->attributes['name'] = $encrypt ? Crypt::encrypt($value) : $value;
$this->attributes['name_encrypted'] = $encrypt;
}
/**

View File

@@ -121,8 +121,9 @@ class Budget extends Model
*/
public function setNameAttribute($value)
{
$this->attributes['name'] = $value;
$this->attributes['encrypted'] = false;
$encrypt = config('firefly.encryption');
$this->attributes['name'] = $encrypt ? Crypt::encrypt($value) : $value;
$this->attributes['encrypted'] = $encrypt;
}
/**

View File

@@ -115,8 +115,9 @@ class Category extends Model
*/
public function setNameAttribute($value)
{
$this->attributes['name'] = $value;
$this->attributes['encrypted'] = false;
$encrypt = config('firefly.encryption');
$this->attributes['name'] = $encrypt ? Crypt::encrypt($value) : $value;
$this->attributes['encrypted'] = $encrypt;
}
/**

View File

@@ -159,8 +159,9 @@ class PiggyBank extends Model
*/
public function setNameAttribute($value)
{
$this->attributes['name'] = $value;
$this->attributes['encrypted'] = false;
$encrypt = config('firefly.encryption');
$this->attributes['name'] = $encrypt ? Crypt::encrypt($value) : $value;
$this->attributes['encrypted'] = $encrypt;
}
/**

View File

@@ -89,7 +89,7 @@ class PiggyBankRepetition extends Model
*/
public function setCurrentamountAttribute($value)
{
$this->attributes['currentamount'] = strval(round($value, 2));
$this->attributes['currentamount'] = strval(round($value, 12));
}
}

View File

@@ -371,8 +371,9 @@ class TransactionJournal extends TransactionJournalSupport
*/
public function setDescriptionAttribute($value)
{
$this->attributes['description'] = $value;
$this->attributes['encrypted'] = false;
$encrypt = config('firefly.encryption');
$this->attributes['description'] = $encrypt ? Crypt::encrypt($value) : $value;
$this->attributes['encrypted'] = $encrypt;
}
/**

View File

@@ -283,6 +283,29 @@ class AccountRepository implements AccountRepositoryInterface
return $last;
}
/**
* Returns the date of the very first transaction in this account.
*
* @param Account $account
*
* @return TransactionJournal
*/
public function oldestJournal(Account $account): TransactionJournal
{
$first = $account->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->orderBy('transaction_journals.date', 'ASC')
->orderBy('transaction_journals.order', 'DESC')
->where('transaction_journals.user_id', $this->user->id)
->orderBy('transaction_journals.id', 'ASC')
->first(['transaction_journals.id']);
if (!is_null($first)) {
return TransactionJournal::find(intval($first->id));
}
return new TransactionJournal();
}
/**
* Returns the date of the very first transaction in this account.
*
@@ -292,18 +315,12 @@ class AccountRepository implements AccountRepositoryInterface
*/
public function oldestJournalDate(Account $account): Carbon
{
$first = new Carbon;
$date = $account->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->orderBy('transaction_journals.date', 'ASC')
->orderBy('transaction_journals.order', 'DESC')
->orderBy('transaction_journals.id', 'ASC')
->first(['transaction_journals.date']);
if (!is_null($date)) {
$first = new Carbon($date->date);
$journal = $this->oldestJournal($account);
if (is_null($journal->id)) {
return new Carbon;
}
return $first;
return $journal->date;
}
/**
@@ -477,7 +494,6 @@ class AccountRepository implements AccountRepositoryInterface
}
/**
* @param float $amount
* @param string $name
*
* @return Account

View File

@@ -15,6 +15,7 @@ namespace FireflyIII\Repositories\Account;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Support\Collection;
/**
@@ -105,6 +106,15 @@ interface AccountRepositoryInterface
*/
public function newestJournalDate(Account $account): Carbon;
/**
* Returns the date of the very first transaction in this account.
*
* @param Account $account
*
* @return TransactionJournal
*/
public function oldestJournal(Account $account): TransactionJournal;
/**
* Returns the date of the very first transaction in this account.
*

View File

@@ -14,8 +14,6 @@ declare(strict_types = 1);
namespace FireflyIII\Repositories\Account;
use Carbon\Carbon;
use FireflyIII\Helpers\Collection\Account as AccountCollection;
use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction;
use FireflyIII\User;
use Illuminate\Database\Query\JoinClause;
@@ -106,55 +104,55 @@ class AccountTasker implements AccountTaskerInterface
* @param Carbon $start
* @param Carbon $end
*
* @return AccountCollection
* @return array
*/
public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): AccountCollection
public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array
{
$startAmount = '0';
$endAmount = '0';
$diff = '0';
$ids = $accounts->pluck('id')->toArray();
$yesterday = clone $start;
$yesterday->subDay();
$startSet = Steam::balancesById($ids, $yesterday);
$backupSet = Steam::balancesById($ids, $start);
$endSet = Steam::balancesById($ids, $end);
$startSet = Steam::balancesById($ids, $yesterday);
$endSet = Steam::balancesById($ids, $end);
Log::debug(
sprintf(
'getAccountReport from %s to %s for %d accounts.',
$start->format('Y-m-d'),
$end->format('Y-m-d'),
$accounts->count()
)
);
$accounts->each(
function (Account $account) use ($startSet, $endSet, $backupSet) {
$account->startBalance = $startSet[$account->id] ?? '0';
$account->endBalance = $endSet[$account->id] ?? '0';
Log::debug('Start of accountreport');
// check backup set just in case:
if ($account->startBalance === '0' && isset($backupSet[$account->id])) {
$account->startBalance = $backupSet[$account->id];
}
}
);
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$return = [
'start' => '0',
'end' => '0',
'difference' => '0',
'accounts' => [],
];
// summarize:
foreach ($accounts as $account) {
$startAmount = bcadd($startAmount, $account->startBalance);
$endAmount = bcadd($endAmount, $account->endBalance);
$diff = bcadd($diff, bcsub($account->endBalance, $account->startBalance));
$id = $account->id;
$entry = [
'name' => $account->name,
'id' => $account->id,
'start_balance' => '0',
'end_balance' => '0',
];
// get first journal date:
$first = $repository->oldestJournal($account);
$entry['start_balance'] = $startSet[$account->id] ?? '0';
$entry['end_balance'] = $endSet[$account->id] ?? '0';
if (!is_null($first->id) && $yesterday < $first->date && $end >= $first->date) {
// something about balance?
$entry['start_balance'] = $first->transactions()->where('account_id', $account->id)->first()->amount;
Log::debug(sprintf('Account was opened before %s, so opening balance is %f', $yesterday->format('Y-m-d'), $entry['start_balance']));
}
$return['start'] = bcadd($return['start'], $entry['start_balance']);
$return['end'] = bcadd($return['end'], $entry['end_balance']);
$return['accounts'][$id] = $entry;
}
$object = new AccountCollection;
$object->setStart($startAmount);
$object->setEnd($endAmount);
$object->setDifference($diff);
$object->setAccounts($accounts);
$return['difference'] = bcsub($return['end'], $return['start']);
return $object;
return $return;
}
/**

View File

@@ -14,7 +14,6 @@ declare(strict_types = 1);
namespace FireflyIII\Repositories\Account;
use Carbon\Carbon;
use FireflyIII\Helpers\Collection\Account as AccountCollection;
use Illuminate\Support\Collection;
/**
@@ -54,8 +53,8 @@ interface AccountTaskerInterface
* @param Carbon $start
* @param Carbon $end
*
* @return AccountCollection
* @return array
*/
public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): AccountCollection;
public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array;
}

View File

@@ -50,7 +50,7 @@ interface ExportJobRepositoryInterface
/**
* @param string $key
*
* @return ExportJob|null
* @return ExportJob
*/
public function findByKey(string $key): ExportJob;

View File

@@ -137,6 +137,14 @@ class JournalRepository implements JournalRepositoryInterface
return $entry;
}
/**
* @return Collection
*/
public function getTransactionTypes(): Collection
{
return TransactionType::orderBy('type', 'ASC')->get();
}
/**
* @param array $data
*
@@ -208,40 +216,6 @@ class JournalRepository implements JournalRepositoryInterface
}
/**
* Store journal only, uncompleted, with attachments if necessary.
*
* @param array $data
*
* @return TransactionJournal
*/
public function storeJournal(array $data): TransactionJournal
{
// find transaction type.
$transactionType = TransactionType::where('type', ucfirst($data['what']))->first();
// store actual journal.
$journal = new TransactionJournal(
[
'user_id' => $this->user->id,
'transaction_type_id' => $transactionType->id,
'transaction_currency_id' => $data['amount_currency_id_amount'],
'description' => $data['description'],
'completed' => 0,
'date' => $data['date'],
]
);
$result = $journal->save();
if ($result) {
return $journal;
}
return new TransactionJournal();
}
/**
* @param TransactionJournal $journal
* @param array $data

View File

@@ -16,6 +16,7 @@ namespace FireflyIII\Repositories\Journal;
use FireflyIII\Models\Account;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag;
/**
@@ -36,6 +37,11 @@ interface JournalRepositoryInterface
*/
public function convert(TransactionJournal $journal, TransactionType $type, Account $source, Account $destination): MessageBag;
/**
* @return Collection
*/
public function getTransactionTypes(): Collection;
/**
* Deletes a journal.
*
@@ -69,15 +75,6 @@ interface JournalRepositoryInterface
*/
public function store(array $data): TransactionJournal;
/**
* Store journal only, uncompleted, with attachments if necessary.
*
* @param array $data
*
* @return TransactionJournal
*/
public function storeJournal(array $data): TransactionJournal;
/**
* @param TransactionJournal $journal
* @param array $data

View File

@@ -49,8 +49,8 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
}
/**
* @param RuleGroup $ruleGroup
* @param RuleGroup $moveTo
* @param RuleGroup $ruleGroup
* @param RuleGroup|null $moveTo
*
* @return bool
*/

View File

@@ -35,8 +35,8 @@ interface RuleGroupRepositoryInterface
public function count(): int;
/**
* @param RuleGroup $ruleGroup
* @param RuleGroup $moveTo
* @param RuleGroup $ruleGroup
* @param RuleGroup|null $moveTo
*
* @return bool
*/

View File

@@ -74,6 +74,8 @@ class AbstractTrigger
return $self;
}
/**
* @param RuleTrigger $trigger
* @param TransactionJournal $journal

View File

@@ -0,0 +1,95 @@
<?php
/**
* BudgetIs.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Rules\Triggers;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use Log;
/**
* Class BudgetIs
*
* @package FireflyIII\Rules\Triggers
*/
final class BudgetIs extends AbstractTrigger implements TriggerInterface
{
/**
* A trigger is said to "match anything", or match any given transaction,
* when the trigger value is very vague or has no restrictions. Easy examples
* are the "AmountMore"-trigger combined with an amount of 0: any given transaction
* has an amount of more than zero! Other examples are all the "Description"-triggers
* which have hard time handling empty trigger values such as "" or "*" (wild cards).
*
* If the user tries to create such a trigger, this method MUST return true so Firefly III
* can stop the storing / updating the trigger. If the trigger is in any way restrictive
* (even if it will still include 99.9% of the users transactions), this method MUST return
* false.
*
* @param null $value
*
* @return bool
*/
public static function willMatchEverything($value = null)
{
if (!is_null($value)) {
return false;
}
Log::error(sprintf('Cannot use %s with a null value.', self::class));
return true;
}
/**
* @param TransactionJournal $journal
*
* @return bool
*/
public function triggered(TransactionJournal $journal): bool
{
$budget = $journal->budgets()->first();
if (!is_null($budget)) {
$name = strtolower($budget->name);
// match on journal:
if ($name === strtolower($this->triggerValue)) {
Log::debug(sprintf('RuleTrigger BudgetIs for journal #%d: "%s" is "%s", return true.', $journal->id, $name, $this->triggerValue));
return true;
}
}
if (is_null($budget)) {
// perhaps transactions have this budget?
/** @var Transaction $transaction */
foreach ($journal->transactions as $transaction) {
$budget = $transaction->budgets()->first();
if (!is_null($budget)) {
$name = strtolower($budget->name);
if ($name === strtolower($this->triggerValue)) {
Log::debug(
sprintf(
'RuleTrigger BudgetIs for journal #%d (transaction #%d): "%s" is "%s", return true.',
$journal->id, $transaction->id, $name, $this->triggerValue
)
);
return true;
}
}
}
}
Log::debug(sprintf('RuleTrigger BudgetIs for journal #%d: does not have budget "%s", return false.', $journal->id, $this->triggerValue));
return false;
}
}

View File

@@ -0,0 +1,95 @@
<?php
/**
* CategoryIs.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Rules\Triggers;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use Log;
/**
* Class CategoryIs
*
* @package FireflyIII\Rules\Triggers
*/
final class CategoryIs extends AbstractTrigger implements TriggerInterface
{
/**
* A trigger is said to "match anything", or match any given transaction,
* when the trigger value is very vague or has no restrictions. Easy examples
* are the "AmountMore"-trigger combined with an amount of 0: any given transaction
* has an amount of more than zero! Other examples are all the "Description"-triggers
* which have hard time handling empty trigger values such as "" or "*" (wild cards).
*
* If the user tries to create such a trigger, this method MUST return true so Firefly III
* can stop the storing / updating the trigger. If the trigger is in any way restrictive
* (even if it will still include 99.9% of the users transactions), this method MUST return
* false.
*
* @param null $value
*
* @return bool
*/
public static function willMatchEverything($value = null)
{
if (!is_null($value)) {
return false;
}
Log::error(sprintf('Cannot use %s with a null value.', self::class));
return true;
}
/**
* @param TransactionJournal $journal
*
* @return bool
*/
public function triggered(TransactionJournal $journal): bool
{
$category = $journal->categories()->first();
if (!is_null($category)) {
$name = strtolower($category->name);
// match on journal:
if ($name === strtolower($this->triggerValue)) {
Log::debug(sprintf('RuleTrigger CategoryIs for journal #%d: "%s" is "%s", return true.', $journal->id, $name, $this->triggerValue));
return true;
}
}
if (is_null($category)) {
// perhaps transactions have this category?
/** @var Transaction $transaction */
foreach ($journal->transactions as $transaction) {
$category = $transaction->categories()->first();
if (!is_null($category)) {
$name = strtolower($category->name);
if ($name === strtolower($this->triggerValue)) {
Log::debug(
sprintf(
'RuleTrigger CategoryIs for journal #%d (transaction #%d): "%s" is "%s", return true.',
$journal->id, $transaction->id, $name, $this->triggerValue
)
);
return true;
}
}
}
}
Log::debug(sprintf('RuleTrigger CategoryIs for journal #%d: does not have category "%s", return false.', $journal->id, $this->triggerValue));
return false;
}
}

View File

@@ -0,0 +1,74 @@
<?php
/**
* TagIs.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Rules\Triggers;
use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionJournal;
use Log;
/**
* Class TagIs
*
* @package FireflyIII\Rules\Triggers
*/
final class TagIs extends AbstractTrigger implements TriggerInterface
{
/**
* A trigger is said to "match anything", or match any given transaction,
* when the trigger value is very vague or has no restrictions. Easy examples
* are the "AmountMore"-trigger combined with an amount of 0: any given transaction
* has an amount of more than zero! Other examples are all the "Description"-triggers
* which have hard time handling empty trigger values such as "" or "*" (wild cards).
*
* If the user tries to create such a trigger, this method MUST return true so Firefly III
* can stop the storing / updating the trigger. If the trigger is in any way restrictive
* (even if it will still include 99.9% of the users transactions), this method MUST return
* false.
*
* @param null $value
*
* @return bool
*/
public static function willMatchEverything($value = null)
{
if (!is_null($value)) {
return false;
}
Log::error(sprintf('Cannot use %s with a null value.', self::class));
return true;
}
/**
* @param TransactionJournal $journal
*
* @return bool
*/
public function triggered(TransactionJournal $journal): bool
{
$tags = $journal->tags()->get();
/** @var Tag $tag */
foreach ($tags as $tag) {
$name = strtolower($tag->tag);
// match on journal:
if ($name === strtolower($this->triggerValue)) {
Log::debug(sprintf('RuleTrigger TagIs for journal #%d: is tagged with "%s", return true.', $journal->id, $name));
return true;
}
}
Log::debug(sprintf('RuleTrigger TagIs for journal #%d: is not tagged with "%s", return false.', $journal->id, $this->triggerValue));
return false;
}
}

View File

@@ -90,11 +90,11 @@ class Amount
$pos_c = $sign;
}
// default: (amount before currency)
// default is amount before currency
$format = $pos_a . $pos_d . '%v' . $space . $pos_b . '%s' . $pos_c . $pos_e;
if ($csPrecedes) {
// (currency before amount)
// alternative is currency before amount
$format = $pos_a . $pos_b . '%s' . $pos_c . $space . $pos_d . '%v' . $pos_e;
}
Log::debug(sprintf('Final format: "%s"', $format));

View File

@@ -285,7 +285,6 @@ class ExpandedForm
/**
* @param $name
* @param null $value
* @param array $options
*
* @return string

View File

@@ -124,6 +124,8 @@ class Steam
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->groupBy('transaction_journals.date')
->orderBy('transaction_journals.date', 'ASC')
->whereNull('transaction_journals.deleted_at')
->get(['transaction_journals.date', DB::raw('SUM(transactions.amount) AS modified')]);
$currentBalance = $startBalance;
foreach ($set as $entry) {
@@ -150,7 +152,7 @@ class Steam
public function balancesById(array $ids, Carbon $date): array
{
// abuse chart properties:
// cache this property.
$cache = new CacheProperties;
$cache->addProperty($ids);
$cache->addProperty('balances');
@@ -163,6 +165,7 @@ class Steam
->where('transaction_journals.date', '<=', $date->format('Y-m-d'))
->groupBy('transactions.account_id')
->whereIn('transactions.account_id', $ids)
->whereNull('transaction_journals.deleted_at')
->get(['transactions.account_id', DB::raw('sum(transactions.amount) AS aggregate')]);
$result = [];

View File

@@ -14,7 +14,6 @@ declare(strict_types = 1);
namespace FireflyIII\Support\Twig;
use Carbon\Carbon;
use Config;
use FireflyIII\Models\Account;
use FireflyIII\Models\TransactionJournal;
use Route;
@@ -42,7 +41,6 @@ class General extends Twig_Extension
$this->formatAmountPlain(),
$this->formatJournal(),
$this->balance(),
$this->getAccountRole(),
$this->formatFilesize(),
$this->mimeIcon(),
];
@@ -234,18 +232,6 @@ class General extends Twig_Extension
);
}
/**
* @return Twig_SimpleFilter
*/
protected function getAccountRole(): Twig_SimpleFilter
{
return new Twig_SimpleFilter(
'getAccountRole', function (string $name): string {
return Config::get('firefly.accountRoles.' . $name);
}
);
}
/**
* @return Twig_SimpleFunction
*/

View File

@@ -25,7 +25,6 @@ declare(strict_types = 1);
bcscale(12);
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);

View File

@@ -5,16 +5,36 @@
"finance",
"finances",
"manager",
"management",
"euro",
"dollar",
"laravel",
"money",
"currency",
"financials",
"financial",
"budgets",
"administration",
"tool",
"tooling",
"help",
"helper",
"assistant",
"planning",
"organizing",
"bills",
"personal finance",
"budgets",
"budgeting",
"budgeting tool",
"budgeting application",
"transactions",
"self hosted",
"self-hosted",
"transfers",
"management"
],
"license": "MIT",
"license": "Creative Commons Attribution-ShareAlike 4.0 International License",
"homepage": "https://github.com/firefly-iii/firefly-iii",
"type": "project",
"authors": [
@@ -28,7 +48,7 @@
"require": {
"php": ">=7.0.0",
"ext-intl": "*",
"laravel/framework": "5.3.28",
"laravel/framework": "5.3.29",
"davejamesmiller/laravel-breadcrumbs": "^3.0",
"watson/validating": "3.*",
"doctrine/dbal": "^2.5",
@@ -73,13 +93,14 @@
],
"post-install-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postInstall",
"php artisan optimize"
"php artisan optimize",
"php artisan firefly:instructions install"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"php artisan firefly:upgrade-instructions",
"php artisan firefly:upgrade-database",
"php artisan firefly:verify",
"php artisan firefly:instructions update",
"php artisan optimize"
]
},

359
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "c1354d0797f44315708cc46642aca068",
"content-hash": "db26ae145d3656fe05d8a222fc21e263",
"packages": [
{
"name": "bacon/bacon-qr-code",
@@ -378,28 +378,29 @@
},
{
"name": "doctrine/collections",
"version": "v1.3.0",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/collections.git",
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
"reference": "1a4fb7e902202c33cce8c55989b945612943c2ba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba",
"reference": "1a4fb7e902202c33cce8c55989b945612943c2ba",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
"php": "^5.6 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
"doctrine/coding-standard": "~0.1@dev",
"phpunit/phpunit": "^5.7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
"dev-master": "1.3.x-dev"
}
},
"autoload": {
@@ -440,20 +441,20 @@
"collections",
"iterator"
],
"time": "2015-04-14T22:21:58+00:00"
"time": "2017-01-03T10:49:41+00:00"
},
{
"name": "doctrine/common",
"version": "v2.6.2",
"version": "v2.7.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/common.git",
"reference": "7bce00698899aa2c06fe7365c76e4d78ddb15fa3"
"reference": "930297026c8009a567ac051fd545bf6124150347"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/common/zipball/7bce00698899aa2c06fe7365c76e4d78ddb15fa3",
"reference": "7bce00698899aa2c06fe7365c76e4d78ddb15fa3",
"url": "https://api.github.com/repos/doctrine/common/zipball/930297026c8009a567ac051fd545bf6124150347",
"reference": "930297026c8009a567ac051fd545bf6124150347",
"shasum": ""
},
"require": {
@@ -462,10 +463,10 @@
"doctrine/collections": "1.*",
"doctrine/inflector": "1.*",
"doctrine/lexer": "1.*",
"php": "~5.5|~7.0"
"php": "~5.6|~7.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8|~5.0"
"phpunit/phpunit": "^5.4.6"
},
"type": "library",
"extra": {
@@ -513,24 +514,24 @@
"persistence",
"spl"
],
"time": "2016-11-30T16:50:46+00:00"
"time": "2017-01-13T14:02:13+00:00"
},
{
"name": "doctrine/dbal",
"version": "v2.5.5",
"version": "v2.5.10",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "9f8c05cd5225a320d56d4bfdb4772f10d045a0c9"
"reference": "fc376f7a61498e18520cd6fa083752a4ca08072b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/9f8c05cd5225a320d56d4bfdb4772f10d045a0c9",
"reference": "9f8c05cd5225a320d56d4bfdb4772f10d045a0c9",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/fc376f7a61498e18520cd6fa083752a4ca08072b",
"reference": "fc376f7a61498e18520cd6fa083752a4ca08072b",
"shasum": ""
},
"require": {
"doctrine/common": ">=2.4,<2.7-dev",
"doctrine/common": ">=2.4,<2.8-dev",
"php": ">=5.3.2"
},
"require-dev": {
@@ -584,7 +585,7 @@
"persistence",
"queryobject"
],
"time": "2016-09-09T19:13:33+00:00"
"time": "2017-01-23T23:17:10+00:00"
},
{
"name": "doctrine/inflector",
@@ -854,16 +855,16 @@
},
{
"name": "laravel/framework",
"version": "v5.3.28",
"version": "v5.3.29",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "a64fc4f8958091ca39623b2e8c8f173cb34fa47a"
"reference": "6fd76dec90466dc3f703d8df72e38130f2ee6a32"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/a64fc4f8958091ca39623b2e8c8f173cb34fa47a",
"reference": "a64fc4f8958091ca39623b2e8c8f173cb34fa47a",
"url": "https://api.github.com/repos/laravel/framework/zipball/6fd76dec90466dc3f703d8df72e38130f2ee6a32",
"reference": "6fd76dec90466dc3f703d8df72e38130f2ee6a32",
"shasum": ""
},
"require": {
@@ -880,7 +881,7 @@
"php": ">=5.6.4",
"psy/psysh": "0.7.*|0.8.*",
"ramsey/uuid": "~3.0",
"swiftmailer/swiftmailer": "~5.1",
"swiftmailer/swiftmailer": "~5.4",
"symfony/console": "3.1.*",
"symfony/debug": "3.1.*",
"symfony/finder": "3.1.*",
@@ -978,20 +979,20 @@
"framework",
"laravel"
],
"time": "2016-12-15T18:03:17+00:00"
"time": "2017-01-06T14:33:56+00:00"
},
{
"name": "laravelcollective/html",
"version": "v5.3.0",
"version": "v5.3.1",
"source": {
"type": "git",
"url": "https://github.com/LaravelCollective/html.git",
"reference": "961ce141c16c6b085128f209496c26efd3e681ca"
"reference": "2f7f2e127c6fed47f269ea29ab5efeb8f65e9d35"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/LaravelCollective/html/zipball/961ce141c16c6b085128f209496c26efd3e681ca",
"reference": "961ce141c16c6b085128f209496c26efd3e681ca",
"url": "https://api.github.com/repos/LaravelCollective/html/zipball/2f7f2e127c6fed47f269ea29ab5efeb8f65e9d35",
"reference": "2f7f2e127c6fed47f269ea29ab5efeb8f65e9d35",
"shasum": ""
},
"require": {
@@ -1032,7 +1033,7 @@
],
"description": "HTML and Form Builders for the Laravel Framework",
"homepage": "http://laravelcollective.com",
"time": "2016-08-27T23:52:43+00:00"
"time": "2016-12-13T14:23:36+00:00"
},
{
"name": "league/commonmark",
@@ -1105,16 +1106,16 @@
},
{
"name": "league/csv",
"version": "8.1.2",
"version": "8.2.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/csv.git",
"reference": "33447984f7a7038fefaa5a6177e8407b66bc85b4"
"reference": "ef7eef710810c8bd0cf9371582ccd0123ff96d4b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/csv/zipball/33447984f7a7038fefaa5a6177e8407b66bc85b4",
"reference": "33447984f7a7038fefaa5a6177e8407b66bc85b4",
"url": "https://api.github.com/repos/thephpleague/csv/zipball/ef7eef710810c8bd0cf9371582ccd0123ff96d4b",
"reference": "ef7eef710810c8bd0cf9371582ccd0123ff96d4b",
"shasum": ""
},
"require": {
@@ -1128,7 +1129,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "8.1-dev"
"dev-master": "8.2-dev"
}
},
"autoload": {
@@ -1158,20 +1159,20 @@
"read",
"write"
],
"time": "2016-10-27T11:21:24+00:00"
"time": "2017-01-25T13:32:07+00:00"
},
{
"name": "league/flysystem",
"version": "1.0.32",
"version": "1.0.33",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "1b5c4a0031697f46e779a9d1b309c2e1b24daeab"
"reference": "5c7f98498b12d47f9de90ec9186a90000125777c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/1b5c4a0031697f46e779a9d1b309c2e1b24daeab",
"reference": "1b5c4a0031697f46e779a9d1b309c2e1b24daeab",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/5c7f98498b12d47f9de90ec9186a90000125777c",
"reference": "5c7f98498b12d47f9de90ec9186a90000125777c",
"shasum": ""
},
"require": {
@@ -1241,7 +1242,7 @@
"sftp",
"storage"
],
"time": "2016-10-19T20:38:46+00:00"
"time": "2017-01-23T10:32:09+00:00"
},
{
"name": "monolog/monolog",
@@ -1323,16 +1324,16 @@
},
{
"name": "mtdowling/cron-expression",
"version": "v1.1.0",
"version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/mtdowling/cron-expression.git",
"reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5"
"reference": "9504fa9ea681b586028adaaa0877db4aecf32bad"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/c9ee7886f5a12902b225a1a12f36bb45f9ab89e5",
"reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5",
"url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/9504fa9ea681b586028adaaa0877db4aecf32bad",
"reference": "9504fa9ea681b586028adaaa0877db4aecf32bad",
"shasum": ""
},
"require": {
@@ -1343,8 +1344,8 @@
},
"type": "library",
"autoload": {
"psr-0": {
"Cron": "src/"
"psr-4": {
"Cron\\": "src/Cron/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1363,30 +1364,36 @@
"cron",
"schedule"
],
"time": "2016-01-26T21:23:30+00:00"
"time": "2017-01-23T04:29:33+00:00"
},
{
"name": "nesbot/carbon",
"version": "1.21.0",
"version": "1.22.1",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
"reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7"
"reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7b08ec6f75791e130012f206e3f7b0e76e18e3d7",
"reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc",
"reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"symfony/translation": "~2.6|~3.0"
"symfony/translation": "~2.6 || ~3.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0|~5.0"
"friendsofphp/php-cs-fixer": "~2",
"phpunit/phpunit": "~4.0 || ~5.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.23-dev"
}
},
"autoload": {
"psr-4": {
"Carbon\\": "src/Carbon/"
@@ -1410,7 +1417,7 @@
"datetime",
"time"
],
"time": "2015-11-04T20:07:17+00:00"
"time": "2017-01-16T07:55:07+00:00"
},
{
"name": "nikic/php-parser",
@@ -1621,16 +1628,16 @@
},
{
"name": "psy/psysh",
"version": "v0.8.0",
"version": "v0.8.1",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/psysh.git",
"reference": "4a8860e13aa68a4bbf2476c014f8a1f14f1bf991"
"reference": "701e8a1cc426ee170f1296f5d9f6b8a26ad25c4a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/4a8860e13aa68a4bbf2476c014f8a1f14f1bf991",
"reference": "4a8860e13aa68a4bbf2476c014f8a1f14f1bf991",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/701e8a1cc426ee170f1296f5d9f6b8a26ad25c4a",
"reference": "701e8a1cc426ee170f1296f5d9f6b8a26ad25c4a",
"shasum": ""
},
"require": {
@@ -1660,7 +1667,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-develop": "0.8.x-dev"
"dev-develop": "0.9.x-dev"
}
},
"autoload": {
@@ -1690,7 +1697,7 @@
"interactive",
"shell"
],
"time": "2016-12-07T17:15:07+00:00"
"time": "2017-01-15T17:54:13+00:00"
},
{
"name": "ramsey/uuid",
@@ -1776,23 +1783,23 @@
},
{
"name": "rcrowe/twigbridge",
"version": "v0.9.3",
"version": "v0.9.4",
"source": {
"type": "git",
"url": "https://github.com/rcrowe/TwigBridge.git",
"reference": "6226d33331bbb1cdf64593a786f7efd1670200a7"
"reference": "effda159c436b08eae1a9d9ba3d28bee8f7b0f3f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/6226d33331bbb1cdf64593a786f7efd1670200a7",
"reference": "6226d33331bbb1cdf64593a786f7efd1670200a7",
"url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/effda159c436b08eae1a9d9ba3d28bee8f7b0f3f",
"reference": "effda159c436b08eae1a9d9ba3d28bee8f7b0f3f",
"shasum": ""
},
"require": {
"illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*",
"illuminate/view": "5.0.*|5.1.*|5.2.*|5.3.*",
"illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*",
"illuminate/view": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*",
"php": ">=5.4.0",
"twig/twig": "~1.15|~2.0"
"twig/twig": "~1.30"
},
"require-dev": {
"laravel/framework": "5.0.*",
@@ -1836,7 +1843,7 @@
"laravel",
"twig"
],
"time": "2016-05-01T16:43:38+00:00"
"time": "2017-01-21T14:33:47+00:00"
},
{
"name": "rmccue/requests",
@@ -1943,16 +1950,16 @@
},
{
"name": "symfony/console",
"version": "v3.1.8",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "221a60fb2f369a065eea1ed96b61183219fdfa6e"
"reference": "047f16485d68c083bd5d9b73ff16f9cb9c1a9f52"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/221a60fb2f369a065eea1ed96b61183219fdfa6e",
"reference": "221a60fb2f369a065eea1ed96b61183219fdfa6e",
"url": "https://api.github.com/repos/symfony/console/zipball/047f16485d68c083bd5d9b73ff16f9cb9c1a9f52",
"reference": "047f16485d68c083bd5d9b73ff16f9cb9c1a9f52",
"shasum": ""
},
"require": {
@@ -2000,20 +2007,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2016-12-08T14:58:14+00:00"
"time": "2017-01-08T20:43:43+00:00"
},
{
"name": "symfony/debug",
"version": "v3.1.8",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "c058661c32f5b462722e36d120905940089cbd9a"
"reference": "c6661361626b3cf5cf2089df98b3b5006a197e85"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/c058661c32f5b462722e36d120905940089cbd9a",
"reference": "c058661c32f5b462722e36d120905940089cbd9a",
"url": "https://api.github.com/repos/symfony/debug/zipball/c6661361626b3cf5cf2089df98b3b5006a197e85",
"reference": "c6661361626b3cf5cf2089df98b3b5006a197e85",
"shasum": ""
},
"require": {
@@ -2057,20 +2064,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2016-11-15T12:55:20+00:00"
"time": "2017-01-28T00:04:57+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "e8f47a327c2f0fd5aa04fa60af2b693006ed7283"
"reference": "9137eb3a3328e413212826d63eeeb0217836e2b6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e8f47a327c2f0fd5aa04fa60af2b693006ed7283",
"reference": "e8f47a327c2f0fd5aa04fa60af2b693006ed7283",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9137eb3a3328e413212826d63eeeb0217836e2b6",
"reference": "9137eb3a3328e413212826d63eeeb0217836e2b6",
"shasum": ""
},
"require": {
@@ -2117,20 +2124,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2016-10-13T06:29:04+00:00"
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "symfony/finder",
"version": "v3.1.8",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "74dcd370c8d057882575e535616fde935e411b19"
"reference": "59687a255d1562f2c17b012418273862083d85f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/74dcd370c8d057882575e535616fde935e411b19",
"reference": "74dcd370c8d057882575e535616fde935e411b19",
"url": "https://api.github.com/repos/symfony/finder/zipball/59687a255d1562f2c17b012418273862083d85f7",
"reference": "59687a255d1562f2c17b012418273862083d85f7",
"shasum": ""
},
"require": {
@@ -2166,20 +2173,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2016-12-13T09:38:21+00:00"
"time": "2017-01-02T20:31:54+00:00"
},
{
"name": "symfony/http-foundation",
"version": "v3.1.8",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "88a1d3cee2dbd06f7103ff63938743b903b65a92"
"reference": "cef0ad49a2e90455cfc649522025b5a2929648c0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/88a1d3cee2dbd06f7103ff63938743b903b65a92",
"reference": "88a1d3cee2dbd06f7103ff63938743b903b65a92",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/cef0ad49a2e90455cfc649522025b5a2929648c0",
"reference": "cef0ad49a2e90455cfc649522025b5a2929648c0",
"shasum": ""
},
"require": {
@@ -2219,20 +2226,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"time": "2016-11-27T04:21:07+00:00"
"time": "2017-01-08T20:43:43+00:00"
},
{
"name": "symfony/http-kernel",
"version": "v3.1.8",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "d7a4671a6f8e4174127770263dcd95bee5713f76"
"reference": "c830387dec1b48c100473d10a6a356c3c3ae2a13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/d7a4671a6f8e4174127770263dcd95bee5713f76",
"reference": "d7a4671a6f8e4174127770263dcd95bee5713f76",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/c830387dec1b48c100473d10a6a356c3c3ae2a13",
"reference": "c830387dec1b48c100473d10a6a356c3c3ae2a13",
"shasum": ""
},
"require": {
@@ -2301,7 +2308,7 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
"time": "2016-12-13T12:52:10+00:00"
"time": "2017-01-28T02:53:17+00:00"
},
{
"name": "symfony/polyfill-mbstring",
@@ -2472,16 +2479,16 @@
},
{
"name": "symfony/process",
"version": "v3.1.8",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "d23427a7f97a373129f61bc3b876fe4c66e2b3c7"
"reference": "2605753c5f8c531623d24d002825ebb1d6a22248"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/d23427a7f97a373129f61bc3b876fe4c66e2b3c7",
"reference": "d23427a7f97a373129f61bc3b876fe4c66e2b3c7",
"url": "https://api.github.com/repos/symfony/process/zipball/2605753c5f8c531623d24d002825ebb1d6a22248",
"reference": "2605753c5f8c531623d24d002825ebb1d6a22248",
"shasum": ""
},
"require": {
@@ -2517,20 +2524,20 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"time": "2016-11-24T01:08:05+00:00"
"time": "2017-01-21T17:13:55+00:00"
},
{
"name": "symfony/routing",
"version": "v3.1.8",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
"reference": "4beb3dceb14cf2dd63dd222d1825ca981a2952cb"
"reference": "f25581d4eb0a82962c291917f826166f0dcd8a9a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/4beb3dceb14cf2dd63dd222d1825ca981a2952cb",
"reference": "4beb3dceb14cf2dd63dd222d1825ca981a2952cb",
"url": "https://api.github.com/repos/symfony/routing/zipball/f25581d4eb0a82962c291917f826166f0dcd8a9a",
"reference": "f25581d4eb0a82962c291917f826166f0dcd8a9a",
"shasum": ""
},
"require": {
@@ -2592,20 +2599,20 @@
"uri",
"url"
],
"time": "2016-11-25T12:27:14+00:00"
"time": "2017-01-28T00:04:57+00:00"
},
{
"name": "symfony/translation",
"version": "v3.1.8",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "2f4b6114b75c506dd1ee7eb485b35facbcb2d873"
"reference": "d5a20fab5f63f44c233c69b3041c3cb1d4945e45"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/2f4b6114b75c506dd1ee7eb485b35facbcb2d873",
"reference": "2f4b6114b75c506dd1ee7eb485b35facbcb2d873",
"url": "https://api.github.com/repos/symfony/translation/zipball/d5a20fab5f63f44c233c69b3041c3cb1d4945e45",
"reference": "d5a20fab5f63f44c233c69b3041c3cb1d4945e45",
"shasum": ""
},
"require": {
@@ -2656,20 +2663,20 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
"time": "2016-11-18T21:15:08+00:00"
"time": "2017-01-21T17:01:39+00:00"
},
{
"name": "symfony/var-dumper",
"version": "v3.1.8",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "5ccbd23a97035886e595ce497dbe94bc88ac0b57"
"reference": "16df11647e5b992d687cb4eeeb9a882d5f5c26b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/5ccbd23a97035886e595ce497dbe94bc88ac0b57",
"reference": "5ccbd23a97035886e595ce497dbe94bc88ac0b57",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/16df11647e5b992d687cb4eeeb9a882d5f5c26b9",
"reference": "16df11647e5b992d687cb4eeeb9a882d5f5c26b9",
"shasum": ""
},
"require": {
@@ -2719,7 +2726,7 @@
"debug",
"dump"
],
"time": "2016-12-08T14:58:14+00:00"
"time": "2017-01-24T13:02:38+00:00"
},
{
"name": "twig/twig",
@@ -2886,16 +2893,16 @@
"packages-dev": [
{
"name": "barryvdh/laravel-debugbar",
"version": "v2.3.1",
"version": "v2.3.2",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-debugbar.git",
"reference": "65b0465e38a9524c9d5eb2dfc0389aba23090625"
"reference": "24e4f0261e352d3fd86d0447791b56ae49398674"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/65b0465e38a9524c9d5eb2dfc0389aba23090625",
"reference": "65b0465e38a9524c9d5eb2dfc0389aba23090625",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/24e4f0261e352d3fd86d0447791b56ae49398674",
"reference": "24e4f0261e352d3fd86d0447791b56ae49398674",
"shasum": ""
},
"require": {
@@ -2936,27 +2943,27 @@
"profiler",
"webprofiler"
],
"time": "2017-01-05T08:53:44+00:00"
"time": "2017-01-19T08:19:49+00:00"
},
{
"name": "barryvdh/laravel-ide-helper",
"version": "v2.2.2",
"version": "v2.2.3",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-ide-helper.git",
"reference": "105f14a50d0959a0e80004a15b3350fdf78f9623"
"reference": "a7fc2ec489aada6062d3a63ddc915004a21e38af"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/105f14a50d0959a0e80004a15b3350fdf78f9623",
"reference": "105f14a50d0959a0e80004a15b3350fdf78f9623",
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/a7fc2ec489aada6062d3a63ddc915004a21e38af",
"reference": "a7fc2ec489aada6062d3a63ddc915004a21e38af",
"shasum": ""
},
"require": {
"barryvdh/reflection-docblock": "^2.0.4",
"illuminate/console": "^5.0,<5.4",
"illuminate/filesystem": "^5.0,<5.4",
"illuminate/support": "^5.0,<5.4",
"illuminate/console": "^5.0,<5.5",
"illuminate/filesystem": "^5.0,<5.5",
"illuminate/support": "^5.0,<5.5",
"php": ">=5.4.0",
"symfony/class-loader": "^2.3|^3.0"
},
@@ -3002,7 +3009,7 @@
"phpstorm",
"sublime"
],
"time": "2016-11-15T08:21:23+00:00"
"time": "2017-01-05T21:20:42+00:00"
},
{
"name": "barryvdh/reflection-docblock",
@@ -3378,16 +3385,16 @@
},
{
"name": "myclabs/deep-copy",
"version": "1.5.5",
"version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108"
"reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/399c1f9781e222f6eb6cc238796f5200d1b7f108",
"reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5a5a9fc8025a08d8919be87d6884d5a92520cefe",
"reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe",
"shasum": ""
},
"require": {
@@ -3416,7 +3423,7 @@
"object",
"object graph"
],
"time": "2016-10-31T17:19:45+00:00"
"time": "2017-01-26T22:05:40+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@@ -3629,16 +3636,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "4.0.4",
"version": "4.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a"
"reference": "c19cfc7cbb0e9338d8c469c7eedecc2a428b0971"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c14196e64a78570034afd0b7a9f3757ba71c2a0a",
"reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c19cfc7cbb0e9338d8c469c7eedecc2a428b0971",
"reference": "c19cfc7cbb0e9338d8c469c7eedecc2a428b0971",
"shasum": ""
},
"require": {
@@ -3688,7 +3695,7 @@
"testing",
"xunit"
],
"time": "2016-12-20T15:22:42+00:00"
"time": "2017-01-20T15:06:43+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -3873,16 +3880,16 @@
},
{
"name": "phpunit/phpunit",
"version": "5.7.5",
"version": "5.7.9",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe"
"reference": "69f832b87c731d5cacad7f91948778fe98335fdd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50fd2be8f3e23e91da825f36f08e5f9633076ffe",
"reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/69f832b87c731d5cacad7f91948778fe98335fdd",
"reference": "69f832b87c731d5cacad7f91948778fe98335fdd",
"shasum": ""
},
"require": {
@@ -3894,7 +3901,7 @@
"myclabs/deep-copy": "~1.3",
"php": "^5.6 || ^7.0",
"phpspec/prophecy": "^1.6.2",
"phpunit/php-code-coverage": "^4.0.3",
"phpunit/php-code-coverage": "^4.0.4",
"phpunit/php-file-iterator": "~1.4",
"phpunit/php-text-template": "~1.2",
"phpunit/php-timer": "^1.0.6",
@@ -3951,7 +3958,7 @@
"testing",
"xunit"
],
"time": "2016-12-28T07:18:51+00:00"
"time": "2017-01-28T06:14:33+00:00"
},
{
"name": "phpunit/phpunit-mock-objects",
@@ -4059,16 +4066,16 @@
},
{
"name": "sebastian/comparator",
"version": "1.2.2",
"version": "1.2.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f"
"reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f",
"reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
"reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
"shasum": ""
},
"require": {
@@ -4119,7 +4126,7 @@
"compare",
"equality"
],
"time": "2016-11-19T09:18:40+00:00"
"time": "2017-01-29T09:50:25+00:00"
},
{
"name": "sebastian/diff",
@@ -4527,16 +4534,16 @@
},
{
"name": "symfony/class-loader",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/class-loader.git",
"reference": "87cd4e69435d98de01d0162c5f9c0ac017075c63"
"reference": "0152f7a47acd564ca62c652975c2b32ac6d613a6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/class-loader/zipball/87cd4e69435d98de01d0162c5f9c0ac017075c63",
"reference": "87cd4e69435d98de01d0162c5f9c0ac017075c63",
"url": "https://api.github.com/repos/symfony/class-loader/zipball/0152f7a47acd564ca62c652975c2b32ac6d613a6",
"reference": "0152f7a47acd564ca62c652975c2b32ac6d613a6",
"shasum": ""
},
"require": {
@@ -4579,20 +4586,20 @@
],
"description": "Symfony ClassLoader Component",
"homepage": "https://symfony.com",
"time": "2016-11-29T08:26:13+00:00"
"time": "2017-01-10T14:14:38+00:00"
},
{
"name": "symfony/css-selector",
"version": "v3.1.8",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "a37b3359566415a91cba55a2d95820b3fa1a9658"
"reference": "722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/a37b3359566415a91cba55a2d95820b3fa1a9658",
"reference": "a37b3359566415a91cba55a2d95820b3fa1a9658",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d",
"reference": "722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d",
"shasum": ""
},
"require": {
@@ -4632,20 +4639,20 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2016-11-03T08:04:31+00:00"
"time": "2017-01-02T20:31:54+00:00"
},
{
"name": "symfony/dom-crawler",
"version": "v3.1.8",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "51e979357eba65b1e6aac7cba75cf5aa6379b8f3"
"reference": "7eede2a901a19928494194f7d1815a77b9a473a0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/51e979357eba65b1e6aac7cba75cf5aa6379b8f3",
"reference": "51e979357eba65b1e6aac7cba75cf5aa6379b8f3",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/7eede2a901a19928494194f7d1815a77b9a473a0",
"reference": "7eede2a901a19928494194f7d1815a77b9a473a0",
"shasum": ""
},
"require": {
@@ -4688,20 +4695,20 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2016-12-10T14:24:45+00:00"
"time": "2017-01-21T17:13:55+00:00"
},
{
"name": "symfony/yaml",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "a7095af4b97a0955f85c8989106c249fa649011f"
"reference": "50eadbd7926e31842893c957eca362b21592a97d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/a7095af4b97a0955f85c8989106c249fa649011f",
"reference": "a7095af4b97a0955f85c8989106c249fa649011f",
"url": "https://api.github.com/repos/symfony/yaml/zipball/50eadbd7926e31842893c957eca362b21592a97d",
"reference": "50eadbd7926e31842893c957eca362b21592a97d",
"shasum": ""
},
"require": {
@@ -4743,7 +4750,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2016-12-10T10:07:06+00:00"
"time": "2017-01-03T13:51:32+00:00"
},
{
"name": "webmozart/assert",

View File

@@ -22,8 +22,9 @@ return [
'single_user_mode' => true,
'is_demo_site' => false,
],
'encryption' => (is_null(env('USE_ENCRYPTION')) || env('USE_ENCRYPTION') === true),
'chart' => 'chartjs',
'version' => '4.3.2',
'version' => '4.3.3',
'csv_import_enabled' => true,
'maxUploadSize' => 5242880,
'allowedMimes' => ['image/png', 'image/jpeg', 'application/pdf'],
@@ -40,12 +41,7 @@ return [
'default_export_format' => 'csv',
'default_import_format' => 'csv',
'bill_periods' => ['weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
'accountRoles' => [
'defaultAsset' => 'Default asset account',
'sharedAsset' => 'Shared asset account',
'savingAsset' => 'Savings account',
'ccAsset' => 'Credit card',
],
'accountRoles' => ['defaultAsset', 'sharedAsset', 'savingAsset', 'ccAsset',],
'ccTypes' => [
'monthlyFull' => 'Full payment every month',
],
@@ -170,7 +166,6 @@ return [
'to_account_ends' => 'FireflyIII\Rules\Triggers\ToAccountEnds',
'to_account_is' => 'FireflyIII\Rules\Triggers\ToAccountIs',
'to_account_contains' => 'FireflyIII\Rules\Triggers\ToAccountContains',
'transaction_type' => 'FireflyIII\Rules\Triggers\TransactionType',
'amount_less' => 'FireflyIII\Rules\Triggers\AmountLess',
'amount_exactly' => 'FireflyIII\Rules\Triggers\AmountExactly',
'amount_more' => 'FireflyIII\Rules\Triggers\AmountMore',
@@ -178,6 +173,10 @@ return [
'description_ends' => 'FireflyIII\Rules\Triggers\DescriptionEnds',
'description_contains' => 'FireflyIII\Rules\Triggers\DescriptionContains',
'description_is' => 'FireflyIII\Rules\Triggers\DescriptionIs',
'transaction_type' => 'FireflyIII\Rules\Triggers\TransactionType',
'category_is' => 'FireflyIII\Rules\Triggers\CategoryIs',
'budget_is' => 'FireflyIII\Rules\Triggers\BudgetIs',
'tag_is' => 'FireflyIII\Rules\Triggers\TagIs',
],
'rule-actions' => [
'set_category' => 'FireflyIII\Rules\Actions\SetCategory',

View File

@@ -12,5 +12,14 @@
declare(strict_types = 1);
return [
'text' => [],
'text' => [
'upgrade' =>
[
'4.3' => 'Make sure you run the migrations and clear your cache. If you need more help, please check Github or the Firefly III website.',
],
'install' =>
[
'4.3' => 'Welcome to Firefly! Make sure you follow the installation guide. If you need more help, please check Github or the Firefly III website. The installation guide has a FAQ which you should check out as well.',
],
],
];

1
public/css/bootstrap-multiselect.css vendored Executable file
View File

@@ -0,0 +1 @@
span.multiselect-native-select{position:relative}span.multiselect-native-select select{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px -1px -1px -3px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;left:50%;top:30px}.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li.multiselect-group label{margin:0;padding:3px 20px 3px 20px;height:100%;font-weight:700}.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.radio,.multiselect-container>li>a>label.checkbox{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container label.checkbox,.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}.form-inline .multiselect-container li a label.checkbox input[type=checkbox],.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;margin-right:0}

View File

@@ -31,7 +31,7 @@ body.waiting * {
}
.preferences-box {
border:1px #ddd solid;
border: 1px #ddd solid;
border-radius: 4px 4px 0 0;
padding: 15px;
margin: 15px;
@@ -101,4 +101,13 @@ body.waiting * {
a[href]:after {
content: none !important;
}
}
}
.edit_tr_buttons {
white-space: nowrap;
}
.edit_tr_buttons .btn {
float: none;
display: inline-block;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -0,0 +1,5 @@
/*! jQuery UI - v1.12.1 - 2017-01-15
* http://jqueryui.com
* Copyright jQuery Foundation and other contributors; Licensed MIT */
.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker .ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;left:.5em;top:.3em}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,20 @@
/*
* create.js
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: Modernizr */
$(document).ready(function () {
"use strict";
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
});

View File

@@ -0,0 +1,20 @@
/*
* create.js
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: Modernizr */
$(document).ready(function () {
"use strict";
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
});

View File

@@ -54,7 +54,7 @@ $(function () {
ui.placeholder.html('<td colspan="' + cellCount + '">&nbsp;</td>');
}
}
).disableSelection();
);
}
});

View File

@@ -0,0 +1,20 @@
/*
* create.js
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: Modernizr */
$(document).ready(function () {
"use strict";
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
});

View File

@@ -0,0 +1,20 @@
/*
* create.js
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: Modernizr */
$(document).ready(function () {
"use strict";
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
});

View File

@@ -8,7 +8,7 @@
* See the LICENSE file for details.
*/
/** global: jobKey */
/** global: jobKey, Modernizr */
var intervalId = 0;
@@ -21,6 +21,14 @@ $(function () {
// - return false,
$('#export').submit(startExport);
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
}
);

View File

@@ -0,0 +1,20 @@
/*
* create.js
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: Modernizr */
$(document).ready(function () {
"use strict";
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
});

View File

@@ -0,0 +1,20 @@
/*
* create.js
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: Modernizr */
$(document).ready(function () {
"use strict";
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
});

View File

@@ -0,0 +1,20 @@
/*
* create.js
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: Modernizr */
$(document).ready(function () {
"use strict";
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
});

View File

@@ -8,7 +8,17 @@
* See the LICENSE file for details.
*/
/** global: minDate */
/** global: minDate, nonSelectedText, allSelectedText, filterPlaceholder */
var defaultMultiSelect = {
disableIfEmpty: true,
nonSelectedText: nonSelectedText,
allSelectedText: allSelectedText,
includeSelectAllOption: true,
enableFiltering: true,
enableCaseInsensitiveFiltering: true,
filterPlaceholder: filterPlaceholder
};
$(function () {
"use strict";
@@ -26,19 +36,24 @@ $(function () {
}
);
// set values from cookies, if any:
// set report type from cookie, if any:
if (!(readCookie('report-type') === null)) {
$('select[name="report_type"]').val(readCookie('report-type'));
}
// set accounts from cookie
if ((readCookie('report-accounts') !== null)) {
var arr = readCookie('report-accounts').split(',');
arr.forEach(function (val) {
$('input[class="account-checkbox"][type="checkbox"][value="' + val + '"]').prop('checked', true);
$('#inputAccounts').find('option[value="' + val + '"]').prop('selected', true);
});
}
// set date:
// make account select a hip new bootstrap multi-select thing.
$('#inputAccounts').multiselect(defaultMultiSelect);
// set date from cookie
var startStr = readCookie('report-start');
var endStr = readCookie('report-end');
if (startStr !== null && endStr !== null && startStr.length == 8 && endStr.length == 8) {
@@ -81,16 +96,18 @@ function setOptionalFromCookies() {
if ((readCookie('report-categories') !== null)) {
arr = readCookie('report-categories').split(',');
arr.forEach(function (val) {
$('input[class="category-checkbox"][type="checkbox"][value="' + val + '"]').prop('checked', true);
$('#inputCategories').find('option[value="' + val + '"]').prop('selected', true);
});
$('#inputCategories').multiselect(defaultMultiSelect);
}
// and budgets!
if ((readCookie('report-budgets') !== null)) {
arr = readCookie('report-budgets').split(',');
arr.forEach(function (val) {
$('input[class="budget-checkbox"][type="checkbox"][value="' + val + '"]').prop('checked', true);
$('#inputBudgets').find('option[value="' + val + '"]').prop('selected', true);
});
$('#inputBudgets').multiselect(defaultMultiSelect);
}
}

View File

@@ -8,47 +8,99 @@
* See the LICENSE file for details.
*/
var triggerCount = 0;
var actionCount = 0;
/** global: triggerCount, actionCount */
$(function () {
"use strict";
if (triggerCount === 0) {
addNewTrigger();
}
if (actionCount === 0) {
addNewAction();
}
if (triggerCount > 0) {
onAddNewTrigger();
}
if (actionCount > 0) {
onAddNewAction();
}
$('.add_rule_trigger').click(addNewTrigger);
$('.add_rule_action').click(addNewAction);
$('.test_rule_triggers').click(testRuleTriggers);
$('.remove-trigger').unbind('click').click(removeTrigger);
$('.remove-action').unbind('click').click(removeAction);
});
/**
* This method triggers when a new trigger must be added to the form.
*/
function addNewTrigger() {
"use strict";
triggerCount++;
// disable the button
$('.add_rule_trigger').attr('disabled', 'disabled');
// get the HTML for the new trigger
$.getJSON('json/trigger', {count: triggerCount}).done(function (data) {
// append it to the other triggers
$('tbody.rule-trigger-tbody').append(data.html);
$('.remove-trigger').unbind('click').click(removeTrigger);
$('.remove-trigger').unbind('click').click(function (e) {
removeTrigger(e);
// update all "select trigger type" dropdowns
// so the accompanying text-box has the correct autocomplete.
onAddNewTrigger();
$('.add_rule_trigger').removeAttr('disabled');
return false;
});
}).fail(function () {
alert('Cannot get a new trigger.');
$('.add_rule_trigger').removeAttr('disabled');
});
return false;
}
/**
* Method triggers when a new action must be added to the form..
*/
function addNewAction() {
"use strict";
actionCount++;
// disable the button
$('.add_rule_action').attr('disabled', 'disabled');
$.getJSON('json/action', {count: actionCount}).done(function (data) {
$('tbody.rule-action-tbody').append(data.html);
// add action things.
$('.remove-action').unbind('click').click(function (e) {
removeAction(e);
$('.remove-action').unbind('click').click(removeAction);
return false;
});
// update all "select trigger type" dropdowns
// so the accompanying text-box has the correct autocomplete.
onAddNewAction();
$('.add_rule_action').removeAttr('disabled');
}).fail(function () {
alert('Cannot get a new action.');
$('.add_rule_action').removeAttr('disabled');
});
return false;
}
/**
* Method fires when a trigger must be removed from the form.
*
* @param e
*/
function removeTrigger(e) {
"use strict";
var target = $(e.target);
@@ -62,8 +114,14 @@ function removeTrigger(e) {
if ($('.rule-trigger-tbody tr').length == 0) {
addNewTrigger();
}
return false;
}
/**
* Method fires when an action must be removed from the form.
*
* @param e
*/
function removeAction(e) {
"use strict";
var target = $(e.target);
@@ -77,6 +135,147 @@ function removeAction(e) {
if ($('.rule-action-tbody tr').length == 0) {
addNewAction();
}
return false;
}
/**
* Method fires when a new action is added. It will update ALL action value input fields.
*/
function onAddNewAction() {
"use strict";
// update all "select action type" dropdown buttons so they will respond correctly
$('select[name^="rule-action["]').unbind('change').change(function (e) {
var target = $(e.target);
updateActionInput(target)
});
$.each($('.rule-action-holder'), function (i, v) {
var holder = $(v);
var select = holder.find('select');
updateActionInput(select);
});
}
/**
* Method fires when a new trigger is added. It will update ALL trigger value input fields.
*/
function onAddNewTrigger() {
"use strict";
// update all "select trigger type" dropdown buttons so they will respond correctly
$('select[name^="rule-trigger["]').unbind('change').change(function (e) {
var target = $(e.target);
updateTriggerInput(target)
});
$.each($('.rule-trigger-holder'), function (i, v) {
var holder = $(v);
var select = holder.find('select');
updateTriggerInput(select);
});
}
/**
* Creates a nice auto complete action depending on the type of the select list value thing.
*
* @param selectList
*/
function updateActionInput(selectList) {
// the actual row this select list is in:
var parent = selectList.parent().parent();
// the text input we're looking for:
var input = parent.find('input[name^="rule-action-value["]');
input.removeAttr('disabled');
switch (selectList.val()) {
case 'set_category':
createAutoComplete(input, 'json/categories');
break;
case 'clear_category':
case 'clear_budget':
case 'remove_all_tags':
input.attr('disabled', 'disabled');
break;
case 'set_budget':
createAutoComplete(input, 'json/budgets');
break;
case 'add_tag':
case 'remove_tag':
createAutoComplete(input, 'json/tags');
break;
case 'set_description':
createAutoComplete(input, 'json/transaction-journals/all');
break;
case 'set_source_account':
createAutoComplete(input, 'json/all-accounts');
break;
case 'set_destination_account':
createAutoComplete(input, 'json/all-accounts');
break;
default:
input.typeahead('destroy');
break;
}
}
/**
* Creates a nice auto complete trigger depending on the type of the select list value thing.
*
* @param selectList
*/
function updateTriggerInput(selectList) {
// the actual row this select list is in:
var parent = selectList.parent().parent();
// the text input we're looking for:
var input = parent.find('input[name^="rule-trigger-value["]');
switch (selectList.val()) {
case 'from_account_starts':
case 'from_account_ends':
case 'from_account_is':
case 'from_account_contains':
case 'to_account_starts':
case 'to_account_ends':
case 'to_account_is':
case 'to_account_contains':
createAutoComplete(input, 'json/all-accounts');
break;
case 'tag_is':
// also make tag thing?
createAutoComplete(input, 'json/tags');
break;
case 'budget_is':
createAutoComplete(input, 'json/budgets');
break;
case 'category_is':
createAutoComplete(input, 'json/categories');
break;
case 'transaction_type':
createAutoComplete(input, 'json/transaction-types');
break;
case 'description_starts':
case 'description_ends':
case 'description_contains':
case 'description_is':
createAutoComplete(input, 'json/transaction-journals/all');
break;
default:
input.typeahead('destroy');
break;
}
}
/**
* Create actual autocomplete
* @param input
* @param URI
*/
function createAutoComplete(input, URI) {
input.typeahead('destroy');
$.getJSON(URI).done(function (data) {
input.typeahead({source: data});
});
}
function testRuleTriggers() {
@@ -105,4 +304,5 @@ function testRuleTriggers() {
}).fail(function () {
alert('Cannot get transactions for given triggers.');
});
return false;
}

View File

@@ -1,41 +0,0 @@
/*
* create.js
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: triggerCount, actionCount */
$(function () {
"use strict";
if (triggerCount === 0) {
addNewTrigger();
}
if (actionCount === 0) {
addNewAction();
}
$('.add_rule_trigger').click(function () {
addNewTrigger();
return false;
});
$('.add_rule_action').click(function () {
addNewAction();
return false;
});
$('.test_rule_triggers').click(function () {
testRuleTriggers();
return false;
});
});

View File

@@ -1,53 +0,0 @@
/*
* edit.js
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: triggerCount, actionCount */
$(function () {
"use strict";
if (triggerCount === 0) {
addNewTrigger();
}
if (actionCount === 0) {
addNewAction();
}
$('.add_rule_trigger').click(function () {
addNewTrigger();
return false;
});
$('.test_rule_triggers').click(function () {
testRuleTriggers();
return false;
});
$('.add_rule_action').click(function () {
addNewAction();
return false;
});
$('.remove-trigger').unbind('click').click(function (e) {
removeTrigger(e);
return false;
});
// add action things.
$('.remove-action').unbind('click').click(function (e) {
removeAction(e);
return false;
});
});

View File

@@ -0,0 +1,20 @@
/*
* create.js
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: Modernizr */
$(document).ready(function () {
"use strict";
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
});

View File

@@ -5,12 +5,19 @@
*
* See the LICENSE file for details.
*/
/** global: zoomLevel, latitude, longitude, google, apiKey, doPlaceMarker */
/** global: zoomLevel, latitude, longitude, google, apiKey, doPlaceMarker, Modernizr */
$(function () {
"use strict";
$('#clearLocation').click(clearLocation);
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
});

View File

@@ -1,99 +0,0 @@
/*
* create-edit.js
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: what */
$(document).ready(function () {
"use strict";
// the destination account name is always an expense account name.
if ($('input[name="destination_account_name"]').length > 0) {
$.getJSON('json/expense-accounts').done(function (data) {
$('input[name="destination_account_name"]').typeahead({source: data});
});
}
// also for multi input
if ($('input[name="destination_account_name[]"]').length > 0) {
$.getJSON('json/expense-accounts').done(function (data) {
$('input[name="destination_account_name[]"]').typeahead({source: data});
});
}
if ($('input[name="tags"]').length > 0) {
$.getJSON('json/tags').done(function (data) {
var opt = {
typeahead: {
source: data,
afterSelect: function(val) { this.$element.val(""); }
}
};
$('input[name="tags"]').tagsinput(
opt
);
});
}
// the source account name is always a revenue account name.
if ($('input[name="source_account_name"]').length > 0) {
$.getJSON('json/revenue-accounts').done(function (data) {
$('input[name="source_account_name"]').typeahead({source: data});
});
}
// also for multi-input:
if ($('input[name="source_account_name[]"]').length > 0) {
$.getJSON('json/revenue-accounts').done(function (data) {
$('input[name="source_account_name[]"]').typeahead({source: data});
});
}
// and for split:
if ($('input[name="journal_source_account_name"]').length > 0) {
$.getJSON('json/revenue-accounts').done(function (data) {
$('input[name="journal_source_account_name"]').typeahead({source: data});
});
}
if ($('input[name="description"]').length > 0 && !(typeof what === "undefined")) {
$.getJSON('json/transaction-journals/' + what).done(function (data) {
$('input[name="description"]').typeahead({source: data});
});
}
// also for multi input:
if ($('input[name="description[]"]').length > 0 && !(typeof what === "undefined")) {
$.getJSON('json/transaction-journals/' + what).done(function (data) {
$('input[name="description[]"]').typeahead({source: data});
});
}
// and for the (rare) journal_description:
if ($('input[name="journal_description"]').length > 0 && !(typeof what === "undefined")) {
$.getJSON('json/transaction-journals/' + what).done(function (data) {
$('input[name="journal_description"]').typeahead({source: data});
});
}
if ($('input[name="category"]').length > 0) {
$.getJSON('json/categories').done(function (data) {
$('input[name="category"]').typeahead({source: data});
});
}
// also for multi input:
if ($('input[name^="category["]').length > 0) {
$.getJSON('json/categories').done(function (data) {
$('input[name^="category["]').typeahead({source: data});
});
}
});

View File

@@ -1,14 +0,0 @@
/*
* edit.js
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
$(document).ready(function () {
"use strict";
// no special JS for edit transaction.
});

View File

@@ -0,0 +1,31 @@
/*
* edit.js
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: what */
$(document).ready(function () {
"use strict";
// destination account names:
if ($('input[name^="destination_account_name["]').length > 0) {
$.getJSON('json/expense-accounts').done(function (data) {
$('input[name^="destination_account_name["]').typeahead({source: data});
});
}
// source account name
if ($('input[name^="source_account_name["]').length > 0) {
$.getJSON('json/revenue-accounts').done(function (data) {
$('input[name^="source_account_name["]').typeahead({source: data});
});
}
$.getJSON('json/categories').done(function (data) {
$('input[name^="category["]').typeahead({source: data});
});
});

View File

@@ -1,14 +1,12 @@
/*
* create.js
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: what, title, breadcrumbs, middleCrumbName, button, piggiesLength, txt, doSwitch, middleCrumbUrl */
/** global: what,Modernizr, title, breadcrumbs, middleCrumbName, button, piggiesLength, txt, doSwitch, middleCrumbUrl */
$(document).ready(function () {
"use strict";
@@ -19,11 +17,65 @@ $(document).ready(function () {
updateButtons();
updateForm();
updateLayout();
updateDescription();
}
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
// get JSON things:
getJSONautocomplete();
});
function updateDescription() {
$.getJSON('json/transaction-journals/' + what).done(function (data) {
$('input[name="description"]').typeahead('destroy');
$('input[name="description"]').typeahead({source: data});
});
}
function getJSONautocomplete() {
// for withdrawals
$.getJSON('json/expense-accounts').done(function (data) {
$('input[name="destination_account_name"]').typeahead({source: data});
});
// for tags:
if ($('input[name="tags"]').length > 0) {
$.getJSON('json/tags').done(function (data) {
var opt = {
typeahead: {
source: data,
afterSelect: function () {
this.$element.val("");
}
}
};
$('input[name="tags"]').tagsinput(
opt
);
});
}
// for deposits
$.getJSON('json/revenue-accounts').done(function (data) {
$('input[name="source_account_name"]').typeahead({source: data});
});
$.getJSON('json/categories').done(function (data) {
$('input[name="category"]').typeahead({source: data});
});
}
function updateLayout() {
"use strict";
$('#subTitle').text(title[what]);
@@ -131,6 +183,7 @@ function clickButton(e) {
updateButtons();
updateForm();
updateLayout();
updateDescription();
}
return false;
}

Some files were not shown because too many files have changed in this diff Show More