Compare commits

..

51 Commits

Author SHA1 Message Date
github-actions
32e5efec7c Auto commit for release 'branch-v6.2' on 2024-12-27 2024-12-27 07:29:17 +01:00
James Cole
36457455ca Rename and clean up commands. 2024-12-27 07:24:47 +01:00
James Cole
062c148e43 Rename all correction commands. 2024-12-27 06:56:08 +01:00
James Cole
2314ce8004 Refactor and renam commands. 2024-12-27 06:48:58 +01:00
James Cole
a3ff73903a Fix bad error message. 2024-12-27 05:44:03 +01:00
James Cole
7c8445707e Add moar debug. 2024-12-26 14:12:05 +01:00
James Cole
291e73da4b Rename bills to subscriptions 2024-12-26 13:41:57 +01:00
James Cole
286a29ca3e Display for bills. 2024-12-26 11:28:31 +01:00
github-actions
71cf6c6a5e Auto commit for release 'branch-v6.2' on 2024-12-26 2024-12-26 10:24:39 +01:00
James Cole
1e8f0adaf8 Fix broken account balance. 2024-12-26 10:20:40 +01:00
James Cole
33531244aa Merge branch 'v6.2' of github.com:firefly-iii/firefly-iii into v6.2
# Conflicts:
#	app/Http/Controllers/Chart/AccountController.php
#	app/Support/Steam.php
2024-12-26 09:19:04 +01:00
James Cole
06049a9a28 Update various pages, clean up some code. 2024-12-26 09:16:17 +01:00
James Cole
d313f5fdf5 Fix chart balance. 2024-12-26 08:53:16 +01:00
github-actions
f4868126c1 Auto commit for release 'branch-v6.2' on 2024-12-26 2024-12-26 05:25:46 +01:00
James Cole
00147e98dd Fix home chart. 2024-12-26 05:21:28 +01:00
James Cole
6d22663ca2 Fix charts and balances. 2024-12-26 05:11:32 +01:00
James Cole
756bb9cf5e Fix overview, skip chart for now. 2024-12-25 11:59:15 +01:00
James Cole
399d7968f5 Fix another null. 2024-12-25 08:30:00 +01:00
James Cole
966b68f42e Merge branch 'v6.2' of github.com:firefly-iii/firefly-iii into v6.2 2024-12-25 08:29:50 +01:00
James Cole
134c551c12 Remove some comments, add others. 2024-12-25 08:23:17 +01:00
github-actions
9aeca15355 Auto commit for release 'branch-v6.2' on 2024-12-25 2024-12-25 08:17:59 +01:00
James Cole
6c6d31830b Fix nullpointer 2024-12-25 08:14:07 +01:00
github-actions
e8cc321898 Auto commit for release 'branch-v6.2' on 2024-12-25 2024-12-25 07:13:41 +01:00
James Cole
e73fe06f7e Expand currency view in accounts. 2024-12-25 07:10:02 +01:00
James Cole
98b579c042 Fix native display. 2024-12-24 19:03:47 +01:00
James Cole
7b3a5c1afd Frontpage seems to be multi currency aware. 2024-12-24 16:56:31 +01:00
James Cole
7e2e49e129 Convert more charts. 2024-12-24 10:29:07 +01:00
James Cole
e8ef630424 Expand native amount things. 2024-12-24 06:34:12 +01:00
James Cole
8805bcf6f6 Various updates to display native/foreign amounts. 2024-12-23 17:32:15 +01:00
James Cole
ff5c9a3aa0 Merge branch 'v6.2' of github.com:firefly-iii/firefly-iii into v6.2 2024-12-23 14:35:34 +01:00
James Cole
3a274dcaa7 Little debug page with routes. 2024-12-23 14:35:27 +01:00
github-actions
ddfededf02 Auto commit for release 'branch-v6.2' on 2024-12-23 2024-12-23 08:40:29 +01:00
James Cole
e1785898ba Add notes to audit report. 2024-12-23 08:35:33 +01:00
James Cole
ae09200f42 Fix import 2024-12-23 08:26:35 +01:00
James Cole
847984f678 New rule triggers for account balance. 2024-12-23 08:22:54 +01:00
James Cole
42305672ac Merge branch 'v6.2' of github.com:firefly-iii/firefly-iii into v6.2 2024-12-23 07:14:12 +01:00
James Cole
25a56d9f72 Chart no longer as a line chart. 2024-12-23 07:13:59 +01:00
github-actions
8f9f08b96f Auto commit for release 'branch-v6.2' on 2024-12-23 2024-12-23 07:01:44 +01:00
James Cole
3c65b46aa5 Merge branch 'v6.2' of github.com:firefly-iii/firefly-iii into v6.2
# Conflicts:
#	app/Support/Steam.php
2024-12-23 06:56:31 +01:00
James Cole
1cf9c76329 Fix array bug. 2024-12-23 06:55:14 +01:00
github-actions
c0499df4ec Auto commit for release 'branch-v6.2' on 2024-12-22 2024-12-22 20:37:54 +01:00
James Cole
d90ac519f7 Clean up balance methods. 2024-12-22 20:32:58 +01:00
James Cole
a0e92b6969 Clean up variety of account balance methods. 2024-12-22 19:42:06 +01:00
James Cole
df49dd23e2 Try to convert balance to native, still internal debates. 2024-12-22 16:41:55 +01:00
James Cole
d4525da6bc Merge branch 'v6.2' of github.com:firefly-iii/firefly-iii into v6.2 2024-12-22 15:54:06 +01:00
James Cole
25b11bd20b Add preference for native amounts. 2024-12-22 15:53:59 +01:00
github-actions
705aac419a Auto commit for release 'branch-v6.2' on 2024-12-22 2024-12-22 14:00:37 +01:00
James Cole
f6e642f72e Add and remove exchange rates 2024-12-22 13:19:23 +01:00
James Cole
565bd87959 Code cleanup 2024-12-22 08:43:12 +01:00
James Cole
5751f7e5a3 Merge branch 'v6.2' of github.com:firefly-iii/firefly-iii into v6.2
# Conflicts:
#	app/Api/V2/Controllers/Model/ExchangeRate/ShowController.php
#	app/Repositories/UserGroups/ExchangeRate/ExchangeRateRepository.php
#	routes/api.php
2024-12-22 08:28:44 +01:00
James Cole
f5a755d4fc Various changes 2024-12-22 08:27:01 +01:00
690 changed files with 10912 additions and 9432 deletions

View File

@@ -30,6 +30,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Api\AccountFilter; use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@@ -78,7 +79,7 @@ class AccountController extends Controller
$query = $data['query']; $query = $data['query'];
$date = $data['date'] ?? today(config('app.timezone')); $date = $data['date'] ?? today(config('app.timezone'));
$return = []; $return = [];
$result = $this->repository->searchAccount((string)$query, $types, $this->parameters->get('limit')); $result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit'));
// TODO this code is duplicated in the V2 Autocomplete controller, which means this code is due to be deprecated. // TODO this code is duplicated in the V2 Autocomplete controller, which means this code is due to be deprecated.
$defaultCurrency = app('amount')->getDefaultCurrency(); $defaultCurrency = app('amount')->getDefaultCurrency();
@@ -89,20 +90,20 @@ class AccountController extends Controller
$currency = $this->repository->getAccountCurrency($account) ?? $defaultCurrency; $currency = $this->repository->getAccountCurrency($account) ?? $defaultCurrency;
if (in_array($account->accountType->type, $this->balanceTypes, true)) { if (in_array($account->accountType->type, $this->balanceTypes, true)) {
$balance = app('steam')->balance($account, $date); $balance = Steam::finalAccountBalance($account, $date);
$nameWithBalance = sprintf( $nameWithBalance = sprintf(
'%s (%s)', '%s (%s)',
$account->name, $account->name,
app('amount')->formatAnything($currency, $balance, false) app('amount')->formatAnything($currency, $balance['balance'], false)
); );
} }
$return[] = [ $return[] = [
'id' => (string)$account->id, 'id' => (string) $account->id,
'name' => $account->name, 'name' => $account->name,
'name_with_balance' => $nameWithBalance, 'name_with_balance' => $nameWithBalance,
'type' => $account->accountType->type, 'type' => $account->accountType->type,
'currency_id' => (string)$currency->id, 'currency_id' => (string) $currency->id,
'currency_name' => $currency->name, 'currency_name' => $currency->name,
'currency_code' => $currency->code, 'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol, 'currency_symbol' => $currency->symbol,
@@ -115,8 +116,8 @@ class AccountController extends Controller
$return, $return,
static function (array $left, array $right) { static function (array $left, array $right) {
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE]; $order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
$posA = (int)array_search($left['type'], $order, true); $posA = (int) array_search($left['type'], $order, true);
$posB = (int)array_search($right['type'], $order, true); $posB = (int) array_search($right['type'], $order, true);
return $posA - $posB; return $posA - $posB;
} }

View File

@@ -67,7 +67,7 @@ class BillController extends Controller
$filtered = $result->map( $filtered = $result->map(
static function (Bill $item) { static function (Bill $item) {
return [ return [
'id' => (string)$item->id, 'id' => (string) $item->id,
'name' => $item->name, 'name' => $item->name,
'active' => $item->active, 'active' => $item->active,
]; ];

View File

@@ -67,7 +67,7 @@ class BudgetController extends Controller
$filtered = $result->map( $filtered = $result->map(
static function (Budget $item) { static function (Budget $item) {
return [ return [
'id' => (string)$item->id, 'id' => (string) $item->id,
'name' => $item->name, 'name' => $item->name,
]; ];
} }

View File

@@ -67,7 +67,7 @@ class CategoryController extends Controller
$filtered = $result->map( $filtered = $result->map(
static function (Category $item) { static function (Category $item) {
return [ return [
'id' => (string)$item->id, 'id' => (string) $item->id,
'name' => $item->name, 'name' => $item->name,
]; ];
} }

View File

@@ -69,7 +69,7 @@ class CurrencyController extends Controller
/** @var TransactionCurrency $currency */ /** @var TransactionCurrency $currency */
foreach ($collection as $currency) { foreach ($collection as $currency) {
$result[] = [ $result[] = [
'id' => (string)$currency->id, 'id' => (string) $currency->id,
'name' => $currency->name, 'name' => $currency->name,
'code' => $currency->code, 'code' => $currency->code,
'symbol' => $currency->symbol, 'symbol' => $currency->symbol,
@@ -95,7 +95,7 @@ class CurrencyController extends Controller
/** @var TransactionCurrency $currency */ /** @var TransactionCurrency $currency */
foreach ($collection as $currency) { foreach ($collection as $currency) {
$result[] = [ $result[] = [
'id' => (string)$currency->id, 'id' => (string) $currency->id,
'name' => sprintf('%s (%s)', $currency->name, $currency->code), 'name' => sprintf('%s (%s)', $currency->name, $currency->code),
'code' => $currency->code, 'code' => $currency->code,
'symbol' => $currency->symbol, 'symbol' => $currency->symbol,

View File

@@ -69,7 +69,7 @@ class ObjectGroupController extends Controller
/** @var ObjectGroup $objectGroup */ /** @var ObjectGroup $objectGroup */
foreach ($result as $objectGroup) { foreach ($result as $objectGroup) {
$return[] = [ $return[] = [
'id' => (string)$objectGroup->id, 'id' => (string) $objectGroup->id,
'name' => $objectGroup->title, 'name' => $objectGroup->title,
'title' => $objectGroup->title, 'title' => $objectGroup->title,
]; ];

View File

@@ -75,14 +75,14 @@ class PiggyBankController extends Controller
$currency = $piggy->transactionCurrency; $currency = $piggy->transactionCurrency;
$objectGroup = $piggy->objectGroups()->first(); $objectGroup = $piggy->objectGroups()->first();
$response[] = [ $response[] = [
'id' => (string)$piggy->id, 'id' => (string) $piggy->id,
'name' => $piggy->name, 'name' => $piggy->name,
'currency_id' => (string)$currency->id, 'currency_id' => (string) $currency->id,
'currency_name' => $currency->name, 'currency_name' => $currency->name,
'currency_code' => $currency->code, 'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol, 'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places, 'currency_decimal_places' => $currency->decimal_places,
'object_group_id' => null === $objectGroup ? null : (string)$objectGroup->id, 'object_group_id' => null === $objectGroup ? null : (string) $objectGroup->id,
'object_group_title' => $objectGroup?->title, 'object_group_title' => $objectGroup?->title,
]; ];
} }
@@ -106,7 +106,7 @@ class PiggyBankController extends Controller
$currentAmount = $this->piggyRepository->getCurrentAmount($piggy); $currentAmount = $this->piggyRepository->getCurrentAmount($piggy);
$objectGroup = $piggy->objectGroups()->first(); $objectGroup = $piggy->objectGroups()->first();
$response[] = [ $response[] = [
'id' => (string)$piggy->id, 'id' => (string) $piggy->id,
'name' => $piggy->name, 'name' => $piggy->name,
'name_with_balance' => sprintf( 'name_with_balance' => sprintf(
'%s (%s / %s)', '%s (%s / %s)',
@@ -114,12 +114,12 @@ class PiggyBankController extends Controller
app('amount')->formatAnything($currency, $currentAmount, false), app('amount')->formatAnything($currency, $currentAmount, false),
app('amount')->formatAnything($currency, $piggy->target_amount, false), app('amount')->formatAnything($currency, $piggy->target_amount, false),
), ),
'currency_id' => (string)$currency->id, 'currency_id' => (string) $currency->id,
'currency_name' => $currency->name, 'currency_name' => $currency->name,
'currency_code' => $currency->code, 'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol, 'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places, 'currency_decimal_places' => $currency->decimal_places,
'object_group_id' => null === $objectGroup ? null : (string)$objectGroup->id, 'object_group_id' => null === $objectGroup ? null : (string) $objectGroup->id,
'object_group_title' => $objectGroup?->title, 'object_group_title' => $objectGroup?->title,
]; ];
} }

View File

@@ -67,7 +67,7 @@ class RecurrenceController extends Controller
/** @var Recurrence $recurrence */ /** @var Recurrence $recurrence */
foreach ($recurrences as $recurrence) { foreach ($recurrences as $recurrence) {
$response[] = [ $response[] = [
'id' => (string)$recurrence->id, 'id' => (string) $recurrence->id,
'name' => $recurrence->title, 'name' => $recurrence->title,
'description' => $recurrence->description, 'description' => $recurrence->description,
]; ];

View File

@@ -66,7 +66,7 @@ class RuleController extends Controller
/** @var Rule $rule */ /** @var Rule $rule */
foreach ($rules as $rule) { foreach ($rules as $rule) {
$response[] = [ $response[] = [
'id' => (string)$rule->id, 'id' => (string) $rule->id,
'name' => $rule->title, 'name' => $rule->title,
'description' => $rule->description, 'description' => $rule->description,
]; ];

View File

@@ -66,7 +66,7 @@ class RuleGroupController extends Controller
/** @var RuleGroup $group */ /** @var RuleGroup $group */
foreach ($groups as $group) { foreach ($groups as $group) {
$response[] = [ $response[] = [
'id' => (string)$group->id, 'id' => (string) $group->id,
'name' => $group->title, 'name' => $group->title,
'description' => $group->description, 'description' => $group->description,
]; ];

View File

@@ -69,7 +69,7 @@ class TagController extends Controller
/** @var Tag $tag */ /** @var Tag $tag */
foreach ($result as $tag) { foreach ($result as $tag) {
$array[] = [ $array[] = [
'id' => (string)$tag->id, 'id' => (string) $tag->id,
'name' => $tag->tag, 'name' => $tag->tag,
'tag' => $tag->tag, 'tag' => $tag->tag,
]; ];

View File

@@ -77,8 +77,8 @@ class TransactionController extends Controller
/** @var TransactionJournal $journal */ /** @var TransactionJournal $journal */
foreach ($filtered as $journal) { foreach ($filtered as $journal) {
$array[] = [ $array[] = [
'id' => (string)$journal->id, 'id' => (string) $journal->id,
'transaction_group_id' => (string)$journal->transaction_group_id, 'transaction_group_id' => (string) $journal->transaction_group_id,
'name' => $journal->description, 'name' => $journal->description,
'description' => $journal->description, 'description' => $journal->description,
]; ];
@@ -97,7 +97,7 @@ class TransactionController extends Controller
$result = new Collection(); $result = new Collection();
if (is_numeric($data['query'])) { if (is_numeric($data['query'])) {
// search for group, not journal. // search for group, not journal.
$firstResult = $this->groupRepository->find((int)$data['query']); $firstResult = $this->groupRepository->find((int) $data['query']);
if (null !== $firstResult) { if (null !== $firstResult) {
// group may contain multiple journals, each a result: // group may contain multiple journals, each a result:
foreach ($firstResult->transactionJournals as $journal) { foreach ($firstResult->transactionJournals as $journal) {
@@ -115,8 +115,8 @@ class TransactionController extends Controller
/** @var TransactionJournal $journal */ /** @var TransactionJournal $journal */
foreach ($result as $journal) { foreach ($result as $journal) {
$array[] = [ $array[] = [
'id' => (string)$journal->id, 'id' => (string) $journal->id,
'transaction_group_id' => (string)$journal->transaction_group_id, 'transaction_group_id' => (string) $journal->transaction_group_id,
'name' => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description), 'name' => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description),
'description' => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description), 'description' => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description),
]; ];

View File

@@ -66,7 +66,7 @@ class TransactionTypeController extends Controller
foreach ($types as $type) { foreach ($types as $type) {
// different key for consistency. // different key for consistency.
$array[] = [ $array[] = [
'id' => (string)$type->id, 'id' => (string) $type->id,
'name' => $type->type, 'name' => $type->type,
'type' => $type->type, 'type' => $type->type,
]; ];

View File

@@ -104,7 +104,7 @@ class AccountController extends Controller
} }
$currentSet = [ $currentSet = [
'label' => $account->name, 'label' => $account->name,
'currency_id' => (string)$currency->id, 'currency_id' => (string) $currency->id,
'currency_code' => $currency->code, 'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol, 'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places, 'currency_decimal_places' => $currency->decimal_places,
@@ -116,13 +116,13 @@ class AccountController extends Controller
]; ];
// TODO this code is also present in the V2 chart account controller so this method is due to be deprecated. // TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
$currentStart = clone $start; $currentStart = clone $start;
$range = app('steam')->balanceInRange($account, $start, clone $end); $range = app('steam')->finalAccountBalanceInRange($account, $start, clone $end, $this->convertToNative);
// 2022-10-11 this method no longer converts to float. // 2022-10-11 this method no longer converts to float.
$previous = array_values($range)[0]; $previous = array_values($range)[0];
while ($currentStart <= $end) { while ($currentStart <= $end) {
$format = $currentStart->format('Y-m-d'); $format = $currentStart->format('Y-m-d');
$label = $currentStart->toAtomString(); $label = $currentStart->toAtomString();
$balance = array_key_exists($format, $range) ? $range[$format] : $previous; $balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
$previous = $balance; $previous = $balance;
$currentStart->addDay(); $currentStart->addDay();
$currentSet['entries'][$label] = $balance; $currentSet['entries'][$label] = $balance;

View File

@@ -50,11 +50,12 @@ abstract class Controller extends BaseController
use DispatchesJobs; use DispatchesJobs;
use ValidatesRequests; use ValidatesRequests;
protected const string CONTENT_TYPE = 'application/vnd.api+json'; protected const string CONTENT_TYPE = 'application/vnd.api+json';
/** @var array<int, string> */ /** @var array<int, string> */
protected array $allowedSort; protected array $allowedSort;
protected ParameterBag $parameters; protected ParameterBag $parameters;
protected bool $convertToNative = false;
/** /**
* Controller constructor. * Controller constructor.
@@ -67,8 +68,10 @@ abstract class Controller extends BaseController
function ($request, $next) { function ($request, $next) {
$this->parameters = $this->getParameters(); $this->parameters = $this->getParameters();
if (auth()->check()) { if (auth()->check()) {
$language = app('steam')->getLanguage(); $language = app('steam')->getLanguage();
$this->convertToNative = app('preferences')->get('convert_to_native', false)->data;
app()->setLocale($language); app()->setLocale($language);
} }
return $next($request); return $next($request);
@@ -82,7 +85,7 @@ abstract class Controller extends BaseController
private function getParameters(): ParameterBag private function getParameters(): ParameterBag
{ {
$bag = new ParameterBag(); $bag = new ParameterBag();
$page = (int)request()->get('page'); $page = (int) request()->get('page');
if ($page < 1) { if ($page < 1) {
$page = 1; $page = 1;
} }
@@ -107,13 +110,13 @@ abstract class Controller extends BaseController
$obj = null; $obj = null;
if (null !== $date) { if (null !== $date) {
try { try {
$obj = Carbon::parse((string)$date); $obj = Carbon::parse((string) $date);
} catch (InvalidDateException|InvalidFormatException $e) { } catch (InvalidDateException|InvalidFormatException $e) {
// don't care // don't care
app('log')->warning( app('log')->warning(
sprintf( sprintf(
'Ignored invalid date "%s" in API controller parameter check: %s', 'Ignored invalid date "%s" in API controller parameter check: %s',
substr((string)$date, 0, 20), substr((string) $date, 0, 20),
$e->getMessage() $e->getMessage()
) )
); );
@@ -134,7 +137,7 @@ abstract class Controller extends BaseController
$value = null; $value = null;
} }
if (null !== $value) { if (null !== $value) {
$bag->set($integer, (int)$value); $bag->set($integer, (int) $value);
} }
if (null === $value if (null === $value
&& 'limit' === $integer // @phpstan-ignore-line && 'limit' === $integer // @phpstan-ignore-line
@@ -144,7 +147,7 @@ abstract class Controller extends BaseController
$user = auth()->user(); $user = auth()->user();
/** @var Preference $pageSize */ /** @var Preference $pageSize */
$pageSize = (int)app('preferences')->getForUser($user, 'listPageSize', 50)->data; $pageSize = (int) app('preferences')->getForUser($user, 'listPageSize', 50)->data;
$bag->set($integer, $pageSize); $bag->set($integer, $pageSize);
} }
} }
@@ -158,7 +161,7 @@ abstract class Controller extends BaseController
$sortParameters = []; $sortParameters = [];
try { try {
$param = (string)request()->query->get('sort'); $param = (string) request()->query->get('sort');
} catch (BadRequestException $e) { } catch (BadRequestException $e) {
app('log')->error('Request field "sort" contains a non-scalar value. Value set to NULL.'); app('log')->error('Request field "sort" contains a non-scalar value. Value set to NULL.');
app('log')->error($e->getMessage()); app('log')->error($e->getMessage());

View File

@@ -70,8 +70,8 @@ class TransactionController extends Controller
// to respond to what is in the $query. // to respond to what is in the $query.
// this is OK because only one thing can be in the query at the moment. // this is OK because only one thing can be in the query at the moment.
if ($this->isUpdateTransactionAccount($params)) { if ($this->isUpdateTransactionAccount($params)) {
$original = $this->repository->find((int)$params['where']['account_id']); $original = $this->repository->find((int) $params['where']['account_id']);
$destination = $this->repository->find((int)$params['update']['account_id']); $destination = $this->repository->find((int) $params['update']['account_id']);
/** @var AccountDestroyService $service */ /** @var AccountDestroyService $service */
$service = app(AccountDestroyService::class); $service = app(AccountDestroyService::class);

View File

@@ -88,7 +88,7 @@ class ExportController extends Controller
->header('Expires', '0') ->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public') ->header('Pragma', 'public')
->header('Content-Length', (string)strlen($data[$key])) ->header('Content-Length', (string) strlen($data[$key]))
; ;
return $response; return $response;

View File

@@ -29,7 +29,6 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\Models\Category; use FireflyIII\Models\Category;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\Recurrence; use FireflyIII\Models\Recurrence;
use FireflyIII\Models\Rule; use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleGroup; use FireflyIII\Models\RuleGroup;

View File

@@ -79,11 +79,11 @@ class AccountController extends Controller
/** @var array $expense */ /** @var array $expense */
foreach ($expenses as $expense) { foreach ($expenses as $expense) {
$result[] = [ $result[] = [
'id' => (string)$expense['id'], 'id' => (string) $expense['id'],
'name' => $expense['name'], 'name' => $expense['name'],
'difference' => $expense['sum'], 'difference' => $expense['sum'],
'difference_float' => (float)$expense['sum'], // intentional float 'difference_float' => (float) $expense['sum'], // intentional float
'currency_id' => (string)$expense['currency_id'], 'currency_id' => (string) $expense['currency_id'],
'currency_code' => $expense['currency_code'], 'currency_code' => $expense['currency_code'],
]; ];
} }
@@ -107,11 +107,11 @@ class AccountController extends Controller
/** @var array $expense */ /** @var array $expense */
foreach ($expenses as $expense) { foreach ($expenses as $expense) {
$result[] = [ $result[] = [
'id' => (string)$expense['id'], 'id' => (string) $expense['id'],
'name' => $expense['name'], 'name' => $expense['name'],
'difference' => $expense['sum'], 'difference' => $expense['sum'],
'difference_float' => (float)$expense['sum'], // intentional float 'difference_float' => (float) $expense['sum'], // intentional float
'currency_id' => (string)$expense['currency_id'], 'currency_id' => (string) $expense['currency_id'],
'currency_code' => $expense['currency_code'], 'currency_code' => $expense['currency_code'],
]; ];
} }

View File

@@ -81,33 +81,33 @@ class BillController extends Controller
$genericSet = $collector->getExtractedJournals(); $genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) { foreach ($genericSet as $journal) {
$billId = (int)$journal['bill_id']; $billId = (int) $journal['bill_id'];
$currencyId = (int)$journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
$key = sprintf('%d-%d', $billId, $currencyId); $key = sprintf('%d-%d', $billId, $currencyId);
$foreignKey = sprintf('%d-%d', $billId, $foreignCurrencyId); $foreignKey = sprintf('%d-%d', $billId, $foreignCurrencyId);
if (0 !== $currencyId) { if (0 !== $currencyId) {
$response[$key] ??= [ $response[$key] ??= [
'id' => (string)$billId, 'id' => (string) $billId,
'name' => $journal['bill_name'], 'name' => $journal['bill_name'],
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$key]['difference'] = bcadd($response[$key]['difference'], $journal['amount']); $response[$key]['difference'] = bcadd($response[$key]['difference'], $journal['amount']);
$response[$key]['difference_float'] = (float)$response[$key]['difference']; // intentional float $response[$key]['difference_float'] = (float) $response[$key]['difference']; // intentional float
} }
if (0 !== $foreignCurrencyId) { if (0 !== $foreignCurrencyId) {
$response[$foreignKey] ??= [ $response[$foreignKey] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignKey]['difference'] = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']); $response[$foreignKey]['difference'] = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']);
$response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; // intentional float $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
} }
} }
@@ -135,28 +135,28 @@ class BillController extends Controller
$genericSet = $collector->getExtractedJournals(); $genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) { foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
if (0 !== $currencyId) { if (0 !== $currencyId) {
$response[$currencyId] ??= [ $response[$currencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']);
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // intentional float $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float
} }
if (0 !== $foreignCurrencyId) { if (0 !== $foreignCurrencyId) {
$response[$foreignCurrencyId] ??= [ $response[$foreignCurrencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']); $response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // intentional float $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; // intentional float
} }
} }

View File

@@ -85,11 +85,11 @@ class BudgetController extends Controller
/** @var array $expense */ /** @var array $expense */
foreach ($expenses as $expense) { foreach ($expenses as $expense) {
$result[] = [ $result[] = [
'id' => (string)$budget->id, 'id' => (string) $budget->id,
'name' => $budget->name, 'name' => $budget->name,
'difference' => $expense['sum'], 'difference' => $expense['sum'],
'difference_float' => (float)$expense['sum'], // intentional float 'difference_float' => (float) $expense['sum'], // intentional float
'currency_id' => (string)$expense['currency_id'], 'currency_id' => (string) $expense['currency_id'],
'currency_code' => $expense['currency_code'], 'currency_code' => $expense['currency_code'],
]; ];
} }
@@ -114,8 +114,8 @@ class BudgetController extends Controller
foreach ($expenses as $expense) { foreach ($expenses as $expense) {
$result[] = [ $result[] = [
'difference' => $expense['sum'], 'difference' => $expense['sum'],
'difference_float' => (float)$expense['sum'], // intentional float 'difference_float' => (float) $expense['sum'], // intentional float
'currency_id' => (string)$expense['currency_id'], 'currency_id' => (string) $expense['currency_id'],
'currency_code' => $expense['currency_code'], 'currency_code' => $expense['currency_code'],
]; ];
} }

View File

@@ -85,11 +85,11 @@ class CategoryController extends Controller
/** @var array $expense */ /** @var array $expense */
foreach ($expenses as $expense) { foreach ($expenses as $expense) {
$result[] = [ $result[] = [
'id' => (string)$category->id, 'id' => (string) $category->id,
'name' => $category->name, 'name' => $category->name,
'difference' => $expense['sum'], 'difference' => $expense['sum'],
'difference_float' => (float)$expense['sum'], // intentional float 'difference_float' => (float) $expense['sum'], // intentional float
'currency_id' => (string)$expense['currency_id'], 'currency_id' => (string) $expense['currency_id'],
'currency_code' => $expense['currency_code'], 'currency_code' => $expense['currency_code'],
]; ];
} }
@@ -114,8 +114,8 @@ class CategoryController extends Controller
foreach ($expenses as $expense) { foreach ($expenses as $expense) {
$result[] = [ $result[] = [
'difference' => $expense['sum'], 'difference' => $expense['sum'],
'difference_float' => (float)$expense['sum'], // intentional float 'difference_float' => (float) $expense['sum'], // intentional float
'currency_id' => (string)$expense['currency_id'], 'currency_id' => (string) $expense['currency_id'],
'currency_code' => $expense['currency_code'], 'currency_code' => $expense['currency_code'],
]; ];
} }

View File

@@ -51,28 +51,28 @@ class PeriodController extends Controller
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts); $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
$genericSet = $collector->getExtractedJournals(); $genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) { foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
if (0 !== $currencyId) { if (0 !== $currencyId) {
$response[$currencyId] ??= [ $response[$currencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']);
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // intentional float $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float
} }
if (0 !== $foreignCurrencyId) { if (0 !== $foreignCurrencyId) {
$response[$foreignCurrencyId] ??= [ $response[$foreignCurrencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']); $response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // intentional float $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; // intentional float
} }
} }

View File

@@ -75,28 +75,28 @@ class TagController extends Controller
$genericSet = $collector->getExtractedJournals(); $genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) { foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
if (0 !== $currencyId) { if (0 !== $currencyId) {
$response[$currencyId] ??= [ $response[$currencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']);
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // float but on purpose. $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
} }
if (0 !== $foreignCurrencyId) { if (0 !== $foreignCurrencyId) {
$response[$foreignCurrencyId] ??= [ $response[$foreignCurrencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']); $response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // float but on purpose. $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; // float but on purpose.
} }
} }
@@ -130,8 +130,8 @@ class TagController extends Controller
/** @var array $journal */ /** @var array $journal */
foreach ($genericSet as $journal) { foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
/** @var array $tag */ /** @var array $tag */
foreach ($journal['tags'] as $tag) { foreach ($journal['tags'] as $tag) {
@@ -142,15 +142,15 @@ class TagController extends Controller
// on currency ID // on currency ID
if (0 !== $currencyId) { if (0 !== $currencyId) {
$response[$key] ??= [ $response[$key] ??= [
'id' => (string)$tagId, 'id' => (string) $tagId,
'name' => $tag['name'], 'name' => $tag['name'],
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$key]['difference'] = bcadd($response[$key]['difference'], $journal['amount']); $response[$key]['difference'] = bcadd($response[$key]['difference'], $journal['amount']);
$response[$key]['difference_float'] = (float)$response[$key]['difference']; // float but on purpose. $response[$key]['difference_float'] = (float) $response[$key]['difference']; // float but on purpose.
} }
// on foreign ID // on foreign ID
@@ -158,11 +158,11 @@ class TagController extends Controller
$response[$foreignKey] = $journal[$foreignKey] ?? [ $response[$foreignKey] = $journal[$foreignKey] ?? [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignKey]['difference'] = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']); $response[$foreignKey]['difference'] = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']);
$response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; // float but on purpose. $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // float but on purpose.
} }
} }
} }

View File

@@ -79,11 +79,11 @@ class AccountController extends Controller
/** @var array $entry */ /** @var array $entry */
foreach ($income as $entry) { foreach ($income as $entry) {
$result[] = [ $result[] = [
'id' => (string)$entry['id'], 'id' => (string) $entry['id'],
'name' => $entry['name'], 'name' => $entry['name'],
'difference' => $entry['sum'], 'difference' => $entry['sum'],
'difference_float' => (float)$entry['sum'], // float but on purpose. 'difference_float' => (float) $entry['sum'], // float but on purpose.
'currency_id' => (string)$entry['currency_id'], 'currency_id' => (string) $entry['currency_id'],
'currency_code' => $entry['currency_code'], 'currency_code' => $entry['currency_code'],
]; ];
} }
@@ -107,11 +107,11 @@ class AccountController extends Controller
/** @var array $entry */ /** @var array $entry */
foreach ($income as $entry) { foreach ($income as $entry) {
$result[] = [ $result[] = [
'id' => (string)$entry['id'], 'id' => (string) $entry['id'],
'name' => $entry['name'], 'name' => $entry['name'],
'difference' => $entry['sum'], 'difference' => $entry['sum'],
'difference_float' => (float)$entry['sum'], // float but on purpose. 'difference_float' => (float) $entry['sum'], // float but on purpose.
'currency_id' => (string)$entry['currency_id'], 'currency_id' => (string) $entry['currency_id'],
'currency_code' => $entry['currency_code'], 'currency_code' => $entry['currency_code'],
]; ];
} }

View File

@@ -85,11 +85,11 @@ class CategoryController extends Controller
/** @var array $expense */ /** @var array $expense */
foreach ($expenses as $expense) { foreach ($expenses as $expense) {
$result[] = [ $result[] = [
'id' => (string)$category->id, 'id' => (string) $category->id,
'name' => $category->name, 'name' => $category->name,
'difference' => $expense['sum'], 'difference' => $expense['sum'],
'difference_float' => (float)$expense['sum'], // float but on purpose. 'difference_float' => (float) $expense['sum'], // float but on purpose.
'currency_id' => (string)$expense['currency_id'], 'currency_id' => (string) $expense['currency_id'],
'currency_code' => $expense['currency_code'], 'currency_code' => $expense['currency_code'],
]; ];
} }
@@ -114,8 +114,8 @@ class CategoryController extends Controller
foreach ($expenses as $expense) { foreach ($expenses as $expense) {
$result[] = [ $result[] = [
'difference' => $expense['sum'], 'difference' => $expense['sum'],
'difference_float' => (float)$expense['sum'], // float but on purpose. 'difference_float' => (float) $expense['sum'], // float but on purpose.
'currency_id' => (string)$expense['currency_id'], 'currency_id' => (string) $expense['currency_id'],
'currency_code' => $expense['currency_code'], 'currency_code' => $expense['currency_code'],
]; ];
} }

View File

@@ -51,31 +51,31 @@ class PeriodController extends Controller
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts); $collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts);
$genericSet = $collector->getExtractedJournals(); $genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) { foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
if (0 !== $currencyId) { if (0 !== $currencyId) {
$response[$currencyId] ??= [ $response[$currencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount'])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // float but on purpose. $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
} }
if (0 !== $foreignCurrencyId) { if (0 !== $foreignCurrencyId) {
$response[$foreignCurrencyId] ??= [ $response[$foreignCurrencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignCurrencyId]['difference'] = bcadd( $response[$foreignCurrencyId]['difference'] = bcadd(
$response[$foreignCurrencyId]['difference'], $response[$foreignCurrencyId]['difference'],
app('steam')->positive($journal['foreign_amount']) app('steam')->positive($journal['foreign_amount'])
); );
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // float but on purpose. $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; // float but on purpose.
} }
} }

View File

@@ -76,31 +76,31 @@ class TagController extends Controller
$genericSet = $collector->getExtractedJournals(); $genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) { foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
if (0 !== $currencyId) { if (0 !== $currencyId) {
$response[$currencyId] ??= [ $response[$currencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount'])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
} }
if (0 !== $foreignCurrencyId) { if (0 !== $foreignCurrencyId) {
$response[$foreignCurrencyId] ??= [ $response[$foreignCurrencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignCurrencyId]['difference'] = bcadd( $response[$foreignCurrencyId]['difference'] = bcadd(
$response[$foreignCurrencyId]['difference'], $response[$foreignCurrencyId]['difference'],
app('steam')->positive($journal['foreign_amount']) app('steam')->positive($journal['foreign_amount'])
); );
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference'];
} }
} }
@@ -134,8 +134,8 @@ class TagController extends Controller
/** @var array $journal */ /** @var array $journal */
foreach ($genericSet as $journal) { foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
/** @var array $tag */ /** @var array $tag */
foreach ($journal['tags'] as $tag) { foreach ($journal['tags'] as $tag) {
@@ -146,15 +146,15 @@ class TagController extends Controller
// on currency ID // on currency ID
if (0 !== $currencyId) { if (0 !== $currencyId) {
$response[$key] ??= [ $response[$key] ??= [
'id' => (string)$tagId, 'id' => (string) $tagId,
'name' => $tag['name'], 'name' => $tag['name'],
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$key]['difference'] = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount'])); $response[$key]['difference'] = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount']));
$response[$key]['difference_float'] = (float)$response[$key]['difference']; $response[$key]['difference_float'] = (float) $response[$key]['difference'];
} }
// on foreign ID // on foreign ID
@@ -162,14 +162,14 @@ class TagController extends Controller
$response[$foreignKey] = $journal[$foreignKey] ?? [ $response[$foreignKey] = $journal[$foreignKey] ?? [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignKey]['difference'] = bcadd( $response[$foreignKey]['difference'] = bcadd(
$response[$foreignKey]['difference'], $response[$foreignKey]['difference'],
app('steam')->positive($journal['foreign_amount']) app('steam')->positive($journal['foreign_amount'])
); );
$response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
} }
} }
} }

View File

@@ -85,11 +85,11 @@ class CategoryController extends Controller
/** @var array $expense */ /** @var array $expense */
foreach ($expenses as $expense) { foreach ($expenses as $expense) {
$result[] = [ $result[] = [
'id' => (string)$category->id, 'id' => (string) $category->id,
'name' => $category->name, 'name' => $category->name,
'difference' => $expense['sum'], 'difference' => $expense['sum'],
'difference_float' => (float)$expense['sum'], 'difference_float' => (float) $expense['sum'],
'currency_id' => (string)$expense['currency_id'], 'currency_id' => (string) $expense['currency_id'],
'currency_code' => $expense['currency_code'], 'currency_code' => $expense['currency_code'],
]; ];
} }
@@ -114,8 +114,8 @@ class CategoryController extends Controller
foreach ($expenses as $expense) { foreach ($expenses as $expense) {
$result[] = [ $result[] = [
'difference' => $expense['sum'], 'difference' => $expense['sum'],
'difference_float' => (float)$expense['sum'], 'difference_float' => (float) $expense['sum'],
'currency_id' => (string)$expense['currency_id'], 'currency_id' => (string) $expense['currency_id'],
'currency_code' => $expense['currency_code'], 'currency_code' => $expense['currency_code'],
]; ];
} }

View File

@@ -51,31 +51,31 @@ class PeriodController extends Controller
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts); $collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
$genericSet = $collector->getExtractedJournals(); $genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) { foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
if (0 !== $currencyId) { if (0 !== $currencyId) {
$response[$currencyId] ??= [ $response[$currencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount'])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
} }
if (0 !== $foreignCurrencyId) { if (0 !== $foreignCurrencyId) {
$response[$foreignCurrencyId] ??= [ $response[$foreignCurrencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignCurrencyId]['difference'] = bcadd( $response[$foreignCurrencyId]['difference'] = bcadd(
$response[$foreignCurrencyId]['difference'], $response[$foreignCurrencyId]['difference'],
app('steam')->positive($journal['foreign_amount']) app('steam')->positive($journal['foreign_amount'])
); );
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference'];
} }
} }

View File

@@ -74,31 +74,31 @@ class TagController extends Controller
$genericSet = $collector->getExtractedJournals(); $genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) { foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
if (0 !== $currencyId) { if (0 !== $currencyId) {
$response[$currencyId] ??= [ $response[$currencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount'])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
} }
if (0 !== $foreignCurrencyId) { if (0 !== $foreignCurrencyId) {
$response[$foreignCurrencyId] ??= [ $response[$foreignCurrencyId] ??= [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignCurrencyId]['difference'] = bcadd( $response[$foreignCurrencyId]['difference'] = bcadd(
$response[$foreignCurrencyId]['difference'], $response[$foreignCurrencyId]['difference'],
app('steam')->positive($journal['foreign_amount']) app('steam')->positive($journal['foreign_amount'])
); );
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference'];
} }
} }
@@ -132,8 +132,8 @@ class TagController extends Controller
/** @var array $journal */ /** @var array $journal */
foreach ($genericSet as $journal) { foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
/** @var array $tag */ /** @var array $tag */
foreach ($journal['tags'] as $tag) { foreach ($journal['tags'] as $tag) {
@@ -144,15 +144,15 @@ class TagController extends Controller
// on currency ID // on currency ID
if (0 !== $currencyId) { if (0 !== $currencyId) {
$response[$key] ??= [ $response[$key] ??= [
'id' => (string)$tagId, 'id' => (string) $tagId,
'name' => $tag['name'], 'name' => $tag['name'],
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$key]['difference'] = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount'])); $response[$key]['difference'] = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount']));
$response[$key]['difference_float'] = (float)$response[$key]['difference']; $response[$key]['difference_float'] = (float) $response[$key]['difference'];
} }
// on foreign ID // on foreign ID
@@ -160,14 +160,14 @@ class TagController extends Controller
$response[$foreignKey] = $journal[$foreignKey] ?? [ $response[$foreignKey] = $journal[$foreignKey] ?? [
'difference' => '0', 'difference' => '0',
'difference_float' => 0, 'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignKey]['difference'] = bcadd( $response[$foreignKey]['difference'] = bcadd(
$response[$foreignKey]['difference'], $response[$foreignKey]['difference'],
app('steam')->positive($journal['foreign_amount']) app('steam')->positive($journal['foreign_amount'])
); );
$response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; // intentional float $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
} }
} }
} }

View File

@@ -105,7 +105,7 @@ class ShowController extends Controller
->header('Expires', '0') ->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public') ->header('Pragma', 'public')
->header('Content-Length', (string)strlen($content)) ->header('Content-Length', (string) strlen($content))
; ;
return $response; return $response;

View File

@@ -59,6 +59,38 @@ class ListController extends Controller
); );
} }
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAccountByPiggyBank
*
* List single resource.
*
* @throws FireflyException
*/
public function accounts(PiggyBank $piggyBank): JsonResponse
{
// types to get, page size:
$pageSize = $this->parameters->get('limit');
$manager = $this->getManager();
$collection = $piggyBank->accounts;
$count = $collection->count();
$events = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($events, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.piggy-banks.accounts', [$piggyBank->id]).$this->buildParams());
/** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($events, $transformer, 'accounts');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
/** /**
* This endpoint is documented at: * This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAttachmentByPiggyBank * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAttachmentByPiggyBank
@@ -119,36 +151,4 @@ class ListController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
} }
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAccountByPiggyBank
*
* List single resource.
*
* @throws FireflyException
*/
public function accounts(PiggyBank $piggyBank): JsonResponse
{
// types to get, page size:
$pageSize = $this->parameters->get('limit');
$manager = $this->getManager();
$collection = $piggyBank->accounts;
$count = $collection->count();
$events = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($events, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.piggy-banks.accounts', [$piggyBank->id]).$this->buildParams());
/** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($events, $transformer, 'accounts');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
} }

View File

@@ -91,7 +91,7 @@ class ListController extends Controller
// filter list on currency preference: // filter list on currency preference:
$collection = $unfiltered->filter( $collection = $unfiltered->filter(
static function (Account $account) use ($currency, $accountRepository) { static function (Account $account) use ($currency, $accountRepository) {
$currencyId = (int)$accountRepository->getMetaValue($account, 'currency_id'); $currencyId = (int) $accountRepository->getMetaValue($account, 'currency_id');
return $currencyId === $currency->id; return $currencyId === $currency->id;
} }

View File

@@ -63,8 +63,8 @@ class AccountController extends Controller
public function search(Request $request): JsonResponse|Response public function search(Request $request): JsonResponse|Response
{ {
$manager = $this->getManager(); $manager = $this->getManager();
$query = trim((string)$request->get('query')); $query = trim((string) $request->get('query'));
$field = trim((string)$request->get('field')); $field = trim((string) $request->get('field'));
$type = $request->get('type') ?? 'all'; $type = $request->get('type') ?? 'all';
if ('' === $query || !in_array($field, $this->validFields, true)) { if ('' === $query || !in_array($field, $this->validFields, true)) {
return response(null, 422); return response(null, 422);

View File

@@ -47,8 +47,8 @@ class TransactionController extends Controller
public function search(Request $request, SearchInterface $searcher): JsonResponse public function search(Request $request, SearchInterface $searcher): JsonResponse
{ {
$manager = $this->getManager(); $manager = $this->getManager();
$fullQuery = (string)$request->get('query'); $fullQuery = (string) $request->get('query');
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page'); $page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page');
$pageSize = $this->parameters->get('limit'); $pageSize = $this->parameters->get('limit');
$searcher->parseQuery($fullQuery); $searcher->parseQuery($fullQuery);
$searcher->setPage($page); $searcher->setPage($page);

View File

@@ -27,19 +27,21 @@ namespace FireflyIII\Api\V1\Controllers\Summary;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Data\DateRequest; use FireflyIII\Api\V1\Requests\Data\DateRequest;
use FireflyIII\Enums\AccountTypeEnum;
use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Report\NetWorthInterface; use FireflyIII\Helpers\Report\NetWorthInterface;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface; use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface; use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
/** /**
* Class BasicController * Class BasicController
@@ -120,48 +122,53 @@ class BasicController extends Controller
private function getBalanceInformation(Carbon $start, Carbon $end): array private function getBalanceInformation(Carbon $start, Carbon $end): array
{ {
// some config settings
$convertToNative = app('preferences')->get('convert_to_native', false)->data;
$default = app('amount')->getDefaultCurrency();
// prep some arrays: // prep some arrays:
$incomes = []; $incomes = [];
$expenses = []; $expenses = [];
$sums = []; $sums = [];
$return = []; $return = [];
// collect income of user using the new group collector. // collect income of user using the new group collector.
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::DEPOSIT->value]); $collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::DEPOSIT->value]);
$set = $collector->getExtractedJournals(); $set = $collector->getExtractedJournals();
/** @var array $transactionJournal */ /** @var array $journal */
foreach ($set as $transactionJournal) { foreach ($set as $journal) {
$currencyId = (int)$transactionJournal['currency_id']; $currencyId = $convertToNative ? $default->id : (int) $journal['currency_id'];
$amount = Amount::getAmountFromJournal($journal);
$incomes[$currencyId] ??= '0'; $incomes[$currencyId] ??= '0';
$incomes[$currencyId] = bcadd( $incomes[$currencyId] = bcadd(
$incomes[$currencyId], $incomes[$currencyId],
bcmul($transactionJournal['amount'], '-1') bcmul($amount, '-1')
); );
$sums[$currencyId] ??= '0'; $sums[$currencyId] ??= '0';
$sums[$currencyId] = bcadd($sums[$currencyId], bcmul($transactionJournal['amount'], '-1')); $sums[$currencyId] = bcadd($sums[$currencyId], bcmul($amount, '-1'));
} }
// collect expenses of user using the new group collector. // collect expenses of user using the new group collector.
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::WITHDRAWAL->value]); $collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
$set = $collector->getExtractedJournals(); $set = $collector->getExtractedJournals();
/** @var array $transactionJournal */ /** @var array $journal */
foreach ($set as $transactionJournal) { foreach ($set as $journal) {
$currencyId = (int)$transactionJournal['currency_id']; $currencyId = $convertToNative ? $default->id : (int) $journal['currency_id'];
$amount = Amount::getAmountFromJournal($journal);
$expenses[$currencyId] ??= '0'; $expenses[$currencyId] ??= '0';
$expenses[$currencyId] = bcadd($expenses[$currencyId], $transactionJournal['amount']); $expenses[$currencyId] = bcadd($expenses[$currencyId], $amount);
$sums[$currencyId] ??= '0'; $sums[$currencyId] ??= '0';
$sums[$currencyId] = bcadd($sums[$currencyId], $transactionJournal['amount']); $sums[$currencyId] = bcadd($sums[$currencyId], $amount);
} }
// format amounts: // format amounts:
$keys = array_keys($sums); $keys = array_keys($sums);
foreach ($keys as $currencyId) { foreach ($keys as $currencyId) {
$currency = $this->currencyRepos->find($currencyId); $currency = $this->currencyRepos->find($currencyId);
if (null === $currency) { if (null === $currency) {
@@ -172,7 +179,7 @@ class BasicController extends Controller
'key' => sprintf('balance-in-%s', $currency->code), 'key' => sprintf('balance-in-%s', $currency->code),
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]), 'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => $sums[$currencyId] ?? '0', 'monetary_value' => $sums[$currencyId] ?? '0',
'currency_id' => (string)$currency->id, 'currency_id' => (string) $currency->id,
'currency_code' => $currency->code, 'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol, 'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places, 'currency_decimal_places' => $currency->decimal_places,
@@ -185,7 +192,7 @@ class BasicController extends Controller
'key' => sprintf('spent-in-%s', $currency->code), 'key' => sprintf('spent-in-%s', $currency->code),
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]), 'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => $expenses[$currencyId] ?? '0', 'monetary_value' => $expenses[$currencyId] ?? '0',
'currency_id' => (string)$currency->id, 'currency_id' => (string) $currency->id,
'currency_code' => $currency->code, 'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol, 'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places, 'currency_decimal_places' => $currency->decimal_places,
@@ -197,7 +204,7 @@ class BasicController extends Controller
'key' => sprintf('earned-in-%s', $currency->code), 'key' => sprintf('earned-in-%s', $currency->code),
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]), 'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => $incomes[$currencyId] ?? '0', 'monetary_value' => $incomes[$currencyId] ?? '0',
'currency_id' => (string)$currency->id, 'currency_id' => (string) $currency->id,
'currency_code' => $currency->code, 'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol, 'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places, 'currency_decimal_places' => $currency->decimal_places,
@@ -231,7 +238,7 @@ class BasicController extends Controller
'key' => sprintf('bills-paid-in-%s', $info['code']), 'key' => sprintf('bills-paid-in-%s', $info['code']),
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]), 'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]),
'monetary_value' => $amount, 'monetary_value' => $amount,
'currency_id' => (string)$info['id'], 'currency_id' => (string) $info['id'],
'currency_code' => $info['code'], 'currency_code' => $info['code'],
'currency_symbol' => $info['symbol'], 'currency_symbol' => $info['symbol'],
'currency_decimal_places' => $info['decimal_places'], 'currency_decimal_places' => $info['decimal_places'],
@@ -250,7 +257,7 @@ class BasicController extends Controller
'key' => sprintf('bills-unpaid-in-%s', $info['code']), 'key' => sprintf('bills-unpaid-in-%s', $info['code']),
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]), 'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]),
'monetary_value' => $amount, 'monetary_value' => $amount,
'currency_id' => (string)$info['id'], 'currency_id' => (string) $info['id'],
'currency_code' => $info['code'], 'currency_code' => $info['code'],
'currency_symbol' => $info['symbol'], 'currency_symbol' => $info['symbol'],
'currency_decimal_places' => $info['decimal_places'], 'currency_decimal_places' => $info['decimal_places'],
@@ -274,24 +281,27 @@ class BasicController extends Controller
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end); $available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
$budgets = $this->budgetRepository->getActiveBudgets(); $budgets = $this->budgetRepository->getActiveBudgets();
$spent = $this->opsRepository->sumExpenses($start, $end, null, $budgets); $spent = $this->opsRepository->sumExpenses($start, $end, null, $budgets);
$days = (int) $today->diffInDays($end, true) + 1;
Log::debug(sprintf('Now in getLeftToSpendInfo("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
foreach ($spent as $row) { foreach ($spent as $row) {
// either an amount was budgeted or 0 is available. // either an amount was budgeted or 0 is available.
$amount = (string)($available[$row['currency_id']] ?? '0'); $currencyId = $row['currency_id'];
$amount = (string) ($available[$currencyId] ?? '0');
$spentInCurrency = $row['sum']; $spentInCurrency = $row['sum'];
$leftToSpend = bcadd($amount, $spentInCurrency); $leftToSpend = bcadd($amount, $spentInCurrency);
$days = (int)$today->diffInDays($end, true) + 1;
$perDay = '0'; $perDay = '0';
if (0 !== $days && bccomp($leftToSpend, '0') > -1) { if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
$perDay = bcdiv($leftToSpend, (string)$days); $perDay = bcdiv($leftToSpend, (string) $days);
} }
Log::debug(sprintf('Spent %s %s', $row['currency_code'], $row['sum']));
$return[] = [ $return[] = [
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']), 'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]), 'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
'monetary_value' => $leftToSpend, 'monetary_value' => $leftToSpend,
'currency_id' => (string)$row['currency_id'], 'currency_id' => (string) $row['currency_id'],
'currency_code' => $row['currency_code'], 'currency_code' => $row['currency_code'],
'currency_symbol' => $row['currency_symbol'], 'currency_symbol' => $row['currency_symbol'],
'currency_decimal_places' => $row['currency_decimal_places'], 'currency_decimal_places' => $row['currency_decimal_places'],
@@ -311,9 +321,11 @@ class BasicController extends Controller
private function getNetWorthInfo(Carbon $start, Carbon $end): array private function getNetWorthInfo(Carbon $start, Carbon $end): array
{ {
Log::debug('getNetWorthInfo');
/** @var User $user */ /** @var User $user */
$user = auth()->user(); $user = auth()->user();
$date = today(config('app.timezone'))->startOfDay(); $date = now(config('app.timezone'));
// start and end in the future? use $end // start and end in the future? use $end
if ($this->notInDateRange($date, $start, $end)) { if ($this->notInDateRange($date, $start, $end)) {
/** @var Carbon $date */ /** @var Carbon $date */
@@ -323,9 +335,7 @@ class BasicController extends Controller
/** @var NetWorthInterface $netWorthHelper */ /** @var NetWorthInterface $netWorthHelper */
$netWorthHelper = app(NetWorthInterface::class); $netWorthHelper = app(NetWorthInterface::class);
$netWorthHelper->setUser($user); $netWorthHelper->setUser($user);
$allAccounts = $this->accountRepository->getActiveAccountsByType( $allAccounts = $this->accountRepository->getActiveAccountsByType([AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::DEBT->value]);
[AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT]
);
// filter list on preference of being included. // filter list on preference of being included.
$filtered = $allAccounts->filter( $filtered = $allAccounts->filter(
@@ -351,7 +361,7 @@ class BasicController extends Controller
'key' => sprintf('net-worth-in-%s', $data['currency_code']), 'key' => sprintf('net-worth-in-%s', $data['currency_code']),
'title' => trans('firefly.box_net_worth_in_currency', ['currency' => $data['currency_symbol']]), 'title' => trans('firefly.box_net_worth_in_currency', ['currency' => $data['currency_symbol']]),
'monetary_value' => $amount, 'monetary_value' => $amount,
'currency_id' => (string)$data['currency_id'], 'currency_id' => (string) $data['currency_id'],
'currency_code' => $data['currency_code'], 'currency_code' => $data['currency_code'],
'currency_symbol' => $data['currency_symbol'], 'currency_symbol' => $data['currency_symbol'],
'currency_decimal_places' => $data['currency_decimal_places'], 'currency_decimal_places' => $data['currency_decimal_places'],
@@ -360,6 +370,7 @@ class BasicController extends Controller
'sub_title' => '', 'sub_title' => '',
]; ];
} }
Log::debug('End of getNetWorthInfo');
return $return; return $return;
} }

View File

@@ -101,8 +101,8 @@ class ConfigurationController extends Controller
return [ return [
'is_demo_site' => $isDemoSite?->data, 'is_demo_site' => $isDemoSite?->data,
'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data, 'permission_update_check' => null === $updateCheck ? null : (int) $updateCheck->data,
'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data, 'last_update_check' => null === $lastCheck ? null : (int) $lastCheck->data,
'single_user_mode' => $singleUser?->data, 'single_user_mode' => $singleUser?->data,
]; ];
} }

View File

@@ -83,12 +83,12 @@ class MoveTransactionsRequest extends FormRequest
$data = $validator->getData(); $data = $validator->getData();
$repository = app(AccountRepositoryInterface::class); $repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user()); $repository->setUser(auth()->user());
$original = $repository->find((int)$data['original_account']); $original = $repository->find((int) $data['original_account']);
$destination = $repository->find((int)$data['destination_account']); $destination = $repository->find((int) $data['destination_account']);
// not the same type: // not the same type:
if ($original->accountType->type !== $destination->accountType->type) { if ($original->accountType->type !== $destination->accountType->type) {
$validator->errors()->add('title', (string)trans('validation.same_account_type')); $validator->errors()->add('title', (string) trans('validation.same_account_type'));
return; return;
} }
@@ -98,7 +98,7 @@ class MoveTransactionsRequest extends FormRequest
// check different scenario's. // check different scenario's.
if (null === $originalCurrency xor null === $destinationCurrency) { if (null === $originalCurrency xor null === $destinationCurrency) {
$validator->errors()->add('title', (string)trans('validation.same_account_currency')); $validator->errors()->add('title', (string) trans('validation.same_account_currency'));
return; return;
} }
@@ -107,7 +107,7 @@ class MoveTransactionsRequest extends FormRequest
return; return;
} }
if ($originalCurrency->code !== $destinationCurrency->code) { if ($originalCurrency->code !== $destinationCurrency->code) {
$validator->errors()->add('title', (string)trans('validation.same_account_currency')); $validator->errors()->add('title', (string) trans('validation.same_account_currency'));
} }
} }
} }

View File

@@ -52,7 +52,7 @@ class ExportRequest extends FormRequest
$accounts = new Collection(); $accounts = new Collection();
foreach ($parts as $part) { foreach ($parts as $part) {
$accountId = (int)$part; $accountId = (int) $part;
if (0 !== $accountId) { if (0 !== $accountId) {
$account = $repository->find($accountId); $account = $repository->find($accountId);
if (null !== $account && AccountType::ASSET === $account->accountType->type) { if (null !== $account && AccountType::ASSET === $account->accountType->type) {

View File

@@ -88,7 +88,7 @@ class GenericRequest extends FormRequest
$array = $this->get('accounts'); $array = $this->get('accounts');
if (is_array($array)) { if (is_array($array)) {
foreach ($array as $accountId) { foreach ($array as $accountId) {
$accountId = (int)$accountId; $accountId = (int) $accountId;
$account = $repository->find($accountId); $account = $repository->find($accountId);
if (null !== $account) { if (null !== $account) {
$this->accounts->push($account); $this->accounts->push($account);
@@ -114,7 +114,7 @@ class GenericRequest extends FormRequest
$array = $this->get('bills'); $array = $this->get('bills');
if (is_array($array)) { if (is_array($array)) {
foreach ($array as $billId) { foreach ($array as $billId) {
$billId = (int)$billId; $billId = (int) $billId;
$bill = $repository->find($billId); $bill = $repository->find($billId);
if (null !== $bill) { if (null !== $bill) {
$this->bills->push($bill); $this->bills->push($bill);
@@ -140,7 +140,7 @@ class GenericRequest extends FormRequest
$array = $this->get('budgets'); $array = $this->get('budgets');
if (is_array($array)) { if (is_array($array)) {
foreach ($array as $budgetId) { foreach ($array as $budgetId) {
$budgetId = (int)$budgetId; $budgetId = (int) $budgetId;
$budget = $repository->find($budgetId); $budget = $repository->find($budgetId);
if (null !== $budget) { if (null !== $budget) {
$this->budgets->push($budget); $this->budgets->push($budget);
@@ -166,7 +166,7 @@ class GenericRequest extends FormRequest
$array = $this->get('categories'); $array = $this->get('categories');
if (is_array($array)) { if (is_array($array)) {
foreach ($array as $categoryId) { foreach ($array as $categoryId) {
$categoryId = (int)$categoryId; $categoryId = (int) $categoryId;
$category = $repository->find($categoryId); $category = $repository->find($categoryId);
if (null !== $category) { if (null !== $category) {
$this->categories->push($category); $this->categories->push($category);
@@ -240,7 +240,7 @@ class GenericRequest extends FormRequest
$array = $this->get('tags'); $array = $this->get('tags');
if (is_array($array)) { if (is_array($array)) {
foreach ($array as $tagId) { foreach ($array as $tagId) {
$tagId = (int)$tagId; $tagId = (int) $tagId;
$tag = $repository->find($tagId); $tag = $repository->find($tagId);
if (null !== $tag) { if (null !== $tag) {
$this->tags->push($tag); $this->tags->push($tag);

View File

@@ -84,7 +84,7 @@ class Request extends FormRequest
$start = new Carbon($data['start']); $start = new Carbon($data['start']);
$end = new Carbon($data['end']); $end = new Carbon($data['end']);
if ($end->isBefore($start)) { if ($end->isBefore($start)) {
$validator->errors()->add('end', (string)trans('validation.date_after')); $validator->errors()->add('end', (string) trans('validation.date_after'));
} }
} }
} }

View File

@@ -96,11 +96,11 @@ class StoreRequest extends FormRequest
$validator->after( $validator->after(
static function (Validator $validator): void { static function (Validator $validator): void {
$data = $validator->getData(); $data = $validator->getData();
$min = (string)($data['amount_min'] ?? '0'); $min = (string) ($data['amount_min'] ?? '0');
$max = (string)($data['amount_max'] ?? '0'); $max = (string) ($data['amount_max'] ?? '0');
if (1 === bccomp($min, $max)) { if (1 === bccomp($min, $max)) {
$validator->errors()->add('amount_min', (string)trans('validation.amount_min_over_max')); $validator->errors()->add('amount_min', (string) trans('validation.amount_min_over_max'));
} }
} }
); );

View File

@@ -104,7 +104,7 @@ class UpdateRequest extends FormRequest
$max = $data['amount_max'] ?? '0'; $max = $data['amount_max'] ?? '0';
if (1 === bccomp($min, $max)) { if (1 === bccomp($min, $max)) {
$validator->errors()->add('amount_min', (string)trans('validation.amount_min_over_max')); $validator->errors()->add('amount_min', (string) trans('validation.amount_min_over_max'));
} }
} }
} }

View File

@@ -65,6 +65,25 @@ class StoreRequest extends FormRequest
return $data; return $data;
} }
private function parseAccounts(mixed $array): array
{
if (!is_array($array)) {
return [];
}
$return = [];
foreach ($array as $entry) {
if (!is_array($entry)) {
continue;
}
$return[] = [
'account_id' => $this->integerFromValue((string) ($entry['account_id'] ?? '0')),
'current_amount' => $this->clearString((string) ($entry['current_amount'] ?? '0')),
];
}
return $return;
}
/** /**
* The rules that the incoming request must be matched against. * The rules that the incoming request must be matched against.
*/ */
@@ -109,7 +128,7 @@ class StoreRequest extends FormRequest
// check currency here. // check currency here.
$accountCurrency = $repository->getAccountCurrency($account); $accountCurrency = $repository->getAccountCurrency($account);
$isMultiCurrency = $repository->getMetaValue($account, 'is_multi_currency'); $isMultiCurrency = $repository->getMetaValue($account, 'is_multi_currency');
$currentAmount = bcadd($currentAmount, (string)($array['current_amount'] ?? '0')); $currentAmount = bcadd($currentAmount, (string) ($array['current_amount'] ?? '0'));
if ($accountCurrency->id !== $currency->id && 'true' !== $isMultiCurrency) { if ($accountCurrency->id !== $currency->id && 'true' !== $isMultiCurrency) {
$validator->errors()->add(sprintf('accounts.%d', $index), trans('validation.invalid_account_currency')); $validator->errors()->add(sprintf('accounts.%d', $index), trans('validation.invalid_account_currency'));
} }
@@ -130,25 +149,6 @@ class StoreRequest extends FormRequest
} }
} }
private function parseAccounts(mixed $array): array
{
if (!is_array($array)) {
return [];
}
$return = [];
foreach ($array as $entry) {
if (!is_array($entry)) {
continue;
}
$return[] = [
'account_id' => $this->integerFromValue((string) ($entry['account_id'] ?? '0')),
'current_amount' => $this->clearString((string) ($entry['current_amount'] ?? '0')),
];
}
return $return;
}
private function getCurrencyFromData(array $data): TransactionCurrency private function getCurrencyFromData(array $data): TransactionCurrency
{ {
if (array_key_exists('transaction_currency_code', $data) && '' !== (string) $data['transaction_currency_code']) { if (array_key_exists('transaction_currency_code', $data) && '' !== (string) $data['transaction_currency_code']) {

View File

@@ -121,10 +121,10 @@ class StoreRequest extends FormRequest
$current['moment'] = $repetition['moment']; $current['moment'] = $repetition['moment'];
} }
if (array_key_exists('skip', $repetition)) { if (array_key_exists('skip', $repetition)) {
$current['skip'] = (int)$repetition['skip']; $current['skip'] = (int) $repetition['skip'];
} }
if (array_key_exists('weekend', $repetition)) { if (array_key_exists('weekend', $repetition)) {
$current['weekend'] = (int)$repetition['weekend']; $current['weekend'] = (int) $repetition['weekend'];
} }
$return[] = $current; $return[] = $current;

View File

@@ -101,15 +101,15 @@ class UpdateRequest extends FormRequest
} }
if (array_key_exists('moment', $repetition)) { if (array_key_exists('moment', $repetition)) {
$current['moment'] = (string)$repetition['moment']; $current['moment'] = (string) $repetition['moment'];
} }
if (array_key_exists('skip', $repetition)) { if (array_key_exists('skip', $repetition)) {
$current['skip'] = (int)$repetition['skip']; $current['skip'] = (int) $repetition['skip'];
} }
if (array_key_exists('weekend', $repetition)) { if (array_key_exists('weekend', $repetition)) {
$current['weekend'] = (int)$repetition['weekend']; $current['weekend'] = (int) $repetition['weekend'];
} }
$return[] = $current; $return[] = $current;
} }

View File

@@ -74,9 +74,9 @@ class StoreRequest extends FormRequest
$return[] = [ $return[] = [
'type' => $trigger['type'] ?? '', 'type' => $trigger['type'] ?? '',
'value' => $trigger['value'] ?? null, 'value' => $trigger['value'] ?? null,
'prohibited' => $this->convertBoolean((string)($trigger['prohibited'] ?? 'false')), 'prohibited' => $this->convertBoolean((string) ($trigger['prohibited'] ?? 'false')),
'active' => $this->convertBoolean((string)($trigger['active'] ?? 'true')), 'active' => $this->convertBoolean((string) ($trigger['active'] ?? 'true')),
'stop_processing' => $this->convertBoolean((string)($trigger['stop_processing'] ?? 'false')), 'stop_processing' => $this->convertBoolean((string) ($trigger['stop_processing'] ?? 'false')),
]; ];
} }
} }
@@ -93,8 +93,8 @@ class StoreRequest extends FormRequest
$return[] = [ $return[] = [
'type' => $action['type'], 'type' => $action['type'],
'value' => $action['value'], 'value' => $action['value'],
'active' => $this->convertBoolean((string)($action['active'] ?? 'true')), 'active' => $this->convertBoolean((string) ($action['active'] ?? 'true')),
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')), 'stop_processing' => $this->convertBoolean((string) ($action['stop_processing'] ?? 'false')),
]; ];
} }
} }
@@ -161,7 +161,7 @@ class StoreRequest extends FormRequest
$triggers = $data['triggers'] ?? []; $triggers = $data['triggers'] ?? [];
// need at least one trigger // need at least one trigger
if (!is_countable($triggers) || 0 === count($triggers)) { if (!is_countable($triggers) || 0 === count($triggers)) {
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger')); $validator->errors()->add('title', (string) trans('validation.at_least_one_trigger'));
} }
} }
@@ -174,7 +174,7 @@ class StoreRequest extends FormRequest
$actions = $data['actions'] ?? []; $actions = $data['actions'] ?? [];
// need at least one trigger // need at least one trigger
if (!is_countable($actions) || 0 === count($actions)) { if (!is_countable($actions) || 0 === count($actions)) {
$validator->errors()->add('title', (string)trans('validation.at_least_one_action')); $validator->errors()->add('title', (string) trans('validation.at_least_one_action'));
} }
} }
@@ -203,7 +203,7 @@ class StoreRequest extends FormRequest
} }
} }
if (true === $allInactive) { if (true === $allInactive) {
$validator->errors()->add(sprintf('triggers.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_trigger')); $validator->errors()->add(sprintf('triggers.%d.active', $inactiveIndex), (string) trans('validation.at_least_one_active_trigger'));
} }
} }
@@ -232,7 +232,7 @@ class StoreRequest extends FormRequest
} }
} }
if (true === $allInactive) { if (true === $allInactive) {
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action')); $validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string) trans('validation.at_least_one_active_action'));
} }
} }
} }

View File

@@ -49,7 +49,7 @@ class TestRequest extends FormRequest
private function getPage(): int private function getPage(): int
{ {
return 0 === (int)$this->query('page') ? 1 : (int)$this->query('page'); return 0 === (int) $this->query('page') ? 1 : (int) $this->query('page');
} }
private function getDate(string $field): ?Carbon private function getDate(string $field): ?Carbon
@@ -58,7 +58,7 @@ class TestRequest extends FormRequest
if (is_array($value)) { if (is_array($value)) {
return null; return null;
} }
$value = (string)$value; $value = (string) $value;
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10)); return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10));
} }

View File

@@ -52,7 +52,7 @@ class TriggerRequest extends FormRequest
if (is_array($value)) { if (is_array($value)) {
return null; return null;
} }
$value = (string)$value; $value = (string) $value;
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10)); return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10));
} }

View File

@@ -109,8 +109,8 @@ class UpdateRequest extends FormRequest
$return[] = [ $return[] = [
'type' => $action['type'], 'type' => $action['type'],
'value' => $action['value'], 'value' => $action['value'],
'active' => $this->convertBoolean((string)($action['active'] ?? 'false')), 'active' => $this->convertBoolean((string) ($action['active'] ?? 'false')),
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')), 'stop_processing' => $this->convertBoolean((string) ($action['stop_processing'] ?? 'false')),
]; ];
} }
} }
@@ -181,7 +181,7 @@ class UpdateRequest extends FormRequest
$triggers = $data['triggers'] ?? null; $triggers = $data['triggers'] ?? null;
// need at least one trigger // need at least one trigger
if (is_array($triggers) && 0 === count($triggers)) { if (is_array($triggers) && 0 === count($triggers)) {
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger')); $validator->errors()->add('title', (string) trans('validation.at_least_one_trigger'));
} }
} }
@@ -208,7 +208,7 @@ class UpdateRequest extends FormRequest
} }
} }
if (true === $allInactive) { if (true === $allInactive) {
$validator->errors()->add(sprintf('triggers.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_trigger')); $validator->errors()->add(sprintf('triggers.%d.active', $inactiveIndex), (string) trans('validation.at_least_one_active_trigger'));
} }
} }
@@ -221,7 +221,7 @@ class UpdateRequest extends FormRequest
$actions = $data['actions'] ?? null; $actions = $data['actions'] ?? null;
// need at least one action // need at least one action
if (is_array($actions) && 0 === count($actions)) { if (is_array($actions) && 0 === count($actions)) {
$validator->errors()->add('title', (string)trans('validation.at_least_one_action')); $validator->errors()->add('title', (string) trans('validation.at_least_one_action'));
} }
} }
@@ -249,7 +249,7 @@ class UpdateRequest extends FormRequest
} }
} }
if (true === $allInactive) { if (true === $allInactive) {
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action')); $validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string) trans('validation.at_least_one_active_action'));
} }
} }
} }

View File

@@ -52,7 +52,7 @@ class TestRequest extends FormRequest
if (is_array($value)) { if (is_array($value)) {
return null; return null;
} }
$value = (string)$value; $value = (string) $value;
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10)); return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10));
} }

View File

@@ -52,7 +52,7 @@ class TriggerRequest extends FormRequest
if (is_array($value)) { if (is_array($value)) {
return null; return null;
} }
$value = (string)$value; $value = (string) $value;
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10)); return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10));
} }

View File

@@ -84,73 +84,73 @@ class StoreRequest extends FormRequest
$return[] = [ $return[] = [
'type' => $this->clearString($object['type']), 'type' => $this->clearString($object['type']),
'date' => $this->dateFromValue($object['date']), 'date' => $this->dateFromValue($object['date']),
'order' => $this->integerFromValue((string)$object['order']), 'order' => $this->integerFromValue((string) $object['order']),
'currency_id' => $this->integerFromValue((string)$object['currency_id']), 'currency_id' => $this->integerFromValue((string) $object['currency_id']),
'currency_code' => $this->clearString((string)$object['currency_code']), 'currency_code' => $this->clearString((string) $object['currency_code']),
// foreign currency info: // foreign currency info:
'foreign_currency_id' => $this->integerFromValue((string)$object['foreign_currency_id']), 'foreign_currency_id' => $this->integerFromValue((string) $object['foreign_currency_id']),
'foreign_currency_code' => $this->clearString((string)$object['foreign_currency_code']), 'foreign_currency_code' => $this->clearString((string) $object['foreign_currency_code']),
// amount and foreign amount. Cannot be 0. // amount and foreign amount. Cannot be 0.
'amount' => $this->clearString((string)$object['amount']), 'amount' => $this->clearString((string) $object['amount']),
'foreign_amount' => $this->clearString((string)$object['foreign_amount']), 'foreign_amount' => $this->clearString((string) $object['foreign_amount']),
// description. // description.
'description' => $this->clearString($object['description']), 'description' => $this->clearString($object['description']),
// source of transaction. If everything is null, assume cash account. // source of transaction. If everything is null, assume cash account.
'source_id' => $this->integerFromValue((string)$object['source_id']), 'source_id' => $this->integerFromValue((string) $object['source_id']),
'source_name' => $this->clearString((string)$object['source_name']), 'source_name' => $this->clearString((string) $object['source_name']),
'source_iban' => $this->clearIban((string)$object['source_iban']), 'source_iban' => $this->clearIban((string) $object['source_iban']),
'source_number' => $this->clearString((string)$object['source_number']), 'source_number' => $this->clearString((string) $object['source_number']),
'source_bic' => $this->clearString((string)$object['source_bic']), 'source_bic' => $this->clearString((string) $object['source_bic']),
// destination of transaction. If everything is null, assume cash account. // destination of transaction. If everything is null, assume cash account.
'destination_id' => $this->integerFromValue((string)$object['destination_id']), 'destination_id' => $this->integerFromValue((string) $object['destination_id']),
'destination_name' => $this->clearString((string)$object['destination_name']), 'destination_name' => $this->clearString((string) $object['destination_name']),
'destination_iban' => $this->clearIban((string)$object['destination_iban']), 'destination_iban' => $this->clearIban((string) $object['destination_iban']),
'destination_number' => $this->clearString((string)$object['destination_number']), 'destination_number' => $this->clearString((string) $object['destination_number']),
'destination_bic' => $this->clearString((string)$object['destination_bic']), 'destination_bic' => $this->clearString((string) $object['destination_bic']),
// budget info // budget info
'budget_id' => $this->integerFromValue((string)$object['budget_id']), 'budget_id' => $this->integerFromValue((string) $object['budget_id']),
'budget_name' => $this->clearString((string)$object['budget_name']), 'budget_name' => $this->clearString((string) $object['budget_name']),
// category info // category info
'category_id' => $this->integerFromValue((string)$object['category_id']), 'category_id' => $this->integerFromValue((string) $object['category_id']),
'category_name' => $this->clearString((string)$object['category_name']), 'category_name' => $this->clearString((string) $object['category_name']),
// journal bill reference. Optional. Will only work for withdrawals // journal bill reference. Optional. Will only work for withdrawals
'bill_id' => $this->integerFromValue((string)$object['bill_id']), 'bill_id' => $this->integerFromValue((string) $object['bill_id']),
'bill_name' => $this->clearString((string)$object['bill_name']), 'bill_name' => $this->clearString((string) $object['bill_name']),
// piggy bank reference. Optional. Will only work for transfers // piggy bank reference. Optional. Will only work for transfers
'piggy_bank_id' => $this->integerFromValue((string)$object['piggy_bank_id']), 'piggy_bank_id' => $this->integerFromValue((string) $object['piggy_bank_id']),
'piggy_bank_name' => $this->clearString((string)$object['piggy_bank_name']), 'piggy_bank_name' => $this->clearString((string) $object['piggy_bank_name']),
// some other interesting properties // some other interesting properties
'reconciled' => $this->convertBoolean((string)$object['reconciled']), 'reconciled' => $this->convertBoolean((string) $object['reconciled']),
'notes' => $this->clearStringKeepNewlines((string)$object['notes']), 'notes' => $this->clearStringKeepNewlines((string) $object['notes']),
'tags' => $this->arrayFromValue($object['tags']), 'tags' => $this->arrayFromValue($object['tags']),
// all custom fields: // all custom fields:
'internal_reference' => $this->clearString((string)$object['internal_reference']), 'internal_reference' => $this->clearString((string) $object['internal_reference']),
'external_id' => $this->clearString((string)$object['external_id']), 'external_id' => $this->clearString((string) $object['external_id']),
'original_source' => sprintf('ff3-v%s', config('firefly.version')), 'original_source' => sprintf('ff3-v%s', config('firefly.version')),
'recurrence_id' => $this->integerFromValue($object['recurrence_id']), 'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
'bunq_payment_id' => $this->clearString((string)$object['bunq_payment_id']), 'bunq_payment_id' => $this->clearString((string) $object['bunq_payment_id']),
'external_url' => $this->clearString((string)$object['external_url']), 'external_url' => $this->clearString((string) $object['external_url']),
'sepa_cc' => $this->clearString((string)$object['sepa_cc']), 'sepa_cc' => $this->clearString((string) $object['sepa_cc']),
'sepa_ct_op' => $this->clearString((string)$object['sepa_ct_op']), 'sepa_ct_op' => $this->clearString((string) $object['sepa_ct_op']),
'sepa_ct_id' => $this->clearString((string)$object['sepa_ct_id']), 'sepa_ct_id' => $this->clearString((string) $object['sepa_ct_id']),
'sepa_db' => $this->clearString((string)$object['sepa_db']), 'sepa_db' => $this->clearString((string) $object['sepa_db']),
'sepa_country' => $this->clearString((string)$object['sepa_country']), 'sepa_country' => $this->clearString((string) $object['sepa_country']),
'sepa_ep' => $this->clearString((string)$object['sepa_ep']), 'sepa_ep' => $this->clearString((string) $object['sepa_ep']),
'sepa_ci' => $this->clearString((string)$object['sepa_ci']), 'sepa_ci' => $this->clearString((string) $object['sepa_ci']),
'sepa_batch_id' => $this->clearString((string)$object['sepa_batch_id']), 'sepa_batch_id' => $this->clearString((string) $object['sepa_batch_id']),
// custom date fields. Must be Carbon objects. Presence is optional. // custom date fields. Must be Carbon objects. Presence is optional.
'interest_date' => $this->dateFromValue($object['interest_date']), 'interest_date' => $this->dateFromValue($object['interest_date']),
'book_date' => $this->dateFromValue($object['book_date']), 'book_date' => $this->dateFromValue($object['book_date']),

View File

@@ -137,7 +137,7 @@ class UpdateRequest extends FormRequest
{ {
foreach ($this->integerFields as $fieldName) { foreach ($this->integerFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) { if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->integerFromValue((string)$transaction[$fieldName]); $current[$fieldName] = $this->integerFromValue((string) $transaction[$fieldName]);
} }
} }
@@ -152,7 +152,7 @@ class UpdateRequest extends FormRequest
{ {
foreach ($this->stringFields as $fieldName) { foreach ($this->stringFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) { if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearString((string)$transaction[$fieldName]); $current[$fieldName] = $this->clearString((string) $transaction[$fieldName]);
} }
} }
@@ -167,7 +167,7 @@ class UpdateRequest extends FormRequest
{ {
foreach ($this->textareaFields as $fieldName) { foreach ($this->textareaFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) { if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearStringKeepNewlines((string)$transaction[$fieldName]); // keep newlines $current[$fieldName] = $this->clearStringKeepNewlines((string) $transaction[$fieldName]); // keep newlines
} }
} }
@@ -183,8 +183,8 @@ class UpdateRequest extends FormRequest
foreach ($this->dateFields as $fieldName) { foreach ($this->dateFields as $fieldName) {
app('log')->debug(sprintf('Now at date field %s', $fieldName)); app('log')->debug(sprintf('Now at date field %s', $fieldName));
if (array_key_exists($fieldName, $transaction)) { if (array_key_exists($fieldName, $transaction)) {
app('log')->debug(sprintf('New value: "%s"', (string)$transaction[$fieldName])); app('log')->debug(sprintf('New value: "%s"', (string) $transaction[$fieldName]));
$current[$fieldName] = $this->dateFromValue((string)$transaction[$fieldName]); $current[$fieldName] = $this->dateFromValue((string) $transaction[$fieldName]);
} }
} }
@@ -199,7 +199,7 @@ class UpdateRequest extends FormRequest
{ {
foreach ($this->booleanFields as $fieldName) { foreach ($this->booleanFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) { if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->convertBoolean((string)$transaction[$fieldName]); $current[$fieldName] = $this->convertBoolean((string) $transaction[$fieldName]);
} }
} }
@@ -234,7 +234,7 @@ class UpdateRequest extends FormRequest
$current[$fieldName] = sprintf('%.12f', $value); $current[$fieldName] = sprintf('%.12f', $value);
} }
if (!is_float($value)) { if (!is_float($value)) {
$current[$fieldName] = (string)$value; $current[$fieldName] = (string) $value;
} }
} }
} }

View File

@@ -98,8 +98,8 @@ class StoreRequest extends FormRequest
$journalRepos->setUser($user); $journalRepos->setUser($user);
$data = $validator->getData(); $data = $validator->getData();
$inwardId = (int)($data['inward_id'] ?? 0); $inwardId = (int) ($data['inward_id'] ?? 0);
$outwardId = (int)($data['outward_id'] ?? 0); $outwardId = (int) ($data['outward_id'] ?? 0);
$inward = $journalRepos->find($inwardId); $inward = $journalRepos->find($inwardId);
$outward = $journalRepos->find($outwardId); $outward = $journalRepos->find($outwardId);

View File

@@ -100,8 +100,8 @@ class UpdateRequest extends FormRequest
$inwardId = $data['inward_id'] ?? $existing->source_id; $inwardId = $data['inward_id'] ?? $existing->source_id;
$outwardId = $data['outward_id'] ?? $existing->destination_id; $outwardId = $data['outward_id'] ?? $existing->destination_id;
$inward = $journalRepos->find((int)$inwardId); $inward = $journalRepos->find((int) $inwardId);
$outward = $journalRepos->find((int)$outwardId); $outward = $journalRepos->find((int) $outwardId);
if (null === $inward) { if (null === $inward) {
$inward = $existing->source; $inward = $existing->source;
} }

View File

@@ -55,9 +55,9 @@ class CreateRequest extends FormRequest
// this is the way. // this is the way.
$return = $this->getAllData($fields); $return = $this->getAllData($fields);
$return['trigger'] = $triggers[$return['trigger']] ?? (int)$return['trigger']; $return['trigger'] = $triggers[$return['trigger']] ?? (int) $return['trigger'];
$return['response'] = $responses[$return['response']] ?? (int)$return['response']; $return['response'] = $responses[$return['response']] ?? (int) $return['response'];
$return['delivery'] = $deliveries[$return['delivery']] ?? (int)$return['delivery']; $return['delivery'] = $deliveries[$return['delivery']] ?? (int) $return['delivery'];
return $return; return $return;
} }

View File

@@ -94,7 +94,7 @@ class UserUpdateRequest extends FormRequest
$isAdmin = auth()->user()->hasRole('owner'); $isAdmin = auth()->user()->hasRole('owner');
// not admin, and not own user? // not admin, and not own user?
if (auth()->check() && false === $isAdmin && $current?->id !== auth()->user()->id) { if (auth()->check() && false === $isAdmin && $current?->id !== auth()->user()->id) {
$validator->errors()->add('email', (string)trans('validation.invalid_selection')); $validator->errors()->add('email', (string) trans('validation.invalid_selection'));
} }
} }
); );

View File

@@ -49,7 +49,7 @@ class PreferenceStoreRequest extends FormRequest
$array['data'] = false; $array['data'] = false;
} }
if (is_numeric($array['data'])) { if (is_numeric($array['data'])) {
$array['data'] = (float)$array['data']; // intentional float. $array['data'] = (float) $array['data']; // intentional float.
} }
return $array; return $array;

View File

@@ -49,7 +49,7 @@ class PreferenceUpdateRequest extends FormRequest
$array['data'] = false; $array['data'] = false;
} }
if (is_numeric($array['data'])) { if (is_numeric($array['data'])) {
$array['data'] = (float)$array['data']; // intentional float. $array['data'] = (float) $array['data']; // intentional float.
} }
return $array; return $array;

View File

@@ -40,9 +40,9 @@ use Illuminate\Support\Facades\Log;
*/ */
class AccountController extends Controller class AccountController extends Controller
{ {
private AccountRepositoryInterface $repository;
private TransactionCurrency $default;
private ExchangeRateConverter $converter; private ExchangeRateConverter $converter;
private TransactionCurrency $default;
private AccountRepositoryInterface $repository;
/** /**
* AccountController constructor. * AccountController constructor.

View File

@@ -63,7 +63,7 @@ class CategoryController extends Controller
$filtered = $result->map( $filtered = $result->map(
static function (Category $item) { static function (Category $item) {
return [ return [
'id' => (string)$item->id, 'id' => (string) $item->id,
'title' => $item->name, 'title' => $item->name,
'meta' => [], 'meta' => [],
]; ];

View File

@@ -45,9 +45,9 @@ class AccountController extends Controller
use CollectsAccountsFromFilter; use CollectsAccountsFromFilter;
use ValidatesUserGroupTrait; use ValidatesUserGroupTrait;
private AccountRepositoryInterface $repository;
private ChartData $chartData; private ChartData $chartData;
private TransactionCurrency $default; private TransactionCurrency $default;
private AccountRepositoryInterface $repository;
public function __construct() public function __construct()
{ {
@@ -92,11 +92,11 @@ class AccountController extends Controller
*/ */
private function renderAccountData(array $params, Account $account): void private function renderAccountData(array $params, Account $account): void
{ {
$currency = $this->repository->getAccountCurrency($account); $currency = $this->repository->getAccountCurrency($account);
if (null === $currency) { if (null === $currency) {
$currency = $this->default; $currency = $this->default;
} }
$currentSet = [ $currentSet = [
'label' => $account->name, 'label' => $account->name,
// the currency that belongs to the account. // the currency that belongs to the account.
@@ -117,23 +117,22 @@ class AccountController extends Controller
'entries' => [], 'entries' => [],
'native_entries' => [], 'native_entries' => [],
]; ];
$currentStart = clone $params['start']; $currentStart = clone $params['start'];
$range = app('steam')->balanceInRange($account, $params['start'], clone $params['end'], $currency); $range = app('steam')->finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative);
$rangeConverted = app('steam')->balanceInRangeConverted($account, $params['start'], clone $params['end'], $this->default);
$previous = array_values($range)[0]; $previous = array_values($range)[0]['balance'];
$previousConverted = array_values($rangeConverted)[0]; $previousNative = array_values($range)[0]['native_balance'];
while ($currentStart <= $params['end']) { while ($currentStart <= $params['end']) {
$format = $currentStart->format('Y-m-d'); $format = $currentStart->format('Y-m-d');
$label = $currentStart->toAtomString(); $label = $currentStart->toAtomString();
$balance = array_key_exists($format, $range) ? $range[$format] : $previous; $balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
$balanceConverted = array_key_exists($format, $rangeConverted) ? $rangeConverted[$format] : $previousConverted; $balanceNative = array_key_exists($format, $range) ? $range[$format]['balance_native'] : $previousNative;
$previous = $balance; $previous = $balance;
$previousConverted = $balanceConverted; $previousNative = $balanceNative;
$currentStart->addDay(); $currentStart->addDay();
$currentSet['entries'][$label] = $balance; $currentSet['entries'][$label] = $balance;
$currentSet['native_entries'][$label] = $balanceConverted; $currentSet['native_entries'][$label] = $balanceNative;
} }
$this->chartData->add($currentSet); $this->chartData->add($currentSet);
} }

View File

@@ -45,9 +45,10 @@ class BalanceController extends Controller
use CleansChartData; use CleansChartData;
use CollectsAccountsFromFilter; use CollectsAccountsFromFilter;
private AccountRepositoryInterface $repository;
private GroupCollectorInterface $collector;
private ChartData $chartData; private ChartData $chartData;
private GroupCollectorInterface $collector;
private AccountRepositoryInterface $repository;
// private TransactionCurrency $default; // private TransactionCurrency $default;
public function __construct() public function __construct()

View File

@@ -54,9 +54,10 @@ class Controller extends BaseController
{ {
use ValidatesUserGroupTrait; use ValidatesUserGroupTrait;
protected const string CONTENT_TYPE = 'application/vnd.api+json'; protected const string CONTENT_TYPE = 'application/vnd.api+json';
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
protected ParameterBag $parameters; protected ParameterBag $parameters;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY]; protected bool $convertToNative = false;
public function __construct() public function __construct()
{ {
@@ -81,7 +82,7 @@ class Controller extends BaseController
$bag->set('limit', 50); $bag->set('limit', 50);
try { try {
$page = (int)request()->get('page'); $page = (int) request()->get('page');
} catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) { } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) {
$page = 1; $page = 1;
} }
@@ -92,8 +93,8 @@ class Controller extends BaseController
if ($page < 1) { if ($page < 1) {
$page = 1; $page = 1;
} }
if ($page > (2 ^ 16)) { if ($page > 2 ** 16) {
$page = (2 ^ 16); $page = 2 ** 16;
} }
$bag->set('page', $page); $bag->set('page', $page);
@@ -111,10 +112,10 @@ class Controller extends BaseController
} }
if (null !== $date) { if (null !== $date) {
try { try {
$obj = Carbon::parse((string)$date, config('app.timezone')); $obj = Carbon::parse((string) $date, config('app.timezone'));
} catch (InvalidDateException|InvalidFormatException $e) { } catch (InvalidDateException|InvalidFormatException $e) {
// don't care // don't care
app('log')->warning(sprintf('Ignored invalid date "%s" in API v2 controller parameter check: %s', substr((string)$date, 0, 20), $e->getMessage())); app('log')->warning(sprintf('Ignored invalid date "%s" in API v2 controller parameter check: %s', substr((string) $date, 0, 20), $e->getMessage()));
} }
// out of range? set to null. // out of range? set to null.
if (null !== $obj && ($obj->year <= 1900 || $obj->year > 2099)) { if (null !== $obj && ($obj->year <= 1900 || $obj->year > 2099)) {
@@ -138,11 +139,11 @@ class Controller extends BaseController
$value = null; $value = null;
} }
if (null !== $value) { if (null !== $value) {
$bag->set($integer, (int)$value); $bag->set($integer, (int) $value);
} }
if (null === $value && 'limit' === $integer && auth()->check()) { if (null === $value && 'limit' === $integer && auth()->check()) {
// set default for user: // set default for user:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; $pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$bag->set($integer, $pageSize); $bag->set($integer, $pageSize);
} }
} }

View File

@@ -48,6 +48,7 @@ class AccountController extends Controller
use Actions\DetachRelationship; use Actions\DetachRelationship;
use Actions\FetchMany; use Actions\FetchMany;
// use Actions\FetchOne; // use Actions\FetchOne;
use Actions\FetchRelated; use Actions\FetchRelated;
use Actions\FetchRelationship; use Actions\FetchRelationship;

View File

@@ -36,9 +36,8 @@ use Illuminate\Support\Facades\Log;
class IndexController extends Controller class IndexController extends Controller
{ {
public const string RESOURCE_KEY = 'accounts'; public const string RESOURCE_KEY = 'accounts';
private AccountRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS]; protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS];
private AccountRepositoryInterface $repository;
/** /**
* AccountController constructor. * AccountController constructor.

View File

@@ -39,9 +39,8 @@ use Illuminate\Http\JsonResponse;
class ShowController extends Controller class ShowController extends Controller
{ {
public const string RESOURCE_KEY = 'accounts'; public const string RESOURCE_KEY = 'accounts';
private AccountRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS]; protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS];
private AccountRepositoryInterface $repository;
/** /**
* AccountController constructor. * AccountController constructor.

View File

@@ -0,0 +1,67 @@
<?php
/*
* DestroyController.php
* Copyright (c) 2024 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\V2\Controllers\Model\ExchangeRate;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Model\ExchangeRate\DestroyRequest;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use Illuminate\Http\JsonResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class DestroyController extends Controller
{
use ValidatesUserGroupTrait;
public const string RESOURCE_KEY = 'exchange-rates';
private ExchangeRateRepositoryInterface $repository;
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
return $next($request);
}
);
}
public function destroy(DestroyRequest $request, TransactionCurrency $from, TransactionCurrency $to): JsonResponse
{
$date = $request->getDate();
$rate = $this->repository->getSpecificRateOnDate($from, $to, $date);
if (null === $rate) {
throw new NotFoundHttpException();
}
$this->repository->deleteRate($rate);
return response()->json([], 204);
}
}

View File

@@ -36,6 +36,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
class IndexController extends Controller class IndexController extends Controller
{ {
use ValidatesUserGroupTrait; use ValidatesUserGroupTrait;
public const string RESOURCE_KEY = 'exchange-rates'; public const string RESOURCE_KEY = 'exchange-rates';
private ExchangeRateRepositoryInterface $repository; private ExchangeRateRepositoryInterface $repository;

View File

@@ -38,6 +38,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
class ShowController extends Controller class ShowController extends Controller
{ {
use ValidatesUserGroupTrait; use ValidatesUserGroupTrait;
public const string RESOURCE_KEY = 'exchange-rates'; public const string RESOURCE_KEY = 'exchange-rates';
private ExchangeRateRepositoryInterface $repository; private ExchangeRateRepositoryInterface $repository;
@@ -57,13 +58,12 @@ class ShowController extends Controller
public function show(TransactionCurrency $from, TransactionCurrency $to): JsonResponse public function show(TransactionCurrency $from, TransactionCurrency $to): JsonResponse
{ {
// $piggies = $this->repository->getAll();
//
$pageSize = $this->parameters->get('limit'); $pageSize = $this->parameters->get('limit');
$page = $this->parameters->get('page');
$rates = $this->repository->getRates($from, $to); $rates = $this->repository->getRates($from, $to);
$count = $rates->count(); $count = $rates->count();
$rates = $rates->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); $rates = $rates->slice(($page - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($rates, $count, $pageSize, $this->parameters->get('page')); $paginator = new LengthAwarePaginator($rates, $count, $pageSize, $page);
$transformer = new ExchangeRateTransformer(); $transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters); // give params to transformer $transformer->setParameters($this->parameters); // give params to transformer

View File

@@ -0,0 +1,81 @@
<?php
/*
* DestroyController.php
* Copyright (c) 2024 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\V2\Controllers\Model\ExchangeRate;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Model\ExchangeRate\StoreRequest;
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
use Illuminate\Http\JsonResponse;
class StoreController extends Controller
{
use ValidatesUserGroupTrait;
public const string RESOURCE_KEY = 'exchange-rates';
private ExchangeRateRepositoryInterface $repository;
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
return $next($request);
}
);
}
public function store(StoreRequest $request): JsonResponse
{
$date = $request->getDate();
$rate = $request->getRate();
$from = $request->getFromCurrency();
$to = $request->getToCurrency();
// already has rate?
$object = $this->repository->getSpecificRateOnDate($from, $to, $date);
if (null !== $object) {
// just update it, no matter.
$rate = $this->repository->updateExchangeRate($object, $rate, $date);
}
if (null === $object) {
// store new
$rate = $this->repository->storeExchangeRate($from, $to, $rate, $date);
}
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters);
return response()
->api($this->jsonApiObject(self::RESOURCE_KEY, $rate, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*
* DestroyController.php
* Copyright (c) 2024 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\V2\Controllers\Model\ExchangeRate;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Model\ExchangeRate\UpdateRequest;
use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
use Illuminate\Http\JsonResponse;
class UpdateController extends Controller
{
use ValidatesUserGroupTrait;
public const string RESOURCE_KEY = 'exchange-rates';
private ExchangeRateRepositoryInterface $repository;
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
return $next($request);
}
);
}
public function update(UpdateRequest $request, CurrencyExchangeRate $exchangeRate): JsonResponse
{
$date = $request->getDate();
$rate = $request->getRate();
$exchangeRate = $this->repository->updateExchangeRate($exchangeRate, $rate, $date);
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters);
return response()
->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
}

View File

@@ -35,9 +35,8 @@ use Illuminate\Pagination\LengthAwarePaginator;
class IndexController extends Controller class IndexController extends Controller
{ {
public const string RESOURCE_KEY = 'transaction-currencies'; public const string RESOURCE_KEY = 'transaction-currencies';
private CurrencyRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY]; protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
private CurrencyRepositoryInterface $repository;
public function __construct() public function __construct()
{ {

View File

@@ -179,7 +179,7 @@ class BasicController extends Controller
$return[] = [ $return[] = [
'key' => sprintf('bills-paid-in-%s', $info['currency_code']), 'key' => sprintf('bills-paid-in-%s', $info['currency_code']),
'value' => $amount, 'value' => $amount,
'currency_id' => (string)$info['currency_id'], 'currency_id' => (string) $info['currency_id'],
'currency_code' => $info['currency_code'], 'currency_code' => $info['currency_code'],
'currency_symbol' => $info['currency_symbol'], 'currency_symbol' => $info['currency_symbol'],
'currency_decimal_places' => $info['currency_decimal_places'], 'currency_decimal_places' => $info['currency_decimal_places'],
@@ -187,7 +187,7 @@ class BasicController extends Controller
$return[] = [ $return[] = [
'key' => 'bills-paid-in-native', 'key' => 'bills-paid-in-native',
'value' => $nativeAmount, 'value' => $nativeAmount,
'currency_id' => (string)$info['native_currency_id'], 'currency_id' => (string) $info['native_currency_id'],
'currency_code' => $info['native_currency_code'], 'currency_code' => $info['native_currency_code'],
'currency_symbol' => $info['native_currency_symbol'], 'currency_symbol' => $info['native_currency_symbol'],
'currency_decimal_places' => $info['native_currency_decimal_places'], 'currency_decimal_places' => $info['native_currency_decimal_places'],
@@ -203,7 +203,7 @@ class BasicController extends Controller
$return[] = [ $return[] = [
'key' => sprintf('bills-unpaid-in-%s', $info['currency_code']), 'key' => sprintf('bills-unpaid-in-%s', $info['currency_code']),
'value' => $amount, 'value' => $amount,
'currency_id' => (string)$info['currency_id'], 'currency_id' => (string) $info['currency_id'],
'currency_code' => $info['currency_code'], 'currency_code' => $info['currency_code'],
'currency_symbol' => $info['currency_symbol'], 'currency_symbol' => $info['currency_symbol'],
'currency_decimal_places' => $info['currency_decimal_places'], 'currency_decimal_places' => $info['currency_decimal_places'],
@@ -211,7 +211,7 @@ class BasicController extends Controller
$return[] = [ $return[] = [
'key' => 'bills-unpaid-in-native', 'key' => 'bills-unpaid-in-native',
'value' => $nativeAmount, 'value' => $nativeAmount,
'currency_id' => (string)$info['native_currency_id'], 'currency_id' => (string) $info['native_currency_id'],
'currency_code' => $info['native_currency_code'], 'currency_code' => $info['native_currency_code'],
'currency_symbol' => $info['native_currency_symbol'], 'currency_symbol' => $info['native_currency_symbol'],
'currency_decimal_places' => $info['native_currency_decimal_places'], 'currency_decimal_places' => $info['native_currency_decimal_places'],
@@ -241,7 +241,7 @@ class BasicController extends Controller
$nativeLeft = [ $nativeLeft = [
'key' => 'left-to-spend-in-native', 'key' => 'left-to-spend-in-native',
'value' => '0', 'value' => '0',
'currency_id' => (string)$default->id, 'currency_id' => (string) $default->id,
'currency_code' => $default->code, 'currency_code' => $default->code,
'currency_symbol' => $default->symbol, 'currency_symbol' => $default->symbol,
'currency_decimal_places' => $default->decimal_places, 'currency_decimal_places' => $default->decimal_places,
@@ -249,7 +249,7 @@ class BasicController extends Controller
$nativePerDay = [ $nativePerDay = [
'key' => 'left-per-day-to-spend-in-native', 'key' => 'left-per-day-to-spend-in-native',
'value' => '0', 'value' => '0',
'currency_id' => (string)$default->id, 'currency_id' => (string) $default->id,
'currency_code' => $default->code, 'currency_code' => $default->code,
'currency_symbol' => $default->symbol, 'currency_symbol' => $default->symbol,
'currency_decimal_places' => $default->decimal_places, 'currency_decimal_places' => $default->decimal_places,
@@ -276,7 +276,7 @@ class BasicController extends Controller
$currencies[$currencyId] = $currency; $currencies[$currencyId] = $currency;
$amount = app('steam')->negative($journal['amount']); $amount = app('steam')->negative($journal['amount']);
$amountNative = $converter->convert($default, $currency, $start, $amount); $amountNative = $converter->convert($default, $currency, $start, $amount);
if ((int)$journal['foreign_currency_id'] === $default->id) { if ((int) $journal['foreign_currency_id'] === $default->id) {
$amountNative = $journal['foreign_amount']; $amountNative = $journal['foreign_amount'];
} }
$spent = bcadd($spent, $amount); $spent = bcadd($spent, $amount);
@@ -296,24 +296,24 @@ class BasicController extends Controller
app('log')->debug(sprintf('Amount left is %s', $left)); app('log')->debug(sprintf('Amount left is %s', $left));
// how much left per day? // how much left per day?
$days = (int)$today->diffInDays($end, true) + 1; $days = (int) $today->diffInDays($end, true) + 1;
$perDay = '0'; $perDay = '0';
$perDayNative = '0'; $perDayNative = '0';
if (0 !== $days && bccomp($left, '0') > -1) { if (0 !== $days && bccomp($left, '0') > -1) {
$perDay = bcdiv($left, (string)$days); $perDay = bcdiv($left, (string) $days);
} }
if (0 !== $days && bccomp($leftNative, '0') > -1) { if (0 !== $days && bccomp($leftNative, '0') > -1) {
$perDayNative = bcdiv($leftNative, (string)$days); $perDayNative = bcdiv($leftNative, (string) $days);
} }
// left // left
$return[] = [ $return[] = [
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']), 'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
'value' => $left, 'value' => $left,
'currency_id' => (string)$row['currency_id'], 'currency_id' => (string) $row['currency_id'],
'currency_code' => $row['currency_code'], 'currency_code' => $row['currency_code'],
'currency_symbol' => $row['currency_symbol'], 'currency_symbol' => $row['currency_symbol'],
'currency_decimal_places' => (int)$row['currency_decimal_places'], 'currency_decimal_places' => (int) $row['currency_decimal_places'],
]; ];
// left (native) // left (native)
$nativeLeft['value'] = $leftNative; $nativeLeft['value'] = $leftNative;
@@ -322,10 +322,10 @@ class BasicController extends Controller
$return[] = [ $return[] = [
'key' => sprintf('left-per-day-to-spend-in-%s', $row['currency_code']), 'key' => sprintf('left-per-day-to-spend-in-%s', $row['currency_code']),
'value' => $perDay, 'value' => $perDay,
'currency_id' => (string)$row['currency_id'], 'currency_id' => (string) $row['currency_id'],
'currency_code' => $row['currency_code'], 'currency_code' => $row['currency_code'],
'currency_symbol' => $row['currency_symbol'], 'currency_symbol' => $row['currency_symbol'],
'currency_decimal_places' => (int)$row['currency_decimal_places'], 'currency_decimal_places' => (int) $row['currency_decimal_places'],
]; ];
// left per day (native) // left per day (native)
@@ -371,7 +371,7 @@ class BasicController extends Controller
$return[] = [ $return[] = [
'key' => 'net-worth-in-native', 'key' => 'net-worth-in-native',
'value' => $netWorthSet['native']['balance'], 'value' => $netWorthSet['native']['balance'],
'currency_id' => (string)$netWorthSet['native']['currency_id'], 'currency_id' => (string) $netWorthSet['native']['currency_id'],
'currency_code' => $netWorthSet['native']['currency_code'], 'currency_code' => $netWorthSet['native']['currency_code'],
'currency_symbol' => $netWorthSet['native']['currency_symbol'], 'currency_symbol' => $netWorthSet['native']['currency_symbol'],
'currency_decimal_places' => $netWorthSet['native']['currency_decimal_places'], 'currency_decimal_places' => $netWorthSet['native']['currency_decimal_places'],
@@ -383,7 +383,7 @@ class BasicController extends Controller
$return[] = [ $return[] = [
'key' => sprintf('net-worth-in-%s', $data['currency_code']), 'key' => sprintf('net-worth-in-%s', $data['currency_code']),
'value' => $data['balance'], 'value' => $data['balance'],
'currency_id' => (string)$data['currency_id'], 'currency_id' => (string) $data['currency_id'],
'currency_code' => $data['currency_code'], 'currency_code' => $data['currency_code'],
'currency_symbol' => $data['currency_symbol'], 'currency_symbol' => $data['currency_symbol'],
'currency_decimal_places' => $data['currency_decimal_places'], 'currency_decimal_places' => $data['currency_decimal_places'],

View File

@@ -73,6 +73,16 @@ class AutocompleteRequest extends FormRequest
return $array; return $array;
} }
private function getAccountTypeParameter(array $types): array
{
$return = [];
foreach ($types as $type) {
$return = array_merge($return, $this->mapAccountTypes($type));
}
return array_unique($return);
}
public function rules(): array public function rules(): array
{ {
$valid = array_keys($this->types); $valid = array_keys($this->types);
@@ -86,14 +96,4 @@ class AutocompleteRequest extends FormRequest
'transaction_types' => 'nullable|in:todo', 'transaction_types' => 'nullable|in:todo',
]; ];
} }
private function getAccountTypeParameter(array $types): array
{
$return = [];
foreach ($types as $type) {
$return = array_merge($return, $this->mapAccountTypes($type));
}
return array_unique($return);
}
} }

View File

@@ -40,7 +40,8 @@ class BalanceChartRequest extends FormRequest
use ChecksLogin; use ChecksLogin;
use ConvertsDataTypes; use ConvertsDataTypes;
use ValidatesUserGroupTrait; use ValidatesUserGroupTrait;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
/** /**
* Get all data from the request. * Get all data from the request.

View File

@@ -0,0 +1,51 @@
<?php
/*
* DestroyRequest.php
* Copyright (c) 2024 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\V2\Request\Model\ExchangeRate;
use Carbon\Carbon;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
class DestroyRequest extends FormRequest
{
use ChecksLogin;
use ConvertsDataTypes;
public function getDate(): Carbon
{
return $this->getCarbonDate('date');
}
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
return [
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
];
}
}

View File

@@ -0,0 +1,70 @@
<?php
/*
* DestroyRequest.php
* Copyright (c) 2024 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\V2\Request\Model\ExchangeRate;
use Carbon\Carbon;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
class StoreRequest extends FormRequest
{
use ChecksLogin;
use ConvertsDataTypes;
public function getDate(): ?Carbon
{
return $this->getCarbonDate('date');
}
public function getRate(): string
{
return (string) $this->get('rate');
}
public function getFromCurrency(): TransactionCurrency
{
return TransactionCurrency::where('code', $this->get('from'))->first();
}
public function getToCurrency(): TransactionCurrency
{
return TransactionCurrency::where('code', $this->get('to'))->first();
}
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
return [
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
'rate' => 'required|numeric|gt:0',
'from' => 'required|exists:transaction_currencies,code',
'to' => 'required|exists:transaction_currencies,code',
];
}
}

View File

@@ -0,0 +1,57 @@
<?php
/*
* DestroyRequest.php
* Copyright (c) 2024 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\V2\Request\Model\ExchangeRate;
use Carbon\Carbon;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
class UpdateRequest extends FormRequest
{
use ChecksLogin;
use ConvertsDataTypes;
public function getDate(): ?Carbon
{
return $this->getCarbonDate('date');
}
public function getRate(): string
{
return (string) $this->get('rate');
}
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
return [
'date' => 'date|after:1900-01-01|before:2099-12-31',
'rate' => 'required|numeric|gt:0',
];
}
}

View File

@@ -87,7 +87,7 @@ class InfiniteListRequest extends FormRequest
public function getAccountTypes(): array public function getAccountTypes(): array
{ {
$type = (string)$this->get('type', 'default'); $type = (string) $this->get('type', 'default');
return $this->mapAccountTypes($type); return $this->mapAccountTypes($type);
} }
@@ -101,7 +101,7 @@ class InfiniteListRequest extends FormRequest
public function getTransactionTypes(): array public function getTransactionTypes(): array
{ {
$type = (string)$this->get('type', 'default'); $type = (string) $this->get('type', 'default');
return $this->mapTransactionTypes($type); return $this->mapTransactionTypes($type);
} }

View File

@@ -76,7 +76,7 @@ class ListRequest extends FormRequest
public function getTransactionTypes(): array public function getTransactionTypes(): array
{ {
$type = (string)$this->get('type', 'default'); $type = (string) $this->get('type', 'default');
return $this->mapTransactionTypes($type); return $this->mapTransactionTypes($type);
} }

View File

@@ -94,73 +94,73 @@ class StoreRequest extends FormRequest
$result = [ $result = [
'type' => $this->clearString($object['type']), 'type' => $this->clearString($object['type']),
'date' => $this->dateFromValue($object['date']), 'date' => $this->dateFromValue($object['date']),
'order' => $this->integerFromValue((string)$object['order']), 'order' => $this->integerFromValue((string) $object['order']),
'currency_id' => $this->integerFromValue((string)$object['currency_id']), 'currency_id' => $this->integerFromValue((string) $object['currency_id']),
'currency_code' => $this->clearString((string)$object['currency_code']), 'currency_code' => $this->clearString((string) $object['currency_code']),
// foreign currency info: // foreign currency info:
'foreign_currency_id' => $this->integerFromValue((string)$object['foreign_currency_id']), 'foreign_currency_id' => $this->integerFromValue((string) $object['foreign_currency_id']),
'foreign_currency_code' => $this->clearString((string)$object['foreign_currency_code']), 'foreign_currency_code' => $this->clearString((string) $object['foreign_currency_code']),
// amount and foreign amount. Cannot be 0. // amount and foreign amount. Cannot be 0.
'amount' => $this->clearString((string)$object['amount']), 'amount' => $this->clearString((string) $object['amount']),
'foreign_amount' => $this->clearString((string)$object['foreign_amount']), 'foreign_amount' => $this->clearString((string) $object['foreign_amount']),
// description. // description.
'description' => $this->clearString($object['description']), 'description' => $this->clearString($object['description']),
// source of transaction. If everything is null, assume cash account. // source of transaction. If everything is null, assume cash account.
'source_id' => $this->integerFromValue((string)$object['source_id']), 'source_id' => $this->integerFromValue((string) $object['source_id']),
'source_name' => $this->clearString((string)$object['source_name']), 'source_name' => $this->clearString((string) $object['source_name']),
'source_iban' => $this->clearString((string)$object['source_iban']), 'source_iban' => $this->clearString((string) $object['source_iban']),
'source_number' => $this->clearString((string)$object['source_number']), 'source_number' => $this->clearString((string) $object['source_number']),
'source_bic' => $this->clearString((string)$object['source_bic']), 'source_bic' => $this->clearString((string) $object['source_bic']),
// destination of transaction. If everything is null, assume cash account. // destination of transaction. If everything is null, assume cash account.
'destination_id' => $this->integerFromValue((string)$object['destination_id']), 'destination_id' => $this->integerFromValue((string) $object['destination_id']),
'destination_name' => $this->clearString((string)$object['destination_name']), 'destination_name' => $this->clearString((string) $object['destination_name']),
'destination_iban' => $this->clearString((string)$object['destination_iban']), 'destination_iban' => $this->clearString((string) $object['destination_iban']),
'destination_number' => $this->clearString((string)$object['destination_number']), 'destination_number' => $this->clearString((string) $object['destination_number']),
'destination_bic' => $this->clearString((string)$object['destination_bic']), 'destination_bic' => $this->clearString((string) $object['destination_bic']),
// budget info // budget info
'budget_id' => $this->integerFromValue((string)$object['budget_id']), 'budget_id' => $this->integerFromValue((string) $object['budget_id']),
'budget_name' => $this->clearString((string)$object['budget_name']), 'budget_name' => $this->clearString((string) $object['budget_name']),
// category info // category info
'category_id' => $this->integerFromValue((string)$object['category_id']), 'category_id' => $this->integerFromValue((string) $object['category_id']),
'category_name' => $this->clearString((string)$object['category_name']), 'category_name' => $this->clearString((string) $object['category_name']),
// journal bill reference. Optional. Will only work for withdrawals // journal bill reference. Optional. Will only work for withdrawals
'bill_id' => $this->integerFromValue((string)$object['bill_id']), 'bill_id' => $this->integerFromValue((string) $object['bill_id']),
'bill_name' => $this->clearString((string)$object['bill_name']), 'bill_name' => $this->clearString((string) $object['bill_name']),
// piggy bank reference. Optional. Will only work for transfers // piggy bank reference. Optional. Will only work for transfers
'piggy_bank_id' => $this->integerFromValue((string)$object['piggy_bank_id']), 'piggy_bank_id' => $this->integerFromValue((string) $object['piggy_bank_id']),
'piggy_bank_name' => $this->clearString((string)$object['piggy_bank_name']), 'piggy_bank_name' => $this->clearString((string) $object['piggy_bank_name']),
// some other interesting properties // some other interesting properties
'reconciled' => $this->convertBoolean((string)$object['reconciled']), 'reconciled' => $this->convertBoolean((string) $object['reconciled']),
'notes' => $this->clearStringKeepNewlines((string)$object['notes']), 'notes' => $this->clearStringKeepNewlines((string) $object['notes']),
'tags' => $this->arrayFromValue($object['tags']), 'tags' => $this->arrayFromValue($object['tags']),
// all custom fields: // all custom fields:
'internal_reference' => $this->clearString((string)$object['internal_reference']), 'internal_reference' => $this->clearString((string) $object['internal_reference']),
'external_id' => $this->clearString((string)$object['external_id']), 'external_id' => $this->clearString((string) $object['external_id']),
'original_source' => sprintf('ff3-v%s', config('firefly.version')), 'original_source' => sprintf('ff3-v%s', config('firefly.version')),
'recurrence_id' => $this->integerFromValue($object['recurrence_id']), 'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
'bunq_payment_id' => $this->clearString((string)$object['bunq_payment_id']), 'bunq_payment_id' => $this->clearString((string) $object['bunq_payment_id']),
'external_url' => $this->clearString((string)$object['external_url']), 'external_url' => $this->clearString((string) $object['external_url']),
'sepa_cc' => $this->clearString((string)$object['sepa_cc']), 'sepa_cc' => $this->clearString((string) $object['sepa_cc']),
'sepa_ct_op' => $this->clearString((string)$object['sepa_ct_op']), 'sepa_ct_op' => $this->clearString((string) $object['sepa_ct_op']),
'sepa_ct_id' => $this->clearString((string)$object['sepa_ct_id']), 'sepa_ct_id' => $this->clearString((string) $object['sepa_ct_id']),
'sepa_db' => $this->clearString((string)$object['sepa_db']), 'sepa_db' => $this->clearString((string) $object['sepa_db']),
'sepa_country' => $this->clearString((string)$object['sepa_country']), 'sepa_country' => $this->clearString((string) $object['sepa_country']),
'sepa_ep' => $this->clearString((string)$object['sepa_ep']), 'sepa_ep' => $this->clearString((string) $object['sepa_ep']),
'sepa_ci' => $this->clearString((string)$object['sepa_ci']), 'sepa_ci' => $this->clearString((string) $object['sepa_ci']),
'sepa_batch_id' => $this->clearString((string)$object['sepa_batch_id']), 'sepa_batch_id' => $this->clearString((string) $object['sepa_batch_id']),
// custom date fields. Must be Carbon objects. Presence is optional. // custom date fields. Must be Carbon objects. Presence is optional.
'interest_date' => $this->dateFromValue($object['interest_date']), 'interest_date' => $this->dateFromValue($object['interest_date']),
'book_date' => $this->dateFromValue($object['book_date']), 'book_date' => $this->dateFromValue($object['book_date']),

View File

@@ -139,7 +139,7 @@ class UpdateRequest extends Request
{ {
foreach ($this->integerFields as $fieldName) { foreach ($this->integerFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) { if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->integerFromValue((string)$transaction[$fieldName]); $current[$fieldName] = $this->integerFromValue((string) $transaction[$fieldName]);
} }
} }
@@ -154,7 +154,7 @@ class UpdateRequest extends Request
{ {
foreach ($this->stringFields as $fieldName) { foreach ($this->stringFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) { if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearString((string)$transaction[$fieldName]); $current[$fieldName] = $this->clearString((string) $transaction[$fieldName]);
} }
} }
@@ -169,7 +169,7 @@ class UpdateRequest extends Request
{ {
foreach ($this->textareaFields as $fieldName) { foreach ($this->textareaFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) { if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearStringKeepNewlines((string)$transaction[$fieldName]); // keep newlines $current[$fieldName] = $this->clearStringKeepNewlines((string) $transaction[$fieldName]); // keep newlines
} }
} }
@@ -185,8 +185,8 @@ class UpdateRequest extends Request
foreach ($this->dateFields as $fieldName) { foreach ($this->dateFields as $fieldName) {
app('log')->debug(sprintf('Now at date field %s', $fieldName)); app('log')->debug(sprintf('Now at date field %s', $fieldName));
if (array_key_exists($fieldName, $transaction)) { if (array_key_exists($fieldName, $transaction)) {
app('log')->debug(sprintf('New value: "%s"', (string)$transaction[$fieldName])); app('log')->debug(sprintf('New value: "%s"', (string) $transaction[$fieldName]));
$current[$fieldName] = $this->dateFromValue((string)$transaction[$fieldName]); $current[$fieldName] = $this->dateFromValue((string) $transaction[$fieldName]);
} }
} }
@@ -201,7 +201,7 @@ class UpdateRequest extends Request
{ {
foreach ($this->booleanFields as $fieldName) { foreach ($this->booleanFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) { if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->convertBoolean((string)$transaction[$fieldName]); $current[$fieldName] = $this->convertBoolean((string) $transaction[$fieldName]);
} }
} }
@@ -236,7 +236,7 @@ class UpdateRequest extends Request
$current[$fieldName] = sprintf('%.12f', $value); $current[$fieldName] = sprintf('%.12f', $value);
} }
if (!is_float($value)) { if (!is_float($value)) {
$current[$fieldName] = (string)$value; $current[$fieldName] = (string) $value;
} }
} }
} }

View File

@@ -52,7 +52,7 @@ class AutoSum
$amount = $getSum($object); $amount = $getSum($object);
$return[$currency->id] ??= [ $return[$currency->id] ??= [
'id' => (string)$currency->id, 'id' => (string) $currency->id,
'name' => $currency->name, 'name' => $currency->name,
'symbol' => $currency->symbol, 'symbol' => $currency->symbol,
'code' => $currency->code, 'code' => $currency->code,

View File

@@ -1,5 +1,25 @@
<?php <?php
/*
* ConvertsDatesToUTC.php
* Copyright (c) 2024 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); declare(strict_types=1);
/* /*
* ConvertDatesToUTC.php * ConvertDatesToUTC.php
@@ -21,7 +41,7 @@ declare(strict_types=1);
* along with this program. If not, see https://www.gnu.org/licenses/. * along with this program. If not, see https://www.gnu.org/licenses/.
*/ */
namespace FireflyIII\Console\Commands\Integrity; namespace FireflyIII\Console\Commands\Correction;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
@@ -31,17 +51,10 @@ use Illuminate\Database\QueryException;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
class ConvertDatesToUTC extends Command class ConvertsDatesToUTC extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:migrate-to-utc';
/** /**
* The console command description. * The console command description.
* *
@@ -49,11 +62,22 @@ class ConvertDatesToUTC extends Command
*/ */
protected $description = 'Convert stored dates to UTC.'; protected $description = 'Convert stored dates to UTC.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'correction:convert-to-utc';
/** /**
* Execute the console command. * Execute the console command.
*/ */
public function handle(): int public function handle(): int
{ {
$this->friendlyWarning('Please do not use this command.');
return 0;
/** /**
* @var string $model * @var string $model
* @var array $fields * @var array $fields

View File

@@ -29,15 +29,12 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Console\Command; use Illuminate\Console\Command;
/** class CorrectsAccountOrder extends Command
* Class FixAccountOrder
*/
class FixAccountOrder extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'Make sure account order is correct.'; protected $description = 'Make sure account order is correct.';
protected $signature = 'firefly-iii:fix-account-order'; protected $signature = 'correction:account-order';
private AccountRepositoryInterface $repository; private AccountRepositoryInterface $repository;
@@ -54,8 +51,6 @@ class FixAccountOrder extends Command
$this->repository->resetAccountOrder(); $this->repository->resetAccountOrder();
} }
$this->friendlyPositive('All accounts are ordered correctly');
return 0; return 0;
} }

View File

@@ -36,15 +36,12 @@ use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\JoinClause; use Illuminate\Database\Query\JoinClause;
/** class CorrectsAccountTypes extends Command
* Class FixAccountTypes
*/
class FixAccountTypes extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'Make sure all journals have the correct from/to account types.'; protected $description = 'Make sure all journals have the correct from/to account types.';
protected $signature = 'firefly-iii:fix-account-types'; protected $signature = 'correction:account-types';
private int $count; private int $count;
private array $expected; private array $expected;
private AccountFactory $factory; private AccountFactory $factory;
@@ -120,9 +117,6 @@ class FixAccountTypes extends Command
} }
} }
} }
if (0 === $this->count) {
$this->friendlyPositive('All account types are OK');
}
if (0 !== $this->count) { if (0 !== $this->count) {
app('log')->debug(sprintf('%d journals had to be fixed.', $this->count)); app('log')->debug(sprintf('%d journals had to be fixed.', $this->count));
$this->friendlyInfo(sprintf('Acted on %d transaction(s)', $this->count)); $this->friendlyInfo(sprintf('Acted on %d transaction(s)', $this->count));

View File

@@ -36,15 +36,12 @@ use FireflyIII\Models\RuleTrigger;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
/** class CorrectsAmounts extends Command
* Class ReportSkeleton
*/
class CorrectAmounts extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'This command makes sure positive and negative amounts are recorded correctly.'; protected $description = 'This command makes sure positive and negative amounts are recorded correctly.';
protected $signature = 'firefly-iii:fix-amount-pos-neg'; protected $signature = 'correction:amounts';
public function handle(): int public function handle(): int
{ {
@@ -72,7 +69,6 @@ class CorrectAmounts extends Command
{ {
$count = AutoBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]); $count = AutoBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
if (0 === $count) { if (0 === $count) {
$this->friendlyPositive('All auto budget amounts are positive.');
return; return;
} }
@@ -83,7 +79,6 @@ class CorrectAmounts extends Command
{ {
$count = AvailableBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]); $count = AvailableBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
if (0 === $count) { if (0 === $count) {
$this->friendlyPositive('All available budget amounts are positive.');
return; return;
} }
@@ -96,7 +91,6 @@ class CorrectAmounts extends Command
$count += Bill::where('amount_max', '<', 0)->update(['amount_max' => DB::raw('amount_max * -1')]); $count += Bill::where('amount_max', '<', 0)->update(['amount_max' => DB::raw('amount_max * -1')]);
$count += Bill::where('amount_min', '<', 0)->update(['amount_min' => DB::raw('amount_min * -1')]); $count += Bill::where('amount_min', '<', 0)->update(['amount_min' => DB::raw('amount_min * -1')]);
if (0 === $count) { if (0 === $count) {
$this->friendlyPositive('All bill amounts are positive.');
return; return;
} }
@@ -107,7 +101,6 @@ class CorrectAmounts extends Command
{ {
$count = BudgetLimit::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]); $count = BudgetLimit::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
if (0 === $count) { if (0 === $count) {
$this->friendlyPositive('All budget limit amounts are positive.');
return; return;
} }
@@ -118,7 +111,6 @@ class CorrectAmounts extends Command
{ {
$count = CurrencyExchangeRate::where('rate', '<', 0)->update(['rate' => DB::raw('rate * -1')]); $count = CurrencyExchangeRate::where('rate', '<', 0)->update(['rate' => DB::raw('rate * -1')]);
if (0 === $count) { if (0 === $count) {
$this->friendlyPositive('All currency exchange rates are positive.');
return; return;
} }
@@ -129,7 +121,6 @@ class CorrectAmounts extends Command
{ {
$count = PiggyBank::where('target_amount', '<', 0)->update(['target_amount' => DB::raw('target_amount * -1')]); $count = PiggyBank::where('target_amount', '<', 0)->update(['target_amount' => DB::raw('target_amount * -1')]);
if (0 === $count) { if (0 === $count) {
$this->friendlyPositive('All piggy bank amounts are positive.');
return; return;
} }
@@ -142,7 +133,6 @@ class CorrectAmounts extends Command
$count += RecurrenceTransaction::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]); $count += RecurrenceTransaction::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
$count += RecurrenceTransaction::where('foreign_amount', '<', 0)->update(['foreign_amount' => DB::raw('foreign_amount * -1')]); $count += RecurrenceTransaction::where('foreign_amount', '<', 0)->update(['foreign_amount' => DB::raw('foreign_amount * -1')]);
if (0 === $count) { if (0 === $count) {
$this->friendlyPositive('All recurring transaction amounts are positive.');
return; return;
} }
@@ -165,7 +155,6 @@ class CorrectAmounts extends Command
} }
} }
if (0 === $fixed) { if (0 === $fixed) {
$this->friendlyPositive('All rule trigger amounts are positive.');
return; return;
} }

View File

@@ -37,15 +37,12 @@ use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Symfony\Component\Console\Command\Command as CommandAlias; use Symfony\Component\Console\Command\Command as CommandAlias;
/** class CorrectsCurrencies extends Command
* Class EnableCurrencies
*/
class EnableCurrencies extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'Enables all currencies in use.'; protected $description = 'Enables all currencies in use.';
protected $signature = 'firefly-iii:enable-currencies'; protected $signature = 'correction:currencies';
/** /**
* Execute the console command. * Execute the console command.
@@ -77,7 +74,7 @@ class EnableCurrencies extends Command
->where('account_meta.name', 'currency_id')->groupBy('data')->get(['data']) ->where('account_meta.name', 'currency_id')->groupBy('data')->get(['data'])
; ;
foreach ($meta as $entry) { foreach ($meta as $entry) {
$found[] = (int)$entry->data; $found[] = (int) $entry->data;
} }
// get all from journals: // get all from journals:
@@ -85,7 +82,7 @@ class EnableCurrencies extends Command
->groupBy('transaction_currency_id')->get(['transaction_currency_id']) ->groupBy('transaction_currency_id')->get(['transaction_currency_id'])
; ;
foreach ($journals as $entry) { foreach ($journals as $entry) {
$found[] = (int)$entry->transaction_currency_id; $found[] = (int) $entry->transaction_currency_id;
} }
// get all from transactions // get all from transactions
@@ -95,8 +92,8 @@ class EnableCurrencies extends Command
->get(['transactions.transaction_currency_id', 'transactions.foreign_currency_id']) ->get(['transactions.transaction_currency_id', 'transactions.foreign_currency_id'])
; ;
foreach ($transactions as $entry) { foreach ($transactions as $entry) {
$found[] = (int)$entry->transaction_currency_id; $found[] = (int) $entry->transaction_currency_id;
$found[] = (int)$entry->foreign_currency_id; $found[] = (int) $entry->foreign_currency_id;
} }
// get all from budget limits // get all from budget limits

View File

@@ -27,14 +27,11 @@ namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command; use Illuminate\Console\Command;
/** class CorrectsDatabase extends Command
* Class CorrectDatabase
*/
class CorrectDatabase extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'Will correct the integrity of your database, if necessary.'; protected $description = 'Will validate and correct the integrity of your database, if necessary.';
protected $signature = 'firefly-iii:correct-database'; protected $signature = 'firefly-iii:correct-database';
/** /**
@@ -49,32 +46,36 @@ class CorrectDatabase extends Command
return 1; return 1;
} }
$commands = [ $commands = [
'firefly-iii:fix-piggies', 'correction:restore-oauth-keys',
'firefly-iii:create-link-types', 'correction:timezones',
'firefly-iii:create-access-tokens', 'correction:create-group-memberships',
'firefly-iii:remove-bills', 'correction:group-information',
'firefly-iii:fix-amount-pos-neg', 'correction:piggy-banks',
'firefly-iii:enable-currencies', 'correction:link-types',
'firefly-iii:fix-transfer-budgets', 'correction:access-tokens',
'firefly-iii:fix-uneven-amount', 'correction:bills',
'firefly-iii:delete-zero-amount', 'correction:amounts',
'firefly-iii:delete-orphaned-transactions', 'correction:currencies',
'firefly-iii:delete-empty-journals', 'correction:transfer-budgets',
'firefly-iii:delete-empty-groups', 'correction:uneven-amounts',
'firefly-iii:fix-account-types', 'correction:zero-amounts',
'firefly-iii:fix-ibans', 'correction:orphaned-transactions',
'firefly-iii:fix-account-order', 'correction:empty-journals',
'firefly-iii:rename-meta-fields', 'correction:empty-groups',
'firefly-iii:fix-ob-currencies', 'correction:account-types',
'firefly-iii:fix-long-descriptions', 'correction:ibans',
'firefly-iii:fix-recurring-transactions', 'correction:account-order',
'firefly-iii:upgrade-group-information', 'correction:meta-fields',
// 'firefly-iii:fix-transaction-types', // very resource heavy. 'correction:opening-balance-currencies',
'firefly-iii:fix-frontpage-accounts', 'correction:long-descriptions',
// new! 'correction:recurring-transactions',
'firefly-iii:unify-group-accounts', 'correction:frontpage-accounts',
'firefly-iii:trigger-credit-recalculation', 'correction:group-accounts',
'firefly-iii:migrate-preferences', 'correction:recalculates-liabilities',
'correction:preferences',
// 'correction:transaction-types', // resource heavy, disabled.
// 'correction:recalculate-native-amounts', // not necessary, disabled.
'firefly-iii:report-integrity',
]; ];
foreach ($commands as $command) { foreach ($commands as $command) {
$this->friendlyLine(sprintf('Now executing command "%s"', $command)); $this->friendlyLine(sprintf('Now executing command "%s"', $command));

View File

@@ -31,15 +31,12 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Console\Command; use Illuminate\Console\Command;
/** class CorrectsFrontpageAccounts extends Command
* Class FixFrontpageAccounts
*/
class FixFrontpageAccounts extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'Fixes a preference that may include deleted accounts or accounts of another type.'; protected $description = 'Fixes a preference that may include deleted accounts or accounts of another type.';
protected $signature = 'firefly-iii:fix-frontpage-accounts'; protected $signature = 'correction:frontpage-accounts';
/** /**
* Execute the console command. * Execute the console command.
@@ -55,7 +52,6 @@ class FixFrontpageAccounts extends Command
$this->fixPreference($preference); $this->fixPreference($preference);
} }
} }
$this->friendlyPositive('Account preferences are OK');
return 0; return 0;
} }
@@ -74,7 +70,7 @@ class FixFrontpageAccounts extends Command
if (is_array($data)) { if (is_array($data)) {
/** @var string $accountId */ /** @var string $accountId */
foreach ($data as $accountId) { foreach ($data as $accountId) {
$accountIdInt = (int)$accountId; $accountIdInt = (int) $accountId;
$account = $repository->find($accountIdInt); $account = $repository->find($accountIdInt);
if (null !== $account if (null !== $account
&& in_array($account->accountType->type, [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE], true) && in_array($account->accountType->type, [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE], true)

View File

@@ -34,12 +34,12 @@ use Illuminate\Console\Command;
/** /**
* Class FixGroupAccounts * Class FixGroupAccounts
*/ */
class FixGroupAccounts extends Command class CorrectsGroupAccounts extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'Unify the source / destination accounts of split groups.'; protected $description = 'Unify the source / destination accounts of split groups.';
protected $signature = 'firefly-iii:unify-group-accounts'; protected $signature = 'correction:group-accounts';
/** /**
* Execute the console command. * Execute the console command.
@@ -53,8 +53,8 @@ class FixGroupAccounts extends Command
/** @var TransactionJournal $journal */ /** @var TransactionJournal $journal */
foreach ($res as $journal) { foreach ($res as $journal) {
if ((int)$journal->the_count > 1) { if ((int) $journal->the_count > 1) {
$groups[] = (int)$journal->transaction_group_id; $groups[] = (int) $journal->transaction_group_id;
} }
} }
$handler = new UpdatedGroupEventHandler(); $handler = new UpdatedGroupEventHandler();
@@ -64,8 +64,6 @@ class FixGroupAccounts extends Command
$handler->unifyAccounts($event); $handler->unifyAccounts($event);
} }
$this->friendlyPositive('Updated possible inconsistent transaction groups.');
return 0; return 0;
} }
} }

View File

@@ -1,8 +1,8 @@
<?php <?php
/* /*
* UpdateGroupInformation.php * CorrectsGroupInformation.php
* Copyright (c) 2022 james@firefly-iii.org * Copyright (c) 2024 james@firefly-iii.org.
* *
* This file is part of Firefly III (https://github.com/firefly-iii). * This file is part of Firefly III (https://github.com/firefly-iii).
* *
@@ -17,12 +17,12 @@
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see https://www.gnu.org/licenses/.
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace FireflyIII\Console\Commands\Integrity; namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
@@ -45,15 +45,12 @@ use FireflyIII\User;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Database\QueryException; use Illuminate\Database\QueryException;
/** class CorrectsGroupInformation extends Command
* Class UpdateGroupInformation
*/
class UpdateGroupInformation extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'Makes sure that every object is linked to a group'; protected $description = 'Makes sure that every object is linked to a group';
protected $signature = 'firefly-iii:upgrade-group-information'; protected $signature = 'correction:group-information';
/** /**
* Execute the console command. * Execute the console command.
@@ -79,7 +76,7 @@ class UpdateGroupInformation extends Command
{ {
$group = $user->userGroup; $group = $user->userGroup;
if (null === $group) { if (null === $group) {
$this->friendlyWarning(sprintf('User "%s" has no group.', $user->email)); $this->friendlyWarning(sprintf('User "%s" has no group. Please run "php artisan firefly-iii:create-group-memberships"', $user->email));
return; return;
} }

View File

@@ -30,15 +30,12 @@ use FireflyIII\Models\AccountType;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
/** class CorrectsIbans extends Command
* Class FixIbans
*/
class FixIbans extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'Removes spaces from IBANs'; protected $description = 'Removes spaces from IBANs';
protected $signature = 'firefly-iii:fix-ibans'; protected $signature = 'correction:ibans';
private int $count = 0; private int $count = 0;
/** /**
@@ -49,9 +46,6 @@ class FixIbans extends Command
$accounts = Account::whereNotNull('iban')->get(); $accounts = Account::whereNotNull('iban')->get();
$this->filterIbans($accounts); $this->filterIbans($accounts);
$this->countAndCorrectIbans($accounts); $this->countAndCorrectIbans($accounts);
if (0 === $this->count) {
$this->friendlyPositive('All IBANs are valid.');
}
return 0; return 0;
} }

View File

@@ -28,24 +28,22 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
/** class CorrectsLongDescriptions extends Command
* Class FixLongDescriptions
*/
class FixLongDescriptions extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
private const int MAX_LENGTH = 1000; private const int MAX_LENGTH = 1000;
protected $description = 'Fixes long descriptions in journals and groups.'; protected $description = 'Fixes long descriptions in journals and groups.';
protected $signature = 'firefly-iii:fix-long-descriptions'; protected $signature = 'correction:long-descriptions';
/** /**
* Execute the console command. * Execute the console command.
*/ */
public function handle(): int public function handle(): int
{ {
$journals = TransactionJournal::get(['id', 'description']); $journals = TransactionJournal::where(DB::raw('LENGTH(description)'), '>', self::MAX_LENGTH)->get(['id', 'description']);
$count = 0; $count = 0;
/** @var TransactionJournal $journal */ /** @var TransactionJournal $journal */
@@ -58,20 +56,17 @@ class FixLongDescriptions extends Command
} }
} }
$groups = TransactionGroup::get(['id', 'title']); $groups = TransactionGroup::where(DB::raw('LENGTH(title)'), '>', self::MAX_LENGTH)->get(['id', 'title']);
/** @var TransactionGroup $group */ /** @var TransactionGroup $group */
foreach ($groups as $group) { foreach ($groups as $group) {
if (strlen((string)$group->title) > self::MAX_LENGTH) { if (strlen((string) $group->title) > self::MAX_LENGTH) {
$group->title = substr($group->title, 0, self::MAX_LENGTH); $group->title = substr($group->title, 0, self::MAX_LENGTH);
$group->save(); $group->save();
$this->friendlyWarning(sprintf('Truncated description of transaction group #%d', $group->id)); $this->friendlyWarning(sprintf('Truncated description of transaction group #%d', $group->id));
++$count; ++$count;
} }
} }
if (0 === $count) {
$this->friendlyPositive('All transaction group and journal title lengths are within bounds.');
}
return 0; return 0;
} }

View File

@@ -26,16 +26,14 @@ namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
/** class CorrectsMetaDataFields extends Command
* Class RenameMetaFields
*/
class RenameMetaFields extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'Rename changed meta fields.'; protected $description = 'Rename changed meta fields.';
protected $signature = 'firefly-iii:rename-meta-fields'; protected $signature = 'correction:meta-fields';
private int $count = 0; private int $count = 0;
@@ -61,9 +59,6 @@ class RenameMetaFields extends Command
foreach ($changes as $original => $update) { foreach ($changes as $original => $update) {
$this->rename($original, $update); $this->rename($original, $update);
} }
if (0 === $this->count) {
$this->friendlyPositive('All meta fields are correct.');
}
if (0 !== $this->count) { if (0 !== $this->count) {
$this->friendlyInfo(sprintf('Renamed %d meta field(s).', $this->count)); $this->friendlyInfo(sprintf('Renamed %d meta field(s).', $this->count));
} }
@@ -73,7 +68,7 @@ class RenameMetaFields extends Command
private function rename(string $original, string $update): void private function rename(string $original, string $update): void
{ {
$total = \DB::table('journal_meta') $total = DB::table('journal_meta')
->where('name', '=', $original) ->where('name', '=', $original)
->update(['name' => $update]) ->update(['name' => $update])
; ;

View File

@@ -46,13 +46,13 @@ use Illuminate\Database\Query\Builder as DatabaseBuilder;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
class RecalculateNativeAmounts extends Command class CorrectsNativeAmounts extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'Recalculate native amounts for all objects.'; protected $description = 'Recalculate native amounts for all objects.';
protected $signature = 'firefly-iii:recalculate-native-amounts'; protected $signature = 'correction:recalculate-native-amounts';
/** /**
* Execute the console command. * Execute the console command.
@@ -108,6 +108,7 @@ class RecalculateNativeAmounts extends Command
private function recalculatePiggyBanks(UserGroup $userGroup, TransactionCurrency $currency): void private function recalculatePiggyBanks(UserGroup $userGroup, TransactionCurrency $currency): void
{ {
$converter = new ExchangeRateConverter(); $converter = new ExchangeRateConverter();
$converter->setUserGroup($userGroup);
$converter->setIgnoreSettings(true); $converter->setIgnoreSettings(true);
$repository = app(PiggyBankRepositoryInterface::class); $repository = app(PiggyBankRepositoryInterface::class);
$repository->setUserGroup($userGroup); $repository->setUserGroup($userGroup);
@@ -181,17 +182,6 @@ class RecalculateNativeAmounts extends Command
Log::debug(sprintf('Recalculated %d auto budgets.', $set->count())); Log::debug(sprintf('Recalculated %d auto budgets.', $set->count()));
} }
private function recalculateBills(UserGroup $userGroup, TransactionCurrency $currency): void
{
$set = $userGroup->bills()->where('transaction_currency_id', '!=', $currency->id)->get();
/** @var Bill $bill */
foreach ($set as $bill) {
$bill->touch();
}
Log::debug(sprintf('Recalculated %d bills.', $set->count()));
}
private function recalculateAvailableBudgets(UserGroup $userGroup, TransactionCurrency $currency): void private function recalculateAvailableBudgets(UserGroup $userGroup, TransactionCurrency $currency): void
{ {
Log::debug('Start with available budgets.'); Log::debug('Start with available budgets.');
@@ -204,17 +194,36 @@ class RecalculateNativeAmounts extends Command
Log::debug(sprintf('Recalculated %d available budgets.', $set->count())); Log::debug(sprintf('Recalculated %d available budgets.', $set->count()));
} }
private function recalculateBills(UserGroup $userGroup, TransactionCurrency $currency): void
{
$set = $userGroup->bills()->where('transaction_currency_id', '!=', $currency->id)->get();
/** @var Bill $bill */
foreach ($set as $bill) {
$bill->touch();
}
Log::debug(sprintf('Recalculated %d bills.', $set->count()));
}
private function calculateTransactions(UserGroup $userGroup, TransactionCurrency $currency): void private function calculateTransactions(UserGroup $userGroup, TransactionCurrency $currency): void
{ {
// custom query because of the potential size of this update. // custom query because of the potential size of this update.
$set = DB::table('transactions') $set = DB::table('transactions')
->join('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->join('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.user_group_id', $userGroup->id) ->where('transaction_journals.user_group_id', $userGroup->id)
->where(static function (DatabaseBuilder $q) use ($currency): void {
$q->whereNot('transactions.transaction_currency_id', $currency->id) ->where(function (DatabaseBuilder $q1) use ($currency): void {
->orWhereNot('transactions.foreign_currency_id', $currency->id) $q1->where(function (DatabaseBuilder $q2) use ($currency): void {
; $q2->whereNot('transactions.transaction_currency_id', $currency->id)->whereNull('transactions.foreign_currency_id');
})->orWhere(function (DatabaseBuilder $q3) use ($currency): void {
$q3->whereNot('transactions.transaction_currency_id', $currency->id)->whereNot('transactions.foreign_currency_id', $currency->id);
});
}) })
// ->where(static function (DatabaseBuilder $q) use ($currency): void {
// $q->whereNot('transactions.transaction_currency_id', $currency->id)
// ->whereNot('transactions.foreign_currency_id', $currency->id)
// ;
// })
->get(['transactions.id']) ->get(['transactions.id'])
; ;
TransactionObserver::$recalculate = false; TransactionObserver::$recalculate = false;

View File

@@ -35,15 +35,12 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
/** class CorrectsOpeningBalanceCurrencies extends Command
* Class CorrectOpeningBalanceCurrencies
*/
class CorrectOpeningBalanceCurrencies extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'Will make sure that opening balance transaction currencies match the account they\'re for.'; protected $description = 'Will make sure that opening balance transaction currencies match the account they\'re for.';
protected $signature = 'firefly-iii:fix-ob-currencies'; protected $signature = 'correction:opening-balance-currencies';
/** /**
* Execute the console command. * Execute the console command.
@@ -62,10 +59,6 @@ class CorrectOpeningBalanceCurrencies extends Command
$message = sprintf('Corrected %d opening balance transaction(s).', $count); $message = sprintf('Corrected %d opening balance transaction(s).', $count);
$this->friendlyInfo($message); $this->friendlyInfo($message);
} }
if (0 === $count) {
$message = 'There was nothing to fix in the opening balance transactions.';
$this->friendlyPositive($message);
}
return 0; return 0;
} }
@@ -115,7 +108,7 @@ class CorrectOpeningBalanceCurrencies extends Command
{ {
$currency = $this->getCurrency($account); $currency = $this->getCurrency($account);
$count = 0; $count = 0;
if ((int)$journal->transaction_currency_id !== $currency->id) { if ((int) $journal->transaction_currency_id !== $currency->id) {
$journal->transaction_currency_id = $currency->id; $journal->transaction_currency_id = $currency->id;
$journal->save(); $journal->save();
$count = 1; $count = 1;

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