Merge branch 'release/5.5.0-beta.1' into main

This commit is contained in:
James Cole 2021-01-29 18:21:06 +01:00
commit 3ed4d28c4a
532 changed files with 24342 additions and 18125 deletions

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Install composer packages
composer install --no-suggest --no-scripts --no-ansi
composer install --no-scripts --no-ansi
# enable test .env file.
cp .ci/.env.ci .env

View File

@ -52,6 +52,11 @@ LOG_CHANNEL=stack
# nothing will get logged, ever.
APP_LOG_LEVEL=notice
# Audit log level.
# set to "emergency" if you dont want to store audit logs.
# leave on info otherwise.
AUDIT_LOG_LEVEL=info
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# For other database types, please see the FAQ: https://docs.firefly-iii.org/support/faq
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
@ -271,6 +276,11 @@ TRACKER_URL=
# To read more about this feature, go to this page: https://docs.firefly-iii.org/support/telemetry
SEND_TELEMETRY=false
#
# Firefly III supports webhooks. These are security sensitive and must be enabled manually first.
#
ALLOW_WEBHOOKS=false
# You can fine tune the start-up of a Docker container by editing these environment variables.
# Use this at your own risk. Disabling certain checks and features may result in lost of inconsistent data.
# However if you know what you're doing you can significantly speed up container start times.

View File

@ -16,7 +16,12 @@ I am running Firefly III version x.x.x, and my problem is:
<!-- What do you need to do to trigger this bug? -->
**Extra info**
<!-- Please add extra info here, such as OS, browser, and the output from the /debug page of your Firefly III installation (click the version at the bottom). -->
<!-- Please add extra info here, such as OS, browser, and the output from the /debug page of your Firefly III installation (click the version at the bottom).
DO NOT PUT ```BACKTICKS``` AROUND THE OUTPUT OF THE /debug PAGE
-->
**Bonus points**
<!-- Before you submit, verify the following please: -->

27
.github/ISSUE_TEMPLATE/Custom.md vendored Normal file
View File

@ -0,0 +1,27 @@
---
name: I have a question or a problem
about: Ask away!
---
I am running Firefly III version x.x.x.
**Description**
<!-- (if relevant of course) -->
**Extra info**
<!-- Please add extra info here, such as OS, browser, and the output from the `/debug`-page of your Firefly III installation (click the version at the bottom).
DO NOT PUT ```BACKTICKS``` AROUND THE OUTPUT OF THE /debug PAGE
-->
**Bonus points**
<!-- Complete the following checklist for bonus points -->
- I have read the FAQ at https://bit.ly/FF3-FAQ
- I added a screenshot
- I added log files <!-- (see https://bit.ly/FF3-get-debug-info) -->
- I was able to replicate the issue on the demo site.
<!-- - I donated money (this is a joke :wink:)-->

View File

@ -1,15 +1,3 @@
# Welcome to Firefly III on Github!
# [Contributing guidelines](https://docs.firefly-iii.org/other-pages/contributing)
:+1::tada: Thank you for taking the time to contribute something to Firefly III!
## Feature requests
I am always interested in expanding Firefly III's many features. Just open a ticket or [drop me a line](mailto:james@firefly-iii.org).
## Pull requests
When contributing to Firefly III, please first discuss the change you wish to make via issue, email, or any other method. I can only accept pull requests against the `develop` branch, never the `main` branch.
## Translations :us: :fr: :de:
If you see a spelling error, grammatical error or a weird translation in your language, please join [our CrowdIn](https://crowdin.com/project/firefly-iii) project. There, you can submit your translations and fixes. The GitHub repository will download these automatically and they will be included in the next release.
[Contributing guidelines](https://docs.firefly-iii.org/other-pages/contributing)

View File

@ -14,7 +14,6 @@ branches:
before_script:
- phpenv config-rm xdebug.ini || return 0
- composer global require hirak/prestissimo --no-plugins --no-scripts
script:
- "./.ci/phpstan.sh"

View File

@ -76,7 +76,7 @@ class AccountController extends Controller
$date = $data['date'] ?? today(config('app.timezone'));
$return = [];
$result = $this->repository->searchAccount((string) $query, $types, $data['limit']);
$result = $this->repository->searchAccount((string)$query, $types, $data['limit']);
$defaultCurrency = app('amount')->getDefaultCurrency();
/** @var Account $account */
@ -97,6 +97,7 @@ class AccountController extends Controller
'currency_id' => $currency->id,
'currency_name' => $currency->name,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
];
}
@ -105,11 +106,14 @@ class AccountController extends Controller
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
usort($return, function ($a, $b) use ($order) {
usort(
$return, function ($a, $b) use ($order) {
$pos_a = array_search($a['type'], $order);
$pos_b = array_search($b['type'], $order);
return $pos_a - $pos_b;
});
}
);
return response()->json($return);
}

View File

@ -24,7 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\BudgetLimitRequest;
use FireflyIII\Api\V1\Requests\BudgetLimitStoreRequest;
use FireflyIII\Api\V1\Requests\BudgetLimitUpdateRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\BudgetLimit;
@ -49,11 +50,8 @@ class BudgetLimitController extends Controller
{
use TransactionFilter;
/** @var BudgetLimitRepositoryInterface */
private $blRepository;
/** @var BudgetRepositoryInterface The budget repository */
private $repository;
private BudgetLimitRepositoryInterface $blRepository;
private BudgetRepositoryInterface $repository;
/**
@ -104,9 +102,10 @@ class BudgetLimitController extends Controller
public function index(Request $request): JsonResponse
{
$manager = $this->getManager();
$budgetId = (int) ($request->get('budget_id') ?? 0);
$manager->parseIncludes('budget');
$budgetId = (int)($request->get('budget_id') ?? 0);
$budget = $this->repository->findNull($budgetId);
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$this->parameters->set('budget_id', $budgetId);
$collection = new Collection;
@ -156,13 +155,13 @@ class BudgetLimitController extends Controller
/**
* Store a newly created resource in storage.
*
* @param BudgetLimitRequest $request
* @param BudgetLimitStoreRequest $request
*
* @return JsonResponse
* @throws FireflyException
*
*/
public function store(BudgetLimitRequest $request): JsonResponse
public function store(BudgetLimitStoreRequest $request): JsonResponse
{
$data = $request->getAll();
$data['start_date'] = $data['start'];
@ -192,7 +191,7 @@ class BudgetLimitController extends Controller
*/
public function transactions(Request $request, BudgetLimit $budgetLimit): JsonResponse
{
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
@ -237,12 +236,12 @@ class BudgetLimitController extends Controller
/**
* Update the specified resource in storage.
*
* @param BudgetLimitRequest $request
* @param BudgetLimit $budgetLimit
* @param BudgetLimitUpdateRequest $request
* @param BudgetLimit $budgetLimit
*
* @return JsonResponse
*/
public function update(BudgetLimitRequest $request, BudgetLimit $budgetLimit): JsonResponse
public function update(BudgetLimitUpdateRequest $request, BudgetLimit $budgetLimit): JsonResponse
{
$data = $request->getAll();
$budgetLimit = $this->blRepository->update($budgetLimit, $data);

View File

@ -149,7 +149,7 @@ class AccountController extends Controller
foreach ($tempData as $entry) {
$currencyId = $entry['currency_id'];
$name = $entry['name'];
$chartData[$currencyId]['entries'][$name] = round($entry['difference'], $chartData[$currencyId]['currency_decimal_places']);
$chartData[$currencyId]['entries'][$name] = round((float) $entry['difference'], $chartData[$currencyId]['currency_decimal_places']);
}
$chartData = array_values($chartData);
@ -206,11 +206,11 @@ class AccountController extends Controller
/** @var Carbon $currentStart */
$currentStart = clone $start;
$range = app('steam')->balanceInRange($account, $start, clone $end);
$previous = round(array_values($range)[0], 12);
$previous = round((float) array_values($range)[0], 12);
while ($currentStart <= $end) {
$format = $currentStart->format('Y-m-d');
$label = $currentStart->format('Y-m-d');
$balance = array_key_exists($format, $range) ? round($range[$format], 12) : $previous;
$balance = array_key_exists($format, $range) ? round((float) $range[$format], 12) : $previous;
$previous = $balance;
$currentStart->addDay();
$currentSet['entries'][$label] = $balance;
@ -300,7 +300,7 @@ class AccountController extends Controller
foreach ($tempData as $entry) {
$currencyId = $entry['currency_id'];
$name = $entry['name'];
$chartData[$currencyId]['entries'][$name] = round($entry['difference'], $chartData[$currencyId]['currency_decimal_places']);
$chartData[$currencyId]['entries'][$name] = round((float) $entry['difference'], $chartData[$currencyId]['currency_decimal_places']);
}
$chartData = array_values($chartData);

View File

@ -105,7 +105,7 @@ class AvailableBudgetController extends Controller
'currency_decimal_places' => $currency->decimal_places,
'type' => 'line', // line, area or bar
'yAxisID' => 0, // 0, 1, 2
'entries' => [round($left, $currency->decimal_places)],
'entries' => [round((float) $left, $currency->decimal_places)],
],
];

View File

@ -23,7 +23,8 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\CurrencyRequest;
use FireflyIII\Api\V1\Requests\CurrencyUpdateRequest;
use FireflyIII\Api\V1\Requests\CurrencyStoreRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Account;
@ -580,12 +581,12 @@ class CurrencyController extends Controller
/**
* Store new currency.
*
* @param CurrencyRequest $request
* @param CurrencyStoreRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(CurrencyRequest $request): JsonResponse
public function store(CurrencyStoreRequest $request): JsonResponse
{
$currency = $this->repository->store($request->getAll());
if (true === $request->boolean('default')) {
@ -664,12 +665,12 @@ class CurrencyController extends Controller
/**
* Update a currency.
*
* @param CurrencyRequest $request
* @param CurrencyUpdateRequest $request
* @param TransactionCurrency $currency
*
* @return JsonResponse
*/
public function update(CurrencyRequest $request, TransactionCurrency $currency): JsonResponse
public function update(CurrencyUpdateRequest $request, TransactionCurrency $currency): JsonResponse
{
$data = $request->getAll();
$currency = $this->repository->update($currency, $data);

View File

@ -1,112 +0,0 @@
<?php
/**
* CurrencyExchangeRateController.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Services\Currency\ExchangeRateInterface;
use FireflyIII\Transformers\CurrencyExchangeRateTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use League\Fractal\Resource\Item;
/**
* Class CurrencyExchangeRateController
*
* @codeCoverageIgnore
*/
class CurrencyExchangeRateController extends Controller
{
/** @var CurrencyRepositoryInterface The currency repository */
private $repository;
/**
* CurrencyExchangeRateController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
$this->repository = app(CurrencyRepositoryInterface::class);
$this->repository->setUser($admin);
return $next($request);
}
);
}
/**
* Show an exchange rate.
*
* @param Request $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function index(Request $request): JsonResponse
{
$manager = $this->getManager();
$fromCurrency = $this->repository->findByCodeNull($request->get('from') ?? 'EUR');
$toCurrency = $this->repository->findByCodeNull($request->get('to') ?? 'USD');
if (null === $fromCurrency) {
throw new FireflyException('200007: Unknown source currency');
}
if (null === $toCurrency) {
throw new FireflyException('200007: Unknown destination currency');
}
/** @var Carbon $dateObj */
$dateObj = Carbon::createFromFormat('Y-m-d', $request->get('date') ?? date('Y-m-d'));
$this->parameters->set('from', $fromCurrency->code);
$this->parameters->set('to', $toCurrency->code);
$this->parameters->set('date', $dateObj->format('Y-m-d'));
$this->parameters->set('amount', $request->get('amount'));
$rate = $this->repository->getExchangeRate($fromCurrency, $toCurrency, $dateObj);
if (null === $rate) {
/** @var User $admin */
$admin = auth()->user();
// create service:
/** @var ExchangeRateInterface $service */
$service = app(ExchangeRateInterface::class);
$service->setUser($admin);
$rate = $service->getRate($fromCurrency, $toCurrency, $dateObj);
}
/** @var CurrencyExchangeRateTransformer $transformer */
$transformer = app(CurrencyExchangeRateTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($rate, $transformer, 'currency_exchange_rates');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
}

View File

@ -0,0 +1,131 @@
<?php
declare(strict_types=1);
/*
* DateController.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Controllers\Insight\Expense;
use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\DateRequest;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\ApiSupport;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
/**
* Class DateController
*
* Shows expense information grouped or limited by date.
* Ie. all expenses grouped by account + currency.
*/
class DateController extends Controller
{
use ApiSupport;
private CurrencyRepositoryInterface $currencyRepository;
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
*
* @codeCoverageIgnore
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser($user);
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
$this->currencyRepository->setUser($user);
return $next($request);
}
);
}
/**
*
*/
public function basic(DateRequest $request): JsonResponse
{
// parameters for chart:
$dates = $request->getAll();
/** @var Carbon $start */
$start = $dates['start'];
/** @var Carbon $end */
$end = $dates['end'];
$start->subDay();
// prep some vars:
$currencies = [];
$chartData = [];
$tempData = [];
// grab all accounts and names
$accounts = $this->repository->getAccountsByType([AccountType::EXPENSE]);
$accountNames = $this->extractNames($accounts);
$startBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $start);
$endBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $end);
// loop the end balances. This is an array for each account ($expenses)
foreach ($endBalances as $accountId => $expenses) {
$accountId = (int)$accountId;
// loop each expense entry (each entry can be a different currency).
foreach ($expenses as $currencyId => $endAmount) {
$currencyId = (int)$currencyId;
// see if there is an accompanying start amount.
// grab the difference and find the currency.
$startAmount = $startBalances[$accountId][$currencyId] ?? '0';
$diff = bcsub($endAmount, $startAmount);
$currencies[$currencyId] = $currencies[$currencyId] ?? $this->currencyRepository->findNull($currencyId);
if (0 !== bccomp($diff, '0')) {
// store the values in a temporary array.
$tempData[] = [
'id' => $accountId,
'name' => $accountNames[$accountId],
'difference' => bcmul($diff, '-1'),
'difference_float' => ((float)$diff) * -1,
'currency_id' => $currencyId,
'currency_code' => $currencies[$currencyId]->code,
];
}
}
}
// sort temp array by amount.
$amounts = array_column($tempData, 'difference_float');
array_multisort($amounts, SORT_ASC, $tempData);
return response()->json($tempData);
}
}

View File

@ -0,0 +1,131 @@
<?php
declare(strict_types=1);
/*
* DateController.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Controllers\Insight\Income;
use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\DateRequest;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\ApiSupport;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
/**
* Class DateController
*
* Shows income information grouped or limited by date.
* Ie. all income grouped by revenue + currency.
*/
class DateController extends Controller
{
use ApiSupport;
private CurrencyRepositoryInterface $currencyRepository;
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
*
* @codeCoverageIgnore
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser($user);
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
$this->currencyRepository->setUser($user);
return $next($request);
}
);
}
/**
*
*/
public function basic(DateRequest $request): JsonResponse
{
// parameters for chart:
$dates = $request->getAll();
/** @var Carbon $start */
$start = $dates['start'];
/** @var Carbon $end */
$end = $dates['end'];
$start->subDay();
// prep some vars:
$currencies = [];
$chartData = [];
$tempData = [];
// grab all accounts and names
$accounts = $this->repository->getAccountsByType([AccountType::REVENUE]);
$accountNames = $this->extractNames($accounts);
$startBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $start);
$endBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $end);
// loop the end balances. This is an array for each account ($expenses)
foreach ($endBalances as $accountId => $expenses) {
$accountId = (int)$accountId;
// loop each expense entry (each entry can be a different currency).
foreach ($expenses as $currencyId => $endAmount) {
$currencyId = (int)$currencyId;
// see if there is an accompanying start amount.
// grab the difference and find the currency.
$startAmount = $startBalances[$accountId][$currencyId] ?? '0';
$diff = bcsub($endAmount, $startAmount);
$currencies[$currencyId] = $currencies[$currencyId] ?? $this->currencyRepository->findNull($currencyId);
if (0 !== bccomp($diff, '0')) {
// store the values in a temporary array.
$tempData[] = [
'id' => $accountId,
'name' => $accountNames[$accountId],
'difference' => $diff,
'difference_float' => (float)$diff,
'currency_id' => $currencyId,
'currency_code' => $currencies[$currencyId]->code,
];
}
}
}
// sort temp array by amount.
$amounts = array_column($tempData, 'difference_float');
array_multisort($amounts, SORT_ASC, $tempData);
return response()->json($tempData);
}
}

View File

@ -23,7 +23,8 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\LinkTypeRequest;
use FireflyIII\Api\V1\Requests\LinkTypeStoreRequest;
use FireflyIII\Api\V1\Requests\LinkTypeUpdateRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\LinkType;
@ -150,12 +151,12 @@ class LinkTypeController extends Controller
/**
* Store new object.
*
* @param LinkTypeRequest $request
* @param LinkTypeStoreRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(LinkTypeRequest $request): JsonResponse
public function store(LinkTypeStoreRequest $request): JsonResponse
{
/** @var User $admin */
$admin = auth()->user();
@ -239,13 +240,13 @@ class LinkTypeController extends Controller
/**
* Update object.
*
* @param LinkTypeRequest $request
* @param LinkTypeUpdateRequest $request
* @param LinkType $linkType
*
* @return JsonResponse
* @throws FireflyException
*/
public function update(LinkTypeRequest $request, LinkType $linkType): JsonResponse
public function update(LinkTypeUpdateRequest $request, LinkType $linkType): JsonResponse
{
if (false === $linkType->editable) {
throw new FireflyException('200020: Link type cannot be changed.');

View File

@ -23,7 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\PiggyBankRequest;
use FireflyIII\Api\V1\Requests\PiggyBankUpdateRequest;
use FireflyIII\Api\V1\Requests\PiggyBankStoreRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\PiggyBank;
@ -224,12 +224,12 @@ class PiggyBankController extends Controller
/**
* Update piggy bank.
*
* @param PiggyBankRequest $request
* @param PiggyBankUpdateRequest $request
* @param PiggyBank $piggyBank
*
* @return JsonResponse
*/
public function update(PiggyBankRequest $request, PiggyBank $piggyBank): JsonResponse
public function update(PiggyBankUpdateRequest $request, PiggyBank $piggyBank): JsonResponse
{
$data = $request->getAll();
$piggyBank = $this->repository->update($piggyBank, $data);

View File

@ -0,0 +1,99 @@
<?php
/*
* IndexController.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Controllers\Preferences;
use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Facades\Navigation;
use Illuminate\Http\JsonResponse;
/**
* Class IndexController
*/
class IndexController extends Controller
{
public const DATE_FORMAT = 'Y-m-d';
/**
* Return users preferred date range settings, the current period
* and some previous / next periods.
*
* @return JsonResponse
*/
public function dateRanges(): JsonResponse
{
$range = app('preferences')->get('viewRange', '1M')->data;
$return = [
'range' => $range,
'ranges' => [],
'default' => null,
];
$today = Carbon::today(config('app.timezone'));
$start = Navigation::startOfPeriod($today, $range);
$todayStr = $today->format(self::DATE_FORMAT);
// optional date ranges. Maybe to be configured later
// current $period
$title = (string)Navigation::periodShow($start, $range);
$return['default'] = $title;
$return['ranges'][$title] = [$start->format(self::DATE_FORMAT),
Navigation::endOfPeriod($start, $range)->format(self::DATE_FORMAT)];
// previous $period
$previousStart = Navigation::subtractPeriod($start, $range);
$title = (string)Navigation::periodShow($previousStart, $range);
$return['ranges'][$title] = [$previousStart->format(self::DATE_FORMAT),
Navigation::endOfPeriod($previousStart, $range)->format(self::DATE_FORMAT)];
// next $period
$nextStart = Navigation::addPeriod($start, $range, 0);
$title = (string)Navigation::periodShow($nextStart, $range);
$return['ranges'][$title] = [$nextStart->format(self::DATE_FORMAT),
Navigation::endOfPeriod($nextStart, $range)->format(self::DATE_FORMAT)];
// --
// last seven days:
$seven = Carbon::today()->subDays(7);
$title = (string)trans('firefly.last_seven_days');
$return['ranges'][$title] = [$seven->format(self::DATE_FORMAT), $todayStr];
// last 30 days:
$thirty = Carbon::today()->subDays(30);
$title = (string)trans('firefly.last_thirty_days');
$return['ranges'][$title] = [$thirty->format(self::DATE_FORMAT), $todayStr];
// last 180 days
$long = Carbon::today()->subDays(180);
$title = (string)trans('firefly.last_180_days');
$return['ranges'][$title] = [$long->format(self::DATE_FORMAT), $todayStr];
// YTD
$YTD = Carbon::today()->startOfYear();
$title = (string)trans('firefly.YTD');
$return['ranges'][$title] = [$YTD->format(self::DATE_FORMAT), $todayStr];
// ---
// everything
$repository = app(JournalRepositoryInterface::class);
$journal = $repository->firstNull();
$first = null === $journal ? clone $YTD : clone $journal->date;
$title = (string)trans('firefly.everything');
$return['ranges'][$title] = [$first->format(self::DATE_FORMAT), $todayStr];
return response()->json($return);
}
}

View File

@ -24,7 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use Exception;
use FireflyIII\Api\V1\Requests\RuleGroupRequest;
use FireflyIII\Api\V1\Requests\RuleGroupUpdateRequest;
use FireflyIII\Api\V1\Requests\RuleGroupStoreRequest;
use FireflyIII\Api\V1\Requests\RuleGroupTestRequest;
use FireflyIII\Api\V1\Requests\RuleGroupTriggerRequest;
use FireflyIII\Exceptions\FireflyException;
@ -221,11 +222,11 @@ class RuleGroupController extends Controller
/**
* Store new object.
*
* @param RuleGroupRequest $request
* @param RuleGroupStoreRequest $request
*
* @return JsonResponse
*/
public function store(RuleGroupRequest $request): JsonResponse
public function store(RuleGroupStoreRequest $request): JsonResponse
{
$ruleGroup = $this->ruleGroupRepository->store($request->getAll());
$manager = $this->getManager();
@ -341,12 +342,12 @@ class RuleGroupController extends Controller
/**
* Update a rule group.
*
* @param RuleGroupRequest $request
* @param RuleGroupUpdateRequest $request
* @param RuleGroup $ruleGroup
*
* @return JsonResponse
*/
public function update(RuleGroupRequest $request, RuleGroup $ruleGroup): JsonResponse
public function update(RuleGroupUpdateRequest $request, RuleGroup $ruleGroup): JsonResponse
{
$ruleGroup = $this->ruleGroupRepository->update($ruleGroup, $request->getAll());
$manager = $this->getManager();

View File

@ -46,12 +46,13 @@ class TransactionController extends Controller
public function search(Request $request, SearchInterface $searcher): JsonResponse
{
$manager = $this->getManager();
$fullQuery = (string) $request->get('query');
$page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page');
$fullQuery = (string)$request->get('query');
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = 0 === (int)$request->get('limit') ? $pageSize : (int)$request->get('limit');
$searcher->parseQuery($fullQuery);
$searcher->setPage($page);
$searcher->setLimit((int) config('firefly.search_result_limit'));
$searcher->setLimit($pageSize);
$groups = $searcher->searchTransactions();
$parameters = ['search' => $fullQuery];
$url = route('api.v1.search.transactions') . '?' . http_build_query($parameters);

View File

@ -47,24 +47,12 @@ use Illuminate\Http\JsonResponse;
*/
class SummaryController extends Controller
{
/** @var AvailableBudgetRepositoryInterface */
private $abRepository;
/** @var AccountRepositoryInterface */
private $accountRepository;
/** @var BillRepositoryInterface */
private $billRepository;
/** @var BudgetRepositoryInterface */
private $budgetRepository;
/** @var CurrencyRepositoryInterface */
private $currencyRepos;
/** @var OperationsRepositoryInterface */
private $opsRepository;
private AvailableBudgetRepositoryInterface $abRepository;
private AccountRepositoryInterface $accountRepository;
private BillRepositoryInterface $billRepository;
private BudgetRepositoryInterface $budgetRepository;
private CurrencyRepositoryInterface $currencyRepos;
private OperationsRepositoryInterface $opsRepository;
/**
* SummaryController constructor.
@ -197,7 +185,7 @@ class SummaryController extends Controller
$return[] = [
'key' => sprintf('balance-in-%s', $currency->code),
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => round($sums[$currencyId] ?? 0, $currency->decimal_places),
'monetary_value' => round((float) $sums[$currencyId] ?? 0, $currency->decimal_places),
'currency_id' => $currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
@ -210,7 +198,7 @@ class SummaryController extends Controller
$return[] = [
'key' => sprintf('spent-in-%s', $currency->code),
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => round($expenses[$currencyId] ?? 0, $currency->decimal_places),
'monetary_value' => round((float) ($expenses[$currencyId] ?? 0), $currency->decimal_places),
'currency_id' => $currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
@ -222,7 +210,7 @@ class SummaryController extends Controller
$return[] = [
'key' => sprintf('earned-in-%s', $currency->code),
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => round($incomes[$currencyId] ?? 0, $currency->decimal_places),
'monetary_value' => round((float) ($incomes[$currencyId] ?? 0), $currency->decimal_places),
'currency_id' => $currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
@ -260,7 +248,7 @@ class SummaryController extends Controller
$return[] = [
'key' => sprintf('bills-paid-in-%s', $currency->code),
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => round($amount, $currency->decimal_places),
'monetary_value' => round((float) $amount, $currency->decimal_places),
'currency_id' => $currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
@ -280,7 +268,7 @@ class SummaryController extends Controller
$return[] = [
'key' => sprintf('bills-unpaid-in-%s', $currency->code),
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => round($amount, $currency->decimal_places),
'monetary_value' => round((float) $amount, $currency->decimal_places),
'currency_id' => $currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
@ -324,7 +312,7 @@ class SummaryController extends Controller
$return[] = [
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
'monetary_value' => round($leftToSpend, $row['currency_decimal_places']),
'monetary_value' => round((float) $leftToSpend, $row['currency_decimal_places']),
'currency_id' => $row['currency_id'],
'currency_code' => $row['currency_code'],
'currency_symbol' => $row['currency_symbol'],
@ -384,7 +372,7 @@ class SummaryController extends Controller
foreach ($netWorthSet as $data) {
/** @var TransactionCurrency $currency */
$currency = $data['currency'];
$amount = round($data['balance'], $currency->decimal_places);
$amount = round((float) $data['balance'], $currency->decimal_places);
if (0.0 === $amount) {
continue;
}

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\TransactionStoreRequest;
use FireflyIII\Api\V1\Requests\TransactionUpdateRequest;
use FireflyIII\Events\DestroyedTransactionGroup;
use FireflyIII\Events\StoredTransactionGroup;
use FireflyIII\Events\UpdatedTransactionGroup;
use FireflyIII\Exceptions\DuplicateTransactionException;
@ -36,6 +37,7 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Journal\JournalAPIRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
use FireflyIII\Rules\IsDuplicateTransaction;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\Transformers\PiggyBankEventTransformer;
@ -45,11 +47,13 @@ use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Validation\ValidationException;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Validator;
/**
* Class TransactionController
@ -142,6 +146,8 @@ class TransactionController extends Controller
public function delete(TransactionGroup $transactionGroup): JsonResponse
{
$this->repository->destroyGroup($transactionGroup);
// trigger just after destruction
event(new DestroyedTransactionGroup($transactionGroup));
return response()->json([], 204);
}
@ -171,7 +177,7 @@ class TransactionController extends Controller
*/
public function index(Request $request): JsonResponse
{
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
@ -289,7 +295,7 @@ class TransactionController extends Controller
* @param TransactionStoreRequest $request
*
* @return JsonResponse
* @throws FireflyException
* @throws FireflyException|ValidationException
*/
public function store(TransactionStoreRequest $request): JsonResponse
{
@ -304,29 +310,16 @@ class TransactionController extends Controller
$transactionGroup = $this->groupRepository->store($data);
} catch (DuplicateTransactionException $e) {
Log::warning('Caught a duplicate transaction. Return error message.');
// return bad validation message.
// TODO use Laravel's internal validation thing to do this.
$response = [
'message' => 'The given data was invalid.',
'errors' => [
'transactions.0.description' => [$e->getMessage()],
],
];
return response()->json($response, 422);
$validator = Validator::make(
['transactions' => [['description' => $e->getMessage()]]], ['transactions.0.description' => new IsDuplicateTransaction]
);
throw new ValidationException($validator);
} catch (FireflyException $e) {
Log::warning('Caught an exception. Return error message.');
Log::error($e->getMessage());
// return bad validation message.
// TODO use Laravel's internal validation thing to do this.
$response = [
'message' => 'The given data was invalid.',
'errors' => [
'transactions.0.description' => [sprintf('Internal exception: %s', $e->getMessage())],
],
];
return response()->json($response, 422);
$message = sprintf('Internal exception: %s', $e->getMessage());
$validator = Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction]);
throw new ValidationException($validator);
}
app('preferences')->mark();
event(new StoredTransactionGroup($transactionGroup, $data['apply_rules'] ?? true));

View File

@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
/*
* CreateController.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Controllers\Webhook;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Webhook\CreateRequest;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Transformers\WebhookTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use League\Fractal\Resource\Item;
/**
* Class CreateController
*/
class CreateController extends Controller
{
private WebhookRepositoryInterface $repository;
/**
* @codeCoverageIgnore
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
/** @var WebhookRepositoryInterface repository */
$this->repository = app(WebhookRepositoryInterface::class);
$this->repository->setUser($admin);
return $next($request);
}
);
}
/**
* @param CreateRequest $request
*
* @return JsonResponse
*/
public function store(CreateRequest $request): JsonResponse
{
$data = $request->getData();
$webhook = $this->repository->store($data);
$manager = $this->getManager();
/** @var WebhookTransformer $transformer */
$transformer = app(WebhookTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($webhook, $transformer, 'webhooks');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
}

View File

@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
/*
* DeleteController.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Controllers\Webhook;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Models\Webhook;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
/**
* Class DeleteController
*/
class DeleteController extends Controller
{
private WebhookRepositoryInterface $repository;
/**
* @codeCoverageIgnore
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
/** @var WebhookRepositoryInterface repository */
$this->repository = app(WebhookRepositoryInterface::class);
$this->repository->setUser($admin);
return $next($request);
}
);
}
/**
* Remove the specified resource from storage.
*
* @param Webhook $webhook
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function destroy(Webhook $webhook): JsonResponse
{
$this->repository->destroy($webhook);
return response()->json([], 204);
}
}

View File

@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
/*
* EditController.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Controllers\Webhook;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Webhook\UpdateRequest;
use FireflyIII\Models\Webhook;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Transformers\WebhookTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use League\Fractal\Resource\Item;
/**
* Class EditController
*/
class EditController extends Controller
{
private WebhookRepositoryInterface $repository;
/**
* @codeCoverageIgnore
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
/** @var WebhookRepositoryInterface repository */
$this->repository = app(WebhookRepositoryInterface::class);
$this->repository->setUser($admin);
return $next($request);
}
);
}
/**
* @param Webhook $webhook
* @param UpdateRequest $request
*
* @return JsonResponse
*/
public function update(Webhook $webhook, UpdateRequest $request): JsonResponse
{
$data = $request->getData();
$webhook = $this->repository->update($webhook, $data);
$manager = $this->getManager();
/** @var WebhookTransformer $transformer */
$transformer = app(WebhookTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($webhook, $transformer, 'webhooks');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
}

View File

@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
/*
* IndexController.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Controllers\Webhook;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Transformers\WebhookTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
/**
* Class IndexController
*/
class IndexController extends Controller
{
private WebhookRepositoryInterface $repository;
/**
* @codeCoverageIgnore
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
/** @var WebhookRepositoryInterface repository */
$this->repository = app(WebhookRepositoryInterface::class);
$this->repository->setUser($admin);
return $next($request);
}
);
}
/**
* Display a listing of the resource.
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function index(): JsonResponse
{
$webhooks = $this->repository->all();
$manager = $this->getManager();
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$count = $webhooks->count();
$bills = $webhooks->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($webhooks, $count, $pageSize, $this->parameters->get('page'));
/** @var WebhookTransformer $transformer */
$transformer = app(WebhookTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($bills, $transformer, 'webhooks');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
}

View File

@ -26,7 +26,10 @@ namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\Location;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\UniqueAccountNumber;
use FireflyIII\Rules\UniqueIban;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -37,18 +40,7 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class AccountStoreRequest extends FormRequest
{
use ConvertsDataTypes, AppendsLocationData;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, AppendsLocationData, ChecksLogin;
/**
* @return array
@ -108,12 +100,13 @@ class AccountStoreRequest extends FormRequest
$accountRoles = implode(',', config('firefly.accountRoles'));
$types = implode(',', array_keys(config('firefly.subTitlesByIdentifier')));
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
$type = $this->string('type');
$rules = [
'name' => 'required|min:1|uniqueAccountForUser',
'type' => 'required|' . sprintf('in:%s', $types),
'iban' => 'iban|nullable',
'iban' => ['iban', 'nullable', new UniqueIban(null, $type)],
'bic' => 'bic|nullable',
'account_number' => 'between:1,255|nullable|uniqueAccountNumberForUser',
'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber(null, $type)],
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'virtual_balance' => 'numeric|nullable',
@ -132,6 +125,7 @@ class AccountStoreRequest extends FormRequest
'interest_period' => 'required_if:type,liability|in:daily,monthly,yearly',
'notes' => 'min:0|max:65536',
];
return Location::requestRules($rules);
}
}

View File

@ -26,7 +26,10 @@ namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\Location;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\UniqueAccountNumber;
use FireflyIII\Rules\UniqueIban;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -37,18 +40,7 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class AccountUpdateRequest extends FormRequest
{
use ConvertsDataTypes, AppendsLocationData;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, AppendsLocationData, ChecksLogin;
/**
* @return array
@ -113,9 +105,9 @@ class AccountUpdateRequest extends FormRequest
$rules = [
'name' => sprintf('min:1|uniqueAccountForUser:%d', $account->id),
'type' => sprintf('in:%s', $types),
'iban' => 'iban|nullable',
'iban' => ['iban', 'nullable', new UniqueIban($account, $this->nullableString('type'))],
'bic' => 'bic|nullable',
'account_number' => sprintf('between:1,255|nullable|uniqueAccountNumberForUser:%d', $account->id),
'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber($account, $this->nullableString('type'))],
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'virtual_balance' => 'numeric|nullable',
@ -134,6 +126,7 @@ class AccountUpdateRequest extends FormRequest
'interest_period' => 'required_if:type,liability|in:daily,monthly,yearly',
'notes' => 'min:0|max:65536',
];
return Location::requestRules($rules);
}
}

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsValidAttachmentModel;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -34,18 +35,7 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class AttachmentStoreRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -33,18 +34,7 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class AttachmentUpdateRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.

View File

@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests\Autocomplete;
use FireflyIII\Models\AccountType;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -33,18 +34,7 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class AutocompleteRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ChecksLogin;
/**
* @return array
@ -60,7 +50,7 @@ class AutocompleteRequest extends FormRequest
$limit = 0 === $limit ? 10 : $limit;
// remove 'initial balance' from allowed types. its internal
$array = array_diff($array, [AccountType::INITIAL_BALANCE]);
$array = array_diff($array, [AccountType::INITIAL_BALANCE, AccountType::RECONCILIATION]);
return [
'types' => $array,

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -33,18 +34,9 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class AvailableBudgetRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.

View File

@ -0,0 +1,73 @@
<?php
/**
* BudgetLimitStoreRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class BudgetLimitStoreRequest
*
* @codeCoverageIgnore
*/
class BudgetLimitStoreRequest extends FormRequest
{
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'budget_id' => $this->integer('budget_id'),
'start' => $this->date('start'),
'end' => $this->date('end'),
'amount' => $this->string('amount'),
'currency_id' => $this->integer('currency_id'),
'currency_code' => $this->string('currency_code'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
return [
'budget_id' => 'required|exists:budgets,id|belongsToUser:budgets,id',
'start' => 'required|before:end|date',
'end' => 'required|after:start|date',
'amount' => 'required|gt:0',
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
];
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
* BudgetLimitRequest.php
* BudgetLimitUpdateRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
@ -23,29 +23,18 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class BudgetLimitRequest
* Class BudgetLimitUpdateRequest
*
* @codeCoverageIgnore
* TODO AFTER 4.8,0: split this into two request classes.
*/
class BudgetLimitRequest extends FormRequest
class BudgetLimitUpdateRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.
@ -85,21 +74,12 @@ class BudgetLimitRequest extends FormRequest
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
$rules['budget_id'] = 'required|exists:budgets,id|belongsToUser:budgets,id';
break;
}
// if request has a budget already, drop the rule.
$budget = $this->route()->parameter('budget');
if (null !== $budget) {
unset($rules['budget_id']);
}
return $rules;
}

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest;
@ -36,18 +37,7 @@ use Illuminate\Validation\Validator;
*/
class BudgetStoreRequest extends FormRequest
{
use ConvertsDataTypes, ValidatesAutoBudgetRequest;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ValidatesAutoBudgetRequest, ChecksLogin;
/**
* Get all data from the request.

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest;
@ -36,18 +37,7 @@ use Illuminate\Validation\Validator;
*/
class BudgetUpdateRequest extends FormRequest
{
use ConvertsDataTypes, ValidatesAutoBudgetRequest;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ValidatesAutoBudgetRequest, ChecksLogin;
/**
* Get all data from the request.

View File

@ -25,6 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -35,18 +36,9 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class ConfigurationRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.

View File

@ -1,6 +1,6 @@
<?php
/**
* CurrencyRequest.php
* CurrencyStoreRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
@ -24,30 +24,19 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class CurrencyRequest
* Class CurrencyStoreRequest
*
* @codeCoverageIgnore
* TODO AFTER 4.8,0: split this into two request classes.
*/
class CurrencyRequest extends FormRequest
class CurrencyStoreRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.
@ -82,7 +71,7 @@ class CurrencyRequest extends FormRequest
*/
public function rules(): array
{
$rules = [
return [
'name' => 'required|between:1,255|unique:transaction_currencies,name',
'code' => 'required|between:3,3|unique:transaction_currencies,code',
'symbol' => 'required|between:1,8|unique:transaction_currencies,symbol',
@ -91,20 +80,5 @@ class CurrencyRequest extends FormRequest
'default' => [new IsBoolean()],
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
$currency = $this->route()->parameter('currency_code');
$rules['name'] = 'required|between:1,255|unique:transaction_currencies,name,' . $currency->id;
$rules['code'] = 'required|between:3,3|unique:transaction_currencies,code,' . $currency->id;
$rules['symbol'] = 'required|between:1,8|unique:transaction_currencies,symbol,' . $currency->id;
break;
}
return $rules;
}
}

View File

@ -0,0 +1,84 @@
<?php
/**
* CurrencyUpdateRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class CurrencyUpdateRequest
*
* @codeCoverageIgnore
*/
class CurrencyUpdateRequest extends FormRequest
{
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
$enabled = true;
$default = false;
if (null !== $this->get('enabled')) {
$enabled = $this->boolean('enabled');
}
if (null !== $this->get('default')) {
$default = $this->boolean('default');
}
return [
'name' => $this->string('name'),
'code' => $this->string('code'),
'symbol' => $this->string('symbol'),
'decimal_places' => $this->integer('decimal_places'),
'default' => $default,
'enabled' => $enabled,
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$currency = $this->route()->parameter('currency_code');
return [
'name' => sprintf('required|between:1,255|unique:transaction_currencies,name,%d', $currency->id),
'code' => sprintf('required|between:3,3|unique:transaction_currencies,code,%d', $currency->id),
'symbol' => sprintf('required|between:1,8|unique:transaction_currencies,symbol,%d', $currency->id),
'decimal_places' => 'between:0,20|numeric|min:0|max:20',
'enabled' => [new IsBoolean()],
'default' => [new IsBoolean()],
];
}
}

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -31,18 +32,7 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class DataDestroyRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check() && !auth()->user()->hasRole('demo');
}
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.

View File

@ -25,6 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -35,18 +36,7 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class DateRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.

View File

@ -1,6 +1,6 @@
<?php
/**
* LinkTypeRequest.php
* LinkTypeStoreRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
@ -24,30 +24,19 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\LinkType;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
/**
* Class LinkTypeRequest
* Class LinkTypeStoreRequest
*
* @codeCoverageIgnore
* TODO AFTER 4.8,0: split this into two request classes.
*/
class LinkTypeRequest extends FormRequest
class LinkTypeStoreRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.
@ -72,26 +61,10 @@ class LinkTypeRequest extends FormRequest
*/
public function rules(): array
{
$rules = [
return [
'name' => 'required|unique:link_types,name|min:1',
'outward' => 'required|unique:link_types,outward|min:1|different:inward',
'inward' => 'required|unique:link_types,inward|min:1|different:outward',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
/** @var LinkType $linkType */
$linkType = $this->route()->parameter('linkType');
$rules['name'] = ['required', Rule::unique('link_types', 'name')->ignore($linkType->id), 'min:1'];
$rules['outward'] = ['required', 'different:inward', Rule::unique('link_types', 'outward')->ignore($linkType->id), 'min:1'];
$rules['inward'] = ['required', 'different:outward', Rule::unique('link_types', 'inward')->ignore($linkType->id), 'min:1'];
break;
}
return $rules;
}
}

View File

@ -0,0 +1,71 @@
<?php
/**
* LinkTypeUpdateRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\LinkType;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
/**
* Class LinkTypeUpdateRequest
*
* @codeCoverageIgnore
*/
class LinkTypeUpdateRequest extends FormRequest
{
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'name' => $this->string('name'),
'outward' => $this->string('outward'),
'inward' => $this->string('inward'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$linkType = $this->route()->parameter('linkType');
return [
'name' => ['required', Rule::unique('link_types', 'name')->ignore($linkType->id), 'min:1'],
'outward' => ['required', 'different:inward', Rule::unique('link_types', 'outward')->ignore($linkType->id), 'min:1'],
'inward' => ['required', 'different:outward', Rule::unique('link_types', 'inward')->ignore($linkType->id), 'min:1'],
];
}
}

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -34,18 +35,7 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class ObjectGroupUpdateRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ChecksLogin;
/**
* @return array

View File

@ -1,105 +0,0 @@
<?php
/**
* PiggyBankRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Rules\IsAssetAccountId;
use FireflyIII\Rules\LessThanPiggyTarget;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class PiggyBankRequest
*
* @codeCoverageIgnore
* TODO AFTER 4.8,0: split this into two request classes.
*/
class PiggyBankRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'name' => $this->string('name'),
'account_id' => $this->integer('account_id'),
'targetamount' => $this->string('target_amount'),
'current_amount' => $this->string('current_amount'),
'startdate' => $this->date('start_date'),
'targetdate' => $this->date('target_date'),
'notes' => $this->nlString('notes'),
'order' => $this->integer('order'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$rules = [
'name' => 'required|between:1,255|uniquePiggyBankForUser',
'current_amount' => ['numeric', 'gte:0', 'lte:target_amount'],
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
/** @var PiggyBank $piggyBank */
$piggyBank = $this->route()->parameter('piggyBank');
$rules['name'] = 'between:1,255|uniquePiggyBankForUser:' . $piggyBank->id;
$rules['account_id'] = ['belongsToUser:accounts', new IsAssetAccountId];
$rules['target_amount'] = 'numeric|gt:0';
$rules['current_amount'] = ['numeric', 'gte:0', new LessThanPiggyTarget];
break;
}
return $rules;
}
}

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -33,18 +34,7 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class PiggyBankStoreRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.

View File

@ -0,0 +1,89 @@
<?php
/**
* PiggyBankUpdateRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsAssetAccountId;
use FireflyIII\Rules\LessThanPiggyTarget;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class PiggyBankUpdateRequest
*
* @codeCoverageIgnore
*/
class PiggyBankUpdateRequest extends FormRequest
{
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
// if the value isn't present, dont return it at all.
// TODO this should be the way to collect fields for all API things.
// TODO make sure piggy bank uses 'start_date' etc. until right up to DB update.
// TODO can we configure this and return it from config?
// TODO this is the way.
$fields = [
'name' => ['name', 'string'],
'account_id' => ['account_id', 'integer'],
'targetamount' => ['target_amount', 'string'],
'current_amount' => ['current_amount', 'string'],
'startdate' => ['start_date', 'date'],
'targetdate' => ['target_date', 'string'],
'notes' => ['notes', 'nlString'],
'order' => ['order', 'integer'],
'object_group' => ['object_group', 'string'],
'object_group_id' => ['object_group_id', 'integer'],
];
return $this->getAllData($fields);
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$piggyBank = $this->route()->parameter('piggyBank');
return [
'name' => 'between:1,255|uniquePiggyBankForUser:' . $piggyBank->id,
'current_amount' => ['numeric', 'gte:0', new LessThanPiggyTarget],
'target_amount' => 'numeric|gt:0',
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',
'account_id' => ['belongsToUser:accounts', new IsAssetAccountId],
];
}
}

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -33,18 +34,9 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class PreferenceRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests;
use Carbon\Carbon;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRecurrenceData;
use FireflyIII\Validation\CurrencyValidation;
@ -39,18 +40,9 @@ use Illuminate\Validation\Validator;
*/
class RecurrenceStoreRequest extends FormRequest
{
use ConvertsDataTypes, RecurrenceValidation, TransactionValidation, CurrencyValidation, GetRecurrenceData;
use ConvertsDataTypes, RecurrenceValidation, TransactionValidation, CurrencyValidation, GetRecurrenceData, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\Recurrence;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRecurrenceData;
use FireflyIII\Validation\CurrencyValidation;
@ -39,18 +40,9 @@ use Illuminate\Validation\Validator;
*/
class RecurrenceUpdateRequest extends FormRequest
{
use ConvertsDataTypes, RecurrenceValidation, TransactionValidation, CurrencyValidation, GetRecurrenceData;
use ConvertsDataTypes, RecurrenceValidation, TransactionValidation, CurrencyValidation, GetRecurrenceData, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.

View File

@ -1,6 +1,6 @@
<?php
/**
* RuleGroupRequest.php
* RuleGroupStoreRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
@ -25,29 +25,18 @@ namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* @codeCoverageIgnore
* Class RuleGroupRequest
* TODO AFTER 4.8,0: split this into two request classes.
* Class RuleGroupStoreRequest
*/
class RuleGroupRequest extends FormRequest
class RuleGroupStoreRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.
@ -76,22 +65,10 @@ class RuleGroupRequest extends FormRequest
*/
public function rules(): array
{
$rules = [
return [
'title' => 'required|between:1,100|uniqueObjectForUser:rule_groups,title',
'description' => 'between:1,5000|nullable',
'active' => [new IsBoolean],
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
/** @var RuleGroup $ruleGroup */
$ruleGroup = $this->route()->parameter('ruleGroup');
$rules['title'] = 'required|between:1,100|uniqueObjectForUser:rule_groups,title,' . $ruleGroup->id;
break;
}
return $rules;
}
}

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests;
use Carbon\Carbon;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Collection;
@ -35,18 +36,9 @@ use Illuminate\Support\Collection;
*/
class RuleGroupTestRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* @return array

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests;
use Carbon\Carbon;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -34,18 +35,9 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class RuleGroupTriggerRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* @return array

View File

@ -0,0 +1,74 @@
<?php
/**
* RuleGroupUpdateRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* @codeCoverageIgnore
* Class RuleGroupUpdateRequest
*/
class RuleGroupUpdateRequest extends FormRequest
{
use ConvertsDataTypes, ChecksLogin;
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
$active = true;
if (null !== $this->get('active')) {
$active = $this->boolean('active');
}
return [
'title' => $this->string('title'),
'description' => $this->string('description'),
'active' => $active,
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$ruleGroup = $this->route()->parameter('ruleGroup');
return [
'title' => 'required|between:1,100|uniqueObjectForUser:rule_groups,title,' . $ruleGroup->id,
'description' => 'between:1,5000|nullable',
'active' => [new IsBoolean],
];
}
}

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest;
@ -36,18 +37,9 @@ use function is_array;
*/
class RuleStoreRequest extends FormRequest
{
use ConvertsDataTypes, GetRuleConfiguration;
use ConvertsDataTypes, GetRuleConfiguration, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests;
use Carbon\Carbon;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -34,18 +35,9 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class RuleTestRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* @return array

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests;
use Carbon\Carbon;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -34,18 +35,9 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class RuleTriggerRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* @return array

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest;
@ -36,18 +37,9 @@ use function is_array;
*/
class RuleUpdateRequest extends FormRequest
{
use ConvertsDataTypes, GetRuleConfiguration;
use ConvertsDataTypes, GetRuleConfiguration, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.

View File

@ -24,6 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\Location;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -34,18 +36,8 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class TagStoreRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin, AppendsLocationData;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
@ -54,20 +46,15 @@ class TagStoreRequest extends FormRequest
*/
public function getAll(): array
{
$hasLocation = false;
if ($this->has('longitude') && $this->has('latitude') && $this->has('zoom_level')) {
$hasLocation = true;
}
return [
$data = [
'tag' => $this->string('tag'),
'date' => $this->date('date'),
'description' => $this->string('description'),
'has_location' => $hasLocation,
'longitude' => $this->string('longitude'),
'latitude' => $this->string('latitude'),
'zoom_level' => $this->integer('zoom_level'),
'has_location' => true,
];
$data = $this->appendLocationData($data, null);
return $data;
}
/**

View File

@ -25,6 +25,8 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\Location;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -35,18 +37,8 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class TagUpdateRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin, AppendsLocationData;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
@ -55,20 +47,15 @@ class TagUpdateRequest extends FormRequest
*/
public function getAll(): array
{
$updateLocation = false;
if ($this->has('longitude') && $this->has('latitude') && $this->has('zoom_level')) {
$updateLocation = true;
}
return [
$data = [
'tag' => $this->string('tag'),
'date' => $this->date('date'),
'description' => $this->string('description'),
'has_location' => $updateLocation,
'longitude' => '' === $this->string('longitude') ? null : $this->string('longitude'),
'latitude' => '' === $this->string('latitude') ? null : $this->string('latitude'),
'zoom_level' => '' === $this->string('zoom_level') ? null : $this->integer('zoom_level'),
'has_location' => true, // pretend location is present.
];
$data = $this->appendLocationData($data, null);
return $data;
}
/**

View File

@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User;
use Illuminate\Foundation\Http\FormRequest;
@ -35,18 +36,9 @@ use Illuminate\Validation\Validator;
*/
class TransactionLinkRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.

View File

@ -28,6 +28,7 @@ use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Support\NullArrayObject;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\GroupValidation;
@ -41,20 +42,7 @@ use Log;
*/
class TransactionStoreRequest extends FormRequest
{
use TransactionValidation, GroupValidation, CurrencyValidation, ConvertsDataTypes;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
Log::debug('Authorize TransactionStoreRequest');
// Only allow authenticated users
return auth()->check();
}
use TransactionValidation, GroupValidation, CurrencyValidation, ConvertsDataTypes, ChecksLogin;
/**
* Get all data. Is pretty complex because of all the ??-statements.

View File

@ -28,6 +28,7 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
@ -40,7 +41,7 @@ use Log;
*/
class TransactionUpdateRequest extends FormRequest
{
use TransactionValidation, GroupValidation, ConvertsDataTypes;
use TransactionValidation, GroupValidation, ConvertsDataTypes, ChecksLogin;
private array $arrayFields;
private array $booleanFields;
@ -50,16 +51,7 @@ class TransactionUpdateRequest extends FormRequest
private array $textareaFields;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data. Is pretty complex because of all the ??-statements.
@ -382,26 +374,10 @@ class TransactionUpdateRequest extends FormRequest
// validate source/destination is equal, depending on the transaction journal type.
$this->validateEqualAccountsForUpdate($validator, $transactionGroup);
// If type is set, source + destination info is mandatory.
// Not going to do this. Not sure where the demand came from.
// validate that the currency fits the source and/or destination account.
// validate all account info
$this->validateAccountInformationUpdate($validator);
// The currency info must match the accounts involved.
// Instead will ignore currency info as much as possible.
// TODO if the transaction_journal_id is empty, some fields are mandatory, like the amount!
// all journals must have a description
// // validate foreign currency info
//
//
// // make sure all splits have valid source + dest info
// the group must have a description if > 1 journal.
}
);
}

View File

@ -25,6 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -34,10 +35,10 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class UserStoreRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin;
/**
* Authorize logged in users.
* Logged in + owner
*
* @return bool
*/

View File

@ -25,6 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -34,10 +35,10 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class UserUpdateRequest extends FormRequest
{
use ConvertsDataTypes;
use ConvertsDataTypes, ChecksLogin;
/**
* Authorize logged in users.
* Logged in + owner
*
* @return bool
*/

View File

@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
/*
* CreateRequest.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Requests\Webhook;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class CreateRequest
*/
class CreateRequest extends FormRequest
{
use ChecksLogin, ConvertsDataTypes;
/**
* @return array
*/
public function getData(): array
{
$triggers = array_flip(config('firefly.webhooks.triggers'));
$responses = array_flip(config('firefly.webhooks.responses'));
$deliveries = array_flip(config('firefly.webhooks.deliveries'));
$fields = [
'title' => ['title', 'string'],
'active' => ['active', 'boolean'],
'trigger' => ['trigger', 'string'],
'response' => ['response', 'string'],
'delivery' => ['delivery', 'string'],
'url' => ['url', 'string'],
];
// this is the way.
$return = $this->getAllData($fields);
$return['trigger'] = $triggers[$return['trigger']] ?? 0;
$return['response'] = $responses[$return['response']] ?? 0;
$return['delivery'] = $deliveries[$return['delivery']] ?? 0;
return $return;
}
/**
* Rules for this request.
*
* @return array
*/
public function rules(): array
{
$triggers = implode(',', array_values(config('firefly.webhooks.triggers')));
$responses = implode(',', array_values(config('firefly.webhooks.responses')));
$deliveries = implode(',', array_values(config('firefly.webhooks.deliveries')));
return [
'title' => 'required|between:1,512|uniqueObjectForUser:webhooks,title',
'active' => [new IsBoolean],
'trigger' => sprintf('required|in:%s', $triggers),
'response' => sprintf('required|in:%s', $responses),
'delivery' => sprintf('required|in:%s', $deliveries),
'url' => ['required', 'url', 'starts_with:https://', 'uniqueWebhook'],
];
}
}

View File

@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
/*
* UpdateRequest.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Requests\Webhook;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class UpdateRequest
*/
class UpdateRequest extends FormRequest
{
use ChecksLogin, ConvertsDataTypes;
/**
* @return array
*/
public function getData(): array
{
$triggers = array_flip(config('firefly.webhooks.triggers'));
$responses = array_flip(config('firefly.webhooks.responses'));
$deliveries = array_flip(config('firefly.webhooks.deliveries'));
$fields = [
'title' => ['title', 'string'],
'active' => ['active', 'boolean'],
'trigger' => ['trigger', 'string'],
'response' => ['response', 'string'],
'delivery' => ['delivery', 'string'],
'url' => ['url', 'string'],
];
// this is the way.
$return = $this->getAllData($fields);
$return['trigger'] = $triggers[$return['trigger']] ?? 0;
$return['response'] = $responses[$return['response']] ?? 0;
$return['delivery'] = $deliveries[$return['delivery']] ?? 0;
$return['secret'] = null !== $this->get('secret');
return $return;
}
/**
* Rules for this request.
*
* @return array
*/
public function rules(): array
{
$triggers = implode(',', array_values(config('firefly.webhooks.triggers')));
$responses = implode(',', array_values(config('firefly.webhooks.responses')));
$deliveries = implode(',', array_values(config('firefly.webhooks.deliveries')));
$webhook = $this->route()->parameter('webhook');
return [
'title' => sprintf('between:1,512|uniqueObjectForUser:webhooks,title,%d', $webhook->id),
'active' => [new IsBoolean],
'trigger' => sprintf('required|in:%s', $triggers),
'response' => sprintf('required|in:%s', $responses),
'delivery' => sprintf('required|in:%s', $deliveries),
'url' => ['required', 'url', 'starts_with:https://', sprintf('uniqueExistingWebhook:%d', $webhook->id)],
];
}
}

View File

@ -0,0 +1,175 @@
<?php
declare(strict_types=1);
/*
* AppendBudgetLimitPeriods.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Console\Command;
use Log;
class AppendBudgetLimitPeriods extends Command
{
public const CONFIG_NAME = '550_budget_limit_periods';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Append budget limits with their (estimated) timeframe.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:budget-limit-periods {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$start = microtime(true);
if ($this->isExecuted() && true !== $this->option('force')) {
$this->warn('This command has already been executed.');
return 0;
}
$this->theresNoLimit();
$this->markAsExecuted();
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Fixed budget limits in %s seconds.', $end));
return 0;
}
/**
* @return bool
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
}
return false; // @codeCoverageIgnore
}
/**
* @param BudgetLimit $limit
*
* @return string|null
*/
private function getLimitPeriod(BudgetLimit $limit): ?string
{
// is daily
if ($limit->end_date->isSameDay($limit->start_date)) {
return 'daily';
}
// is weekly
if ('1' === $limit->start_date->format('N') && '7' === $limit->end_date->format('N') && 6 === $limit->end_date->diffInDays($limit->start_date)) {
return 'weekly';
}
// is monthly
if (
'1' === $limit->start_date->format('j') // first day
&& $limit->end_date->format('j') === $limit->end_date->format('t') // last day
&& $limit->start_date->isSameMonth($limit->end_date)
) {
return 'monthly';
}
// is quarter
$start = ['1-1', '1-4', '1-7', '1-10'];
$end = ['31-3', '30-6', '30-9', '31-12'];
if (
in_array($limit->start_date->format('j-n'), $start, true) // start of quarter
&& in_array($limit->end_date->format('j-n'), $end, true) // end of quarter
&& 2 === $limit->start_date->diffInMonths($limit->end_date)
) {
return 'quarterly';
}
// is half year
$start = ['1-1', '1-7'];
$end = ['30-6', '31-12'];
if (
in_array($limit->start_date->format('j-n'), $start) // start of quarter
&& in_array($limit->end_date->format('j-n'), $end) // end of quarter
&& 5 === $limit->start_date->diffInMonths($limit->end_date)
) {
return 'half_year';
}
// is yearly
if ('1-1' === $limit->start_date->format('j-n') && '31-12' === $limit->end_date->format('j-n')) {
return 'yearly';
}
return null;
}
/**
*
*/
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
*
*/
private function theresNoLimit(): void
{
$limits = BudgetLimit::whereNull('period')->get();
/** @var BudgetLimit $limit */
foreach ($limits as $limit) {
$this->fixLimit($limit);
}
}
/**
* @param BudgetLimit $limit
*/
private function fixLimit(BudgetLimit $limit)
{
$period = $this->getLimitPeriod($limit);
if (null === $period) {
$message = sprintf('Could not guesstimate budget limit #%d (%s - %s) period.', $limit->id, $limit->start_date->format('Y-m-d'), $limit->end_date->format('Y-m-d'));
$this->warn($message);
Log::warning($message);
return;
}
$limit->period = $period;
$limit->save();
$msg = sprintf('Budget limit #%d (%s - %s) period is "%s".', $limit->id, $limit->start_date->format('Y-m-d'), $limit->end_date->format('Y-m-d'), $period);
Log::debug($msg);
}
}

View File

@ -0,0 +1,50 @@
<?php
/**
* DestroyedTransactionGroup.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events;
use FireflyIII\Models\TransactionGroup;
use Illuminate\Queue\SerializesModels;
/**
* Class DestroyedTransactionGroup.
*
* @codeCoverageIgnore
*/
class DestroyedTransactionGroup extends Event
{
use SerializesModels;
public TransactionGroup $transactionGroup;
/**
* Create a new event instance.
*
* @param TransactionGroup $transactionGroup
*/
public function __construct(TransactionGroup $transactionGroup)
{
$this->transactionGroup = $transactionGroup;
}
}

View File

@ -0,0 +1,48 @@
<?php
/*
* DestroyedTransactionLink.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events;
use FireflyIII\Models\TransactionJournalLink;
use Illuminate\Queue\SerializesModels;
/**
* Class DestroyedTransactionLink
*/
class DestroyedTransactionLink extends Event
{
use SerializesModels;
private TransactionJournalLink $link;
/**
* DestroyedTransactionLink constructor.
*
* @param TransactionJournalLink $link
*/
public function __construct(TransactionJournalLink $link)
{
$this->link = $link;
}
}

View File

@ -47,4 +47,4 @@ class DetectedNewIPAddress extends Event
$this->ipAddress = $ipAddress;
$this->user = $user;
}
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
/*
* RequestedSendWebhookMessages.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Events;
use Illuminate\Queue\SerializesModels;
class RequestedSendWebhookMessages extends Event
{
use SerializesModels;
}

View File

@ -36,10 +36,8 @@ class StoredTransactionGroup extends Event
{
use SerializesModels;
/** @var bool */
public $applyRules;
/** @var TransactionGroup The group that was stored. */
public $transactionGroup;
public bool $applyRules;
public TransactionGroup $transactionGroup;
/**

View File

@ -0,0 +1,47 @@
<?php
/*
* StoredTransactionLink.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events;
use FireflyIII\Models\TransactionJournalLink;
use Illuminate\Queue\SerializesModels;
/**
* Class StoredTransactionLink
*/
class StoredTransactionLink extends Event
{
use SerializesModels;
private TransactionJournalLink $link;
/**
* DestroyedTransactionLink constructor.
*
* @param TransactionJournalLink $link
*/
public function __construct(TransactionJournalLink $link)
{
$this->link = $link;
}
}

View File

@ -0,0 +1,47 @@
<?php
/*
* UpdatedTransactionLink.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events;
use FireflyIII\Models\TransactionJournalLink;
use Illuminate\Queue\SerializesModels;
/**
* Class UpdatedTransactionLink
*/
class UpdatedTransactionLink extends Event
{
use SerializesModels;
private TransactionJournalLink $link;
/**
* DestroyedTransactionLink constructor.
*
* @param TransactionJournalLink $link
*/
public function __construct(TransactionJournalLink $link)
{
$this->link = $link;
}
}

View File

@ -116,6 +116,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
return redirect(route('tags.index'));
break;
case 'categories.show':
case 'categories.show.all':
$request->session()->reflash();
return redirect(route('categories.index'));

View File

@ -41,10 +41,8 @@ class RecurrenceFactory
{
use TransactionTypeTrait, RecurringTransactionTrait;
/** @var MessageBag */
private $errors;
/** @var User */
private $user;
private MessageBag $errors;
private User $user;
/**
@ -54,9 +52,6 @@ class RecurrenceFactory
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
$this->errors = new MessageBag;
}

View File

@ -38,18 +38,12 @@ use Log;
*/
class TransactionFactory
{
/** @var Account */
private $account;
/** @var TransactionCurrency */
private $currency;
/** @var TransactionCurrency */
private $foreignCurrency;
/** @var TransactionJournal */
private $journal;
/** @var bool */
private $reconciled;
/** @var User */
private $user;
private Account $account;
private TransactionCurrency $currency;
private ?TransactionCurrency $foreignCurrency;
private TransactionJournal $journal;
private bool $reconciled;
private User $user;
/**
@ -59,9 +53,6 @@ class TransactionFactory
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
$this->reconciled = false;
}

View File

@ -74,31 +74,8 @@ class TransactionJournalFactory
*/
public function __construct()
{
$this->errorOnHash = false;
// TODO move valid meta fields to config.
$this->fields = [
// sepa
'sepa_cc', 'sepa_ct_op', 'sepa_ct_id',
'sepa_db', 'sepa_country', 'sepa_ep',
'sepa_ci', 'sepa_batch_id', 'external_uri',
// dates
'interest_date', 'book_date', 'process_date',
'due_date', 'payment_date', 'invoice_date',
// others
'recurrence_id', 'internal_reference', 'bunq_payment_id',
'import_hash', 'import_hash_v2', 'external_id', 'original_source',
// recurring transactions
'recurrence_total', 'recurrence_count',
];
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
$this->errorOnHash = false;
$this->fields = config('firefly.journal_meta_fields');
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
$this->typeRepository = app(TransactionTypeRepositoryInterface::class);
$this->billRepository = app(BillRepositoryInterface::class);
@ -201,7 +178,7 @@ class TransactionJournalFactory
$set = [
'journal' => $journal,
'name' => $field,
'data' => (string) ($data[$field] ?? ''),
'data' => (string)($data[$field] ?? ''),
];
Log::debug(sprintf('Going to store meta-field "%s", with value "%s".', $set['name'], $set['data']));
@ -248,11 +225,11 @@ class TransactionJournalFactory
$type = $this->typeRepository->findTransactionType(null, $row['type']);
$carbon = $row['date'] ?? today(config('app.timezone'));
$order = $row['order'] ?? 0;
$currency = $this->currencyRepository->findCurrency((int) $row['currency_id'], $row['currency_code']);
$currency = $this->currencyRepository->findCurrency((int)$row['currency_id'], $row['currency_code']);
$foreignCurrency = $this->currencyRepository->findCurrencyNull($row['foreign_currency_id'], $row['foreign_currency_code']);
$bill = $this->billRepository->findBill((int) $row['bill_id'], $row['bill_name']);
$bill = $this->billRepository->findBill((int)$row['bill_id'], $row['bill_name']);
$billId = TransactionType::WITHDRAWAL === $type->type && null !== $bill ? $bill->id : null;
$description = app('steam')->cleanString((string) $row['description']);
$description = app('steam')->cleanString((string)$row['description']);
/** Manipulate basic fields */
$carbon->setTimezone(config('app.timezone'));
@ -267,11 +244,12 @@ class TransactionJournalFactory
return null;
}
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
// typeOverrule: the account validator may have another opinion on the transaction type.
// not sure what to do with this.
/** create or get source and destination accounts */
$sourceInfo = [
'id' => (int) $row['source_id'],
'id' => (int)$row['source_id'],
'name' => $row['source_name'],
'iban' => $row['source_iban'],
'number' => $row['source_number'],
@ -280,7 +258,7 @@ class TransactionJournalFactory
];
$destInfo = [
'id' => (int) $row['destination_id'],
'id' => (int)$row['destination_id'],
'name' => $row['destination_name'],
'iban' => $row['destination_iban'],
'number' => $row['destination_number'],
@ -324,7 +302,7 @@ class TransactionJournalFactory
$transactionFactory->setForeignCurrency($foreignCurrency);
$transactionFactory->setReconciled($row['reconciled'] ?? false);
try {
$negative = $transactionFactory->createNegative((string) $row['amount'], (string) $row['foreign_amount']);
$negative = $transactionFactory->createNegative((string)$row['amount'], (string)$row['foreign_amount']);
} catch (FireflyException $e) {
Log::error('Exception creating negative transaction.');
Log::error($e->getMessage());
@ -343,7 +321,7 @@ class TransactionJournalFactory
$transactionFactory->setForeignCurrency($foreignCurrency);
$transactionFactory->setReconciled($row['reconciled'] ?? false);
try {
$transactionFactory->createPositive((string) $row['amount'], (string) $row['foreign_amount']);
$transactionFactory->createPositive((string)$row['amount'], (string)$row['foreign_amount']);
} catch (FireflyException $e) {
Log::error('Exception creating positive transaction.');
Log::error($e->getMessage());
@ -356,7 +334,6 @@ class TransactionJournalFactory
// verify that journal has two transactions. Otherwise, delete and cancel.
// TODO this can't be faked so it can't be tested.
$journal->completed = true;
$journal->save();
@ -524,7 +501,7 @@ class TransactionJournalFactory
$json = json_encode($dataRow, JSON_THROW_ON_ERROR, 512);
if (false === $json) {
// @codeCoverageIgnoreStart
$json = json_encode((string) microtime(), JSON_THROW_ON_ERROR, 512);
$json = json_encode((string)microtime(), JSON_THROW_ON_ERROR, 512);
Log::error(sprintf('Could not hash the original row! %s', json_last_error_msg()), $dataRow);
// @codeCoverageIgnoreEnd
}
@ -560,7 +537,7 @@ class TransactionJournalFactory
return;
}
$piggyBank = $this->piggyRepository->findPiggyBank((int) $data['piggy_bank_id'], $data['piggy_bank_name']);
$piggyBank = $this->piggyRepository->findPiggyBank((int)$data['piggy_bank_id'], $data['piggy_bank_name']);
if (null !== $piggyBank) {
$this->piggyEventFactory->create($journal, $piggyBank);
@ -583,8 +560,8 @@ class TransactionJournalFactory
$this->accountValidator->setTransactionType($transactionType);
// validate source account.
$sourceId = $data['source_id'] ? (int) $data['source_id'] : null;
$sourceName = $data['source_name'] ? (string) $data['source_name'] : null;
$sourceId = $data['source_id'] ? (int)$data['source_id'] : null;
$sourceName = $data['source_name'] ? (string)$data['source_name'] : null;
$validSource = $this->accountValidator->validateSource($sourceId, $sourceName, null);
// do something with result:
@ -593,8 +570,8 @@ class TransactionJournalFactory
}
Log::debug('Source seems valid.');
// validate destination account
$destinationId = $data['destination_id'] ? (int) $data['destination_id'] : null;
$destinationName = $data['destination_name'] ? (string) $data['destination_name'] : null;
$destinationId = $data['destination_id'] ? (int)$data['destination_id'] : null;
$destinationName = $data['destination_name'] ? (string)$data['destination_name'] : null;
$validDestination = $this->accountValidator->validateDestination($destinationId, $destinationName, null);
// do something with result:
if (false === $validDestination) {

View File

@ -34,18 +34,6 @@ use Log;
*/
class TransactionJournalMetaFactory
{
/**
* Constructor.
*
* @codeCoverageIgnore
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**
* @param array $data
*

View File

@ -33,18 +33,6 @@ use Log;
*/
class TransactionTypeFactory
{
/**
* Constructor.
*
* @codeCoverageIgnore
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**
* @param string $type
*

View File

@ -30,18 +30,6 @@ use Log;
*/
class ChartJsGenerator implements GeneratorInterface
{
/**
* Constructor.
*
* @codeCoverageIgnore
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**
* Expects data as:.
*

View File

@ -52,7 +52,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
*/
public function __construct()
{
$this->expenses = new Collection;
$this->expenses = [];
}
/**

View File

@ -1,7 +1,8 @@
<?php
/**
* ExchangeRateInterface.php
* Copyright (c) 2019 james@firefly-iii.org
declare(strict_types=1);
/*
* MessageGeneratorInterface.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@ -18,33 +19,40 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Currency;
namespace FireflyIII\Generator\Webhook;
use Carbon\Carbon;
use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\User;
use Illuminate\Support\Collection;
/**
* Interface ExchangeRateInterface
* Interface MessageGeneratorInterface
*/
interface ExchangeRateInterface
interface MessageGeneratorInterface
{
/**
* @param TransactionCurrency $fromCurrency
* @param TransactionCurrency $toCurrency
* @param Carbon $date
*
* @return CurrencyExchangeRate
* @return int
*/
public function getRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): CurrencyExchangeRate;
public function getVersion(): int;
/**
*
*/
public function generateMessages(): void;
/**
* @param User $user
*
* @return mixed
*/
public function setUser(User $user);
public function setUser(User $user): void;
/**
* @param Collection $objects
*/
public function setObjects(Collection $objects): void;
/**
* @param int $trigger
*/
public function setTrigger(int $trigger): void;
}

View File

@ -0,0 +1,237 @@
<?php
declare(strict_types=1);
/*
* WebhookMessageGenerator.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Generator\Webhook;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\Webhook;
use FireflyIII\Models\WebhookMessage;
use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Log;
use Ramsey\Uuid\Uuid;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
* Class StandardMessageGenerator
*/
class StandardMessageGenerator implements MessageGeneratorInterface
{
private int $version = 0;
private User $user;
private Collection $objects;
private int $trigger;
private Collection $webhooks;
/**
*
*/
public function generateMessages(): void
{
Log::debug(__METHOD__);
// get the webhooks:
$this->webhooks = $this->getWebhooks();
// do some debugging
Log::debug(
sprintf('StandardMessageGenerator will generate messages for %d object(s) and %d webhook(s).', $this->objects->count(), $this->webhooks->count())
);
$this->run();
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
/**
* @param Collection $objects
*/
public function setObjects(Collection $objects): void
{
$this->objects = $objects;
}
/**
* @param int $trigger
*/
public function setTrigger(int $trigger): void
{
$this->trigger = $trigger;
}
/**
* @return Collection
*/
private function getWebhooks(): Collection
{
return $this->user->webhooks()->where('active', 1)->where('trigger', $this->trigger)->get(['webhooks.*']);
}
/**
*
*/
private function run(): void
{
Log::debug('Now in StandardMessageGenerator::run');
/** @var Webhook $webhook */
foreach ($this->webhooks as $webhook) {
$this->runWebhook($webhook);
}
Log::debug('Done with StandardMessageGenerator::run');
}
/**
* @param Webhook $webhook
*/
private function runWebhook(Webhook $webhook): void
{
Log::debug(sprintf('Now in runWebhook(#%d)', $webhook->id));
/** @var Model $object */
foreach ($this->objects as $object) {
$this->generateMessage($webhook, $object);
}
}
/**
* @param Webhook $webhook
* @param Model $model
*/
private function generateMessage(Webhook $webhook, Model $model): void
{
$class = get_class($model);
Log::debug(sprintf('Now in generateMessage(#%d, %s#%d)', $webhook->id, $class, $model->id));
$uuid = Uuid::uuid4();
$basicMessage = [
'uuid' => $uuid->toString(),
'user_id' => 0,
'trigger' => config('firefly.webhooks.triggers')[$webhook->trigger],
'response' => config('firefly.webhooks.responses')[$webhook->response],
'url' => $webhook->url,
'version' => sprintf('v%d', $this->getVersion()),
'content' => [],
];
// depends on the model how user_id is set:
switch ($class) {
default:
Log::error(sprintf('Webhook #%d was given %s#%d to deal with but can\'t extract user ID from it.', $webhook->id, $class, $model->id));
return;
case TransactionGroup::class:
/** @var TransactionGroup $model */
$basicMessage['user_id'] = $model->user->id;
break;
}
// then depends on the response what to put in the message:
switch ($webhook->response) {
default:
Log::error(
sprintf('The response code for webhook #%d is "%d" and the message generator cant handle it. Soft fail.', $webhook->id, $webhook->response)
);
return;
case Webhook::RESPONSE_NONE:
$basicMessage['content'] = [];
break;
case Webhook::RESPONSE_TRANSACTIONS:
$transformer = new TransactionGroupTransformer;
try {
$basicMessage['content'] = $transformer->transformObject($model);
} catch (FireflyException $e) {
Log::error(
sprintf('The transformer could not include the requested transaction group for webhook #%d: %s', $webhook->id, $e->getMessage())
);
return;
}
break;
case Webhook::RESPONSE_ACCOUNTS:
$accounts = $this->collectAccounts($model);
foreach ($accounts as $account) {
$transformer = new AccountTransformer;
$transformer->setParameters(new ParameterBag);
$basicMessage['content'][] = $transformer->transform($account);
}
}
$this->storeMessage($webhook, $basicMessage);
}
/**
* @param TransactionGroup $transactionGroup
*
* @return Collection
*/
private function collectAccounts(TransactionGroup $transactionGroup): Collection
{
$accounts = new Collection;
/** @var TransactionJournal $journal */
foreach ($transactionGroup->transactionJournals as $journal) {
/** @var Transaction $transaction */
foreach ($journal->transactions as $transaction) {
$accounts->push($transaction->account);
}
}
return $accounts->unique();
}
/**
* @param Webhook $webhook
* @param array $message
*
* @return WebhookMessage
*/
private function storeMessage(Webhook $webhook, array $message): WebhookMessage
{
$webhookMessage = new WebhookMessage;
$webhookMessage->webhook()->associate($webhook);
$webhookMessage->sent = false;
$webhookMessage->errored = false;
$webhookMessage->uuid = $message['uuid'];
$webhookMessage->message = $message;
$webhookMessage->save();
Log::debug(sprintf('Stored new webhook message #%d', $webhookMessage->id));
return $webhookMessage;
}
/**
* @inheritDoc
*/
public function getVersion(): int
{
return $this->version;
}
}

View File

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
/*
* DestroyedGroupEventHandler.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\DestroyedTransactionGroup;
use FireflyIII\Events\RequestedSendWebhookMessages;
use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
use FireflyIII\Models\Webhook;
use Illuminate\Support\Collection;
use Log;
/**
* Class DestroyedGroupEventHandler
*/
class DestroyedGroupEventHandler
{
/**
* @param DestroyedTransactionGroup $destroyedGroupEvent
*/
public function triggerWebhooks(DestroyedTransactionGroup $destroyedGroupEvent): void
{
Log::debug('DestroyedTransactionGroup:triggerWebhooks');
$group = $destroyedGroupEvent->transactionGroup;
$user = $group->user;
/** @var MessageGeneratorInterface $engine */
$engine = app(MessageGeneratorInterface::class);
$engine->setUser($user);
$engine->setObjects(new Collection([$group]));
$engine->setTrigger(Webhook::TRIGGER_DESTROY_TRANSACTION);
$engine->generateMessages();
event(new RequestedSendWebhookMessages);
}
}

View File

@ -22,11 +22,15 @@ declare(strict_types=1);
namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\RequestedSendWebhookMessages;
use FireflyIII\Events\StoredTransactionGroup;
use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\Webhook;
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
use FireflyIII\TransactionRules\Engine\RuleEngine;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
use Illuminate\Support\Collection;
use Log;
/**
@ -59,15 +63,45 @@ class StoredGroupEventHandler
// collect rules:
$ruleRepository = app(RuleRepositoryInterface::class);
$ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$ruleRepository->setUser($storedGroupEvent->transactionGroup->user);
$rules = $ruleRepository->getStoreRules();
$ruleGroupRepository->setUser($storedGroupEvent->transactionGroup->user);
// file rule engine.
// add the groups to the rule engine.
// it should run the rules in the group and cancel the group if necessary.
$groups = $ruleGroupRepository->getRuleGroupsWithRules();
// create and fire rule engine.
$newRuleEngine = app(RuleEngineInterface::class);
$newRuleEngine->setUser($storedGroupEvent->transactionGroup->user);
$newRuleEngine->addOperator(['type' => 'journal_id', 'value' => $journalIds]);
$newRuleEngine->setRules($rules);
$newRuleEngine->setRuleGroups($groups);
$newRuleEngine->fire();
}
/**
* This method processes all webhooks that respond to the "stored transaction group" trigger (100)
*
* @param StoredTransactionGroup $storedGroupEvent
*/
public function triggerWebhooks(StoredTransactionGroup $storedGroupEvent): void
{
Log::debug(__METHOD__);
$group = $storedGroupEvent->transactionGroup;
$user = $group->user;
/** @var MessageGeneratorInterface $engine */
$engine = app(MessageGeneratorInterface::class);
$engine->setUser($user);
// tell the generator which trigger it should look for
$engine->setTrigger(Webhook::TRIGGER_STORE_TRANSACTION);
// tell the generator which objects to process
$engine->setObjects(new Collection([$group]));
// tell the generator to generate the messages
$engine->generateMessages();
// trigger event to send them:
event(new RequestedSendWebhookMessages);
}
}

View File

@ -22,14 +22,17 @@ declare(strict_types=1);
namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\RequestedSendWebhookMessages;
use FireflyIII\Events\UpdatedTransactionGroup;
use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Models\Webhook;
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
use FireflyIII\TransactionRules\Engine\RuleEngine;
use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
use Illuminate\Support\Collection;
use Log;
/**
@ -112,4 +115,21 @@ class UpdatedGroupEventHandler
$newRuleEngine->fire();
}
/**
* @param UpdatedTransactionGroup $updatedGroupEvent
*/
public function triggerWebhooks(UpdatedTransactionGroup $updatedGroupEvent): void
{
Log::debug('UpdatedGroupEventHandler:triggerWebhooks');
$group = $updatedGroupEvent->transactionGroup;
$user = $group->user;
/** @var MessageGeneratorInterface $engine */
$engine = app(MessageGeneratorInterface::class);
$engine->setUser($user);
$engine->setObjects(new Collection([$group]));
$engine->setTrigger(Webhook::TRIGGER_UPDATE_TRANSACTION);
$engine->generateMessages();
event(new RequestedSendWebhookMessages);
}
}

View File

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
/*
* WebhookEventHandler.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Handlers\Events;
use FireflyIII\Jobs\SendWebhookMessage;
use FireflyIII\Models\WebhookMessage;
use Log;
/**
* Class WebhookEventHandler
*/
class WebhookEventHandler
{
/**
* Will try to send at most 3 messages so the flow doesn't get broken too much.
*/
public function sendWebhookMessages(): void
{
// kick off the job!
$messages = WebhookMessage
::where('webhook_messages.sent', 0)
->where('webhook_messages.errored', 0)
->get(['webhook_messages.*'])
->filter(
function (WebhookMessage $message) {
return $message->webhookAttempts()->count() <= 2;
}
)->splice(0, 3);
Log::debug(sprintf('Found %d webhook message(s) ready to be send.', $messages->count()));
foreach ($messages as $message) {
SendWebhookMessage::dispatch($message)->afterResponse();
}
}
}

View File

@ -70,10 +70,6 @@ class AttachmentHelper implements AttachmentHelperInterface
$this->messages = new MessageBag;
$this->attachments = new Collection;
$this->uploadDisk = Storage::disk('upload');
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}

View File

@ -165,6 +165,16 @@ class GroupCollector implements GroupCollectorInterface
*/
public function getGroups(): Collection
{
$filterQuery = false;
// now filter the query according to the page and the limit (if necessary)
if ($filterQuery) {
if (null !== $this->limit && null !== $this->page) {
$offset = ($this->page - 1) * $this->limit;
$this->query->take($this->limit)->skip($offset);
}
}
/** @var Collection $result */
$result = $this->query->get($this->fields);
@ -173,10 +183,12 @@ class GroupCollector implements GroupCollectorInterface
$this->total = $collection->count();
// now filter the array according to the page and the limit (if necessary)
if (null !== $this->limit && null !== $this->page) {
$offset = ($this->page - 1) * $this->limit;
if (!$filterQuery) {
if (null !== $this->limit && null !== $this->page) {
$offset = ($this->page - 1) * $this->limit;
return $collection->slice($offset, $this->limit);
return $collection->slice($offset, $this->limit);
}
}
return $collection;
@ -190,30 +202,13 @@ class GroupCollector implements GroupCollectorInterface
public function getPaginatedGroups(): LengthAwarePaginator
{
$set = $this->getGroups();
if(0===$this->limit) {
if (0 === $this->limit) {
$this->setLimit(50);
}
return new LengthAwarePaginator($set, $this->total, $this->limit, $this->page);
}
/**
* Return the sum of all journals.
* TODO ignores the currency.
*
* @return string
*/
public function getSum(): string
{
$journals = $this->getExtractedJournals();
$sum = '0';
/** @var array $journal */
foreach ($journals as $journal) {
$amount = (string) $journal['amount'];
$sum = bcadd($sum, $amount);
}
return $sum;
}
/**
* Limit results to a specific currency, either foreign or normal one.
@ -260,6 +255,20 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
/**
* Limit the result to a set of specific transaction groups.
*
* @param array $groupIds
*
* @return GroupCollectorInterface
*/
public function setIds(array $groupIds): GroupCollectorInterface {
$this->query->whereIn('transaction_groups.id', $groupIds);
return $this;
}
/**
* Limit the number of returned entries.
*
@ -440,6 +449,7 @@ class GroupCollector implements GroupCollectorInterface
$this->startQuery();
}
return $this;
}
@ -484,7 +494,7 @@ class GroupCollector implements GroupCollectorInterface
private function convertToInteger(array $array): array
{
foreach ($this->integerFields as $field) {
$array[$field] = array_key_exists($field, $array) ? (int) $array[$field] : null;
$array[$field] = array_key_exists($field, $array) ? (int)$array[$field] : null;
}
return $array;
@ -516,7 +526,7 @@ class GroupCollector implements GroupCollectorInterface
->where(
static function (EloquentBuilder $q1) {
$q1->where('attachments.attachable_type', TransactionJournal::class);
$q1->where('attachments.uploaded',1);
$q1->where('attachments.uploaded', 1);
$q1->orWhereNull('attachments.attachable_type');
}
);
@ -533,7 +543,7 @@ class GroupCollector implements GroupCollectorInterface
{
$newArray = $newJournal->toArray();
if (array_key_exists('attachment_id', $newArray)) {
$attachmentId = (int) $newJournal['tag_id'];
$attachmentId = (int)$newJournal['tag_id'];
$existingJournal['attachments'][$attachmentId] = [
'id' => $attachmentId,
];
@ -552,7 +562,7 @@ class GroupCollector implements GroupCollectorInterface
{
$newArray = $newJournal->toArray();
if (array_key_exists('tag_id', $newArray)) { // assume the other fields are present as well.
$tagId = (int) $newJournal['tag_id'];
$tagId = (int)$newJournal['tag_id'];
$tagDate = null;
try {
@ -562,7 +572,7 @@ class GroupCollector implements GroupCollectorInterface
}
$existingJournal['tags'][$tagId] = [
'id' => (int) $newArray['tag_id'],
'id' => (int)$newArray['tag_id'],
'name' => $newArray['tag_name'],
'date' => $tagDate,
'description' => $newArray['tag_description'],
@ -588,21 +598,21 @@ class GroupCollector implements GroupCollectorInterface
// make new array
$parsedGroup = $this->parseAugmentedJournal($augumentedJournal);
$groupArray = [
'id' => (int) $augumentedJournal->transaction_group_id,
'user_id' => (int) $augumentedJournal->user_id,
'id' => (int)$augumentedJournal->transaction_group_id,
'user_id' => (int)$augumentedJournal->user_id,
'title' => $augumentedJournal->transaction_group_title,
'transaction_type' => $parsedGroup['transaction_type_type'],
'count' => 1,
'sums' => [],
'transactions' => [],
];
$journalId = (int) $augumentedJournal->transaction_journal_id;
$journalId = (int)$augumentedJournal->transaction_journal_id;
$groupArray['transactions'][$journalId] = $parsedGroup;
$groups[$groupId] = $groupArray;
continue;
}
// or parse the rest.
$journalId = (int) $augumentedJournal->transaction_journal_id;
$journalId = (int)$augumentedJournal->transaction_journal_id;
if (array_key_exists($journalId, $groups[$groupId]['transactions'])) {
@ -649,9 +659,9 @@ class GroupCollector implements GroupCollectorInterface
// convert values to integers:
$result = $this->convertToInteger($result);
$result['reconciled'] = 1 === (int) $result['reconciled'];
$result['reconciled'] = 1 === (int)$result['reconciled'];
if (isset($augumentedJournal['tag_id'])) { // assume the other fields are present as well.
$tagId = (int) $augumentedJournal['tag_id'];
$tagId = (int)$augumentedJournal['tag_id'];
$tagDate = null;
try {
$tagDate = Carbon::parse($augumentedJournal['tag_date']);
@ -660,7 +670,7 @@ class GroupCollector implements GroupCollectorInterface
}
$result['tags'][$tagId] = [
'id' => (int) $result['tag_id'],
'id' => (int)$result['tag_id'],
'name' => $result['tag_name'],
'date' => $tagDate,
'description' => $result['tag_description'],
@ -669,7 +679,7 @@ class GroupCollector implements GroupCollectorInterface
// also merge attachments:
if (isset($augumentedJournal['attachment_id'])) {
$attachmentId = (int) $augumentedJournal['attachment_id'];
$attachmentId = (int)$augumentedJournal['attachment_id'];
$result['attachments'][$attachmentId] = [
'id' => $attachmentId,
];
@ -692,7 +702,7 @@ class GroupCollector implements GroupCollectorInterface
foreach ($groups as $groudId => $group) {
/** @var array $transaction */
foreach ($group['transactions'] as $transaction) {
$currencyId = (int) $transaction['currency_id'];
$currencyId = (int)$transaction['currency_id'];
// set default:
if (!isset($groups[$groudId]['sums'][$currencyId])) {
@ -705,7 +715,7 @@ class GroupCollector implements GroupCollectorInterface
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['amount'] ?? '0');
if (null !== $transaction['foreign_amount'] && null !== $transaction['foreign_currency_id']) {
$currencyId = (int) $transaction['foreign_currency_id'];
$currencyId = (int)$transaction['foreign_currency_id'];
// set default:
if (!isset($groups[$groudId]['sums'][$currencyId])) {

View File

@ -105,13 +105,6 @@ interface GroupCollectorInterface
*/
public function getPaginatedGroups(): LengthAwarePaginator;
/**
* Return the sum of all journals.
*
* @return string
*/
public function getSum(): string;
/**
* Define which accounts can be part of the source and destination transactions.
*
@ -247,6 +240,15 @@ interface GroupCollectorInterface
*/
public function setJournalIds(array $journalIds): GroupCollectorInterface;
/**
* Limit the result to a set of specific transaction groups.
*
* @param array $groupIds
*
* @return GroupCollectorInterface
*/
public function setIds(array $groupIds): GroupCollectorInterface;
/**
* Limit the number of returned entries.
*

View File

@ -39,10 +39,6 @@ class FiscalHelper implements FiscalHelperInterface
public function __construct()
{
$this->useCustomFiscalYear = app('preferences')->get('customFiscalYear', false)->data;
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**

View File

@ -44,9 +44,6 @@ class Help implements HelpInterface
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
$this->userAgent = sprintf($this->userAgent, config('firefly.version'));
}

View File

@ -47,16 +47,6 @@ class NetWorth implements NetWorthInterface
/** @var User */
private $user;
/**
* Constructor.
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**
* Returns the user's net worth in an array with the following layout:
*

View File

@ -27,6 +27,7 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use Illuminate\Support\Collection;
@ -39,16 +40,6 @@ use Log;
*/
class PopupReport implements PopupReportInterface
{
/**
* Constructor.
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**
* Collect the transactions for one account and one budget.
*
@ -216,10 +207,17 @@ class PopupReport implements PopupReportInterface
$repository = app(JournalRepositoryInterface::class);
$repository->setUser($account->user);
$accountRepository = app(AccountRepositoryInterface::class);
$accountRepository->setUser($account->user);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))
// set report accounts + the request accounts:
$set = $attributes['accounts'] ?? new Collection;
$set->push($account);
$collector->setBothAccounts($set)
->setRange($attributes['startDate'], $attributes['endDate'])
->withAccountInformation()
->withBudgetInformation()

View File

@ -49,12 +49,6 @@ class ReportHelper implements ReportHelperInterface
public function __construct(BudgetRepositoryInterface $budgetRepository)
{
$this->budgetRepository = $budgetRepository;
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**

View File

@ -0,0 +1,71 @@
<?php
declare(strict_types=1);
/*
* Sha3SignatureGenerator.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Helpers\Webhook;
use FireflyIII\Models\WebhookMessage;
use JsonException;
/**
* Class Sha3SignatureGenerator
*/
class Sha3SignatureGenerator implements SignatureGeneratorInterface
{
private int $version = 1;
/**
* @inheritDoc
*/
public function getVersion(): int
{
return $this->version;
}
/**
* @inheritDoc
*/
public function generate(WebhookMessage $message): string
{
try {
$json = json_encode($message->message, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
// TODO needs FireflyException.
return sprintf('t=1,v%d=err-invalid-signature', $this->getVersion());
}
// signature v1 is generated using the following structure:
// The signed_payload string is created by concatenating:
// The timestamp (as a string)
// The character .
// The character .
// The actual JSON payload (i.e., the request body)
$timestamp = time();
$payload = sprintf('%s.%s', $timestamp, $json);
$signature = hash_hmac('sha3-256', $payload, $message->webhook->secret, false);
// signature string:
// header included in each signed event contains a timestamp and one or more signatures.
// The timestamp is prefixed by t=, and each signature is prefixed by a scheme.
// Schemes start with v, followed by an integer. Currently, the only valid live signature scheme is v1.
return sprintf('t=%s,v%d=%s', $timestamp, $this->getVersion(), $signature);
}
}

View File

@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
/*
* SignatureGeneratorInterface.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Helpers\Webhook;
use FireflyIII\Models\WebhookMessage;
/**
* Interface SignatureGeneratorInterface
*/
interface SignatureGeneratorInterface
{
/**
* Return the version of this signature generator.
*
* @return int
*/
public function getVersion(): int;
/**
* @param WebhookMessage $message
*
* @return string
*/
public function generate(WebhookMessage $message): string;
}

View File

@ -125,6 +125,7 @@ class ShowController extends Controller
->setPage($page)->withAccountInformation()->withCategoryInformation()
->setRange($start, $end);
$groups = $collector->getPaginatedGroups();
$groups->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]));
$showAll = false;
$balance = app('steam')->balance($account, $end);

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth;
use Adldap;
use Cookie;
use DB;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Providers\RouteServiceProvider;
@ -130,7 +131,7 @@ class LoginController extends Controller
$count = DB::table('users')->count();
$loginProvider = config('firefly.login_provider');
$title = (string) trans('firefly.login_page_title');
$title = (string)trans('firefly.login_page_title');
if (0 === $count && 'eloquent' === $loginProvider) {
return redirect(route('register')); // @codeCoverageIgnore
}
@ -199,9 +200,13 @@ class LoginController extends Controller
return redirect($logoutUri);
}
if ('remote_user_guard' === $authGuard && '' === $logoutUri) {
session()->flash('error',trans('firefly.cant_logout_guard'));
session()->flash('error', trans('firefly.cant_logout_guard'));
}
// also logout current 2FA tokens.
$cookieName = config('google2fa.cookie_name', 'google2fa_token');
Cookie::forget($cookieName);
$this->guard()->logout();
$request->session()->invalidate();

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