Merge branch 'release/4.3.3'

This commit is contained in:
James Cole
2017-01-30 11:18:29 +01:00
164 changed files with 4881 additions and 1373 deletions

View File

@@ -43,6 +43,7 @@ CACHE_PREFIX=firefly
GOOGLE_MAPS_API_KEY= GOOGLE_MAPS_API_KEY=
ANALYTICS_ID= ANALYTICS_ID=
SITE_OWNER=mail@example.com SITE_OWNER=mail@example.com
USE_ENCRYPTION=true
PUSHER_KEY= PUSHER_KEY=
PUSHER_SECRET= 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 language: php
sudo: false
php: php:
- '7.0' - 7.0
- 7.1
cache:
directories:
- vendor
- $HOME/.composer/cache
install: install:
- phpenv config-rm xdebug.ini - if [[ "$(php -v | grep 'PHP 7')" ]]; then phpenv config-rm xdebug.ini; fi
- rm composer.lock - rm composer.lock
- composer update --no-scripts - composer update --no-scripts
- cp .env.testing .env
- php artisan clear-compiled - php artisan clear-compiled
- php artisan optimize - php artisan optimize
- php artisan env - php artisan env

View File

@@ -2,6 +2,28 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/). 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 ## [4.3.2] - 2017-01-09

View File

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

View File

@@ -33,7 +33,7 @@ class UpgradeFireflyInstructions extends Command
* *
* @var string * @var string
*/ */
protected $signature = 'firefly:upgrade-instructions'; protected $signature = 'firefly:instructions {task}';
/** /**
* Create a new command instance. * Create a new command instance.
@@ -49,11 +49,60 @@ class UpgradeFireflyInstructions extends Command
*/ */
public function handle() 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 */ /** @var string $version */
$version = config('firefly.version'); $version = config('firefly.version');
$config = config('upgrade.text'); $config = config('upgrade.text.install');
$text = null; $text = '';
foreach (array_keys($config) as $compare) { foreach (array_keys($config) as $compare) {
// if string starts with: // if string starts with:
$len = strlen($compare); $len = strlen($compare);
@@ -62,22 +111,53 @@ class UpgradeFireflyInstructions extends Command
} }
} }
$this->showLine();
$this->boxed('');
if (is_null($text)) { 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; return;
} }
$this->line('+------------------------------------------------------------------------------+'); $this->boxed(sprintf('Thank you for installing Firefly III, v%s!', $version));
$this->line(''); $this->boxedInfo($text);
$this->line(sprintf('Thank you for installing Firefly III, v%s', $version)); $this->boxed('');
$this->info(wordwrap($text)); $this->showLine();
$this->line(''); }
$this->line('+------------------------------------------------------------------------------+');
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\CreateImport;
use FireflyIII\Console\Commands\EncryptFile; use FireflyIII\Console\Commands\EncryptFile;
use FireflyIII\Console\Commands\Import; use FireflyIII\Console\Commands\Import;
use FireflyIII\Console\Commands\MoveRepository;
use FireflyIII\Console\Commands\ScanAttachments; use FireflyIII\Console\Commands\ScanAttachments;
use FireflyIII\Console\Commands\UpgradeDatabase; use FireflyIII\Console\Commands\UpgradeDatabase;
use FireflyIII\Console\Commands\UpgradeFireflyInstructions; use FireflyIII\Console\Commands\UpgradeFireflyInstructions;
use FireflyIII\Console\Commands\UseEncryption;
use FireflyIII\Console\Commands\VerifyDatabase; use FireflyIII\Console\Commands\VerifyDatabase;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel; use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
@@ -63,6 +63,7 @@ class Kernel extends ConsoleKernel
EncryptFile::class, EncryptFile::class,
ScanAttachments::class, ScanAttachments::class,
UpgradeDatabase::class, UpgradeDatabase::class,
UseEncryption::class,
]; ];
/** /**

View File

@@ -111,9 +111,9 @@ class Handler extends ExceptionHandler
/** /**
* Convert an authentication exception into an unauthenticated response. * 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) protected function unauthenticated($request)
{ {

View File

@@ -51,7 +51,6 @@ final class Entry
public $destination_account_id; public $destination_account_id;
public $destination_account_name; public $destination_account_name;
public $budget_id; public $budget_id;
public $budget_name; public $budget_name;
public $category_id; public $category_id;
@@ -74,15 +73,15 @@ final class Entry
{ {
$entry = new self; $entry = new self;
$entry->journal_id = $object->transaction_journal_id; $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->amount = $object->amount;
$entry->date = $object->date; $entry->date = $object->date;
$entry->transaction_type = $object->transaction_type; $entry->transaction_type = $object->transaction_type;
$entry->currency_code = $object->transaction_currency_code; $entry->currency_code = $object->transaction_currency_code;
$entry->source_account_id = $object->account_id; $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_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_id = $object->category_id ?? '';
$entry->category_name = $object->category_name ?? ''; $entry->category_name = $object->category_name ?? '';
$entry->budget_id = $object->budget_id ?? ''; $entry->budget_id = $object->budget_id ?? '';

View File

@@ -32,9 +32,9 @@ class AttachmentHelper implements AttachmentHelperInterface
/** @var MessageBag */ /** @var MessageBag */
public $messages; public $messages;
/** @var array */ /** @var array */
protected $allowedMimes; protected $allowedMimes = [];
/** @var int */ /** @var int */
protected $maxUploadSize; protected $maxUploadSize = 0;
/** @var \Illuminate\Contracts\Filesystem\Filesystem */ /** @var \Illuminate\Contracts\Filesystem\Filesystem */
protected $uploadDisk; protected $uploadDisk;
@@ -44,8 +44,8 @@ class AttachmentHelper implements AttachmentHelperInterface
*/ */
public function __construct() public function __construct()
{ {
$this->maxUploadSize = config('firefly.maxUploadSize'); $this->maxUploadSize = intval(config('firefly.maxUploadSize'));
$this->allowedMimes = config('firefly.allowedMimes'); $this->allowedMimes = (array) config('firefly.allowedMimes');
$this->errors = new MessageBag; $this->errors = new MessageBag;
$this->messages = new MessageBag; $this->messages = new MessageBag;
$this->uploadDisk = Storage::disk('upload'); $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 public function getJournals(): Collection
{ {
$this->run = true; $this->run = true;
/** @var Collection $set */
$set = $this->query->get(array_values($this->fields)); $set = $this->query->get(array_values($this->fields));
Log::debug(sprintf('Count of set is %d', $set->count())); Log::debug(sprintf('Count of set is %d', $set->count()));
$set = $this->filterTransfers($set); $set = $this->filterTransfers($set);

View File

@@ -75,6 +75,11 @@ class AccountController extends Controller
$defaultCurrency = Amount::getDefaultCurrency(); $defaultCurrency = Amount::getDefaultCurrency();
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what); $subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
$subTitle = trans('firefly.make_new_' . $what . '_account'); $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 // pre fill some data
Session::flash('preFilled', ['currency_id' => $defaultCurrency->id,]); Session::flash('preFilled', ['currency_id' => $defaultCurrency->id,]);
@@ -87,7 +92,7 @@ class AccountController extends Controller
Session::flash('gaEventCategory', 'accounts'); Session::flash('gaEventCategory', 'accounts');
Session::flash('gaEventAction', 'create-' . $what); 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 */ /** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class); $repository = app(CurrencyRepositoryInterface::class);
$currencies = ExpandedForm::makeSelectList($repository->get()); $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"). // put previous url in session if not redirect from store (not "return_to_edit").
if (session('accounts.edit.fromUpdate') !== true) { if (session('accounts.edit.fromUpdate') !== true) {
@@ -185,7 +195,7 @@ class AccountController extends Controller
Session::flash('gaEventCategory', 'accounts'); Session::flash('gaEventCategory', 'accounts');
Session::flash('gaEventAction', 'edit-' . $what); 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\Http\Requests\AttachmentFormRequest;
use FireflyIII\Models\Attachment; use FireflyIII\Models\Attachment;
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use Illuminate\Http\Response as LaravelResponse;
use Preferences; use Preferences;
use Response; use Response;
use Session; use Session;
@@ -100,7 +101,9 @@ class AttachmentController extends Controller
$content = $repository->getContent($attachment); $content = $repository->getContent($attachment);
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\')); $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-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream') ->header('Content-Type', 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename=' . $quoted) ->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('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public') ->header('Pragma', 'public')
->header('Content-Length', strlen($content)); ->header('Content-Length', strlen($content));
return $response;
} }
throw new FireflyException('Could not find the indicated attachment. The file is no longer there.'); 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.'); 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')); $page = intval($request->get('page')) == 0 ? 1 : intval($request->get('page'));
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data); $pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
$subTitle = trans( $subTitle = trans(
@@ -289,7 +287,6 @@ class BudgetController extends Controller
'end' => $budgetLimit->end_date->formatLocalized($this->monthAndDayFormat), 'end' => $budgetLimit->end_date->formatLocalized($this->monthAndDayFormat),
] ]
); );
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::CASH]);
// collector: // collector:
/** @var JournalCollectorInterface $collector */ /** @var JournalCollectorInterface $collector */

View File

@@ -24,6 +24,7 @@ use FireflyIII\Models\ExportJob;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface; use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface;
use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface as EJRI; use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface as EJRI;
use Illuminate\Http\Response as LaravelResponse;
use Preferences; use Preferences;
use Response; use Response;
use View; use View;
@@ -73,8 +74,9 @@ class ExportController extends Controller
$job->change('export_downloaded'); $job->change('export_downloaded');
/** @var LaravelResponse $response */
return response($content, 200) $response = response($content, 200);
$response
->header('Content-Description', 'File Transfer') ->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream') ->header('Content-Type', 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename=' . $quoted) ->header('Content-Disposition', 'attachment; filename=' . $quoted)
@@ -85,6 +87,8 @@ class ExportController extends Controller
->header('Pragma', 'public') ->header('Pragma', 'public')
->header('Content-Length', strlen($content)); ->header('Content-Length', strlen($content));
return $response;
} }
/** /**
@@ -128,8 +132,7 @@ class ExportController extends Controller
* @param AccountRepositoryInterface $repository * @param AccountRepositoryInterface $repository
* @param EJRI $jobs * @param EJRI $jobs
* *
* @return string * @return \Illuminate\Http\JsonResponse
*
*/ */
public function postIndex(ExportFormRequest $request, AccountRepositoryInterface $repository, EJRI $jobs) 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\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface; use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response as LaravelResponse;
use Log; use Log;
use Response; use Response;
use Session; use Session;
@@ -120,8 +121,9 @@ class ImportController extends Controller
$result = json_encode($config, JSON_PRETTY_PRINT); $result = json_encode($config, JSON_PRETTY_PRINT);
$name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\')); $name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\'));
return response($result, 200) /** @var LaravelResponse $response */
->header('Content-disposition', 'attachment; filename=' . $name) $response = response($result, 200);
$response->header('Content-disposition', 'attachment; filename=' . $name)
->header('Content-Type', 'application/json') ->header('Content-Type', 'application/json')
->header('Content-Description', 'File Transfer') ->header('Content-Description', 'File Transfer')
->header('Connection', 'Keep-Alive') ->header('Connection', 'Keep-Alive')
@@ -130,6 +132,8 @@ class ImportController extends Controller
->header('Pragma', 'public') ->header('Pragma', 'public')
->header('Content-Length', strlen($result)); ->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\AccountRepositoryInterface;
use FireflyIII\Repositories\Account\AccountTaskerInterface; use FireflyIII\Repositories\Account\AccountTaskerInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface; 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\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@@ -61,6 +63,43 @@ class JsonController extends Controller
return Response::json(['html' => $view]); 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 * @param BillRepositoryInterface $repository
* *
@@ -158,20 +197,30 @@ class JsonController extends Controller
} }
/** /**
* Returns a list of categories. * @param BudgetRepositoryInterface $repository
*
* @param CRI $repository
* *
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
public function categories(CRI $repository) public function budgets(BudgetRepositoryInterface $repository)
{ {
$list = $repository->getCategories(); $return = array_unique($repository->getBudgets()->pluck('name')->toArray());
$return = []; sort($return);
foreach ($list as $entry) {
$return[] = $entry->name; 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); return Response::json($return);
} }
@@ -195,14 +244,10 @@ class JsonController extends Controller
*/ */
public function expenseAccounts(AccountRepositoryInterface $repository) public function expenseAccounts(AccountRepositoryInterface $repository)
{ {
$list = $repository->getAccountsByType([AccountType::EXPENSE, AccountType::BENEFICIARY]); $return = array_unique($repository->getAccountsByType([AccountType::EXPENSE, AccountType::BENEFICIARY])->pluck('name')->toArray());
$return = []; sort($return);
foreach ($list as $entry) {
$return[] = $entry->name;
}
return Response::json($return); return Response::json($return);
} }
/** /**
@@ -213,14 +258,10 @@ class JsonController extends Controller
*/ */
public function revenueAccounts(AccountRepositoryInterface $repository) public function revenueAccounts(AccountRepositoryInterface $repository)
{ {
$list = $repository->getAccountsByType([AccountType::REVENUE]); $return = array_unique($repository->getAccountsByType([AccountType::REVENUE])->pluck('name')->toArray());
$return = []; sort($return);
foreach ($list as $entry) {
$return[] = $entry->name;
}
return Response::json($return); return Response::json($return);
} }
/** /**
@@ -232,11 +273,8 @@ class JsonController extends Controller
*/ */
public function tags(TagRepositoryInterface $tagRepository) public function tags(TagRepositoryInterface $tagRepository)
{ {
$list = $tagRepository->get(); $return = array_unique($tagRepository->get()->pluck('tag')->toArray());
$return = []; sort($return);
foreach ($list as $entry) {
$return[] = $entry->tag;
}
return Response::json($return); return Response::json($return);
@@ -278,23 +316,27 @@ class JsonController extends Controller
*/ */
public function transactionJournals(JournalCollectorInterface $collector, string $what) public function transactionJournals(JournalCollectorInterface $collector, string $what)
{ {
$descriptions = [];
$type = config('firefly.transactionTypesByWhat.' . $what); $type = config('firefly.transactionTypesByWhat.' . $what);
$types = [$type]; $types = [$type];
// use journal collector instead:
$collector->setTypes($types)->setLimit(100)->setPage(1); $collector->setTypes($types)->setLimit(100)->setPage(1);
$journals = $collector->getJournals(); $return = array_unique($collector->getJournals()->pluck('description')->toArray());
foreach ($journals as $j) { sort($return);
$descriptions[] = $j->description;
return Response::json($return);
} }
$descriptions = array_unique($descriptions); /**
sort($descriptions); *
*/
return Response::json($descriptions); public function transactionTypes(JournalRepositoryInterface $repository)
{
$return = array_unique($repository->getTransactionTypes()->pluck('type')->toArray());
sort($return);
return Response::json($return);
} }
/** /**

View File

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

View File

@@ -163,11 +163,11 @@ class MassController extends Controller
$journal->transaction_count = $journal->transactions()->count(); $journal->transaction_count = $journal->transactions()->count();
if (!is_null($sources->first())) { if (!is_null($sources->first())) {
$journal->source_account_id = $sources->first()->id; $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())) { if (!is_null($destinations->first())) {
$journal->destination_account_id = $destinations->first()->id; $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; $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 * @param string $what
* *
@@ -113,7 +149,10 @@ class SingleController extends Controller
asort($piggies); 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('gaEventCategory', 'transactions');
Session::flash('gaEventAction', 'delete-' . $what); 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'); Session::forget('transactions.edit.fromUpdate');
return view( return view(
'transactions.edit', 'transactions.single.edit',
compact('journal', 'optionalFields', 'assetAccounts', 'what', 'budgetList', 'subTitle') compact('journal', 'optionalFields', 'assetAccounts', 'what', 'budgetList', 'subTitle')
)->with('data', $preFilled); )->with('data', $preFilled);
} }
@@ -265,6 +304,7 @@ class SingleController extends Controller
return redirect(route('transactions.create', [$request->input('what')]))->withInput(); return redirect(route('transactions.create', [$request->input('what')]))->withInput();
} }
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null; $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
$this->attachments->saveAttachmentsForModel($journal, $files); $this->attachments->saveAttachmentsForModel($journal, $files);
@@ -315,6 +355,7 @@ class SingleController extends Controller
$data = $request->getJournalData(); $data = $request->getJournalData();
$journal = $repository->update($journal, $data); $journal = $repository->update($journal, $data);
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null; $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
$this->attachments->saveAttachmentsForModel($journal, $files); $this->attachments->saveAttachmentsForModel($journal, $files);

View File

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

View File

@@ -72,9 +72,6 @@ class Range
// set view variables. // set view variables.
$this->configureView(); $this->configureView();
// get variables for date range:
$this->datePicker();
// set more view variables: // set more view variables:
$this->configureList(); $this->configureList();
} }
@@ -96,7 +93,6 @@ class Range
{ {
$pref = Preferences::get('language', config('firefly.default_language', 'en_US')); $pref = Preferences::get('language', config('firefly.default_language', 'en_US'));
$lang = $pref->data; $lang = $pref->data;
App::setLocale($lang); App::setLocale($lang);
Carbon::setLocale(substr($lang, 0, 2)); Carbon::setLocale(substr($lang, 0, 2));
$locale = explode(',', trans('config.locale')); $locale = explode(',', trans('config.locale'));
@@ -105,94 +101,15 @@ class Range
setlocale(LC_TIME, $locale); setlocale(LC_TIME, $locale);
setlocale(LC_MONETARY, $locale); setlocale(LC_MONETARY, $locale);
// save some formats: // save some formats:
$monthFormat = (string)trans('config.month');
$monthAndDayFormat = (string)trans('config.month_and_day'); $monthAndDayFormat = (string)trans('config.month_and_day');
$dateTimeFormat = (string)trans('config.date_time'); $dateTimeFormat = (string)trans('config.date_time');
$defaultCurrency = Amount::getDefaultCurrency(); $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('monthAndDayFormat', $monthAndDayFormat);
View::share('dateTimeFormat', $dateTimeFormat); View::share('dateTimeFormat', $dateTimeFormat);
View::share('language', $lang);
View::share('localeconv', $localeconv);
View::share('defaultCurrency', $defaultCurrency); 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; namespace FireflyIII\Http\Requests;
use Carbon\Carbon;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/** /**
@@ -39,21 +38,21 @@ class AccountFormRequest extends Request
public function getAccountData(): array public function getAccountData(): array
{ {
return [ return [
'name' => trim(strval($this->input('name'))), 'name' => $this->string('name'),
'active' => intval($this->input('active')) === 1, 'active' => $this->boolean('active'),
'accountType' => $this->input('what'), 'accountType' => $this->string('what'),
'currency_id' => intval($this->input('currency_id')), 'currency_id' => $this->integer('currency_id'),
'virtualBalance' => round($this->input('virtualBalance'), 12), 'virtualBalance' => $this->float('virtualBalance'),
'virtualBalanceCurrency' => intval($this->input('amount_currency_id_virtualBalance')), 'virtualBalanceCurrency' => $this->integer('amount_currency_id_virtualBalance'),
'iban' => trim(strval($this->input('iban'))), 'iban' => $this->string('iban'),
'BIC' => trim(strval($this->input('BIC'))), 'BIC' => $this->string('BIC'),
'accountNumber' => trim(strval($this->input('accountNumber'))), 'accountNumber' => $this->string('accountNumber'),
'accountRole' => $this->input('accountRole'), 'accountRole' => $this->string('accountRole'),
'openingBalance' => round($this->input('openingBalance'), 12), 'openingBalance' => $this->float('openingBalance'),
'openingBalanceDate' => new Carbon((string)$this->input('openingBalanceDate')), 'openingBalanceDate' => $this->date('openingBalanceDate'),
'openingBalanceCurrency' => intval($this->input('amount_currency_id_openingBalance')), 'openingBalanceCurrency' => $this->integer('amount_currency_id_openingBalance'),
'ccType' => $this->input('ccType'), 'ccType' => $this->string('ccType'),
'ccMonthlyPaymentDate' => $this->input('ccMonthlyPaymentDate'), 'ccMonthlyPaymentDate' => $this->string('ccMonthlyPaymentDate'),
]; ];
} }
@@ -72,7 +71,7 @@ class AccountFormRequest extends Request
$idRule = ''; $idRule = '';
if (!is_null($repository->find(intval($this->get('id')))->id)) { if (!is_null($repository->find(intval($this->get('id')))->id)) {
$idRule = 'belongsToUser:accounts'; $idRule = 'belongsToUser:accounts';
$nameRule = 'required|min:1|uniqueAccountForUser:' . $this->get('id'); $nameRule = 'required|min:1|uniqueAccountForUser:' . intval($this->get('id'));
} }
return [ return [

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -13,6 +13,7 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests; namespace FireflyIII\Http\Requests;
use Carbon\Carbon;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
/** /**
@@ -20,7 +21,123 @@ use Illuminate\Foundation\Http\FormRequest;
* *
* @package FireflyIII\Http\Requests * @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 public function getRuleData(): array
{ {
return [ return [
'title' => trim($this->get('title')), 'title' => $this->string('title'),
'active' => intval($this->get('active')) == 1, 'active' => $this->boolean('active'),
'trigger' => trim($this->get('trigger')), 'trigger' => $this->string('trigger'),
'description' => trim($this->get('description')), 'description' => $this->string('description'),
'rule-triggers' => $this->get('rule-trigger'), 'rule-triggers' => $this->get('rule-trigger'),
'rule-trigger-values' => $this->get('rule-trigger-value'), 'rule-trigger-values' => $this->get('rule-trigger-value'),
'rule-trigger-stop' => $this->get('rule-trigger-stop'), 'rule-trigger-stop' => $this->get('rule-trigger-stop'),
'rule-actions' => $this->get('rule-action'), 'rule-actions' => $this->get('rule-action'),
'rule-action-values' => $this->get('rule-action-value'), 'rule-action-values' => $this->get('rule-action-value'),
'rule-action-stop' => $this->get('rule-action-stop'), '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 public function getRuleGroupData(): array
{ {
return [ return [
'title' => trim($this->input('title')), 'title' => $this->string('title'),
'description' => trim($this->input('description')), 'description' => $this->string('description'),
]; ];
} }

View File

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

View File

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

View File

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

View File

@@ -93,7 +93,6 @@ class Account extends Model
} }
/** @var Account $account */ /** @var Account $account */
foreach ($set as $account) { foreach ($set as $account) {
if ($account->name == $fields['name']) { if ($account->name == $fields['name']) {
@@ -316,8 +315,9 @@ class Account extends Model
*/ */
public function setNameAttribute($value) public function setNameAttribute($value)
{ {
$this->attributes['name'] = $value; $encrypt = config('firefly.encryption');
$this->attributes['encrypted'] = false; $this->attributes['name'] = $encrypt ? Crypt::encrypt($value) : $value;
$this->attributes['encrypted'] = $encrypt;
} }
/** /**

View File

@@ -120,8 +120,9 @@ class Bill extends Model
*/ */
public function setMatchAttribute($value) public function setMatchAttribute($value)
{ {
$this->attributes['match'] = Crypt::encrypt($value); $encrypt = config('firefly.encryption');
$this->attributes['match_encrypted'] = true; $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) public function setNameAttribute($value)
{ {
$this->attributes['name'] = Crypt::encrypt($value); $encrypt = config('firefly.encryption');
$this->attributes['name_encrypted'] = true; $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) public function setNameAttribute($value)
{ {
$this->attributes['name'] = $value; $encrypt = config('firefly.encryption');
$this->attributes['encrypted'] = false; $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) public function setNameAttribute($value)
{ {
$this->attributes['name'] = $value; $encrypt = config('firefly.encryption');
$this->attributes['encrypted'] = false; $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) public function setNameAttribute($value)
{ {
$this->attributes['name'] = $value; $encrypt = config('firefly.encryption');
$this->attributes['encrypted'] = false; $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) 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) public function setDescriptionAttribute($value)
{ {
$this->attributes['description'] = $value; $encrypt = config('firefly.encryption');
$this->attributes['encrypted'] = false; $this->attributes['description'] = $encrypt ? Crypt::encrypt($value) : $value;
$this->attributes['encrypted'] = $encrypt;
} }
/** /**

View File

@@ -283,6 +283,29 @@ class AccountRepository implements AccountRepositoryInterface
return $last; 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. * 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 public function oldestJournalDate(Account $account): Carbon
{ {
$first = new Carbon; $journal = $this->oldestJournal($account);
$date = $account->transactions() if (is_null($journal->id)) {
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') return new Carbon;
->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);
} }
return $first; return $journal->date;
} }
/** /**
@@ -477,7 +494,6 @@ class AccountRepository implements AccountRepositoryInterface
} }
/** /**
* @param float $amount
* @param string $name * @param string $name
* *
* @return Account * @return Account

View File

@@ -15,6 +15,7 @@ namespace FireflyIII\Repositories\Account;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
/** /**
@@ -105,6 +106,15 @@ interface AccountRepositoryInterface
*/ */
public function newestJournalDate(Account $account): Carbon; 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. * 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; namespace FireflyIII\Repositories\Account;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Helpers\Collection\Account as AccountCollection;
use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Database\Query\JoinClause; use Illuminate\Database\Query\JoinClause;
@@ -106,55 +104,55 @@ class AccountTasker implements AccountTaskerInterface
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @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(); $ids = $accounts->pluck('id')->toArray();
$yesterday = clone $start; $yesterday = clone $start;
$yesterday->subDay(); $yesterday->subDay();
$startSet = Steam::balancesById($ids, $yesterday); $startSet = Steam::balancesById($ids, $yesterday);
$backupSet = Steam::balancesById($ids, $start);
$endSet = Steam::balancesById($ids, $end); $endSet = Steam::balancesById($ids, $end);
Log::debug( Log::debug('Start of accountreport');
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';
// check backup set just in case: /** @var AccountRepositoryInterface $repository */
if ($account->startBalance === '0' && isset($backupSet[$account->id])) { $repository = app(AccountRepositoryInterface::class);
$account->startBalance = $backupSet[$account->id];
} $return = [
} 'start' => '0',
); 'end' => '0',
'difference' => '0',
'accounts' => [],
];
// summarize:
foreach ($accounts as $account) { foreach ($accounts as $account) {
$startAmount = bcadd($startAmount, $account->startBalance); $id = $account->id;
$endAmount = bcadd($endAmount, $account->endBalance); $entry = [
$diff = bcadd($diff, bcsub($account->endBalance, $account->startBalance)); '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; $return['difference'] = bcsub($return['end'], $return['start']);
$object->setStart($startAmount);
$object->setEnd($endAmount);
$object->setDifference($diff);
$object->setAccounts($accounts);
return $return;
return $object;
} }
/** /**

View File

@@ -14,7 +14,6 @@ declare(strict_types = 1);
namespace FireflyIII\Repositories\Account; namespace FireflyIII\Repositories\Account;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Helpers\Collection\Account as AccountCollection;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
/** /**
@@ -54,8 +53,8 @@ interface AccountTaskerInterface
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @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 * @param string $key
* *
* @return ExportJob|null * @return ExportJob
*/ */
public function findByKey(string $key): ExportJob; public function findByKey(string $key): ExportJob;

View File

@@ -137,6 +137,14 @@ class JournalRepository implements JournalRepositoryInterface
return $entry; return $entry;
} }
/**
* @return Collection
*/
public function getTransactionTypes(): Collection
{
return TransactionType::orderBy('type', 'ASC')->get();
}
/** /**
* @param array $data * @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 TransactionJournal $journal
* @param array $data * @param array $data

View File

@@ -16,6 +16,7 @@ namespace FireflyIII\Repositories\Journal;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType; use FireflyIII\Models\TransactionType;
use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag; use Illuminate\Support\MessageBag;
/** /**
@@ -36,6 +37,11 @@ interface JournalRepositoryInterface
*/ */
public function convert(TransactionJournal $journal, TransactionType $type, Account $source, Account $destination): MessageBag; public function convert(TransactionJournal $journal, TransactionType $type, Account $source, Account $destination): MessageBag;
/**
* @return Collection
*/
public function getTransactionTypes(): Collection;
/** /**
* Deletes a journal. * Deletes a journal.
* *
@@ -69,15 +75,6 @@ interface JournalRepositoryInterface
*/ */
public function store(array $data): TransactionJournal; 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 TransactionJournal $journal
* @param array $data * @param array $data

View File

@@ -50,7 +50,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
/** /**
* @param RuleGroup $ruleGroup * @param RuleGroup $ruleGroup
* @param RuleGroup $moveTo * @param RuleGroup|null $moveTo
* *
* @return bool * @return bool
*/ */

View File

@@ -36,7 +36,7 @@ interface RuleGroupRepositoryInterface
/** /**
* @param RuleGroup $ruleGroup * @param RuleGroup $ruleGroup
* @param RuleGroup $moveTo * @param RuleGroup|null $moveTo
* *
* @return bool * @return bool
*/ */

View File

@@ -74,6 +74,8 @@ class AbstractTrigger
return $self; return $self;
} }
/** /**
* @param RuleTrigger $trigger * @param RuleTrigger $trigger
* @param TransactionJournal $journal * @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; $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; $format = $pos_a . $pos_d . '%v' . $space . $pos_b . '%s' . $pos_c . $pos_e;
if ($csPrecedes) { if ($csPrecedes) {
// (currency before amount) // alternative is currency before amount
$format = $pos_a . $pos_b . '%s' . $pos_c . $space . $pos_d . '%v' . $pos_e; $format = $pos_a . $pos_b . '%s' . $pos_c . $space . $pos_d . '%v' . $pos_e;
} }
Log::debug(sprintf('Final format: "%s"', $format)); Log::debug(sprintf('Final format: "%s"', $format));

View File

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

View File

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

View File

@@ -14,7 +14,6 @@ declare(strict_types = 1);
namespace FireflyIII\Support\Twig; namespace FireflyIII\Support\Twig;
use Carbon\Carbon; use Carbon\Carbon;
use Config;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use Route; use Route;
@@ -42,7 +41,6 @@ class General extends Twig_Extension
$this->formatAmountPlain(), $this->formatAmountPlain(),
$this->formatJournal(), $this->formatJournal(),
$this->balance(), $this->balance(),
$this->getAccountRole(),
$this->formatFilesize(), $this->formatFilesize(),
$this->mimeIcon(), $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 * @return Twig_SimpleFunction
*/ */

View File

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

View File

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

View File

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

View File

@@ -12,5 +12,14 @@
declare(strict_types = 1); declare(strict_types = 1);
return [ 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

@@ -102,3 +102,12 @@ body.waiting * {
content: none !important; 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>'); 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. * See the LICENSE file for details.
*/ */
/** global: jobKey */ /** global: jobKey, Modernizr */
var intervalId = 0; var intervalId = 0;
@@ -21,6 +21,14 @@ $(function () {
// - return false, // - return false,
$('#export').submit(startExport); $('#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. * 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 () { $(function () {
"use strict"; "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)) { if (!(readCookie('report-type') === null)) {
$('select[name="report_type"]').val(readCookie('report-type')); $('select[name="report_type"]').val(readCookie('report-type'));
} }
// set accounts from cookie
if ((readCookie('report-accounts') !== null)) { if ((readCookie('report-accounts') !== null)) {
var arr = readCookie('report-accounts').split(','); var arr = readCookie('report-accounts').split(',');
arr.forEach(function (val) { 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 startStr = readCookie('report-start');
var endStr = readCookie('report-end'); var endStr = readCookie('report-end');
if (startStr !== null && endStr !== null && startStr.length == 8 && endStr.length == 8) { if (startStr !== null && endStr !== null && startStr.length == 8 && endStr.length == 8) {
@@ -81,16 +96,18 @@ function setOptionalFromCookies() {
if ((readCookie('report-categories') !== null)) { if ((readCookie('report-categories') !== null)) {
arr = readCookie('report-categories').split(','); arr = readCookie('report-categories').split(',');
arr.forEach(function (val) { 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! // and budgets!
if ((readCookie('report-budgets') !== null)) { if ((readCookie('report-budgets') !== null)) {
arr = readCookie('report-budgets').split(','); arr = readCookie('report-budgets').split(',');
arr.forEach(function (val) { 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. * See the LICENSE file for details.
*/ */
var triggerCount = 0; /** global: triggerCount, actionCount */
var actionCount = 0;
$(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() { function addNewTrigger() {
"use strict"; "use strict";
triggerCount++; 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) { $.getJSON('json/trigger', {count: triggerCount}).done(function (data) {
// append it to the other triggers
$('tbody.rule-trigger-tbody').append(data.html); $('tbody.rule-trigger-tbody').append(data.html);
$('.remove-trigger').unbind('click').click(removeTrigger);
$('.remove-trigger').unbind('click').click(function (e) { // update all "select trigger type" dropdowns
removeTrigger(e); // so the accompanying text-box has the correct autocomplete.
onAddNewTrigger();
$('.add_rule_trigger').removeAttr('disabled');
return false;
});
}).fail(function () { }).fail(function () {
alert('Cannot get a new trigger.'); 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() { function addNewAction() {
"use strict"; "use strict";
actionCount++; actionCount++;
// disable the button
$('.add_rule_action').attr('disabled', 'disabled');
$.getJSON('json/action', {count: actionCount}).done(function (data) { $.getJSON('json/action', {count: actionCount}).done(function (data) {
$('tbody.rule-action-tbody').append(data.html); $('tbody.rule-action-tbody').append(data.html);
// add action things. // add action things.
$('.remove-action').unbind('click').click(function (e) { $('.remove-action').unbind('click').click(removeAction);
removeAction(e);
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 () { }).fail(function () {
alert('Cannot get a new action.'); 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) { function removeTrigger(e) {
"use strict"; "use strict";
var target = $(e.target); var target = $(e.target);
@@ -62,8 +114,14 @@ function removeTrigger(e) {
if ($('.rule-trigger-tbody tr').length == 0) { if ($('.rule-trigger-tbody tr').length == 0) {
addNewTrigger(); addNewTrigger();
} }
return false;
} }
/**
* Method fires when an action must be removed from the form.
*
* @param e
*/
function removeAction(e) { function removeAction(e) {
"use strict"; "use strict";
var target = $(e.target); var target = $(e.target);
@@ -77,6 +135,147 @@ function removeAction(e) {
if ($('.rule-action-tbody tr').length == 0) { if ($('.rule-action-tbody tr').length == 0) {
addNewAction(); 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() { function testRuleTriggers() {
@@ -105,4 +304,5 @@ function testRuleTriggers() {
}).fail(function () { }).fail(function () {
alert('Cannot get transactions for given triggers.'); 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. * See the LICENSE file for details.
*/ */
/** global: zoomLevel, latitude, longitude, google, apiKey, doPlaceMarker */ /** global: zoomLevel, latitude, longitude, google, apiKey, doPlaceMarker, Modernizr */
$(function () { $(function () {
"use strict"; "use strict";
$('#clearLocation').click(clearLocation); $('#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 * create.js
* Copyright (C) 2016 thegrumpydictator@gmail.com * 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.
* 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. * 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 () { $(document).ready(function () {
"use strict"; "use strict";
@@ -19,11 +17,65 @@ $(document).ready(function () {
updateButtons(); updateButtons();
updateForm(); updateForm();
updateLayout(); 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() { function updateLayout() {
"use strict"; "use strict";
$('#subTitle').text(title[what]); $('#subTitle').text(title[what]);
@@ -131,6 +183,7 @@ function clickButton(e) {
updateButtons(); updateButtons();
updateForm(); updateForm();
updateLayout(); updateLayout();
updateDescription();
} }
return false; return false;
} }

View File

@@ -0,0 +1,62 @@
/*
* 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, Modernizr */
$(document).ready(function () {
"use strict";
// give date a datepicker if not natively supported.
if (!Modernizr.inputtypes.date) {
$('input[type="date"]').datepicker(
{
dateFormat: 'yy-mm-dd'
}
);
}
// 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});
});
}
$.getJSON('json/tags').done(function (data) {
var opt = {
typeahead: {
source: data,
afterSelect: function () {
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});
});
}
$.getJSON('json/transaction-journals/' + what).done(function (data) {
$('input[name="description"]').typeahead({source: data});
});
$.getJSON('json/categories').done(function (data) {
$('input[name="category"]').typeahead({source: data});
});
});

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