mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Clean up some code.
This commit is contained in:
parent
b930ad4da7
commit
7d8d773f8f
@ -66,9 +66,9 @@ class PiggyBankController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function piggyBanks(AutocompleteRequest $request): JsonResponse
|
public function piggyBanks(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
/** @var PiggyBank $piggy */
|
/** @var PiggyBank $piggy */
|
||||||
foreach ($piggies as $piggy) {
|
foreach ($piggies as $piggy) {
|
||||||
@ -96,9 +96,9 @@ class PiggyBankController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function piggyBanksWithBalance(AutocompleteRequest $request): JsonResponse
|
public function piggyBanksWithBalance(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
/** @var PiggyBank $piggy */
|
/** @var PiggyBank $piggy */
|
||||||
foreach ($piggies as $piggy) {
|
foreach ($piggies as $piggy) {
|
||||||
|
@ -63,8 +63,8 @@ class DestroyController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function destroy(DestroyRequest $request): JsonResponse
|
public function destroy(DestroyRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$objects = $request->getObjects();
|
$objects = $request->getObjects();
|
||||||
$this->unused = $request->boolean('unused', false);
|
$this->unused = $request->boolean('unused', false);
|
||||||
|
|
||||||
$allExceptAssets = [AccountType::BENEFICIARY, AccountType::CASH, AccountType::CREDITCARD, AccountType::DEFAULT, AccountType::EXPENSE, AccountType::IMPORT, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT, AccountType::RECONCILIATION, AccountType::REVENUE];
|
$allExceptAssets = [AccountType::BENEFICIARY, AccountType::CASH, AccountType::CREDITCARD, AccountType::DEFAULT, AccountType::EXPENSE, AccountType::IMPORT, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT, AccountType::RECONCILIATION, AccountType::REVENUE];
|
||||||
$all = [AccountType::ASSET, AccountType::BENEFICIARY, AccountType::CASH, AccountType::CREDITCARD, AccountType::DEBT, AccountType::DEFAULT, AccountType::EXPENSE, AccountType::IMPORT, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::RECONCILIATION];
|
$all = [AccountType::ASSET, AccountType::BENEFICIARY, AccountType::CASH, AccountType::CREDITCARD, AccountType::DEBT, AccountType::DEFAULT, AccountType::EXPENSE, AccountType::IMPORT, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::RECONCILIATION];
|
||||||
@ -101,11 +101,11 @@ class DestroyController extends Controller
|
|||||||
private function destroyBudgets(): void
|
private function destroyBudgets(): void
|
||||||
{
|
{
|
||||||
/** @var AvailableBudgetRepositoryInterface $abRepository */
|
/** @var AvailableBudgetRepositoryInterface $abRepository */
|
||||||
$abRepository = app(AvailableBudgetRepositoryInterface::class);
|
$abRepository = app(AvailableBudgetRepositoryInterface::class);
|
||||||
$abRepository->destroyAll();
|
$abRepository->destroyAll();
|
||||||
|
|
||||||
/** @var BudgetLimitRepositoryInterface $blRepository */
|
/** @var BudgetLimitRepositoryInterface $blRepository */
|
||||||
$blRepository = app(BudgetLimitRepositoryInterface::class);
|
$blRepository = app(BudgetLimitRepositoryInterface::class);
|
||||||
$blRepository->destroyAll();
|
$blRepository->destroyAll();
|
||||||
|
|
||||||
/** @var BudgetRepositoryInterface $budgetRepository */
|
/** @var BudgetRepositoryInterface $budgetRepository */
|
||||||
|
@ -53,7 +53,7 @@ class PurgeController extends Controller
|
|||||||
public function purge(): JsonResponse
|
public function purge(): JsonResponse
|
||||||
{
|
{
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
// some manual code, too lazy to call all repositories.
|
// some manual code, too lazy to call all repositories.
|
||||||
|
|
||||||
@ -67,14 +67,14 @@ class PurgeController extends Controller
|
|||||||
$repository = app(PiggyBankRepositoryInterface::class);
|
$repository = app(PiggyBankRepositoryInterface::class);
|
||||||
$repository->setUser($user);
|
$repository->setUser($user);
|
||||||
$repository->purgeAll();
|
$repository->purgeAll();
|
||||||
// $set = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
|
// $set = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
|
||||||
// ->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*'])
|
// ->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*'])
|
||||||
// ;
|
// ;
|
||||||
//
|
//
|
||||||
// /** @var PiggyBank $piggy */
|
// /** @var PiggyBank $piggy */
|
||||||
// foreach ($set as $piggy) {
|
// foreach ($set as $piggy) {
|
||||||
// $piggy->forceDelete();
|
// $piggy->forceDelete();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// rule group
|
// rule group
|
||||||
RuleGroup::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
RuleGroup::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
||||||
|
@ -28,7 +28,6 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,6 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,6 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
@ -72,14 +72,14 @@ class StoreController extends Controller
|
|||||||
$data['notes'] = $data['notes'];
|
$data['notes'] = $data['notes'];
|
||||||
$data['budget_id'] = $budget->id;
|
$data['budget_id'] = $budget->id;
|
||||||
|
|
||||||
$budgetLimit = $this->blRepository->store($data);
|
$budgetLimit = $this->blRepository->store($data);
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var BudgetLimitTransformer $transformer */
|
/** @var BudgetLimitTransformer $transformer */
|
||||||
$transformer = app(BudgetLimitTransformer::class);
|
$transformer = app(BudgetLimitTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($budgetLimit, $transformer, 'budget_limits');
|
$resource = new Item($budgetLimit, $transformer, 'budget_limits');
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,6 @@ 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\Models\AccountType;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
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;
|
||||||
|
@ -53,10 +53,11 @@ class UpdateRequest extends FormRequest
|
|||||||
'currency_code' => ['currency_code', 'convertString'],
|
'currency_code' => ['currency_code', 'convertString'],
|
||||||
'notes' => ['notes', 'stringWithNewlines'],
|
'notes' => ['notes', 'stringWithNewlines'],
|
||||||
];
|
];
|
||||||
if(false === $this->has('notes')) {
|
if (false === $this->has('notes')) {
|
||||||
// ignore notes, not submitted.
|
// ignore notes, not submitted.
|
||||||
unset($fields['notes']);
|
unset($fields['notes']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getAllData($fields);
|
return $this->getAllData($fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
|
||||||
use FireflyIII\Rules\IsValidZeroOrMoreAmount;
|
use FireflyIII\Rules\IsValidZeroOrMoreAmount;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
@ -96,9 +95,9 @@ class StoreRequest extends FormRequest
|
|||||||
$validator->after(
|
$validator->after(
|
||||||
function (Validator $validator): void {
|
function (Validator $validator): void {
|
||||||
// validate start before end only if both are there.
|
// validate start before end only if both are there.
|
||||||
$data = $validator->getData();
|
$data = $validator->getData();
|
||||||
$currency = $this->getCurrencyFromData($data);
|
$currency = $this->getCurrencyFromData($data);
|
||||||
$targetAmount = (string) ($data['target_amount'] ?? '0');
|
$targetAmount = (string) ($data['target_amount'] ?? '0');
|
||||||
$currentAmount = '0';
|
$currentAmount = '0';
|
||||||
if (array_key_exists('accounts', $data) && is_array($data['accounts'])) {
|
if (array_key_exists('accounts', $data) && is_array($data['accounts'])) {
|
||||||
$repository = app(AccountRepositoryInterface::class);
|
$repository = app(AccountRepositoryInterface::class);
|
||||||
@ -110,18 +109,18 @@ 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'));
|
||||||
}
|
}
|
||||||
$type = $account->accountType->type;
|
$type = $account->accountType->type;
|
||||||
if (!in_array($type, $types, true)) {
|
if (!in_array($type, $types, true)) {
|
||||||
$validator->errors()->add(sprintf('accounts.%d', $index), trans('validation.invalid_account_type'));
|
$validator->errors()->add(sprintf('accounts.%d', $index), trans('validation.invalid_account_type'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(bccomp($targetAmount, $currentAmount) === -1 && bccomp($targetAmount, '0') === 1) {
|
if (-1 === bccomp($targetAmount, $currentAmount) && 1 === bccomp($targetAmount, '0')) {
|
||||||
$validator->errors()->add('target_amount', trans('validation.current_amount_too_much'));
|
$validator->errors()->add('target_amount', trans('validation.current_amount_too_much'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,6 +145,7 @@ class StoreRequest extends FormRequest
|
|||||||
'current_amount' => $this->clearString((string) ($entry['current_amount'] ?? '0')),
|
'current_amount' => $this->clearString((string) ($entry['current_amount'] ?? '0')),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +163,7 @@ class StoreRequest extends FormRequest
|
|||||||
return $currency;
|
return $currency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new FireflyException('Unexpected empty currency.');
|
throw new FireflyException('Unexpected empty currency.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ use FireflyIII\Enums\TransactionTypeEnum;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Chart\ChartData;
|
use FireflyIII\Support\Chart\ChartData;
|
||||||
use FireflyIII\Support\Http\Api\AccountBalanceGrouped;
|
use FireflyIII\Support\Http\Api\AccountBalanceGrouped;
|
||||||
|
@ -31,7 +31,6 @@ use FireflyIII\Enums\TransactionTypeEnum;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\AccountType;
|
use FireflyIII\Models\AccountType;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||||
|
@ -33,7 +33,6 @@ 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\Models\AccountType;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Models\UserGroup;
|
use FireflyIII\Models\UserGroup;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
|
||||||
|
@ -265,8 +265,8 @@ class ApplyRules extends Command
|
|||||||
private function verifyInputDates(): void
|
private function verifyInputDates(): void
|
||||||
{
|
{
|
||||||
// parse start date.
|
// parse start date.
|
||||||
$inputStart = today(config('app.timezone'))->startOfMonth();
|
$inputStart = today(config('app.timezone'))->startOfMonth();
|
||||||
$startString = $this->option('start_date');
|
$startString = $this->option('start_date');
|
||||||
if (null === $startString) {
|
if (null === $startString) {
|
||||||
/** @var JournalRepositoryInterface $repository */
|
/** @var JournalRepositoryInterface $repository */
|
||||||
$repository = app(JournalRepositoryInterface::class);
|
$repository = app(JournalRepositoryInterface::class);
|
||||||
@ -281,8 +281,8 @@ class ApplyRules extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parse end date
|
// parse end date
|
||||||
$inputEnd = today(config('app.timezone'));
|
$inputEnd = today(config('app.timezone'));
|
||||||
$endString = $this->option('end_date');
|
$endString = $this->option('end_date');
|
||||||
if (null !== $endString && '' !== $endString) {
|
if (null !== $endString && '' !== $endString) {
|
||||||
$inputEnd = Carbon::createFromFormat('Y-m-d', $endString);
|
$inputEnd = Carbon::createFromFormat('Y-m-d', $endString);
|
||||||
}
|
}
|
||||||
@ -297,7 +297,7 @@ class ApplyRules extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->start_date = $inputStart;
|
$this->start_date = $inputStart;
|
||||||
$this->endDate = $inputEnd;
|
$this->endDate = $inputEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function grabAllRules(): void
|
private function grabAllRules(): void
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
/*
|
/*
|
||||||
* UpgradeMultiPiggyBanks.php
|
* UpgradeMultiPiggyBanks.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
@ -34,17 +36,15 @@ class UpgradeMultiPiggyBanks extends Command
|
|||||||
|
|
||||||
public const string CONFIG_NAME = '620_make_multi_piggies';
|
public const string CONFIG_NAME = '620_make_multi_piggies';
|
||||||
|
|
||||||
protected $description = 'Upgrade piggybanks so they can use multiple accounts.';
|
protected $description = 'Upgrade piggybanks so they can use multiple accounts.';
|
||||||
|
|
||||||
protected $signature = 'firefly-iii:upgrade-multi-piggies {--F|force : Force the execution of this command.}';
|
protected $signature = 'firefly-iii:upgrade-multi-piggies {--F|force : Force the execution of this command.}';
|
||||||
|
|
||||||
private PiggyBankRepositoryInterface $repository;
|
private PiggyBankRepositoryInterface $repository;
|
||||||
private AccountRepositoryInterface $accountRepository;
|
private AccountRepositoryInterface $accountRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
@ -61,9 +61,6 @@ class UpgradeMultiPiggyBanks extends Command
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
||||||
@ -74,10 +71,6 @@ class UpgradeMultiPiggyBanks extends Command
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private function markAsExecuted(): void
|
private function markAsExecuted(): void
|
||||||
{
|
{
|
||||||
app('fireflyconfig')->set(self::CONFIG_NAME, true);
|
app('fireflyconfig')->set(self::CONFIG_NAME, true);
|
||||||
@ -89,6 +82,7 @@ class UpgradeMultiPiggyBanks extends Command
|
|||||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||||
$set = PiggyBank::whereNotNull('account_id')->get();
|
$set = PiggyBank::whereNotNull('account_id')->get();
|
||||||
Log::debug(sprintf('Will update %d piggy banks(s).', $set->count()));
|
Log::debug(sprintf('Will update %d piggy banks(s).', $set->count()));
|
||||||
|
|
||||||
/** @var PiggyBank $piggyBank */
|
/** @var PiggyBank $piggyBank */
|
||||||
foreach ($set as $piggyBank) {
|
foreach ($set as $piggyBank) {
|
||||||
$this->upgradePiggyBank($piggyBank);
|
$this->upgradePiggyBank($piggyBank);
|
||||||
@ -99,8 +93,8 @@ class UpgradeMultiPiggyBanks extends Command
|
|||||||
{
|
{
|
||||||
$this->repository->setUser($piggyBank->account->user);
|
$this->repository->setUser($piggyBank->account->user);
|
||||||
$this->accountRepository->setUser($piggyBank->account->user);
|
$this->accountRepository->setUser($piggyBank->account->user);
|
||||||
$repetition = $this->repository->getRepetition($piggyBank);
|
$repetition = $this->repository->getRepetition($piggyBank);
|
||||||
$currency = $this->accountRepository->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrencyByUserGroup($piggyBank->account->user->userGroup);
|
$currency = $this->accountRepository->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrencyByUserGroup($piggyBank->account->user->userGroup);
|
||||||
|
|
||||||
// update piggy bank to have a currency.
|
// update piggy bank to have a currency.
|
||||||
$piggyBank->transaction_currency_id = $currency->id;
|
$piggyBank->transaction_currency_id = $currency->id;
|
||||||
@ -108,7 +102,7 @@ class UpgradeMultiPiggyBanks extends Command
|
|||||||
|
|
||||||
// store current amount in account association.
|
// store current amount in account association.
|
||||||
$piggyBank->accounts()->sync([$piggyBank->account->id => ['current_amount' => $repetition->current_amount]]);
|
$piggyBank->accounts()->sync([$piggyBank->account->id => ['current_amount' => $repetition->current_amount]]);
|
||||||
$piggyBank->account_id = null;
|
$piggyBank->account_id = null;
|
||||||
$piggyBank->save();
|
$piggyBank->save();
|
||||||
|
|
||||||
// remove all repetitions (no longer used)
|
// remove all repetitions (no longer used)
|
||||||
|
@ -43,7 +43,7 @@ class RegisteredUser extends Event
|
|||||||
*/
|
*/
|
||||||
public function __construct(OwnerNotifiable $owner, User $user)
|
public function __construct(OwnerNotifiable $owner, User $user)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->owner = $owner;
|
$this->owner = $owner;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UnknownUserAttemptedLogin.php
|
* UnknownUserAttemptedLogin.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
@ -24,7 +25,6 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Events\Security;
|
namespace FireflyIII\Events\Security;
|
||||||
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
|
|
||||||
class UnknownUserAttemptedLogin
|
class UnknownUserAttemptedLogin
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TestEmailChannel.php
|
* TestEmailChannel.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
|
@ -43,7 +43,8 @@ use Illuminate\Support\Facades\Notification;
|
|||||||
*/
|
*/
|
||||||
class AdminEventHandler
|
class AdminEventHandler
|
||||||
{
|
{
|
||||||
public function sendLoginAttemptNotification(UnknownUserAttemptedLogin $event): void {
|
public function sendLoginAttemptNotification(UnknownUserAttemptedLogin $event): void
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
$owner = new OwnerNotifiable();
|
$owner = new OwnerNotifiable();
|
||||||
Notification::send($owner, new UnknownUserLoginAttempt($event->address));
|
Notification::send($owner, new UnknownUserLoginAttempt($event->address));
|
||||||
@ -64,13 +65,13 @@ class AdminEventHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function sendInvitationNotification(InvitationCreated $event): void
|
public function sendInvitationNotification(InvitationCreated $event): void
|
||||||
{
|
{
|
||||||
$sendMail = app('fireflyconfig')->get('notification_invite_created', true)->data;
|
$sendMail = app('fireflyconfig')->get('notification_invite_created', true)->data;
|
||||||
if (false === $sendMail) {
|
if (false === $sendMail) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$owner = new OwnerNotifiable();
|
$owner = new OwnerNotifiable();
|
||||||
Notification::send($owner, new UserInvitation($owner, $event->invitee));
|
Notification::send($owner, new UserInvitation($owner, $event->invitee));
|
||||||
@ -131,18 +132,27 @@ class AdminEventHandler
|
|||||||
switch ($event->channel) {
|
switch ($event->channel) {
|
||||||
case 'email':
|
case 'email':
|
||||||
$class = TestNotificationEmail::class;
|
$class = TestNotificationEmail::class;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'slack':
|
case 'slack':
|
||||||
$class = TestNotificationSlack::class;
|
$class = TestNotificationSlack::class;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'ntfy':
|
case 'ntfy':
|
||||||
$class = TestNotificationNtfy::class;
|
$class = TestNotificationNtfy::class;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'pushover':
|
case 'pushover':
|
||||||
$class = TestNotificationPushover::class;
|
$class = TestNotificationPushover::class;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
app('log')->error(sprintf('Unknown channel "%s" in sendTestNotification method.', $event->channel));
|
app('log')->error(sprintf('Unknown channel "%s" in sendTestNotification method.', $event->channel));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Log::debug(sprintf('Will send %s as a notification.', $class));
|
Log::debug(sprintf('Will send %s as a notification.', $class));
|
||||||
|
@ -82,8 +82,8 @@ class UserEventHandler
|
|||||||
$repository = app(UserRepositoryInterface::class);
|
$repository = app(UserRepositoryInterface::class);
|
||||||
|
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = $event->user;
|
$user = $event->user;
|
||||||
$count = $repository->count();
|
$count = $repository->count();
|
||||||
|
|
||||||
// only act when there is 1 user in the system and he has no admin rights.
|
// only act when there is 1 user in the system and he has no admin rights.
|
||||||
if (1 === $count && !$repository->hasRole($user, 'owner')) {
|
if (1 === $count && !$repository->hasRole($user, 'owner')) {
|
||||||
@ -115,13 +115,13 @@ class UserEventHandler
|
|||||||
*/
|
*/
|
||||||
public function createGroupMembership(RegisteredUser $event): void
|
public function createGroupMembership(RegisteredUser $event): void
|
||||||
{
|
{
|
||||||
$user = $event->user;
|
$user = $event->user;
|
||||||
$groupExists = true;
|
$groupExists = true;
|
||||||
$groupTitle = $user->email;
|
$groupTitle = $user->email;
|
||||||
$index = 1;
|
$index = 1;
|
||||||
|
|
||||||
/** @var UserGroup $group */
|
/** @var UserGroup $group */
|
||||||
$group = null;
|
$group = null;
|
||||||
|
|
||||||
// create a new group.
|
// create a new group.
|
||||||
while (true === $groupExists) { // @phpstan-ignore-line
|
while (true === $groupExists) { // @phpstan-ignore-line
|
||||||
@ -131,7 +131,7 @@ class UserEventHandler
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$groupTitle = sprintf('%s-%d', $user->email, $index);
|
$groupTitle = sprintf('%s-%d', $user->email, $index);
|
||||||
++$index;
|
++$index;
|
||||||
if ($index > 99) {
|
if ($index > 99) {
|
||||||
throw new FireflyException('Email address can no longer be used for registrations.');
|
throw new FireflyException('Email address can no longer be used for registrations.');
|
||||||
@ -139,7 +139,7 @@ class UserEventHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @var null|UserRole $role */
|
/** @var null|UserRole $role */
|
||||||
$role = UserRole::where('title', UserRoleEnum::OWNER->value)->first();
|
$role = UserRole::where('title', UserRoleEnum::OWNER->value)->first();
|
||||||
if (null === $role) {
|
if (null === $role) {
|
||||||
throw new FireflyException('The user role is unexpectedly empty. Did you run all migrations?');
|
throw new FireflyException('The user role is unexpectedly empty. Did you run all migrations?');
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ class UserEventHandler
|
|||||||
$repository = app(UserRepositoryInterface::class);
|
$repository = app(UserRepositoryInterface::class);
|
||||||
|
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = $event->user;
|
$user = $event->user;
|
||||||
if ($repository->hasRole($user, 'demo')) {
|
if ($repository->hasRole($user, 'demo')) {
|
||||||
// set user back to English.
|
// set user back to English.
|
||||||
app('preferences')->setForUser($user, 'language', 'en_US');
|
app('preferences')->setForUser($user, 'language', 'en_US');
|
||||||
@ -186,7 +186,7 @@ class UserEventHandler
|
|||||||
return; // do not email demo user.
|
return; // do not email demo user.
|
||||||
}
|
}
|
||||||
|
|
||||||
$list = app('preferences')->getForUser($user, 'login_ip_history', [])->data;
|
$list = app('preferences')->getForUser($user, 'login_ip_history', [])->data;
|
||||||
if (!is_array($list)) {
|
if (!is_array($list)) {
|
||||||
$list = [];
|
$list = [];
|
||||||
}
|
}
|
||||||
@ -223,6 +223,7 @@ class UserEventHandler
|
|||||||
$sendMail = (bool) app('fireflyconfig')->get('notification_admin_new_reg', true)->data;
|
$sendMail = (bool) app('fireflyconfig')->get('notification_admin_new_reg', true)->data;
|
||||||
if ($sendMail) {
|
if ($sendMail) {
|
||||||
$owner = $event->owner;
|
$owner = $event->owner;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Notification::send($owner, new AdminRegistrationNotification($event->owner, $event->user));
|
Notification::send($owner, new AdminRegistrationNotification($event->owner, $event->user));
|
||||||
} catch (\Exception $e) { // @phpstan-ignore-line
|
} catch (\Exception $e) { // @phpstan-ignore-line
|
||||||
@ -369,7 +370,7 @@ class UserEventHandler
|
|||||||
public function storeUserIPAddress(ActuallyLoggedIn $event): void
|
public function storeUserIPAddress(ActuallyLoggedIn $event): void
|
||||||
{
|
{
|
||||||
app('log')->debug('Now in storeUserIPAddress');
|
app('log')->debug('Now in storeUserIPAddress');
|
||||||
$user = $event->user;
|
$user = $event->user;
|
||||||
|
|
||||||
if ($user->hasRole('demo')) {
|
if ($user->hasRole('demo')) {
|
||||||
app('log')->debug('Do not log demo user logins');
|
app('log')->debug('Do not log demo user logins');
|
||||||
@ -386,8 +387,8 @@ class UserEventHandler
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$inArray = false;
|
$inArray = false;
|
||||||
$ip = request()->ip();
|
$ip = request()->ip();
|
||||||
app('log')->debug(sprintf('User logging in from IP address %s', $ip));
|
app('log')->debug(sprintf('User logging in from IP address %s', $ip));
|
||||||
|
|
||||||
// update array if in array
|
// update array if in array
|
||||||
@ -415,7 +416,7 @@ class UserEventHandler
|
|||||||
$preference = array_values($preference);
|
$preference = array_values($preference);
|
||||||
|
|
||||||
/** @var bool $send */
|
/** @var bool $send */
|
||||||
$send = app('preferences')->getForUser($user, 'notification_user_login', true)->data;
|
$send = app('preferences')->getForUser($user, 'notification_user_login', true)->data;
|
||||||
app('preferences')->setForUser($user, 'login_ip_history', $preference);
|
app('preferences')->setForUser($user, 'login_ip_history', $preference);
|
||||||
|
|
||||||
if (false === $inArray && true === $send) {
|
if (false === $inArray && true === $send) {
|
||||||
|
@ -36,14 +36,14 @@ class PiggyBankObserver
|
|||||||
{
|
{
|
||||||
app('log')->debug('Observe "created" of a piggy bank. DO NOTHING.');
|
app('log')->debug('Observe "created" of a piggy bank. DO NOTHING.');
|
||||||
|
|
||||||
// $repetition = new PiggyBankRepetition();
|
// $repetition = new PiggyBankRepetition();
|
||||||
// $repetition->piggyBank()->associate($piggyBank);
|
// $repetition->piggyBank()->associate($piggyBank);
|
||||||
// $repetition->start_date = $piggyBank->start_date;
|
// $repetition->start_date = $piggyBank->start_date;
|
||||||
// $repetition->start_date_tz = $piggyBank->start_date->format('e');
|
// $repetition->start_date_tz = $piggyBank->start_date->format('e');
|
||||||
// $repetition->target_date = $piggyBank->target_date;
|
// $repetition->target_date = $piggyBank->target_date;
|
||||||
// $repetition->target_date_tz = $piggyBank->target_date?->format('e');
|
// $repetition->target_date_tz = $piggyBank->target_date?->format('e');
|
||||||
// $repetition->current_amount = '0';
|
// $repetition->current_amount = '0';
|
||||||
// $repetition->save();
|
// $repetition->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,15 +23,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Http\Controllers\Admin;
|
namespace FireflyIII\Http\Controllers\Admin;
|
||||||
|
|
||||||
use FireflyIII\Events\AdminRequestedTestMessage;
|
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
use FireflyIII\Http\Middleware\IsDemoUser;
|
use FireflyIII\Http\Middleware\IsDemoUser;
|
||||||
use FireflyIII\Support\Notifications\UrlValidator;
|
|
||||||
use FireflyIII\User;
|
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Routing\Redirector;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NotificationController.php
|
* NotificationController.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
@ -36,25 +37,25 @@ class NotificationController extends Controller
|
|||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
Log::channel('audit')->info('User visits notifications index.');
|
Log::channel('audit')->info('User visits notifications index.');
|
||||||
$title = (string) trans('firefly.administration');
|
$title = (string) trans('firefly.administration');
|
||||||
$mainTitleIcon = 'fa-hand-spock-o';
|
$mainTitleIcon = 'fa-hand-spock-o';
|
||||||
$subTitle = (string) trans('firefly.title_owner_notifications');
|
$subTitle = (string) trans('firefly.title_owner_notifications');
|
||||||
$subTitleIcon = 'envelope-o';
|
$subTitleIcon = 'envelope-o';
|
||||||
|
|
||||||
// notification settings:
|
// notification settings:
|
||||||
$slackUrl = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
$slackUrl = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
||||||
$pushoverAppToken = app('fireflyconfig')->getEncrypted('pushover_app_token', '')->data;
|
$pushoverAppToken = app('fireflyconfig')->getEncrypted('pushover_app_token', '')->data;
|
||||||
$pushoverUserToken = app('fireflyconfig')->getEncrypted('pushover_user_token', '')->data;
|
$pushoverUserToken = app('fireflyconfig')->getEncrypted('pushover_user_token', '')->data;
|
||||||
$ntfyServer = app('fireflyconfig')->getEncrypted('ntfy_server', 'https://ntfy.sh')->data;
|
$ntfyServer = app('fireflyconfig')->getEncrypted('ntfy_server', 'https://ntfy.sh')->data;
|
||||||
$ntfyTopic = app('fireflyconfig')->getEncrypted('ntfy_topic', '')->data;
|
$ntfyTopic = app('fireflyconfig')->getEncrypted('ntfy_topic', '')->data;
|
||||||
$ntfyAuth = app('fireflyconfig')->get('ntfy_auth', false)->data;
|
$ntfyAuth = app('fireflyconfig')->get('ntfy_auth', false)->data;
|
||||||
$ntfyUser = app('fireflyconfig')->getEncrypted('ntfy_user', '')->data;
|
$ntfyUser = app('fireflyconfig')->getEncrypted('ntfy_user', '')->data;
|
||||||
$ntfyPass = app('fireflyconfig')->getEncrypted('ntfy_pass', '')->data;
|
$ntfyPass = app('fireflyconfig')->getEncrypted('ntfy_pass', '')->data;
|
||||||
$channels = config('notifications.channels');
|
$channels = config('notifications.channels');
|
||||||
$forcedAvailability = [];
|
$forcedAvailability = [];
|
||||||
|
|
||||||
// admin notification settings:
|
// admin notification settings:
|
||||||
$notifications = [];
|
$notifications = [];
|
||||||
foreach (config('notifications.notifications.owner') as $key => $info) {
|
foreach (config('notifications.notifications.owner') as $key => $info) {
|
||||||
if ($info['enabled']) {
|
if ($info['enabled']) {
|
||||||
$notifications[$key] = app('fireflyconfig')->get(sprintf('notification_%s', $key), true)->data;
|
$notifications[$key] = app('fireflyconfig')->get(sprintf('notification_%s', $key), true)->data;
|
||||||
@ -68,18 +69,31 @@ class NotificationController extends Controller
|
|||||||
$forcedAvailability['ntfy'] = '' !== $ntfyTopic;
|
$forcedAvailability['ntfy'] = '' !== $ntfyTopic;
|
||||||
$forcedAvailability['pushover'] = '' !== $pushoverAppToken && '' !== $pushoverUserToken;
|
$forcedAvailability['pushover'] = '' !== $pushoverAppToken && '' !== $pushoverUserToken;
|
||||||
|
|
||||||
return view('admin.notifications.index',
|
return view(
|
||||||
compact(
|
'admin.notifications.index',
|
||||||
'title', 'subTitle', 'forcedAvailability', 'mainTitleIcon', 'subTitleIcon', 'channels',
|
compact(
|
||||||
'slackUrl', 'notifications',
|
'title',
|
||||||
'pushoverAppToken', 'pushoverUserToken',
|
'subTitle',
|
||||||
'ntfyServer', 'ntfyTopic', 'ntfyAuth', 'ntfyUser', 'ntfyPass'
|
'forcedAvailability',
|
||||||
));
|
'mainTitleIcon',
|
||||||
|
'subTitleIcon',
|
||||||
|
'channels',
|
||||||
|
'slackUrl',
|
||||||
|
'notifications',
|
||||||
|
'pushoverAppToken',
|
||||||
|
'pushoverUserToken',
|
||||||
|
'ntfyServer',
|
||||||
|
'ntfyTopic',
|
||||||
|
'ntfyAuth',
|
||||||
|
'ntfyUser',
|
||||||
|
'ntfyPass'
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function postIndex(NotificationRequest $request): RedirectResponse
|
public function postIndex(NotificationRequest $request): RedirectResponse
|
||||||
{
|
{
|
||||||
$all = $request->getAll();
|
$all = $request->getAll();
|
||||||
|
|
||||||
foreach (config('notifications.notifications.owner') as $key => $info) {
|
foreach (config('notifications.notifications.owner') as $key => $info) {
|
||||||
if (array_key_exists($key, $all)) {
|
if (array_key_exists($key, $all)) {
|
||||||
@ -112,7 +126,9 @@ class NotificationController extends Controller
|
|||||||
switch ($channel) {
|
switch ($channel) {
|
||||||
default:
|
default:
|
||||||
session()->flash('error', (string) trans('firefly.notification_test_failed', ['channel' => $channel]));
|
session()->flash('error', (string) trans('firefly.notification_test_failed', ['channel' => $channel]));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'email':
|
case 'email':
|
||||||
case 'slack':
|
case 'slack':
|
||||||
case 'pushover':
|
case 'pushover':
|
||||||
|
@ -28,7 +28,6 @@ use FireflyIII\Events\ActuallyLoggedIn;
|
|||||||
use FireflyIII\Events\Security\UnknownUserAttemptedLogin;
|
use FireflyIII\Events\Security\UnknownUserAttemptedLogin;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
|
||||||
use FireflyIII\Providers\RouteServiceProvider;
|
use FireflyIII\Providers\RouteServiceProvider;
|
||||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||||
use Illuminate\Contracts\Foundation\Application;
|
use Illuminate\Contracts\Foundation\Application;
|
||||||
@ -70,7 +69,7 @@ class LoginController extends Controller
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->username = 'email';
|
$this->username = 'email';
|
||||||
$this->middleware('guest')->except('logout');
|
$this->middleware('guest')->except('logout');
|
||||||
$this->repository = app(UserRepositoryInterface::class);
|
$this->repository = app(UserRepositoryInterface::class);
|
||||||
}
|
}
|
||||||
@ -128,7 +127,7 @@ class LoginController extends Controller
|
|||||||
}
|
}
|
||||||
app('log')->warning('Login attempt failed.');
|
app('log')->warning('Login attempt failed.');
|
||||||
$username = (string) $request->get($this->username());
|
$username = (string) $request->get($this->username());
|
||||||
if(null === $this->repository->findByEmail($username)) {
|
if (null === $this->repository->findByEmail($username)) {
|
||||||
// send event to owner.
|
// send event to owner.
|
||||||
event(new UnknownUserAttemptedLogin($username));
|
event(new UnknownUserAttemptedLogin($username));
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ class RegisterController extends Controller
|
|||||||
$this->validator($request->all())->validate();
|
$this->validator($request->all())->validate();
|
||||||
$user = $this->createUser($request->all());
|
$user = $this->createUser($request->all());
|
||||||
app('log')->info(sprintf('Registered new user %s', $user->email));
|
app('log')->info(sprintf('Registered new user %s', $user->email));
|
||||||
$owner = new OwnerNotifiable();
|
$owner = new OwnerNotifiable();
|
||||||
event(new RegisteredUser($owner, $user));
|
event(new RegisteredUser($owner, $user));
|
||||||
|
|
||||||
$this->guard()->login($user);
|
$this->guard()->login($user);
|
||||||
|
@ -84,7 +84,7 @@ class BudgetLimitController extends Controller
|
|||||||
$budgetLimits = $this->blRepository->getBudgetLimits($budget, $start, $end);
|
$budgetLimits = $this->blRepository->getBudgetLimits($budget, $start, $end);
|
||||||
|
|
||||||
// remove already budgeted currencies with the same date range
|
// remove already budgeted currencies with the same date range
|
||||||
$currencies = $collection->filter(
|
$currencies = $collection->filter(
|
||||||
static function (TransactionCurrency $currency) use ($budgetLimits, $start, $end) {
|
static function (TransactionCurrency $currency) use ($budgetLimits, $start, $end) {
|
||||||
/** @var BudgetLimit $limit */
|
/** @var BudgetLimit $limit */
|
||||||
foreach ($budgetLimits as $limit) {
|
foreach ($budgetLimits as $limit) {
|
||||||
@ -107,6 +107,7 @@ class BudgetLimitController extends Controller
|
|||||||
public function show(BudgetLimit $budgetLimit)
|
public function show(BudgetLimit $budgetLimit)
|
||||||
{
|
{
|
||||||
$notes = $this->blRepository->getNoteText($budgetLimit);
|
$notes = $this->blRepository->getNoteText($budgetLimit);
|
||||||
|
|
||||||
return view('budgets.budget-limits.show', compact('budgetLimit', 'notes'));
|
return view('budgets.budget-limits.show', compact('budgetLimit', 'notes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +117,7 @@ class BudgetLimitController extends Controller
|
|||||||
public function edit(BudgetLimit $budgetLimit)
|
public function edit(BudgetLimit $budgetLimit)
|
||||||
{
|
{
|
||||||
$notes = $this->blRepository->getNoteText($budgetLimit);
|
$notes = $this->blRepository->getNoteText($budgetLimit);
|
||||||
|
|
||||||
return view('budgets.budget-limits.edit', compact('budgetLimit', 'notes'));
|
return view('budgets.budget-limits.edit', compact('budgetLimit', 'notes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +137,7 @@ class BudgetLimitController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function store(Request $request): JsonResponse | RedirectResponse
|
public function store(Request $request): JsonResponse|RedirectResponse
|
||||||
{
|
{
|
||||||
app('log')->debug('Going to store new budget-limit.', $request->all());
|
app('log')->debug('Going to store new budget-limit.', $request->all());
|
||||||
// first search for existing one and update it if necessary.
|
// first search for existing one and update it if necessary.
|
||||||
@ -144,14 +146,14 @@ class BudgetLimitController extends Controller
|
|||||||
if (null === $currency || null === $budget) {
|
if (null === $currency || null === $budget) {
|
||||||
throw new FireflyException('No valid currency or budget.');
|
throw new FireflyException('No valid currency or budget.');
|
||||||
}
|
}
|
||||||
$start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
|
$start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
|
||||||
$end = Carbon::createFromFormat('Y-m-d', $request->get('end'));
|
$end = Carbon::createFromFormat('Y-m-d', $request->get('end'));
|
||||||
|
|
||||||
if (null === $start || null === $end) {
|
if (null === $start || null === $end) {
|
||||||
return response()->json([]);
|
return response()->json([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$amount = (string) $request->get('amount');
|
$amount = (string) $request->get('amount');
|
||||||
$start->startOfDay();
|
$start->startOfDay();
|
||||||
$end->startOfDay();
|
$end->startOfDay();
|
||||||
|
|
||||||
@ -161,7 +163,7 @@ class BudgetLimitController extends Controller
|
|||||||
|
|
||||||
app('log')->debug(sprintf('Start: %s, end: %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
|
app('log')->debug(sprintf('Start: %s, end: %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
|
||||||
|
|
||||||
$limit = $this->blRepository->find($budget, $currency, $start, $end);
|
$limit = $this->blRepository->find($budget, $currency, $start, $end);
|
||||||
|
|
||||||
// sanity check on amount:
|
// sanity check on amount:
|
||||||
if (0 === bccomp($amount, '0')) {
|
if (0 === bccomp($amount, '0')) {
|
||||||
@ -195,25 +197,25 @@ class BudgetLimitController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
// parse notes, if any.
|
// parse notes, if any.
|
||||||
$notes = (string) $request->get('notes');
|
$notes = (string) $request->get('notes');
|
||||||
$this->blRepository->setNoteText($limit, $notes);
|
$this->blRepository->setNoteText($limit, $notes);
|
||||||
|
|
||||||
if ($request->expectsJson()) {
|
if ($request->expectsJson()) {
|
||||||
$array = $limit->toArray();
|
$array = $limit->toArray();
|
||||||
// add some extra metadata:
|
// add some extra metadata:
|
||||||
$spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection([$budget]), $currency);
|
$spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection([$budget]), $currency);
|
||||||
$array['spent'] = $spentArr[$currency->id]['sum'] ?? '0';
|
$array['spent'] = $spentArr[$currency->id]['sum'] ?? '0';
|
||||||
$array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount']));
|
$array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount']));
|
||||||
$array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
|
$array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
|
||||||
$array['days_left'] = (string) $this->activeDaysLeft($start, $end);
|
$array['days_left'] = (string) $this->activeDaysLeft($start, $end);
|
||||||
// left per day:
|
// left per day:
|
||||||
$array['left_per_day'] = 0 === bccomp('0', $array['days_left']) ? bcadd($array['spent'], $array['amount']) : bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
|
$array['left_per_day'] = 0 === bccomp('0', $array['days_left']) ? bcadd($array['spent'], $array['amount']) : bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
|
||||||
|
|
||||||
// left per day formatted.
|
// left per day formatted.
|
||||||
$array['left_per_day_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $array['left_per_day']);
|
$array['left_per_day_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $array['left_per_day']);
|
||||||
|
|
||||||
// notes:
|
// notes:
|
||||||
$array['notes'] = $this->blRepository->getNoteText($limit);
|
$array['notes'] = $this->blRepository->getNoteText($limit);
|
||||||
|
|
||||||
return response()->json($array);
|
return response()->json($array);
|
||||||
}
|
}
|
||||||
@ -223,7 +225,7 @@ class BudgetLimitController extends Controller
|
|||||||
|
|
||||||
public function update(Request $request, BudgetLimit $budgetLimit): JsonResponse|RedirectResponse
|
public function update(Request $request, BudgetLimit $budgetLimit): JsonResponse|RedirectResponse
|
||||||
{
|
{
|
||||||
$amount = (string) $request->get('amount');
|
$amount = (string) $request->get('amount');
|
||||||
if ('' === $amount) {
|
if ('' === $amount) {
|
||||||
$amount = '0';
|
$amount = '0';
|
||||||
}
|
}
|
||||||
@ -235,7 +237,7 @@ class BudgetLimitController extends Controller
|
|||||||
$budgetId = $budgetLimit->budget_id;
|
$budgetId = $budgetLimit->budget_id;
|
||||||
$currency = $budgetLimit->transactionCurrency;
|
$currency = $budgetLimit->transactionCurrency;
|
||||||
$this->blRepository->destroyBudgetLimit($budgetLimit);
|
$this->blRepository->destroyBudgetLimit($budgetLimit);
|
||||||
$array = [
|
$array = [
|
||||||
'budget_id' => $budgetId,
|
'budget_id' => $budgetId,
|
||||||
'left_formatted' => app('amount')->formatAnything($currency, '0'),
|
'left_formatted' => app('amount')->formatAnything($currency, '0'),
|
||||||
'left_per_day_formatted' => app('amount')->formatAnything($currency, '0'),
|
'left_per_day_formatted' => app('amount')->formatAnything($currency, '0'),
|
||||||
@ -248,29 +250,29 @@ class BudgetLimitController extends Controller
|
|||||||
if (-1 === bccomp($amount, '0')) {
|
if (-1 === bccomp($amount, '0')) {
|
||||||
$amount = bcmul($amount, '-1');
|
$amount = bcmul($amount, '-1');
|
||||||
}
|
}
|
||||||
$notes = (string)$request->get('notes');
|
$notes = (string)$request->get('notes');
|
||||||
if(strlen($notes) > 32768) {
|
if (strlen($notes) > 32768) {
|
||||||
$notes = substr($notes, 0, 32768);
|
$notes = substr($notes, 0, 32768);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$limit = $this->blRepository->update($budgetLimit, ['amount' => $amount,'notes' => $notes]);
|
$limit = $this->blRepository->update($budgetLimit, ['amount' => $amount, 'notes' => $notes]);
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
$array = $limit->toArray();
|
$array = $limit->toArray();
|
||||||
|
|
||||||
$spentArr = $this->opsRepository->sumExpenses(
|
$spentArr = $this->opsRepository->sumExpenses(
|
||||||
$limit->start_date,
|
$limit->start_date,
|
||||||
$limit->end_date,
|
$limit->end_date,
|
||||||
null,
|
null,
|
||||||
new Collection([$budgetLimit->budget]),
|
new Collection([$budgetLimit->budget]),
|
||||||
$budgetLimit->transactionCurrency
|
$budgetLimit->transactionCurrency
|
||||||
);
|
);
|
||||||
$daysLeft = $this->activeDaysLeft($limit->start_date, $limit->end_date);
|
$daysLeft = $this->activeDaysLeft($limit->start_date, $limit->end_date);
|
||||||
$array['spent'] = $spentArr[$budgetLimit->transactionCurrency->id]['sum'] ?? '0';
|
$array['spent'] = $spentArr[$budgetLimit->transactionCurrency->id]['sum'] ?? '0';
|
||||||
$array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount']));
|
$array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount']));
|
||||||
$array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
|
$array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
|
||||||
$array['days_left'] = (string) $daysLeft;
|
$array['days_left'] = (string) $daysLeft;
|
||||||
$array['left_per_day'] = 0 === $daysLeft ? bcadd($array['spent'], $array['amount']) : bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
|
$array['left_per_day'] = 0 === $daysLeft ? bcadd($array['spent'], $array['amount']) : bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
|
||||||
|
|
||||||
// left per day formatted.
|
// left per day formatted.
|
||||||
$array['amount'] = app('steam')->bcround($limit['amount'], $limit->transactionCurrency->decimal_places);
|
$array['amount'] = app('steam')->bcround($limit['amount'], $limit->transactionCurrency->decimal_places);
|
||||||
@ -278,6 +280,7 @@ class BudgetLimitController extends Controller
|
|||||||
if ('true' === $request->get('redirect')) {
|
if ('true' === $request->get('redirect')) {
|
||||||
return redirect(route('budgets.index'));
|
return redirect(route('budgets.index'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($array);
|
return response()->json($array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ class IndexController extends Controller
|
|||||||
$array['budgeted'][] = [
|
$array['budgeted'][] = [
|
||||||
'id' => $limit->id,
|
'id' => $limit->id,
|
||||||
'amount' => $amount,
|
'amount' => $amount,
|
||||||
'notes' => $this->blRepository->getNoteText($limit),
|
'notes' => $this->blRepository->getNoteText($limit),
|
||||||
'start_date' => $limit->start_date->isoFormat($this->monthAndDayFormat),
|
'start_date' => $limit->start_date->isoFormat($this->monthAndDayFormat),
|
||||||
'end_date' => $limit->end_date->isoFormat($this->monthAndDayFormat),
|
'end_date' => $limit->end_date->isoFormat($this->monthAndDayFormat),
|
||||||
'in_range' => $limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end),
|
'in_range' => $limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end),
|
||||||
|
@ -43,7 +43,6 @@ use Illuminate\Support\Facades\Log;
|
|||||||
*/
|
*/
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HomeController constructor.
|
* HomeController constructor.
|
||||||
*/
|
*/
|
||||||
@ -62,8 +61,8 @@ class HomeController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function dateRange(Request $request): JsonResponse
|
public function dateRange(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$stringStart = '';
|
$stringStart = '';
|
||||||
$stringEnd = '';
|
$stringEnd = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stringStart = e((string) $request->get('start'));
|
$stringStart = e((string) $request->get('start'));
|
||||||
@ -98,7 +97,7 @@ class HomeController extends Controller
|
|||||||
app('log')->debug('Range is now marked as "custom".');
|
app('log')->debug('Range is now marked as "custom".');
|
||||||
}
|
}
|
||||||
|
|
||||||
$diff = $start->diffInDays($end, true) + 1;
|
$diff = $start->diffInDays($end, true) + 1;
|
||||||
|
|
||||||
if ($diff > 366) {
|
if ($diff > 366) {
|
||||||
$request->session()->flash('warning', (string) trans('firefly.warning_much_data', ['days' => (int) $diff]));
|
$request->session()->flash('warning', (string) trans('firefly.warning_much_data', ['days' => (int) $diff]));
|
||||||
@ -153,13 +152,13 @@ class HomeController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @var Carbon $start */
|
/** @var Carbon $start */
|
||||||
$start = session('start', today(config('app.timezone'))->startOfMonth());
|
$start = session('start', today(config('app.timezone'))->startOfMonth());
|
||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = session('end', today(config('app.timezone'))->endOfMonth());
|
$end = session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
$accounts = $repository->getAccountsById($frontpageArray);
|
$accounts = $repository->getAccountsById($frontpageArray);
|
||||||
$today = today(config('app.timezone'));
|
$today = today(config('app.timezone'));
|
||||||
$accounts = $accounts->sortBy('order'); // sort frontpage accounts by order
|
$accounts = $accounts->sortBy('order'); // sort frontpage accounts by order
|
||||||
|
|
||||||
app('log')->debug('Frontpage accounts are ', $frontpageArray);
|
app('log')->debug('Frontpage accounts are ', $frontpageArray);
|
||||||
|
|
||||||
@ -169,14 +168,14 @@ class HomeController extends Controller
|
|||||||
// collect groups for each transaction.
|
// collect groups for each transaction.
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setAccounts(new Collection([$account]))->withAccountInformation()->setRange($start, $end)->setLimit(10)->setPage(1);
|
$collector->setAccounts(new Collection([$account]))->withAccountInformation()->setRange($start, $end)->setLimit(10)->setPage(1);
|
||||||
$set = $collector->getExtractedJournals();
|
$set = $collector->getExtractedJournals();
|
||||||
$transactions[] = ['transactions' => $set, 'account' => $account];
|
$transactions[] = ['transactions' => $set, 'account' => $account];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
event(new RequestedVersionCheckStatus($user));
|
event(new RequestedVersionCheckStatus($user));
|
||||||
|
|
||||||
return view('index', compact('count', 'subTitle', 'transactions', 'billCount', 'start', 'end', 'today', 'pageTitle'));
|
return view('index', compact('count', 'subTitle', 'transactions', 'billCount', 'start', 'end', 'today', 'pageTitle'));
|
||||||
@ -187,11 +186,11 @@ class HomeController extends Controller
|
|||||||
$subTitle = (string) trans('firefly.welcome_back');
|
$subTitle = (string) trans('firefly.welcome_back');
|
||||||
$pageTitle = (string) trans('firefly.main_dashboard_page_title');
|
$pageTitle = (string) trans('firefly.main_dashboard_page_title');
|
||||||
|
|
||||||
$start = session('start', today(config('app.timezone'))->startOfMonth());
|
$start = session('start', today(config('app.timezone'))->startOfMonth());
|
||||||
$end = session('end', today(config('app.timezone'))->endOfMonth());
|
$end = session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
|
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
event(new RequestedVersionCheckStatus($user));
|
event(new RequestedVersionCheckStatus($user));
|
||||||
|
|
||||||
return view('index', compact('subTitle', 'start', 'end', 'pageTitle'));
|
return view('index', compact('subTitle', 'start', 'end', 'pageTitle'));
|
||||||
|
@ -94,7 +94,7 @@ class CreateController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(PiggyBankStoreRequest $request)
|
public function store(PiggyBankStoreRequest $request)
|
||||||
{
|
{
|
||||||
$data = $request->getPiggyBankData();
|
$data = $request->getPiggyBankData();
|
||||||
|
|
||||||
if (null === $data['start_date']) {
|
if (null === $data['start_date']) {
|
||||||
$data['start_date'] = today(config('app.timezone'));
|
$data['start_date'] = today(config('app.timezone'));
|
||||||
@ -107,7 +107,7 @@ class CreateController extends Controller
|
|||||||
|
|
||||||
// store attachment(s):
|
// store attachment(s):
|
||||||
/** @var null|array $files */
|
/** @var null|array $files */
|
||||||
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
|
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
|
||||||
if (null !== $files && !auth()->user()->hasRole('demo')) {
|
if (null !== $files && !auth()->user()->hasRole('demo')) {
|
||||||
$this->attachments->saveAttachmentsForModel($piggyBank, $files);
|
$this->attachments->saveAttachmentsForModel($piggyBank, $files);
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ class CreateController extends Controller
|
|||||||
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
|
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
|
||||||
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments'));
|
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments'));
|
||||||
}
|
}
|
||||||
$redirect = redirect($this->getPreviousUrl('piggy-banks.create.url'));
|
$redirect = redirect($this->getPreviousUrl('piggy-banks.create.url'));
|
||||||
|
|
||||||
if (1 === (int) $request->get('create_another')) {
|
if (1 === (int) $request->get('create_another')) {
|
||||||
session()->put('piggy-banks.create.fromStore', true);
|
session()->put('piggy-banks.create.fromStore', true);
|
||||||
|
@ -81,13 +81,13 @@ class IndexController extends Controller
|
|||||||
{
|
{
|
||||||
$this->cleanupObjectGroups();
|
$this->cleanupObjectGroups();
|
||||||
$this->piggyRepos->resetOrder();
|
$this->piggyRepos->resetOrder();
|
||||||
$collection = $this->piggyRepos->getPiggyBanks();
|
$collection = $this->piggyRepos->getPiggyBanks();
|
||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = session('end', today(config('app.timezone'))->endOfMonth());
|
$end = session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
|
|
||||||
// transform piggies using the transformer:
|
// transform piggies using the transformer:
|
||||||
$parameters = new ParameterBag();
|
$parameters = new ParameterBag();
|
||||||
$parameters->set('end', $end);
|
$parameters->set('end', $end);
|
||||||
|
|
||||||
|
|
||||||
@ -96,10 +96,10 @@ class IndexController extends Controller
|
|||||||
$accountTransformer->setParameters($parameters);
|
$accountTransformer->setParameters($parameters);
|
||||||
|
|
||||||
// data
|
// data
|
||||||
$piggyBanks = $this->groupPiggyBanks($collection);
|
$piggyBanks = $this->groupPiggyBanks($collection);
|
||||||
$accounts = $this->collectAccounts($collection);
|
$accounts = $this->collectAccounts($collection);
|
||||||
$accounts = $this->mergeAccountsAndPiggies($piggyBanks, $accounts);
|
$accounts = $this->mergeAccountsAndPiggies($piggyBanks, $accounts);
|
||||||
$piggyBanks = $this->makeSums($piggyBanks);
|
$piggyBanks = $this->makeSums($piggyBanks);
|
||||||
|
|
||||||
ksort($piggyBanks);
|
ksort($piggyBanks);
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ class IndexController extends Controller
|
|||||||
foreach ($piggyBanks as $groupOrder => $group) {
|
foreach ($piggyBanks as $groupOrder => $group) {
|
||||||
$groupId = $group['object_group_id'];
|
$groupId = $group['object_group_id'];
|
||||||
foreach ($group['piggy_banks'] as $piggy) {
|
foreach ($group['piggy_banks'] as $piggy) {
|
||||||
$currencyId = $piggy['currency_id'];
|
$currencyId = $piggy['currency_id'];
|
||||||
$sums[$groupId][$currencyId] ??= [
|
$sums[$groupId][$currencyId] ??= [
|
||||||
'target' => '0',
|
'target' => '0',
|
||||||
'saved' => '0',
|
'saved' => '0',
|
||||||
@ -164,47 +164,51 @@ class IndexController extends Controller
|
|||||||
/** @var PiggyBankTransformer $transformer */
|
/** @var PiggyBankTransformer $transformer */
|
||||||
$transformer = app(PiggyBankTransformer::class);
|
$transformer = app(PiggyBankTransformer::class);
|
||||||
$transformer->setParameters(new ParameterBag());
|
$transformer->setParameters(new ParameterBag());
|
||||||
$piggyBanks = [];
|
$piggyBanks = [];
|
||||||
|
|
||||||
/** @var PiggyBank $piggy */
|
/** @var PiggyBank $piggy */
|
||||||
foreach ($collection as $piggy) {
|
foreach ($collection as $piggy) {
|
||||||
$array = $transformer->transform($piggy);
|
$array = $transformer->transform($piggy);
|
||||||
$groupOrder = (int) $array['object_group_order'];
|
$groupOrder = (int) $array['object_group_order'];
|
||||||
$piggyBanks[$groupOrder] ??= [
|
$piggyBanks[$groupOrder] ??= [
|
||||||
'object_group_id' => $array['object_group_id'] ?? 0,
|
'object_group_id' => $array['object_group_id'] ?? 0,
|
||||||
'object_group_title' => $array['object_group_title'] ?? trans('firefly.default_group_title_name'),
|
'object_group_title' => $array['object_group_title'] ?? trans('firefly.default_group_title_name'),
|
||||||
'piggy_banks' => [],
|
'piggy_banks' => [],
|
||||||
];
|
];
|
||||||
$array['attachments'] = $this->piggyRepos->getAttachments($piggy);
|
$array['attachments'] = $this->piggyRepos->getAttachments($piggy);
|
||||||
|
|
||||||
// sum the total amount for the index.
|
// sum the total amount for the index.
|
||||||
$piggyBanks[$groupOrder]['piggy_banks'][] = $array;
|
$piggyBanks[$groupOrder]['piggy_banks'][] = $array;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $piggyBanks;
|
return $piggyBanks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function collectAccounts(Collection $collection): array
|
private function collectAccounts(Collection $collection): array
|
||||||
{
|
{
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = session('end', today(config('app.timezone'))->endOfMonth());
|
$end = session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
|
|
||||||
// transform piggies using the transformer:
|
// transform piggies using the transformer:
|
||||||
$parameters = new ParameterBag();
|
$parameters = new ParameterBag();
|
||||||
$parameters->set('end', $end);
|
$parameters->set('end', $end);
|
||||||
|
|
||||||
/** @var AccountTransformer $accountTransformer */
|
/** @var AccountTransformer $accountTransformer */
|
||||||
$accountTransformer = app(AccountTransformer::class);
|
$accountTransformer = app(AccountTransformer::class);
|
||||||
$accountTransformer->setParameters($parameters);
|
$accountTransformer->setParameters($parameters);
|
||||||
|
|
||||||
$return = [];
|
$return = [];
|
||||||
|
|
||||||
/** @var PiggyBank $piggy */
|
/** @var PiggyBank $piggy */
|
||||||
foreach ($collection as $piggy) {
|
foreach ($collection as $piggy) {
|
||||||
$accounts = $piggy->accounts;
|
$accounts = $piggy->accounts;
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
$array = $accountTransformer->transform($account);
|
$array = $accountTransformer->transform($account);
|
||||||
$accountId = (int) $array['id'];
|
$accountId = (int) $array['id'];
|
||||||
if (!array_key_exists($accountId, $return)) {
|
if (!array_key_exists($accountId, $return)) {
|
||||||
$return[$accountId] = $array;
|
$return[$accountId] = $array;
|
||||||
|
|
||||||
// add some interesting details:
|
// add some interesting details:
|
||||||
$return[$accountId]['left'] = $return[$accountId]['current_balance'];
|
$return[$accountId]['left'] = $return[$accountId]['current_balance'];
|
||||||
@ -214,20 +218,21 @@ class IndexController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// calculate new interesting fields:
|
// calculate new interesting fields:
|
||||||
// $return[$accountId]['left'] -= $array['current_amount'];
|
// $return[$accountId]['left'] -= $array['current_amount'];
|
||||||
// $return[$accountId]['saved'] += $array['current_amount'];
|
// $return[$accountId]['saved'] += $array['current_amount'];
|
||||||
// $return[$accountId]['target'] += $array['target_amount'];
|
// $return[$accountId]['target'] += $array['target_amount'];
|
||||||
// $return[$accountId]['to_save'] += ($array['target_amount'] - $array['current_amount']);
|
// $return[$accountId]['to_save'] += ($array['target_amount'] - $array['current_amount']);
|
||||||
// $return['account_name'] = $account['name'];
|
// $return['account_name'] = $account['name'];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function mergeAccountsAndPiggies(array $piggyBanks, array $accounts): array
|
private function mergeAccountsAndPiggies(array $piggyBanks, array $accounts): array
|
||||||
{
|
{
|
||||||
/** @var array $piggyBank */
|
// @var array $piggyBank
|
||||||
foreach ($piggyBanks as $group) {
|
foreach ($piggyBanks as $group) {
|
||||||
foreach ($group['piggy_banks'] as $piggyBank) {
|
foreach ($group['piggy_banks'] as $piggyBank) {
|
||||||
// loop all accounts in this piggy bank subtract the current amount from "left to save" in the $accounts array.
|
// loop all accounts in this piggy bank subtract the current amount from "left to save" in the $accounts array.
|
||||||
@ -243,6 +248,7 @@ class IndexController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $accounts;
|
return $accounts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,14 +66,14 @@ class PreferencesController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(AccountRepositoryInterface $repository)
|
public function index(AccountRepositoryInterface $repository)
|
||||||
{
|
{
|
||||||
$accounts = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
|
$accounts = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
|
||||||
$isDocker = env('IS_DOCKER', false);
|
$isDocker = env('IS_DOCKER', false);
|
||||||
$groupedAccounts = [];
|
$groupedAccounts = [];
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
$type = $account->accountType->type;
|
$type = $account->accountType->type;
|
||||||
$role = sprintf('opt_group_%s', $repository->getMetaValue($account, 'account_role'));
|
$role = sprintf('opt_group_%s', $repository->getMetaValue($account, 'account_role'));
|
||||||
|
|
||||||
if (in_array($type, [AccountType::MORTGAGE, AccountType::DEBT, AccountType::LOAN], true)) {
|
if (in_array($type, [AccountType::MORTGAGE, AccountType::DEBT, AccountType::LOAN], true)) {
|
||||||
$role = sprintf('opt_group_l_%s', $type);
|
$role = sprintf('opt_group_l_%s', $type);
|
||||||
@ -94,42 +94,49 @@ class PreferencesController extends Controller
|
|||||||
if (!is_array($frontpageAccounts)) {
|
if (!is_array($frontpageAccounts)) {
|
||||||
$frontpageAccounts = $accountIds;
|
$frontpageAccounts = $accountIds;
|
||||||
}
|
}
|
||||||
$language = app('steam')->getLanguage();
|
$language = app('steam')->getLanguage();
|
||||||
$languages = config('firefly.languages');
|
$languages = config('firefly.languages');
|
||||||
$locale = app('preferences')->get('locale', config('firefly.default_locale', 'equal'))->data;
|
$locale = app('preferences')->get('locale', config('firefly.default_locale', 'equal'))->data;
|
||||||
$listPageSize = app('preferences')->get('listPageSize', 50)->data;
|
$listPageSize = app('preferences')->get('listPageSize', 50)->data;
|
||||||
$darkMode = app('preferences')->get('darkMode', 'browser')->data;
|
$darkMode = app('preferences')->get('darkMode', 'browser')->data;
|
||||||
$customFiscalYear = app('preferences')->get('customFiscalYear', 0)->data;
|
$customFiscalYear = app('preferences')->get('customFiscalYear', 0)->data;
|
||||||
$fiscalYearStartStr = app('preferences')->get('fiscalYearStart', '01-01')->data;
|
$fiscalYearStartStr = app('preferences')->get('fiscalYearStart', '01-01')->data;
|
||||||
if (is_array($fiscalYearStartStr)) {
|
if (is_array($fiscalYearStartStr)) {
|
||||||
$fiscalYearStartStr = '01-01';
|
$fiscalYearStartStr = '01-01';
|
||||||
}
|
}
|
||||||
$fiscalYearStart = sprintf('%s-%s', date('Y'), (string) $fiscalYearStartStr);
|
$fiscalYearStart = sprintf('%s-%s', date('Y'), (string) $fiscalYearStartStr);
|
||||||
$tjOptionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
|
$tjOptionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
|
||||||
$availableDarkModes = config('firefly.available_dark_modes');
|
$availableDarkModes = config('firefly.available_dark_modes');
|
||||||
|
|
||||||
// notifications settings
|
// notifications settings
|
||||||
$slackUrl = app('preferences')->getEncrypted('slack_webhook_url', '')->data;
|
$slackUrl = app('preferences')->getEncrypted('slack_webhook_url', '')->data;
|
||||||
$pushoverAppToken = app('preferences')->getEncrypted('pushover_app_token', '')->data;
|
$pushoverAppToken = app('preferences')->getEncrypted('pushover_app_token', '')->data;
|
||||||
$pushoverUserToken = app('preferences')->getEncrypted('pushover_user_token', '')->data;
|
$pushoverUserToken = app('preferences')->getEncrypted('pushover_user_token', '')->data;
|
||||||
$ntfyServer = app('preferences')->getEncrypted('ntfy_server', 'https://ntfy.sh')->data;
|
$ntfyServer = app('preferences')->getEncrypted('ntfy_server', 'https://ntfy.sh')->data;
|
||||||
$ntfyTopic = app('preferences')->getEncrypted('ntfy_topic', '')->data;
|
$ntfyTopic = app('preferences')->getEncrypted('ntfy_topic', '')->data;
|
||||||
$ntfyAuth = app('preferences')->get('ntfy_auth', false)->data;
|
$ntfyAuth = app('preferences')->get('ntfy_auth', false)->data;
|
||||||
$ntfyUser = app('preferences')->getEncrypted('ntfy_user', '')->data;
|
$ntfyUser = app('preferences')->getEncrypted('ntfy_user', '')->data;
|
||||||
$ntfyPass = app('preferences')->getEncrypted('ntfy_pass', '')->data;
|
$ntfyPass = app('preferences')->getEncrypted('ntfy_pass', '')->data;
|
||||||
|
$channels = config('notifications.channels');
|
||||||
|
$forcedAvailability = [];
|
||||||
|
|
||||||
|
// notification preferences
|
||||||
// notification preferences (single value for each):
|
$notifications = [];
|
||||||
$notifications = [];
|
|
||||||
foreach (config('notifications.notifications.user') as $key => $info) {
|
foreach (config('notifications.notifications.user') as $key => $info) {
|
||||||
if ($info['enabled']) {
|
if ($info['enabled']) {
|
||||||
$notifications[$key]
|
$notifications[$key]
|
||||||
= [
|
= [
|
||||||
'enabled' => app('preferences')->get(sprintf('notification_%s', $key), true)->data,
|
'enabled' => app('preferences')->get(sprintf('notification_%s', $key), true)->data,
|
||||||
'configurable' => $info['configurable'],
|
'configurable' => $info['configurable'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// loop all channels to see if they are available.
|
||||||
|
foreach ($channels as $channel => $info) {
|
||||||
|
$forcedAvailability[$channel] = true;
|
||||||
|
}
|
||||||
|
$forcedAvailability['ntfy'] = '' !== $ntfyTopic;
|
||||||
|
$forcedAvailability['pushover'] = '' !== $pushoverAppToken && '' !== $pushoverUserToken;
|
||||||
|
|
||||||
ksort($languages);
|
ksort($languages);
|
||||||
|
|
||||||
@ -141,7 +148,7 @@ class PreferencesController extends Controller
|
|||||||
app('log')->error($e->getMessage());
|
app('log')->error($e->getMessage());
|
||||||
$locales = [];
|
$locales = [];
|
||||||
}
|
}
|
||||||
$locales = ['equal' => (string) trans('firefly.equal_to_language')] + $locales;
|
$locales = ['equal' => (string) trans('firefly.equal_to_language')] + $locales;
|
||||||
// an important fallback is that the frontPageAccount array gets refilled automatically
|
// an important fallback is that the frontPageAccount array gets refilled automatically
|
||||||
// when it turns up empty.
|
// when it turns up empty.
|
||||||
if (0 === count($frontpageAccounts)) {
|
if (0 === count($frontpageAccounts)) {
|
||||||
@ -151,7 +158,7 @@ class PreferencesController extends Controller
|
|||||||
// for the demo user, the notification settings are automatically emptied.
|
// for the demo user, the notification settings are automatically emptied.
|
||||||
// this isn't really secure, but it means that the demo site has semi-secret notification settings.
|
// this isn't really secure, but it means that the demo site has semi-secret notification settings.
|
||||||
if (auth()->user()->hasRole('demo')) {
|
if (auth()->user()->hasRole('demo')) {
|
||||||
$slackUrl = '';
|
$slackUrl = '';
|
||||||
$pushoverAppToken = '';
|
$pushoverAppToken = '';
|
||||||
$pushoverUserToken = '';
|
$pushoverUserToken = '';
|
||||||
$ntfyServer = '';
|
$ntfyServer = '';
|
||||||
@ -161,9 +168,32 @@ class PreferencesController extends Controller
|
|||||||
$ntfyPass = '';
|
$ntfyPass = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return view('preferences.index', compact('language', 'pushoverAppToken', 'pushoverUserToken',
|
return view('preferences.index', compact(
|
||||||
'ntfyServer', 'ntfyTopic', 'ntfyAuth', 'ntfyUser', 'ntfyPass',
|
'language',
|
||||||
'groupedAccounts', 'isDocker', 'frontpageAccounts', 'languages', 'darkMode', 'availableDarkModes', 'notifications', 'slackUrl', 'locales', 'locale', 'tjOptionalFields', 'viewRange', 'customFiscalYear', 'listPageSize', 'fiscalYearStart'));
|
'pushoverAppToken',
|
||||||
|
'pushoverUserToken',
|
||||||
|
'ntfyServer',
|
||||||
|
'ntfyTopic',
|
||||||
|
'ntfyAuth',
|
||||||
|
'ntfyUser',
|
||||||
|
'forcedAvailability',
|
||||||
|
'ntfyPass',
|
||||||
|
'groupedAccounts',
|
||||||
|
'isDocker',
|
||||||
|
'frontpageAccounts',
|
||||||
|
'languages',
|
||||||
|
'darkMode',
|
||||||
|
'availableDarkModes',
|
||||||
|
'notifications',
|
||||||
|
'slackUrl',
|
||||||
|
'locales',
|
||||||
|
'locale',
|
||||||
|
'tjOptionalFields',
|
||||||
|
'viewRange',
|
||||||
|
'customFiscalYear',
|
||||||
|
'listPageSize',
|
||||||
|
'fiscalYearStart'
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,8 +218,9 @@ class PreferencesController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extract notifications:
|
// extract notifications:
|
||||||
$all = $request->all();
|
$all = $request->all();
|
||||||
die('fix the reference to the available notifications.');
|
|
||||||
|
exit('fix the reference to the available notifications.');
|
||||||
foreach (config('firefly.available_notifications') as $option) {
|
foreach (config('firefly.available_notifications') as $option) {
|
||||||
$key = sprintf('notification_%s', $option);
|
$key = sprintf('notification_%s', $option);
|
||||||
if (array_key_exists($key, $all)) {
|
if (array_key_exists($key, $all)) {
|
||||||
@ -219,8 +250,8 @@ class PreferencesController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// custom fiscal year
|
// custom fiscal year
|
||||||
$customFiscalYear = 1 === (int) $request->get('customFiscalYear');
|
$customFiscalYear = 1 === (int) $request->get('customFiscalYear');
|
||||||
$string = strtotime((string) $request->get('fiscalYearStart'));
|
$string = strtotime((string) $request->get('fiscalYearStart'));
|
||||||
if (false !== $string) {
|
if (false !== $string) {
|
||||||
$fiscalYearStart = date('m-d', $string);
|
$fiscalYearStart = date('m-d', $string);
|
||||||
app('preferences')->set('customFiscalYear', $customFiscalYear);
|
app('preferences')->set('customFiscalYear', $customFiscalYear);
|
||||||
@ -229,15 +260,15 @@ class PreferencesController extends Controller
|
|||||||
|
|
||||||
// save page size:
|
// save page size:
|
||||||
app('preferences')->set('listPageSize', 50);
|
app('preferences')->set('listPageSize', 50);
|
||||||
$listPageSize = (int) $request->get('listPageSize');
|
$listPageSize = (int) $request->get('listPageSize');
|
||||||
if ($listPageSize > 0 && $listPageSize < 1337) {
|
if ($listPageSize > 0 && $listPageSize < 1337) {
|
||||||
app('preferences')->set('listPageSize', $listPageSize);
|
app('preferences')->set('listPageSize', $listPageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// language:
|
// language:
|
||||||
/** @var Preference $currentLang */
|
/** @var Preference $currentLang */
|
||||||
$currentLang = app('preferences')->get('language', 'en_US');
|
$currentLang = app('preferences')->get('language', 'en_US');
|
||||||
$lang = $request->get('language');
|
$lang = $request->get('language');
|
||||||
if (array_key_exists($lang, config('firefly.languages'))) {
|
if (array_key_exists($lang, config('firefly.languages'))) {
|
||||||
app('preferences')->set('language', $lang);
|
app('preferences')->set('language', $lang);
|
||||||
}
|
}
|
||||||
@ -254,8 +285,8 @@ class PreferencesController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// optional fields for transactions:
|
// optional fields for transactions:
|
||||||
$setOptions = $request->get('tj') ?? [];
|
$setOptions = $request->get('tj') ?? [];
|
||||||
$optionalTj = [
|
$optionalTj = [
|
||||||
'interest_date' => array_key_exists('interest_date', $setOptions),
|
'interest_date' => array_key_exists('interest_date', $setOptions),
|
||||||
'book_date' => array_key_exists('book_date', $setOptions),
|
'book_date' => array_key_exists('book_date', $setOptions),
|
||||||
'process_date' => array_key_exists('process_date', $setOptions),
|
'process_date' => array_key_exists('process_date', $setOptions),
|
||||||
@ -272,7 +303,7 @@ class PreferencesController extends Controller
|
|||||||
app('preferences')->set('transaction_journal_optional_fields', $optionalTj);
|
app('preferences')->set('transaction_journal_optional_fields', $optionalTj);
|
||||||
|
|
||||||
// dark mode
|
// dark mode
|
||||||
$darkMode = $request->get('darkMode') ?? 'browser';
|
$darkMode = $request->get('darkMode') ?? 'browser';
|
||||||
if (in_array($darkMode, config('firefly.available_dark_modes'), true)) {
|
if (in_array($darkMode, config('firefly.available_dark_modes'), true)) {
|
||||||
app('preferences')->set('darkMode', $darkMode);
|
app('preferences')->set('darkMode', $darkMode);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NotificationRequest.php
|
* NotificationRequest.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
@ -35,24 +36,25 @@ class NotificationRequest extends FormRequest
|
|||||||
|
|
||||||
public function getAll(): array
|
public function getAll(): array
|
||||||
{
|
{
|
||||||
$return = [];
|
$return = [];
|
||||||
foreach (config('notifications.notifications.owner') as $key => $info) {
|
foreach (config('notifications.notifications.owner') as $key => $info) {
|
||||||
$value = false;
|
$value = false;
|
||||||
if ($this->has(sprintf('notification_%s', $key))) {
|
if ($this->has(sprintf('notification_%s', $key))) {
|
||||||
$value = true;
|
$value = true;
|
||||||
}
|
}
|
||||||
$return[$key] = $value;
|
$return[$key] = $value;
|
||||||
}
|
}
|
||||||
$return['slack_webhook_url'] = $this->convertString('slack_webhook_url');
|
$return['slack_webhook_url'] = $this->convertString('slack_webhook_url');
|
||||||
|
|
||||||
$return['pushover_app_token'] = $this->convertString('pushover_app_token');
|
$return['pushover_app_token'] = $this->convertString('pushover_app_token');
|
||||||
$return['pushover_user_token'] = $this->convertString('pushover_user_token');
|
$return['pushover_user_token'] = $this->convertString('pushover_user_token');
|
||||||
|
|
||||||
$return['ntfy_server'] = $this->convertString('ntfy_server');
|
$return['ntfy_server'] = $this->convertString('ntfy_server');
|
||||||
$return['ntfy_topic'] = $this->convertString('ntfy_topic');
|
$return['ntfy_topic'] = $this->convertString('ntfy_topic');
|
||||||
$return['ntfy_auth'] = $this->convertBoolean($this->get('ntfy_auth'));
|
$return['ntfy_auth'] = $this->convertBoolean($this->get('ntfy_auth'));
|
||||||
$return['ntfy_user'] = $this->convertString('ntfy_user');
|
$return['ntfy_user'] = $this->convertString('ntfy_user');
|
||||||
$return['ntfy_pass'] = $this->convertString('ntfy_pass');
|
$return['ntfy_pass'] = $this->convertString('ntfy_pass');
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,14 +65,14 @@ class NotificationRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
$rules = [
|
$rules = [
|
||||||
'slack_webhook_url' => ['nullable', 'url', 'min:1', new IsValidSlackOrDiscordUrl()],
|
'slack_webhook_url' => ['nullable', 'url', 'min:1', new IsValidSlackOrDiscordUrl()],
|
||||||
'ntfy_server' => ['nullable', 'url', 'min:1'],
|
'ntfy_server' => ['nullable', 'url', 'min:1'],
|
||||||
'ntfy_user' => ['required_with:ntfy_pass,ntfy_auth', 'nullable', 'string', 'min:1'],
|
'ntfy_user' => ['required_with:ntfy_pass,ntfy_auth', 'nullable', 'string', 'min:1'],
|
||||||
'ntfy_pass' => ['required_with:ntfy_user,ntfy_auth', 'nullable', 'string', 'min:1'],
|
'ntfy_pass' => ['required_with:ntfy_user,ntfy_auth', 'nullable', 'string', 'min:1'],
|
||||||
];
|
];
|
||||||
foreach (config('notifications.notifications.owner') as $key => $info) {
|
foreach (config('notifications.notifications.owner') as $key => $info) {
|
||||||
$rules[sprintf('notification_%s', $key)] = 'in:0,1';
|
$rules[sprintf('notification_%s', $key)] = 'in:0,1';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ class PiggyBankStoreRequest extends FormRequest
|
|||||||
$accounts = [];
|
$accounts = [];
|
||||||
}
|
}
|
||||||
foreach ($accounts as $item) {
|
foreach ($accounts as $item) {
|
||||||
$data['accounts'][] = ['account_id' => (int) ($item)];
|
$data['accounts'][] = ['account_id' => (int) $item];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
@ -105,7 +105,7 @@ class PiggyBankStoreRequest extends FormRequest
|
|||||||
if ($accountCurrency->id !== $currency->id && 'true' !== $isMultiCurrency) {
|
if ($accountCurrency->id !== $currency->id && 'true' !== $isMultiCurrency) {
|
||||||
$validator->errors()->add('accounts', trans('validation.invalid_account_currency'));
|
$validator->errors()->add('accounts', trans('validation.invalid_account_currency'));
|
||||||
}
|
}
|
||||||
$type = $account->accountType->type;
|
$type = $account->accountType->type;
|
||||||
if (!in_array($type, $types, true)) {
|
if (!in_array($type, $types, true)) {
|
||||||
$validator->errors()->add('accounts', trans('validation.invalid_account_type'));
|
$validator->errors()->add('accounts', trans('validation.invalid_account_type'));
|
||||||
}
|
}
|
||||||
@ -127,6 +127,7 @@ class PiggyBankStoreRequest extends FormRequest
|
|||||||
if (null === $currency) {
|
if (null === $currency) {
|
||||||
return app('amount')->getDefaultCurrency();
|
return app('amount')->getDefaultCurrency();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $currency;
|
return $currency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,18 +44,18 @@ class PiggyBank extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'start_date' => 'date',
|
'start_date' => 'date',
|
||||||
'target_date' => 'date',
|
'target_date' => 'date',
|
||||||
'order' => 'int',
|
'order' => 'int',
|
||||||
'active' => 'boolean',
|
'active' => 'boolean',
|
||||||
'encrypted' => 'boolean',
|
'encrypted' => 'boolean',
|
||||||
'target_amount' => 'string',
|
'target_amount' => 'string',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['name', 'account_id', 'order', 'target_amount', 'start_date', 'start_date_tz', 'target_date', 'target_date_tz', 'active','transaction_currency_id'];
|
protected $fillable = ['name', 'account_id', 'order', 'target_amount', 'start_date', 'start_date_tz', 'target_date', 'target_date_tz', 'active', 'transaction_currency_id'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
||||||
@ -67,9 +67,10 @@ class PiggyBank extends Model
|
|||||||
if (auth()->check()) {
|
if (auth()->check()) {
|
||||||
$piggyBankId = (int)$value;
|
$piggyBankId = (int)$value;
|
||||||
$piggyBank = self::where('piggy_banks.id', $piggyBankId)
|
$piggyBank = self::where('piggy_banks.id', $piggyBankId)
|
||||||
->leftJoin('account_piggy_bank','account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
->leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||||
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||||
->where('accounts.user_id', auth()->user()->id)->first(['piggy_banks.*']);
|
->where('accounts.user_id', auth()->user()->id)->first(['piggy_banks.*'])
|
||||||
|
;
|
||||||
if (null !== $piggyBank) {
|
if (null !== $piggyBank) {
|
||||||
return $piggyBank;
|
return $piggyBank;
|
||||||
}
|
}
|
||||||
|
@ -40,11 +40,11 @@ class PiggyBankRepetition extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'start_date' => SeparateTimezoneCaster::class,
|
'start_date' => SeparateTimezoneCaster::class,
|
||||||
'target_date' => SeparateTimezoneCaster::class,
|
'target_date' => SeparateTimezoneCaster::class,
|
||||||
'virtual_balance' => 'string',
|
'virtual_balance' => 'string',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['piggy_bank_id', 'start_date', 'start_date_tz', 'target_date', 'target_date_tz', 'current_amount'];
|
protected $fillable = ['piggy_bank_id', 'start_date', 'start_date_tz', 'target_date', 'target_date_tz', 'current_amount'];
|
||||||
|
@ -38,7 +38,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UnknownUserLoginAttempt.php
|
* UnknownUserLoginAttempt.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
@ -64,15 +65,14 @@ class UnknownUserLoginAttempt extends Notification
|
|||||||
/**
|
/**
|
||||||
* Get the mail representation of the notification.
|
* Get the mail representation of the notification.
|
||||||
*
|
*
|
||||||
* @return MailMessage
|
|
||||||
*
|
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||||
*/
|
*/
|
||||||
public function toMail(OwnerNotifiable $notifiable): MailMessage
|
public function toMail(OwnerNotifiable $notifiable): MailMessage
|
||||||
{
|
{
|
||||||
return new MailMessage()
|
return new MailMessage()
|
||||||
->markdown('emails.owner.unknown-user', ['address' => $this->address])
|
->markdown('emails.owner.unknown-user', ['address' => $this->address])
|
||||||
->subject((string) trans('email.unknown_user_subject'));
|
->subject((string) trans('email.unknown_user_subject'))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,7 +90,8 @@ class UnknownUserLoginAttempt extends Notification
|
|||||||
public function toPushover(OwnerNotifiable $notifiable): PushoverMessage
|
public function toPushover(OwnerNotifiable $notifiable): PushoverMessage
|
||||||
{
|
{
|
||||||
return PushoverMessage::create((string) trans('email.unknown_user_message', ['address' => $this->address]))
|
return PushoverMessage::create((string) trans('email.unknown_user_message', ['address' => $this->address]))
|
||||||
->title((string) trans('email.unknown_user_subject'));
|
->title((string) trans('email.unknown_user_subject'))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toNtfy(OwnerNotifiable $notifiable): Message
|
public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||||
@ -108,7 +109,7 @@ class UnknownUserLoginAttempt extends Notification
|
|||||||
config(['ntfy-notification-channel.authentication.password' => $settings['ntfy_pass']]);
|
config(['ntfy-notification-channel.authentication.password' => $settings['ntfy_pass']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = new Message();
|
$message = new Message();
|
||||||
$message->topic($settings['ntfy_topic']);
|
$message->topic($settings['ntfy_topic']);
|
||||||
$message->title((string) trans('email.unknown_user_subject'));
|
$message->title((string) trans('email.unknown_user_subject'));
|
||||||
$message->body((string) trans('email.unknown_user_message', ['address' => $this->address]));
|
$message->body((string) trans('email.unknown_user_message', ['address' => $this->address]));
|
||||||
|
@ -83,7 +83,8 @@ class UserInvitation extends Notification
|
|||||||
{
|
{
|
||||||
return (new MailMessage())
|
return (new MailMessage())
|
||||||
->markdown('emails.invitation-created', ['email' => $this->invitee->user->email, 'invitee' => $this->invitee->email])
|
->markdown('emails.invitation-created', ['email' => $this->invitee->user->email, 'invitee' => $this->invitee->email])
|
||||||
->subject((string) trans('email.invitation_created_subject'));
|
->subject((string) trans('email.invitation_created_subject'))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,7 +108,8 @@ class UserInvitation extends Notification
|
|||||||
Log::debug('Now in toPushover() for UserInvitation');
|
Log::debug('Now in toPushover() for UserInvitation');
|
||||||
|
|
||||||
return PushoverMessage::create((string) trans('email.invitation_created_body', ['email' => $this->invitee->user->email, 'invitee' => $this->invitee->email]))
|
return PushoverMessage::create((string) trans('email.invitation_created_body', ['email' => $this->invitee->user->email, 'invitee' => $this->invitee->email]))
|
||||||
->title((string) trans('email.invitation_created_subject'));
|
->title((string) trans('email.invitation_created_subject'))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toNtfy(OwnerNotifiable $notifiable): Message
|
public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||||
@ -126,7 +128,7 @@ class UserInvitation extends Notification
|
|||||||
config(['ntfy-notification-channel.authentication.password' => $settings['ntfy_pass']]);
|
config(['ntfy-notification-channel.authentication.password' => $settings['ntfy_pass']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = new Message();
|
$message = new Message();
|
||||||
$message->topic($settings['ntfy_topic']);
|
$message->topic($settings['ntfy_topic']);
|
||||||
$message->title((string) trans('email.invitation_created_subject'));
|
$message->title((string) trans('email.invitation_created_subject'));
|
||||||
$message->body((string) trans('email.invitation_created_body', ['email' => $this->invitee->user->email, 'invitee' => $this->invitee->email]));
|
$message->body((string) trans('email.invitation_created_body', ['email' => $this->invitee->user->email, 'invitee' => $this->invitee->email]));
|
||||||
|
@ -51,7 +51,7 @@ class UserRegistration extends Notification
|
|||||||
*/
|
*/
|
||||||
public function __construct(OwnerNotifiable $owner, User $user)
|
public function __construct(OwnerNotifiable $owner, User $user)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->owner = $owner;
|
$this->owner = $owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,8 @@ class UserRegistration extends Notification
|
|||||||
{
|
{
|
||||||
return (new MailMessage())
|
return (new MailMessage())
|
||||||
->markdown('emails.registered-admin', ['email' => $this->user->email, 'id' => $this->user->id])
|
->markdown('emails.registered-admin', ['email' => $this->user->email, 'id' => $this->user->id])
|
||||||
->subject((string) trans('email.registered_subject_admin'));
|
->subject((string) trans('email.registered_subject_admin'))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,7 +102,8 @@ class UserRegistration extends Notification
|
|||||||
Log::debug('Now in toPushover() for UserRegistration');
|
Log::debug('Now in toPushover() for UserRegistration');
|
||||||
|
|
||||||
return PushoverMessage::create((string) trans('email.admin_new_user_registered', ['email' => $this->user->email, 'invitee' => $this->user->email]))
|
return PushoverMessage::create((string) trans('email.admin_new_user_registered', ['email' => $this->user->email, 'invitee' => $this->user->email]))
|
||||||
->title((string) trans('email.registered_subject_admin'));
|
->title((string) trans('email.registered_subject_admin'))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toNtfy(OwnerNotifiable $notifiable): Message
|
public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||||
@ -120,10 +122,10 @@ class UserRegistration extends Notification
|
|||||||
config(['ntfy-notification-channel.authentication.password' => $settings['ntfy_pass']]);
|
config(['ntfy-notification-channel.authentication.password' => $settings['ntfy_pass']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = new Message();
|
$message = new Message();
|
||||||
$message->topic($settings['ntfy_topic']);
|
$message->topic($settings['ntfy_topic']);
|
||||||
$message->title((string) trans('email.registered_subject_admin'));
|
$message->title((string) trans('email.registered_subject_admin'));
|
||||||
$message->body((string) trans('email.admin_new_user_registered', ['email' => $this->user->email, 'invitee' => $this->user->email]) );
|
$message->body((string) trans('email.admin_new_user_registered', ['email' => $this->user->email, 'invitee' => $this->user->email]));
|
||||||
|
|
||||||
return $message;
|
return $message;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ namespace FireflyIII\Notifications\Admin;
|
|||||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||||
use FireflyIII\Notifications\ReturnsSettings;
|
use FireflyIII\Notifications\ReturnsSettings;
|
||||||
use FireflyIII\Support\Notifications\UrlValidator;
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
use Illuminate\Notifications\Messages\SlackMessage;
|
use Illuminate\Notifications\Messages\SlackMessage;
|
||||||
@ -108,7 +107,8 @@ class VersionCheckResult extends Notification
|
|||||||
Log::debug('Now in toPushover() for VersionCheckResult');
|
Log::debug('Now in toPushover() for VersionCheckResult');
|
||||||
|
|
||||||
return PushoverMessage::create($this->message)
|
return PushoverMessage::create($this->message)
|
||||||
->title((string) trans('email.new_version_email_subject'));
|
->title((string) trans('email.new_version_email_subject'))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toNtfy(OwnerNotifiable $notifiable): Message
|
public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||||
@ -127,7 +127,7 @@ class VersionCheckResult extends Notification
|
|||||||
config(['ntfy-notification-channel.authentication.password' => $settings['ntfy_pass']]);
|
config(['ntfy-notification-channel.authentication.password' => $settings['ntfy_pass']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = new Message();
|
$message = new Message();
|
||||||
$message->topic($settings['ntfy_topic']);
|
$message->topic($settings['ntfy_topic']);
|
||||||
$message->title((string) trans('email.new_version_email_subject'));
|
$message->title((string) trans('email.new_version_email_subject'));
|
||||||
$message->body($this->message);
|
$message->body($this->message);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AdminNotifiable.php
|
* AdminNotifiable.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
@ -30,13 +31,13 @@ use NotificationChannels\Pushover\PushoverReceiver;
|
|||||||
|
|
||||||
class OwnerNotifiable
|
class OwnerNotifiable
|
||||||
{
|
{
|
||||||
|
|
||||||
public function routeNotificationForSlack(): string
|
public function routeNotificationForSlack(): string
|
||||||
{
|
{
|
||||||
$res = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
$res = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
||||||
if (is_array($res)) {
|
if (is_array($res)) {
|
||||||
$res = '';
|
$res = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (string) $res;
|
return (string) $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,8 +46,10 @@ class OwnerNotifiable
|
|||||||
Log::debug('Return settings for routeNotificationForPushover');
|
Log::debug('Return settings for routeNotificationForPushover');
|
||||||
$pushoverAppToken = (string) app('fireflyconfig')->getEncrypted('pushover_app_token', '')->data;
|
$pushoverAppToken = (string) app('fireflyconfig')->getEncrypted('pushover_app_token', '')->data;
|
||||||
$pushoverUserToken = (string) app('fireflyconfig')->getEncrypted('pushover_user_token', '')->data;
|
$pushoverUserToken = (string) app('fireflyconfig')->getEncrypted('pushover_user_token', '')->data;
|
||||||
|
|
||||||
return PushoverReceiver::withUserKey($pushoverUserToken)
|
return PushoverReceiver::withUserKey($pushoverUserToken)
|
||||||
->withApplicationToken($pushoverAppToken);
|
->withApplicationToken($pushoverAppToken)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,9 +62,10 @@ class OwnerNotifiable
|
|||||||
*/
|
*/
|
||||||
public function routeNotificationFor($driver, $notification = null)
|
public function routeNotificationFor($driver, $notification = null)
|
||||||
{
|
{
|
||||||
$method = 'routeNotificationFor' . Str::studly($driver);
|
$method = 'routeNotificationFor'.Str::studly($driver);
|
||||||
if (method_exists($this, $method)) {
|
if (method_exists($this, $method)) {
|
||||||
Log::debug(sprintf('Redirect for settings to "%s".', $method));
|
Log::debug(sprintf('Redirect for settings to "%s".', $method));
|
||||||
|
|
||||||
return $this->{$method}($notification); // @phpstan-ignore-line
|
return $this->{$method}($notification); // @phpstan-ignore-line
|
||||||
}
|
}
|
||||||
Log::debug(sprintf('No method "%s" found, return generic settings.', $method));
|
Log::debug(sprintf('No method "%s" found, return generic settings.', $method));
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ReturnsAvailableChannels.php
|
* ReturnsAvailableChannels.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
@ -46,8 +47,8 @@ class ReturnsAvailableChannels
|
|||||||
private static function returnOwnerChannels(): array
|
private static function returnOwnerChannels(): array
|
||||||
{
|
{
|
||||||
|
|
||||||
$channels = ['mail'];
|
$channels = ['mail'];
|
||||||
$slackUrl = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
$slackUrl = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
||||||
if (UrlValidator::isValidWebhookURL($slackUrl)) {
|
if (UrlValidator::isValidWebhookURL($slackUrl)) {
|
||||||
$channels[] = 'slack';
|
$channels[] = 'slack';
|
||||||
}
|
}
|
||||||
@ -73,8 +74,8 @@ class ReturnsAvailableChannels
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log::debug(sprintf('Final channel set in ReturnsAvailableChannels: %s ', implode(', ', $channels)));
|
Log::debug(sprintf('Final channel set in ReturnsAvailableChannels: %s ', implode(', ', $channels)));
|
||||||
|
|
||||||
// only the owner can get notifications over
|
// only the owner can get notifications over
|
||||||
return $channels;
|
return $channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ReturnsSettings.php
|
* ReturnsSettings.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
@ -34,6 +35,7 @@ class ReturnsSettings
|
|||||||
if ('ntfy' === $channel) {
|
if ('ntfy' === $channel) {
|
||||||
return self::getNtfySettings($type, $user);
|
return self::getNtfySettings($type, $user);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new FireflyException(sprintf('Cannot handle channel "%s"', $channel));
|
throw new FireflyException(sprintf('Cannot handle channel "%s"', $channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ class ReturnsSettings
|
|||||||
$settings['ntfy_user'] = FireflyConfig::getEncrypted('ntfy_user', '')->data;
|
$settings['ntfy_user'] = FireflyConfig::getEncrypted('ntfy_user', '')->data;
|
||||||
$settings['ntfy_pass'] = FireflyConfig::getEncrypted('ntfy_pass', '')->data;
|
$settings['ntfy_pass'] = FireflyConfig::getEncrypted('ntfy_pass', '')->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $settings;
|
return $settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,6 @@ class TestNotificationEmail extends Notification
|
|||||||
/**
|
/**
|
||||||
* Get the array representation of the notification.
|
* Get the array representation of the notification.
|
||||||
*
|
*
|
||||||
* @param OwnerNotifiable $notifiable
|
|
||||||
*
|
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
@ -73,9 +71,11 @@ class TestNotificationEmail extends Notification
|
|||||||
public function toMail(OwnerNotifiable $notifiable)
|
public function toMail(OwnerNotifiable $notifiable)
|
||||||
{
|
{
|
||||||
$address = (string) config('firefly.site_owner');
|
$address = (string) config('firefly.site_owner');
|
||||||
|
|
||||||
return (new MailMessage())
|
return (new MailMessage())
|
||||||
->markdown('emails.admin-test', ['email' => $address])
|
->markdown('emails.admin-test', ['email' => $address])
|
||||||
->subject((string) trans('email.admin_test_subject'));
|
->subject((string) trans('email.admin_test_subject'))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,13 +26,12 @@ namespace FireflyIII\Notifications\Test;
|
|||||||
|
|
||||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||||
use FireflyIII\Notifications\ReturnsSettings;
|
use FireflyIII\Notifications\ReturnsSettings;
|
||||||
use FireflyIII\User;
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Notifications\Notification;
|
use Illuminate\Notifications\Notification;
|
||||||
use Ntfy\Message;
|
use Ntfy\Message;
|
||||||
use Wijourdil\NtfyNotificationChannel\Channels\NtfyChannel;
|
use Wijourdil\NtfyNotificationChannel\Channels\NtfyChannel;
|
||||||
|
|
||||||
//use Illuminate\Notifications\Slack\SlackMessage;
|
// use Illuminate\Notifications\Slack\SlackMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TestNotification
|
* Class TestNotification
|
||||||
@ -66,7 +65,6 @@ class TestNotificationNtfy extends Notification
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function toNtfy(OwnerNotifiable $notifiable): Message
|
public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||||
{
|
{
|
||||||
$settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
$settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||||
@ -82,7 +80,7 @@ class TestNotificationNtfy extends Notification
|
|||||||
config(['ntfy-notification-channel.authentication.password' => $settings['ntfy_pass']]);
|
config(['ntfy-notification-channel.authentication.password' => $settings['ntfy_pass']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = new Message();
|
$message = new Message();
|
||||||
$message->topic($settings['ntfy_topic']);
|
$message->topic($settings['ntfy_topic']);
|
||||||
$message->title((string) trans('email.admin_test_subject'));
|
$message->title((string) trans('email.admin_test_subject'));
|
||||||
$message->body((string) trans('email.admin_test_message', ['channel' => 'ntfy']));
|
$message->body((string) trans('email.admin_test_message', ['channel' => 'ntfy']));
|
||||||
|
@ -25,17 +25,13 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Notifications\Test;
|
namespace FireflyIII\Notifications\Test;
|
||||||
|
|
||||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||||
use FireflyIII\User;
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
|
||||||
use Illuminate\Notifications\Notification;
|
use Illuminate\Notifications\Notification;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use NotificationChannels\Pushover\PushoverChannel;
|
use NotificationChannels\Pushover\PushoverChannel;
|
||||||
use NotificationChannels\Pushover\PushoverMessage;
|
use NotificationChannels\Pushover\PushoverMessage;
|
||||||
use Ntfy\Message;
|
|
||||||
use Wijourdil\NtfyNotificationChannel\Channels\NtfyChannel;
|
|
||||||
|
|
||||||
//use Illuminate\Notifications\Slack\SlackMessage;
|
// use Illuminate\Notifications\Slack\SlackMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TestNotification
|
* Class TestNotification
|
||||||
@ -57,8 +53,6 @@ class TestNotificationPushover extends Notification
|
|||||||
/**
|
/**
|
||||||
* Get the array representation of the notification.
|
* Get the array representation of the notification.
|
||||||
*
|
*
|
||||||
* @param OwnerNotifiable $notifiable
|
|
||||||
*
|
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
@ -69,16 +63,15 @@ class TestNotificationPushover extends Notification
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function toPushover(OwnerNotifiable $notifiable): PushoverMessage
|
public function toPushover(OwnerNotifiable $notifiable): PushoverMessage
|
||||||
{
|
{
|
||||||
Log::debug('Now in toPushover()');
|
Log::debug('Now in toPushover()');
|
||||||
|
|
||||||
return PushoverMessage::create((string)trans('email.admin_test_message', ['channel' => 'Pushover']))
|
return PushoverMessage::create((string)trans('email.admin_test_message', ['channel' => 'Pushover']))
|
||||||
->title((string)trans('email.admin_test_subject'));
|
->title((string)trans('email.admin_test_subject'))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||||
*/
|
*/
|
||||||
|
@ -29,7 +29,7 @@ use Illuminate\Bus\Queueable;
|
|||||||
use Illuminate\Notifications\Messages\SlackMessage;
|
use Illuminate\Notifications\Messages\SlackMessage;
|
||||||
use Illuminate\Notifications\Notification;
|
use Illuminate\Notifications\Notification;
|
||||||
|
|
||||||
//use Illuminate\Notifications\Slack\SlackMessage;
|
// use Illuminate\Notifications\Slack\SlackMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TestNotification
|
* Class TestNotification
|
||||||
@ -51,8 +51,6 @@ class TestNotificationSlack extends Notification
|
|||||||
/**
|
/**
|
||||||
* Get the array representation of the notification.
|
* Get the array representation of the notification.
|
||||||
*
|
*
|
||||||
* @param OwnerNotifiable $notifiable
|
|
||||||
*
|
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
@ -66,15 +64,12 @@ class TestNotificationSlack extends Notification
|
|||||||
/**
|
/**
|
||||||
* Get the Slack representation of the notification.
|
* Get the Slack representation of the notification.
|
||||||
*
|
*
|
||||||
* @param OwnerNotifiable $notifiable
|
|
||||||
*
|
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public function toSlack(OwnerNotifiable $notifiable)
|
public function toSlack(OwnerNotifiable $notifiable)
|
||||||
{
|
{
|
||||||
return new SlackMessage()->content((string) trans('email.admin_test_subject'));
|
return new SlackMessage()->content((string) trans('email.admin_test_subject'));
|
||||||
//return new SlackMessage()->text((string) trans('email.admin_test_subject'))->to($url);
|
// return new SlackMessage()->text((string) trans('email.admin_test_subject'))->to($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,8 +77,6 @@ class TestNotificationSlack extends Notification
|
|||||||
*
|
*
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||||
*
|
*
|
||||||
* @param OwnerNotifiable $notifiable
|
|
||||||
*
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function via(OwnerNotifiable $notifiable)
|
public function via(OwnerNotifiable $notifiable)
|
||||||
|
@ -25,7 +25,6 @@ namespace FireflyIII\Providers;
|
|||||||
|
|
||||||
use FireflyIII\Events\ActuallyLoggedIn;
|
use FireflyIII\Events\ActuallyLoggedIn;
|
||||||
use FireflyIII\Events\Admin\InvitationCreated;
|
use FireflyIII\Events\Admin\InvitationCreated;
|
||||||
use FireflyIII\Events\AdminRequestedTestMessage;
|
|
||||||
use FireflyIII\Events\DestroyedTransactionGroup;
|
use FireflyIII\Events\DestroyedTransactionGroup;
|
||||||
use FireflyIII\Events\DetectedNewIPAddress;
|
use FireflyIII\Events\DetectedNewIPAddress;
|
||||||
use FireflyIII\Events\Model\BudgetLimit\Created;
|
use FireflyIII\Events\Model\BudgetLimit\Created;
|
||||||
@ -137,7 +136,7 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
'FireflyIII\Handlers\Events\UserEventHandler@sendEmailChangeUndoMail',
|
'FireflyIII\Handlers\Events\UserEventHandler@sendEmailChangeUndoMail',
|
||||||
],
|
],
|
||||||
// admin related
|
// admin related
|
||||||
TestNotificationChannel::class => [
|
TestNotificationChannel::class => [
|
||||||
'FireflyIII\Handlers\Events\AdminEventHandler@sendTestNotification',
|
'FireflyIII\Handlers\Events\AdminEventHandler@sendTestNotification',
|
||||||
],
|
],
|
||||||
NewVersionAvailable::class => [
|
NewVersionAvailable::class => [
|
||||||
@ -147,7 +146,7 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
'FireflyIII\Handlers\Events\AdminEventHandler@sendInvitationNotification',
|
'FireflyIII\Handlers\Events\AdminEventHandler@sendInvitationNotification',
|
||||||
'FireflyIII\Handlers\Events\UserEventHandler@sendRegistrationInvite',
|
'FireflyIII\Handlers\Events\UserEventHandler@sendRegistrationInvite',
|
||||||
],
|
],
|
||||||
UnknownUserAttemptedLogin::class => [
|
UnknownUserAttemptedLogin::class => [
|
||||||
'FireflyIII\Handlers\Events\AdminEventHandler@sendLoginAttemptNotification',
|
'FireflyIII\Handlers\Events\AdminEventHandler@sendLoginAttemptNotification',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -50,10 +50,10 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function budgeted(Carbon $start, Carbon $end, TransactionCurrency $currency, ?Collection $budgets = null): string
|
public function budgeted(Carbon $start, Carbon $end, TransactionCurrency $currency, ?Collection $budgets = null): string
|
||||||
{
|
{
|
||||||
$query = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
|
$query = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
|
||||||
|
|
||||||
// same complex where query as below.
|
// same complex where query as below.
|
||||||
->where(
|
->where(
|
||||||
static function (Builder $q5) use ($start, $end): void {
|
static function (Builder $q5) use ($start, $end): void {
|
||||||
$q5->where(
|
$q5->where(
|
||||||
static function (Builder $q1) use ($start, $end): void {
|
static function (Builder $q1) use ($start, $end): void {
|
||||||
@ -63,27 +63,30 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
$q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d'));
|
$q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d'));
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
->orWhere(
|
->orWhere(
|
||||||
static function (Builder $q3) use ($start, $end): void {
|
static function (Builder $q3) use ($start, $end): void {
|
||||||
$q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d'));
|
$q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d'));
|
||||||
$q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d'));
|
$q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d'));
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
->orWhere(
|
->orWhere(
|
||||||
static function (Builder $q4) use ($start, $end): void {
|
static function (Builder $q4) use ($start, $end): void {
|
||||||
// or start is before start AND end is after end.
|
// or start is before start AND end is after end.
|
||||||
$q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d'));
|
$q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d'));
|
||||||
$q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d'));
|
$q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d'));
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
->where('budget_limits.transaction_currency_id', $currency->id)
|
->where('budget_limits.transaction_currency_id', $currency->id)
|
||||||
->whereNull('budgets.deleted_at')
|
->whereNull('budgets.deleted_at')
|
||||||
->where('budgets.active', true)
|
->where('budgets.active', true)
|
||||||
->where('budgets.user_id', $this->user->id);
|
->where('budgets.user_id', $this->user->id)
|
||||||
|
;
|
||||||
if (null !== $budgets && $budgets->count() > 0) {
|
if (null !== $budgets && $budgets->count() > 0) {
|
||||||
$query->whereIn('budget_limits.budget_id', $budgets->pluck('id')->toArray());
|
$query->whereIn('budget_limits.budget_id', $budgets->pluck('id')->toArray());
|
||||||
}
|
}
|
||||||
@ -135,17 +138,19 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
// both are NULL:
|
// both are NULL:
|
||||||
if (null === $start && null === $end) {
|
if (null === $start && null === $end) {
|
||||||
return BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
|
return BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
|
||||||
->with(['budget'])
|
->with(['budget'])
|
||||||
->where('budgets.user_id', $this->user->id)
|
->where('budgets.user_id', $this->user->id)
|
||||||
->whereNull('budgets.deleted_at')
|
->whereNull('budgets.deleted_at')
|
||||||
->get(['budget_limits.*']);
|
->get(['budget_limits.*'])
|
||||||
|
;
|
||||||
}
|
}
|
||||||
// one of the two is NULL.
|
// one of the two is NULL.
|
||||||
if (null === $start xor null === $end) {
|
if (null === $start xor null === $end) {
|
||||||
$query = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
|
$query = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
|
||||||
->with(['budget'])
|
->with(['budget'])
|
||||||
->whereNull('budgets.deleted_at')
|
->whereNull('budgets.deleted_at')
|
||||||
->where('budgets.user_id', $this->user->id);
|
->where('budgets.user_id', $this->user->id)
|
||||||
|
;
|
||||||
if (null !== $end) {
|
if (null !== $end) {
|
||||||
// end date must be before $end.
|
// end date must be before $end.
|
||||||
$query->where('end_date', '<=', $end->format('Y-m-d 00:00:00'));
|
$query->where('end_date', '<=', $end->format('Y-m-d 00:00:00'));
|
||||||
@ -160,36 +165,39 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
|
|
||||||
// neither are NULL:
|
// neither are NULL:
|
||||||
return BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
|
return BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
|
||||||
->with(['budget'])
|
->with(['budget'])
|
||||||
->where('budgets.user_id', $this->user->id)
|
->where('budgets.user_id', $this->user->id)
|
||||||
->whereNull('budgets.deleted_at')
|
->whereNull('budgets.deleted_at')
|
||||||
->where(
|
->where(
|
||||||
static function (Builder $q5) use ($start, $end): void {
|
static function (Builder $q5) use ($start, $end): void {
|
||||||
$q5->where(
|
$q5->where(
|
||||||
static function (Builder $q1) use ($start, $end): void {
|
static function (Builder $q1) use ($start, $end): void {
|
||||||
$q1->where(
|
$q1->where(
|
||||||
static function (Builder $q2) use ($start, $end): void {
|
static function (Builder $q2) use ($start, $end): void {
|
||||||
$q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d'));
|
$q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d'));
|
||||||
$q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d'));
|
$q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d'));
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
->orWhere(
|
->orWhere(
|
||||||
static function (Builder $q3) use ($start, $end): void {
|
static function (Builder $q3) use ($start, $end): void {
|
||||||
$q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d'));
|
$q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d'));
|
||||||
$q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d'));
|
$q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d'));
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
}
|
;
|
||||||
)
|
}
|
||||||
->orWhere(
|
)
|
||||||
static function (Builder $q4) use ($start, $end): void {
|
->orWhere(
|
||||||
// or start is before start AND end is after end.
|
static function (Builder $q4) use ($start, $end): void {
|
||||||
$q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d'));
|
// or start is before start AND end is after end.
|
||||||
$q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d'));
|
$q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d'));
|
||||||
}
|
$q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d'));
|
||||||
);
|
}
|
||||||
}
|
)
|
||||||
)->get(['budget_limits.*']);
|
;
|
||||||
|
}
|
||||||
|
)->get(['budget_limits.*'])
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBudgetLimits(Budget $budget, ?Carbon $start = null, ?Carbon $end = null): Collection
|
public function getBudgetLimits(Budget $budget, ?Carbon $start = null, ?Carbon $end = null): Collection
|
||||||
@ -214,38 +222,41 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
|
|
||||||
// when both dates are set:
|
// when both dates are set:
|
||||||
return $budget->budgetlimits()
|
return $budget->budgetlimits()
|
||||||
->where(
|
->where(
|
||||||
static function (Builder $q5) use ($start, $end): void { // @phpstan-ignore-line
|
static function (Builder $q5) use ($start, $end): void { // @phpstan-ignore-line
|
||||||
$q5->where(
|
$q5->where(
|
||||||
static function (Builder $q1) use ($start, $end): void {
|
static function (Builder $q1) use ($start, $end): void {
|
||||||
// budget limit ends within period
|
// budget limit ends within period
|
||||||
$q1->where(
|
$q1->where(
|
||||||
static function (Builder $q2) use ($start, $end): void {
|
static function (Builder $q2) use ($start, $end): void {
|
||||||
$q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d 00:00:00'));
|
$q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d 00:00:00'));
|
||||||
$q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d 23:59:59'));
|
$q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d 23:59:59'));
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
// budget limit start within period
|
// budget limit start within period
|
||||||
->orWhere(
|
->orWhere(
|
||||||
static function (Builder $q3) use ($start, $end): void {
|
static function (Builder $q3) use ($start, $end): void {
|
||||||
$q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d 00:00:00'));
|
$q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d 00:00:00'));
|
||||||
$q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d 23:59:59'));
|
$q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d 23:59:59'));
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
}
|
;
|
||||||
)
|
}
|
||||||
->orWhere(
|
)
|
||||||
static function (Builder $q4) use ($start, $end): void {
|
->orWhere(
|
||||||
// or start is before start AND end is after end.
|
static function (Builder $q4) use ($start, $end): void {
|
||||||
$q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d 23:59:59'));
|
// or start is before start AND end is after end.
|
||||||
$q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d 00:00:00'));
|
$q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d 23:59:59'));
|
||||||
}
|
$q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d 00:00:00'));
|
||||||
);
|
}
|
||||||
}
|
)
|
||||||
)->orderBy('budget_limits.start_date', 'DESC')->get(['budget_limits.*']);
|
;
|
||||||
|
}
|
||||||
|
)->orderBy('budget_limits.start_date', 'DESC')->get(['budget_limits.*'])
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUser(null | Authenticatable | User $user): void
|
public function setUser(null|Authenticatable|User $user): void
|
||||||
{
|
{
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
@ -259,33 +270,34 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
{
|
{
|
||||||
// if no currency has been provided, use the user's default currency:
|
// if no currency has been provided, use the user's default currency:
|
||||||
/** @var TransactionCurrencyFactory $factory */
|
/** @var TransactionCurrencyFactory $factory */
|
||||||
$factory = app(TransactionCurrencyFactory::class);
|
$factory = app(TransactionCurrencyFactory::class);
|
||||||
$currency = $factory->find($data['currency_id'] ?? null, $data['currency_code'] ?? null);
|
$currency = $factory->find($data['currency_id'] ?? null, $data['currency_code'] ?? null);
|
||||||
if (null === $currency) {
|
if (null === $currency) {
|
||||||
$currency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
|
$currency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
|
||||||
}
|
}
|
||||||
$currency->enabled = true;
|
$currency->enabled = true;
|
||||||
$currency->save();
|
$currency->save();
|
||||||
|
|
||||||
// find the budget:
|
// find the budget:
|
||||||
$budget = $this->user->budgets()->find((int) $data['budget_id']);
|
$budget = $this->user->budgets()->find((int) $data['budget_id']);
|
||||||
if (null === $budget) {
|
if (null === $budget) {
|
||||||
throw new FireflyException('200004: Budget does not exist.');
|
throw new FireflyException('200004: Budget does not exist.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// find limit with same date range and currency.
|
// find limit with same date range and currency.
|
||||||
$limit = $budget->budgetlimits()
|
$limit = $budget->budgetlimits()
|
||||||
->where('budget_limits.start_date', $data['start_date']->format('Y-m-d'))
|
->where('budget_limits.start_date', $data['start_date']->format('Y-m-d'))
|
||||||
->where('budget_limits.end_date', $data['end_date']->format('Y-m-d'))
|
->where('budget_limits.end_date', $data['end_date']->format('Y-m-d'))
|
||||||
->where('budget_limits.transaction_currency_id', $currency->id)
|
->where('budget_limits.transaction_currency_id', $currency->id)
|
||||||
->first(['budget_limits.*']);
|
->first(['budget_limits.*'])
|
||||||
|
;
|
||||||
if (null !== $limit) {
|
if (null !== $limit) {
|
||||||
throw new FireflyException('200027: Budget limit already exists.');
|
throw new FireflyException('200027: Budget limit already exists.');
|
||||||
}
|
}
|
||||||
app('log')->debug('No existing budget limit, create a new one');
|
app('log')->debug('No existing budget limit, create a new one');
|
||||||
|
|
||||||
// or create one and return it.
|
// or create one and return it.
|
||||||
$limit = new BudgetLimit();
|
$limit = new BudgetLimit();
|
||||||
$limit->budget()->associate($budget);
|
$limit->budget()->associate($budget);
|
||||||
$limit->start_date = $data['start_date']->format('Y-m-d');
|
$limit->start_date = $data['start_date']->format('Y-m-d');
|
||||||
$limit->end_date = $data['end_date']->format('Y-m-d');
|
$limit->end_date = $data['end_date']->format('Y-m-d');
|
||||||
@ -293,7 +305,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
$limit->transaction_currency_id = $currency->id;
|
$limit->transaction_currency_id = $currency->id;
|
||||||
$limit->save();
|
$limit->save();
|
||||||
|
|
||||||
$noteText = (string) ($data['notes'] ?? '');
|
$noteText = (string) ($data['notes'] ?? '');
|
||||||
if ('' !== $noteText) {
|
if ('' !== $noteText) {
|
||||||
$this->setNoteText($limit, $noteText);
|
$this->setNoteText($limit, $noteText);
|
||||||
}
|
}
|
||||||
@ -303,13 +315,13 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
return $limit;
|
return $limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function find(Budget $budget, TransactionCurrency $currency, Carbon $start, Carbon $end): ?BudgetLimit
|
public function find(Budget $budget, TransactionCurrency $currency, Carbon $start, Carbon $end): ?BudgetLimit
|
||||||
{
|
{
|
||||||
return $budget->budgetlimits()
|
return $budget->budgetlimits()
|
||||||
->where('transaction_currency_id', $currency->id)
|
->where('transaction_currency_id', $currency->id)
|
||||||
->where('start_date', $start->format('Y-m-d'))
|
->where('start_date', $start->format('Y-m-d'))
|
||||||
->where('end_date', $end->format('Y-m-d'))->first();
|
->where('end_date', $end->format('Y-m-d'))->first()
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -317,8 +329,8 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function update(BudgetLimit $budgetLimit, array $data): BudgetLimit
|
public function update(BudgetLimit $budgetLimit, array $data): BudgetLimit
|
||||||
{
|
{
|
||||||
$budgetLimit->amount = array_key_exists('amount', $data) ? $data['amount'] : $budgetLimit->amount;
|
$budgetLimit->amount = array_key_exists('amount', $data) ? $data['amount'] : $budgetLimit->amount;
|
||||||
$budgetLimit->budget_id = array_key_exists('budget_id', $data) ? $data['budget_id'] : $budgetLimit->budget_id;
|
$budgetLimit->budget_id = array_key_exists('budget_id', $data) ? $data['budget_id'] : $budgetLimit->budget_id;
|
||||||
|
|
||||||
if (array_key_exists('start', $data)) {
|
if (array_key_exists('start', $data)) {
|
||||||
$budgetLimit->start_date = $data['start']->startOfDay();
|
$budgetLimit->start_date = $data['start']->startOfDay();
|
||||||
@ -330,7 +342,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if no currency has been provided, use the user's default currency:
|
// if no currency has been provided, use the user's default currency:
|
||||||
$currency = null;
|
$currency = null;
|
||||||
|
|
||||||
// update if relevant:
|
// update if relevant:
|
||||||
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
|
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
|
||||||
@ -342,14 +354,14 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
if (null === $currency) {
|
if (null === $currency) {
|
||||||
$currency = $budgetLimit->transactionCurrency ?? app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
|
$currency = $budgetLimit->transactionCurrency ?? app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
|
||||||
}
|
}
|
||||||
$currency->enabled = true;
|
$currency->enabled = true;
|
||||||
$currency->save();
|
$currency->save();
|
||||||
|
|
||||||
$budgetLimit->transaction_currency_id = $currency->id;
|
$budgetLimit->transaction_currency_id = $currency->id;
|
||||||
$budgetLimit->save();
|
$budgetLimit->save();
|
||||||
|
|
||||||
// update notes if they exist.
|
// update notes if they exist.
|
||||||
if(array_key_exists('notes', $data)) {
|
if (array_key_exists('notes', $data)) {
|
||||||
$this->setNoteText($budgetLimit, (string)$data['notes']);
|
$this->setNoteText($budgetLimit, (string)$data['notes']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,26 +371,29 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
public function updateLimitAmount(Budget $budget, Carbon $start, Carbon $end, string $amount): ?BudgetLimit
|
public function updateLimitAmount(Budget $budget, Carbon $start, Carbon $end, string $amount): ?BudgetLimit
|
||||||
{
|
{
|
||||||
// count the limits:
|
// count the limits:
|
||||||
$limits = $budget->budgetlimits()
|
$limits = $budget->budgetlimits()
|
||||||
->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
|
->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
|
||||||
->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
|
->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
|
||||||
->count('budget_limits.*');
|
->count('budget_limits.*')
|
||||||
|
;
|
||||||
app('log')->debug(sprintf('Found %d budget limits.', $limits));
|
app('log')->debug(sprintf('Found %d budget limits.', $limits));
|
||||||
|
|
||||||
// there might be a budget limit for these dates:
|
// there might be a budget limit for these dates:
|
||||||
/** @var null|BudgetLimit $limit */
|
/** @var null|BudgetLimit $limit */
|
||||||
$limit = $budget->budgetlimits()
|
$limit = $budget->budgetlimits()
|
||||||
->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
|
->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
|
||||||
->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
|
->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
|
||||||
->first(['budget_limits.*']);
|
->first(['budget_limits.*'])
|
||||||
|
;
|
||||||
|
|
||||||
// if more than 1 limit found, delete the others:
|
// if more than 1 limit found, delete the others:
|
||||||
if ($limits > 1 && null !== $limit) {
|
if ($limits > 1 && null !== $limit) {
|
||||||
app('log')->debug(sprintf('Found more than 1, delete all except #%d', $limit->id));
|
app('log')->debug(sprintf('Found more than 1, delete all except #%d', $limit->id));
|
||||||
$budget->budgetlimits()
|
$budget->budgetlimits()
|
||||||
->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
|
->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
|
||||||
->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
|
->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
|
||||||
->where('budget_limits.id', '!=', $limit->id)->delete();
|
->where('budget_limits.id', '!=', $limit->id)->delete()
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete if amount is zero.
|
// delete if amount is zero.
|
||||||
@ -400,7 +415,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
}
|
}
|
||||||
app('log')->debug('No existing budget limit, create a new one');
|
app('log')->debug('No existing budget limit, create a new one');
|
||||||
// or create one and return it.
|
// or create one and return it.
|
||||||
$limit = new BudgetLimit();
|
$limit = new BudgetLimit();
|
||||||
$limit->budget()->associate($budget);
|
$limit->budget()->associate($budget);
|
||||||
$limit->start_date = $start->startOfDay();
|
$limit->start_date = $start->startOfDay();
|
||||||
$limit->start_date_tz = $start->format('e');
|
$limit->start_date_tz = $start->format('e');
|
||||||
@ -413,12 +428,14 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
|||||||
return $limit;
|
return $limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\Override] public function getNoteText(BudgetLimit $budgetLimit): string
|
#[\Override]
|
||||||
|
public function getNoteText(BudgetLimit $budgetLimit): string
|
||||||
{
|
{
|
||||||
return (string) $budgetLimit->notes()->first()?->text;
|
return (string) $budgetLimit->notes()->first()?->text;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\Override] public function setNoteText(BudgetLimit $budgetLimit, string $text): void
|
#[\Override]
|
||||||
|
public function setNoteText(BudgetLimit $budgetLimit, string $text): void
|
||||||
{
|
{
|
||||||
$dbNote = $budgetLimit->notes()->first();
|
$dbNote = $budgetLimit->notes()->first();
|
||||||
if ('' !== $text) {
|
if ('' !== $text) {
|
||||||
|
@ -49,6 +49,7 @@ interface BudgetLimitRepositoryInterface
|
|||||||
public function destroyAll(): void;
|
public function destroyAll(): void;
|
||||||
|
|
||||||
public function getNoteText(BudgetLimit $budgetLimit): string;
|
public function getNoteText(BudgetLimit $budgetLimit): string;
|
||||||
|
|
||||||
public function setNoteText(BudgetLimit $budgetLimit, string $text): void;
|
public function setNoteText(BudgetLimit $budgetLimit, string $text): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -106,7 +106,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\Override] public function find(int $currencyId): ?TransactionCurrency
|
#[\Override]
|
||||||
|
public function find(int $currencyId): ?TransactionCurrency
|
||||||
{
|
{
|
||||||
return TransactionCurrency::find($currencyId);
|
return TransactionCurrency::find($currencyId);
|
||||||
}
|
}
|
||||||
|
@ -30,11 +30,9 @@ use FireflyIII\Factory\PiggyBankFactory;
|
|||||||
use FireflyIII\Models\Note;
|
use FireflyIII\Models\Note;
|
||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Models\PiggyBankRepetition;
|
use FireflyIII\Models\PiggyBankRepetition;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
|
use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
|
||||||
use FireflyIII\Support\Facades\Amount;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Database\QueryException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trait ModifiesPiggyBanks
|
* Trait ModifiesPiggyBanks
|
||||||
@ -59,7 +57,7 @@ trait ModifiesPiggyBanks
|
|||||||
|
|
||||||
public function removeAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool
|
public function removeAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool
|
||||||
{
|
{
|
||||||
$repetition = $this->getRepetition($piggyBank);
|
$repetition = $this->getRepetition($piggyBank);
|
||||||
if (null === $repetition) {
|
if (null === $repetition) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -74,11 +72,11 @@ trait ModifiesPiggyBanks
|
|||||||
|
|
||||||
public function addAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool
|
public function addAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool
|
||||||
{
|
{
|
||||||
$repetition = $this->getRepetition($piggyBank);
|
$repetition = $this->getRepetition($piggyBank);
|
||||||
if (null === $repetition) {
|
if (null === $repetition) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$currentAmount = $repetition->current_amount ?? '0';
|
$currentAmount = $repetition->current_amount ?? '0';
|
||||||
$repetition->current_amount = bcadd($currentAmount, $amount);
|
$repetition->current_amount = bcadd($currentAmount, $amount);
|
||||||
$repetition->save();
|
$repetition->save();
|
||||||
|
|
||||||
@ -143,15 +141,15 @@ trait ModifiesPiggyBanks
|
|||||||
|
|
||||||
public function setCurrentAmount(PiggyBank $piggyBank, string $amount): PiggyBank
|
public function setCurrentAmount(PiggyBank $piggyBank, string $amount): PiggyBank
|
||||||
{
|
{
|
||||||
$repetition = $this->getRepetition($piggyBank);
|
$repetition = $this->getRepetition($piggyBank);
|
||||||
if (null === $repetition) {
|
if (null === $repetition) {
|
||||||
return $piggyBank;
|
return $piggyBank;
|
||||||
}
|
}
|
||||||
$max = $piggyBank->target_amount;
|
$max = $piggyBank->target_amount;
|
||||||
if (1 === bccomp($amount, $max) && 0 !== bccomp($piggyBank->target_amount, '0')) {
|
if (1 === bccomp($amount, $max) && 0 !== bccomp($piggyBank->target_amount, '0')) {
|
||||||
$amount = $max;
|
$amount = $max;
|
||||||
}
|
}
|
||||||
$difference = bcsub($amount, $repetition->current_amount);
|
$difference = bcsub($amount, $repetition->current_amount);
|
||||||
$repetition->current_amount = $amount;
|
$repetition->current_amount = $amount;
|
||||||
$repetition->save();
|
$repetition->save();
|
||||||
|
|
||||||
@ -184,10 +182,10 @@ trait ModifiesPiggyBanks
|
|||||||
{
|
{
|
||||||
$factory = new PiggyBankFactory();
|
$factory = new PiggyBankFactory();
|
||||||
$factory->user = $this->user;
|
$factory->user = $this->user;
|
||||||
|
|
||||||
return $factory->store($data);
|
return $factory->store($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function setOrder(PiggyBank $piggyBank, int $newOrder): bool
|
public function setOrder(PiggyBank $piggyBank, int $newOrder): bool
|
||||||
{
|
{
|
||||||
$oldOrder = $piggyBank->order;
|
$oldOrder = $piggyBank->order;
|
||||||
@ -220,7 +218,8 @@ trait ModifiesPiggyBanks
|
|||||||
if ('' === $note) {
|
if ('' === $note) {
|
||||||
$dbNote = $piggyBank->notes()->first();
|
$dbNote = $piggyBank->notes()->first();
|
||||||
$dbNote?->delete();
|
$dbNote?->delete();
|
||||||
return ;
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
$dbNote = $piggyBank->notes()->first();
|
$dbNote = $piggyBank->notes()->first();
|
||||||
if (null === $dbNote) {
|
if (null === $dbNote) {
|
||||||
@ -249,7 +248,7 @@ trait ModifiesPiggyBanks
|
|||||||
// remove money from the rep.
|
// remove money from the rep.
|
||||||
$repetition = $this->getRepetition($piggyBank);
|
$repetition = $this->getRepetition($piggyBank);
|
||||||
if (null !== $repetition && $repetition->current_amount > $piggyBank->target_amount && 0 !== bccomp($piggyBank->target_amount, '0')) {
|
if (null !== $repetition && $repetition->current_amount > $piggyBank->target_amount && 0 !== bccomp($piggyBank->target_amount, '0')) {
|
||||||
$difference = bcsub($piggyBank->target_amount, $repetition->current_amount);
|
$difference = bcsub($piggyBank->target_amount, $repetition->current_amount);
|
||||||
|
|
||||||
// an amount will be removed, create "negative" event:
|
// an amount will be removed, create "negative" event:
|
||||||
event(new ChangedAmount($piggyBank, $difference, null, null));
|
event(new ChangedAmount($piggyBank, $difference, null, null));
|
||||||
|
@ -95,7 +95,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
|
|
||||||
public function getAttachments(PiggyBank $piggyBank): Collection
|
public function getAttachments(PiggyBank $piggyBank): Collection
|
||||||
{
|
{
|
||||||
$set = $piggyBank->attachments()->get();
|
$set = $piggyBank->attachments()->get();
|
||||||
|
|
||||||
/** @var \Storage $disk */
|
/** @var \Storage $disk */
|
||||||
$disk = \Storage::disk('upload');
|
$disk = \Storage::disk('upload');
|
||||||
@ -122,12 +122,14 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
$amount = '' === $amount ? '0' : $amount;
|
$amount = '' === $amount ? '0' : $amount;
|
||||||
$sum = bcadd($sum, $amount);
|
$sum = bcadd($sum, $amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sum;
|
return $sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRepetition(PiggyBank $piggyBank): ?PiggyBankRepetition
|
public function getRepetition(PiggyBank $piggyBank): ?PiggyBankRepetition
|
||||||
{
|
{
|
||||||
throw new FireflyException('[b] Piggy bank repetitions are EOL.');
|
throw new FireflyException('[b] Piggy bank repetitions are EOL.');
|
||||||
|
|
||||||
return $piggyBank->piggyBankRepetitions()->first();
|
return $piggyBank->piggyBankRepetitions()->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,15 +148,15 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
throw new FireflyException('[c] Piggy bank repetitions are EOL.');
|
throw new FireflyException('[c] Piggy bank repetitions are EOL.');
|
||||||
app('log')->debug(sprintf('Now in getExactAmount(%d, %d, %d)', $piggyBank->id, $repetition->id, $journal->id));
|
app('log')->debug(sprintf('Now in getExactAmount(%d, %d, %d)', $piggyBank->id, $repetition->id, $journal->id));
|
||||||
|
|
||||||
$operator = null;
|
$operator = null;
|
||||||
$currency = null;
|
$currency = null;
|
||||||
|
|
||||||
/** @var JournalRepositoryInterface $journalRepost */
|
/** @var JournalRepositoryInterface $journalRepost */
|
||||||
$journalRepost = app(JournalRepositoryInterface::class);
|
$journalRepost = app(JournalRepositoryInterface::class);
|
||||||
$journalRepost->setUser($this->user);
|
$journalRepost->setUser($this->user);
|
||||||
|
|
||||||
/** @var AccountRepositoryInterface $accountRepos */
|
/** @var AccountRepositoryInterface $accountRepos */
|
||||||
$accountRepos = app(AccountRepositoryInterface::class);
|
$accountRepos = app(AccountRepositoryInterface::class);
|
||||||
$accountRepos->setUser($this->user);
|
$accountRepos->setUser($this->user);
|
||||||
|
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
|
$defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
|
||||||
@ -163,10 +165,10 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
app('log')->debug(sprintf('Piggy bank #%d currency is %s', $piggyBank->id, $piggyBankCurrency->code));
|
app('log')->debug(sprintf('Piggy bank #%d currency is %s', $piggyBank->id, $piggyBankCurrency->code));
|
||||||
|
|
||||||
/** @var Transaction $source */
|
/** @var Transaction $source */
|
||||||
$source = $journal->transactions()->with(['account'])->where('amount', '<', 0)->first();
|
$source = $journal->transactions()->with(['account'])->where('amount', '<', 0)->first();
|
||||||
|
|
||||||
/** @var Transaction $destination */
|
/** @var Transaction $destination */
|
||||||
$destination = $journal->transactions()->with(['account'])->where('amount', '>', 0)->first();
|
$destination = $journal->transactions()->with(['account'])->where('amount', '>', 0)->first();
|
||||||
|
|
||||||
// matches source, which means amount will be removed from piggy:
|
// matches source, which means amount will be removed from piggy:
|
||||||
if ($source->account_id === $piggyBank->account_id) {
|
if ($source->account_id === $piggyBank->account_id) {
|
||||||
@ -188,7 +190,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
}
|
}
|
||||||
// currency of the account + the piggy bank currency are almost the same.
|
// currency of the account + the piggy bank currency are almost the same.
|
||||||
// which amount from the transaction matches?
|
// which amount from the transaction matches?
|
||||||
$amount = null;
|
$amount = null;
|
||||||
if ((int) $source->transaction_currency_id === $currency->id) {
|
if ((int) $source->transaction_currency_id === $currency->id) {
|
||||||
app('log')->debug('Use normal amount');
|
app('log')->debug('Use normal amount');
|
||||||
$amount = app('steam')->{$operator}($source->amount); // @phpstan-ignore-line
|
$amount = app('steam')->{$operator}($source->amount); // @phpstan-ignore-line
|
||||||
@ -204,8 +206,8 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
app('log')->debug(sprintf('The currency is %s and the amount is %s', $currency->code, $amount));
|
app('log')->debug(sprintf('The currency is %s and the amount is %s', $currency->code, $amount));
|
||||||
$room = bcsub($piggyBank->target_amount, $repetition->current_amount);
|
$room = bcsub($piggyBank->target_amount, $repetition->current_amount);
|
||||||
$compare = bcmul($repetition->current_amount, '-1');
|
$compare = bcmul($repetition->current_amount, '-1');
|
||||||
|
|
||||||
if (0 === bccomp($piggyBank->target_amount, '0')) {
|
if (0 === bccomp($piggyBank->target_amount, '0')) {
|
||||||
// amount is zero? then the "room" is positive amount of we wish to add or remove.
|
// amount is zero? then the "room" is positive amount of we wish to add or remove.
|
||||||
@ -237,14 +239,13 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
return (string) $amount;
|
return (string) $amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUser(null | Authenticatable | User $user): void
|
public function setUser(null|Authenticatable|User $user): void
|
||||||
{
|
{
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return note for piggy bank.
|
* Return note for piggy bank.
|
||||||
*/
|
*/
|
||||||
@ -263,12 +264,12 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
{
|
{
|
||||||
$currency = app('amount')->getDefaultCurrency();
|
$currency = app('amount')->getDefaultCurrency();
|
||||||
|
|
||||||
$set = $this->getPiggyBanks();
|
$set = $this->getPiggyBanks();
|
||||||
|
|
||||||
/** @var PiggyBank $piggy */
|
/** @var PiggyBank $piggy */
|
||||||
foreach ($set as $piggy) {
|
foreach ($set as $piggy) {
|
||||||
$currentAmount = $this->getRepetition($piggy)->current_amount ?? '0';
|
$currentAmount = $this->getRepetition($piggy)->current_amount ?? '0';
|
||||||
$piggy->name = $piggy->name . ' (' . app('amount')->formatAnything($currency, $currentAmount, false) . ')';
|
$piggy->name = $piggy->name.' ('.app('amount')->formatAnything($currency, $currentAmount, false).')';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $set;
|
return $set;
|
||||||
@ -276,8 +277,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
|
|
||||||
public function getPiggyBanks(): Collection
|
public function getPiggyBanks(): Collection
|
||||||
{
|
{
|
||||||
return PiggyBank
|
return PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||||
::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
|
||||||
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||||
->where('accounts.user_id', auth()->user()->id)
|
->where('accounts.user_id', auth()->user()->id)
|
||||||
->with(
|
->with(
|
||||||
@ -286,7 +286,8 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
'objectGroups',
|
'objectGroups',
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']);
|
->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*'])
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -344,17 +345,20 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
$search->whereLike('piggy_banks.name', sprintf('%%%s%%', $query));
|
$search->whereLike('piggy_banks.name', sprintf('%%%s%%', $query));
|
||||||
}
|
}
|
||||||
$search->orderBy('piggy_banks.order', 'ASC')
|
$search->orderBy('piggy_banks.order', 'ASC')
|
||||||
->orderBy('piggy_banks.name', 'ASC');
|
->orderBy('piggy_banks.name', 'ASC')
|
||||||
|
;
|
||||||
|
|
||||||
return $search->take($limit)->get();
|
return $search->take($limit)->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\Override] public function purgeAll(): void
|
#[\Override]
|
||||||
|
public function purgeAll(): void
|
||||||
{
|
{
|
||||||
throw new FireflyException('TODO Not implemented');
|
throw new FireflyException('TODO Not implemented');
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\Override] public function resetOrder(): void
|
#[\Override]
|
||||||
|
public function resetOrder(): void
|
||||||
{
|
{
|
||||||
$factory = new PiggyBankFactory();
|
$factory = new PiggyBankFactory();
|
||||||
$factory->user = $this->user;
|
$factory->user = $this->user;
|
||||||
|
@ -129,7 +129,7 @@ interface PiggyBankRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function setOrder(PiggyBank $piggyBank, int $newOrder): bool;
|
public function setOrder(PiggyBank $piggyBank, int $newOrder): bool;
|
||||||
|
|
||||||
public function setUser(null | Authenticatable | User $user): void;
|
public function setUser(null|Authenticatable|User $user): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store new piggy bank.
|
* Store new piggy bank.
|
||||||
|
@ -18,11 +18,11 @@ class IsValidDiscordUrl implements ValidationRule
|
|||||||
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
||||||
{
|
{
|
||||||
$value = (string)$value;
|
$value = (string)$value;
|
||||||
if('' === $value) {
|
if ('' === $value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!str_starts_with($value, 'https://discord.com/api/webhooks/')) {
|
if (!str_starts_with($value, 'https://discord.com/api/webhooks/')) {
|
||||||
$fail('validation.active_url')->translate();
|
$fail('validation.active_url')->translate();
|
||||||
$message = sprintf('IsValidDiscordUrl: "%s" is not a discord URL.', substr($value, 0, 255));
|
$message = sprintf('IsValidDiscordUrl: "%s" is not a discord URL.', substr($value, 0, 255));
|
||||||
Log::debug($message);
|
Log::debug($message);
|
||||||
|
@ -18,11 +18,11 @@ class IsValidSlackOrDiscordUrl implements ValidationRule
|
|||||||
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
||||||
{
|
{
|
||||||
$value = (string)$value;
|
$value = (string)$value;
|
||||||
if('' === $value) {
|
if ('' === $value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!str_starts_with($value, 'https://hooks.slack.com/services/') && !str_starts_with($value, 'https://discord.com/api/webhooks/')) {
|
if (!str_starts_with($value, 'https://hooks.slack.com/services/') && !str_starts_with($value, 'https://discord.com/api/webhooks/')) {
|
||||||
$fail('validation.active_url')->translate();
|
$fail('validation.active_url')->translate();
|
||||||
$message = sprintf('IsValidSlackUrl: "%s" is not a discord or slack URL.', substr($value, 0, 255));
|
$message = sprintf('IsValidSlackUrl: "%s" is not a discord or slack URL.', substr($value, 0, 255));
|
||||||
Log::debug($message);
|
Log::debug($message);
|
||||||
|
@ -18,11 +18,11 @@ class IsValidSlackUrl implements ValidationRule
|
|||||||
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
||||||
{
|
{
|
||||||
$value = (string)$value;
|
$value = (string)$value;
|
||||||
if('' === $value) {
|
if ('' === $value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!str_starts_with($value, 'https://hooks.slack.com/services/')) {
|
if (!str_starts_with($value, 'https://hooks.slack.com/services/')) {
|
||||||
$fail('validation.active_url')->translate();
|
$fail('validation.active_url')->translate();
|
||||||
$message = sprintf('IsValidSlackUrl: "%s" is not a slack URL.', substr($value, 0, 255));
|
$message = sprintf('IsValidSlackUrl: "%s" is not a slack URL.', substr($value, 0, 255));
|
||||||
Log::debug($message);
|
Log::debug($message);
|
||||||
|
@ -289,6 +289,7 @@ class ExpandedForm
|
|||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
@ -299,7 +300,7 @@ class ExpandedForm
|
|||||||
$classes = $this->getHolderClasses($name);
|
$classes = $this->getHolderClasses($name);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$html = view('form.password', compact('classes', 'value','name', 'label', 'options'))->render();
|
$html = view('form.password', compact('classes', 'value', 'name', 'label', 'options'))->render();
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
app('log')->debug(sprintf('Could not render passwordWithValue(): %s', $e->getMessage()));
|
app('log')->debug(sprintf('Could not render passwordWithValue(): %s', $e->getMessage()));
|
||||||
$html = 'Could not render passwordWithValue.';
|
$html = 'Could not render passwordWithValue.';
|
||||||
|
@ -37,7 +37,7 @@ class FireflyConfig
|
|||||||
{
|
{
|
||||||
public function delete(string $name): void
|
public function delete(string $name): void
|
||||||
{
|
{
|
||||||
$fullName = 'ff-config-' . $name;
|
$fullName = 'ff-config-'.$name;
|
||||||
if (\Cache::has($fullName)) {
|
if (\Cache::has($fullName)) {
|
||||||
\Cache::forget($fullName);
|
\Cache::forget($fullName);
|
||||||
}
|
}
|
||||||
@ -57,14 +57,18 @@ class FireflyConfig
|
|||||||
}
|
}
|
||||||
if ('' === $result->data) {
|
if ('' === $result->data) {
|
||||||
Log::warning(sprintf('Empty encrypted configuration value found: "%s"', $name));
|
Log::warning(sprintf('Empty encrypted configuration value found: "%s"', $name));
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$result->data = decrypt($result->data);
|
$result->data = decrypt($result->data);
|
||||||
} catch (DecryptException $e) {
|
} catch (DecryptException $e) {
|
||||||
Log::error(sprintf('Could not decrypt configuration value "%s": %s', $name, $e->getMessage()));
|
Log::error(sprintf('Could not decrypt configuration value "%s": %s', $name, $e->getMessage()));
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +79,7 @@ class FireflyConfig
|
|||||||
*/
|
*/
|
||||||
public function get(string $name, $default = null): ?Configuration
|
public function get(string $name, $default = null): ?Configuration
|
||||||
{
|
{
|
||||||
$fullName = 'ff-config-' . $name;
|
$fullName = 'ff-config-'.$name;
|
||||||
if (\Cache::has($fullName)) {
|
if (\Cache::has($fullName)) {
|
||||||
return \Cache::get($fullName);
|
return \Cache::get($fullName);
|
||||||
}
|
}
|
||||||
@ -83,7 +87,7 @@ class FireflyConfig
|
|||||||
try {
|
try {
|
||||||
/** @var null|Configuration $config */
|
/** @var null|Configuration $config */
|
||||||
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
|
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
|
||||||
} catch (\Exception | QueryException $e) {
|
} catch (\Exception|QueryException $e) {
|
||||||
throw new FireflyException(sprintf('Could not poll the database: %s', $e->getMessage()), 0, $e);
|
throw new FireflyException(sprintf('Could not poll the database: %s', $e->getMessage()), 0, $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,8 +110,10 @@ class FireflyConfig
|
|||||||
$encrypted = encrypt($value);
|
$encrypted = encrypt($value);
|
||||||
} catch (EncryptException $e) {
|
} catch (EncryptException $e) {
|
||||||
Log::error(sprintf('Could not encrypt configuration value "%s": %s', $name, $e->getMessage()));
|
Log::error(sprintf('Could not encrypt configuration value "%s": %s', $name, $e->getMessage()));
|
||||||
|
|
||||||
throw new FireflyException(sprintf('Could not encrypt configuration value "%s". Cowardly refuse to continue.', $name));
|
throw new FireflyException(sprintf('Could not encrypt configuration value "%s". Cowardly refuse to continue.', $name));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->set($name, $encrypted);
|
return $this->set($name, $encrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,13 +135,13 @@ class FireflyConfig
|
|||||||
$item->name = $name;
|
$item->name = $name;
|
||||||
$item->data = $value;
|
$item->data = $value;
|
||||||
$item->save();
|
$item->save();
|
||||||
\Cache::forget('ff-config-' . $name);
|
\Cache::forget('ff-config-'.$name);
|
||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
}
|
}
|
||||||
$config->data = $value;
|
$config->data = $value;
|
||||||
$config->save();
|
$config->save();
|
||||||
\Cache::forget('ff-config-' . $name);
|
\Cache::forget('ff-config-'.$name);
|
||||||
|
|
||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
@ -155,8 +155,9 @@ class AccountForm
|
|||||||
*/
|
*/
|
||||||
public function assetLiabilityMultiAccountList(string $name, $value = null, ?array $options = null): string
|
public function assetLiabilityMultiAccountList(string $name, $value = null, ?array $options = null): string
|
||||||
{
|
{
|
||||||
$types = [AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::DEBT->value,AccountTypeEnum::LOAN->value];
|
$types = [AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value];
|
||||||
$grouped = $this->getAccountsGrouped($types);
|
$grouped = $this->getAccountsGrouped($types);
|
||||||
|
|
||||||
return $this->multiSelect($name, $grouped, $value, $options);
|
return $this->multiSelect($name, $grouped, $value, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,14 +64,18 @@ class Preferences
|
|||||||
}
|
}
|
||||||
if ('' === $result->data) {
|
if ('' === $result->data) {
|
||||||
Log::warning(sprintf('Empty encrypted preference found: "%s"', $name));
|
Log::warning(sprintf('Empty encrypted preference found: "%s"', $name));
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$result->data = decrypt($result->data);
|
$result->data = decrypt($result->data);
|
||||||
} catch (DecryptException $e) {
|
} catch (DecryptException $e) {
|
||||||
Log::error(sprintf('Could not decrypt preference "%s": %s', $name, $e->getMessage()));
|
Log::error(sprintf('Could not decrypt preference "%s": %s', $name, $e->getMessage()));
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,12 +85,13 @@ class Preferences
|
|||||||
$encrypted = encrypt($value);
|
$encrypted = encrypt($value);
|
||||||
} catch (EncryptException $e) {
|
} catch (EncryptException $e) {
|
||||||
Log::error(sprintf('Could not encrypt preference "%s": %s', $name, $e->getMessage()));
|
Log::error(sprintf('Could not encrypt preference "%s": %s', $name, $e->getMessage()));
|
||||||
|
|
||||||
throw new FireflyException(sprintf('Could not encrypt preference "%s". Cowardly refuse to continue.', $name));
|
throw new FireflyException(sprintf('Could not encrypt preference "%s". Cowardly refuse to continue.', $name));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->set($name, $encrypted);
|
return $this->set($name, $encrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function get(string $name, null|array|bool|int|string $default = null): ?Preference
|
public function get(string $name, null|array|bool|int|string $default = null): ?Preference
|
||||||
{
|
{
|
||||||
/** @var null|User $user */
|
/** @var null|User $user */
|
||||||
|
@ -55,8 +55,8 @@ class BudgetLimitTransformer extends AbstractTransformer
|
|||||||
*/
|
*/
|
||||||
public function transform(BudgetLimit $budgetLimit): array
|
public function transform(BudgetLimit $budgetLimit): array
|
||||||
{
|
{
|
||||||
$repository = app(OperationsRepository::class);
|
$repository = app(OperationsRepository::class);
|
||||||
$limitRepos = app(BudgetLimitRepositoryInterface::class);
|
$limitRepos = app(BudgetLimitRepositoryInterface::class);
|
||||||
$repository->setUser($budgetLimit->budget->user);
|
$repository->setUser($budgetLimit->budget->user);
|
||||||
$limitRepos->setUser($budgetLimit->budget->user);
|
$limitRepos->setUser($budgetLimit->budget->user);
|
||||||
$expenses = $repository->sumExpenses(
|
$expenses = $repository->sumExpenses(
|
||||||
@ -82,7 +82,7 @@ class BudgetLimitTransformer extends AbstractTransformer
|
|||||||
$currencySymbol = $currency->symbol;
|
$currencySymbol = $currency->symbol;
|
||||||
$currencyDecimalPlaces = $currency->decimal_places;
|
$currencyDecimalPlaces = $currency->decimal_places;
|
||||||
}
|
}
|
||||||
$amount = app('steam')->bcround($amount, $currencyDecimalPlaces);
|
$amount = app('steam')->bcround($amount, $currencyDecimalPlaces);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => (string) $budgetLimit->id,
|
'id' => (string) $budgetLimit->id,
|
||||||
@ -103,7 +103,7 @@ class BudgetLimitTransformer extends AbstractTransformer
|
|||||||
'links' => [
|
'links' => [
|
||||||
[
|
[
|
||||||
'rel' => 'self',
|
'rel' => 'self',
|
||||||
'uri' => '/budgets/limits/' . $budgetLimit->id,
|
'uri' => '/budgets/limits/'.$budgetLimit->id,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -54,22 +54,22 @@ class PiggyBankTransformer extends AbstractTransformer
|
|||||||
*/
|
*/
|
||||||
public function transform(PiggyBank $piggyBank): array
|
public function transform(PiggyBank $piggyBank): array
|
||||||
{
|
{
|
||||||
$user = $piggyBank->accounts()->first()->user;
|
$user = $piggyBank->accounts()->first()->user;
|
||||||
|
|
||||||
// set up repositories
|
// set up repositories
|
||||||
$this->accountRepos->setUser($user);
|
$this->accountRepos->setUser($user);
|
||||||
$this->piggyRepos->setUser($user);
|
$this->piggyRepos->setUser($user);
|
||||||
|
|
||||||
// note
|
// note
|
||||||
$notes = $this->piggyRepos->getNoteText($piggyBank);
|
$notes = $this->piggyRepos->getNoteText($piggyBank);
|
||||||
$notes = '' === $notes ? null : $notes;
|
$notes = '' === $notes ? null : $notes;
|
||||||
|
|
||||||
$objectGroupId = null;
|
$objectGroupId = null;
|
||||||
$objectGroupOrder = null;
|
$objectGroupOrder = null;
|
||||||
$objectGroupTitle = null;
|
$objectGroupTitle = null;
|
||||||
|
|
||||||
/** @var null|ObjectGroup $objectGroup */
|
/** @var null|ObjectGroup $objectGroup */
|
||||||
$objectGroup = $piggyBank->objectGroups->first();
|
$objectGroup = $piggyBank->objectGroups->first();
|
||||||
if (null !== $objectGroup) {
|
if (null !== $objectGroup) {
|
||||||
$objectGroupId = $objectGroup->id;
|
$objectGroupId = $objectGroup->id;
|
||||||
$objectGroupOrder = $objectGroup->order;
|
$objectGroupOrder = $objectGroup->order;
|
||||||
@ -77,14 +77,14 @@ class PiggyBankTransformer extends AbstractTransformer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get currently saved amount:
|
// get currently saved amount:
|
||||||
$currency = $piggyBank->transactionCurrency;
|
$currency = $piggyBank->transactionCurrency;
|
||||||
$currentAmount = app('steam')->bcround($this->piggyRepos->getCurrentAmount($piggyBank), $currency->decimal_places);
|
$currentAmount = app('steam')->bcround($this->piggyRepos->getCurrentAmount($piggyBank), $currency->decimal_places);
|
||||||
|
|
||||||
// Amounts, depending on 0.0 state of target amount
|
// Amounts, depending on 0.0 state of target amount
|
||||||
$percentage = null;
|
$percentage = null;
|
||||||
$targetAmount = $piggyBank->target_amount;
|
$targetAmount = $piggyBank->target_amount;
|
||||||
$leftToSave = null;
|
$leftToSave = null;
|
||||||
$savePerMonth = null;
|
$savePerMonth = null;
|
||||||
if (0 !== bccomp($targetAmount, '0')) { // target amount is not 0.00
|
if (0 !== bccomp($targetAmount, '0')) { // target amount is not 0.00
|
||||||
$leftToSave = bcsub($piggyBank->target_amount, $currentAmount);
|
$leftToSave = bcsub($piggyBank->target_amount, $currentAmount);
|
||||||
$percentage = (int) bcmul(bcdiv($currentAmount, $targetAmount), '100');
|
$percentage = (int) bcmul(bcdiv($currentAmount, $targetAmount), '100');
|
||||||
@ -92,16 +92,16 @@ class PiggyBankTransformer extends AbstractTransformer
|
|||||||
$leftToSave = app('steam')->bcround($leftToSave, $currency->decimal_places);
|
$leftToSave = app('steam')->bcround($leftToSave, $currency->decimal_places);
|
||||||
$savePerMonth = app('steam')->bcround($this->piggyRepos->getSuggestedMonthlyAmount($piggyBank), $currency->decimal_places);
|
$savePerMonth = app('steam')->bcround($this->piggyRepos->getSuggestedMonthlyAmount($piggyBank), $currency->decimal_places);
|
||||||
}
|
}
|
||||||
$startDate = $piggyBank->start_date?->format('Y-m-d');
|
$startDate = $piggyBank->start_date?->format('Y-m-d');
|
||||||
$targetDate = $piggyBank->target_date?->format('Y-m-d');
|
$targetDate = $piggyBank->target_date?->format('Y-m-d');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => (string) $piggyBank->id,
|
'id' => (string) $piggyBank->id,
|
||||||
'created_at' => $piggyBank->created_at->toAtomString(),
|
'created_at' => $piggyBank->created_at->toAtomString(),
|
||||||
'updated_at' => $piggyBank->updated_at->toAtomString(),
|
'updated_at' => $piggyBank->updated_at->toAtomString(),
|
||||||
'accounts' => $this->renderAccounts($piggyBank),
|
'accounts' => $this->renderAccounts($piggyBank),
|
||||||
//'account_id' => (string)$piggyBank->account_id,
|
// 'account_id' => (string)$piggyBank->account_id,
|
||||||
//'account_name' => $piggyBank->account->name,
|
// 'account_name' => $piggyBank->account->name,
|
||||||
'name' => $piggyBank->name,
|
'name' => $piggyBank->name,
|
||||||
'currency_id' => (string) $currency->id,
|
'currency_id' => (string) $currency->id,
|
||||||
'currency_code' => $currency->code,
|
'currency_code' => $currency->code,
|
||||||
@ -123,7 +123,7 @@ class PiggyBankTransformer extends AbstractTransformer
|
|||||||
'links' => [
|
'links' => [
|
||||||
[
|
[
|
||||||
'rel' => 'self',
|
'rel' => 'self',
|
||||||
'uri' => '/piggy_banks/' . $piggyBank->id,
|
'uri' => '/piggy_banks/'.$piggyBank->id,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@ -134,12 +134,13 @@ class PiggyBankTransformer extends AbstractTransformer
|
|||||||
$return = [];
|
$return = [];
|
||||||
foreach ($piggyBank->accounts()->get() as $account) {
|
foreach ($piggyBank->accounts()->get() as $account) {
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'id' => $account->id,
|
'id' => $account->id,
|
||||||
'name' => $account->name,
|
'name' => $account->name,
|
||||||
'current_amount' => $account->pivot->current_amount,
|
'current_amount' => $account->pivot->current_amount,
|
||||||
// TODO add balance, add left to save.
|
// TODO add balance, add left to save.
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,7 @@ class PiggyBankTransformer extends AbstractTransformer
|
|||||||
|
|
||||||
// grab repetitions (for current amount):
|
// grab repetitions (for current amount):
|
||||||
$repetitions = PiggyBankRepetition::whereIn('piggy_bank_id', $piggyBanks)->get();
|
$repetitions = PiggyBankRepetition::whereIn('piggy_bank_id', $piggyBanks)->get();
|
||||||
|
|
||||||
throw new FireflyException('[d] Piggy bank repetitions are EOL.');
|
throw new FireflyException('[d] Piggy bank repetitions are EOL.');
|
||||||
|
|
||||||
/** @var PiggyBankRepetition $repetition */
|
/** @var PiggyBankRepetition $repetition */
|
||||||
|
76
app/User.php
76
app/User.php
@ -49,10 +49,8 @@ use FireflyIII\Models\TransactionJournal;
|
|||||||
use FireflyIII\Models\UserGroup;
|
use FireflyIII\Models\UserGroup;
|
||||||
use FireflyIII\Models\UserRole;
|
use FireflyIII\Models\UserRole;
|
||||||
use FireflyIII\Models\Webhook;
|
use FireflyIII\Models\Webhook;
|
||||||
use FireflyIII\Notifications\Admin\UserInvitation;
|
|
||||||
use FireflyIII\Notifications\Admin\UserRegistration;
|
use FireflyIII\Notifications\Admin\UserRegistration;
|
||||||
use FireflyIII\Notifications\Admin\VersionCheckResult;
|
use FireflyIII\Notifications\Admin\VersionCheckResult;
|
||||||
use FireflyIII\Notifications\Test\TestNotificationDiscord;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
@ -260,38 +258,38 @@ class User extends Authenticatable
|
|||||||
app('log')->debug(sprintf('in hasAnyRoleInGroup(%s)', implode(', ', $roles)));
|
app('log')->debug(sprintf('in hasAnyRoleInGroup(%s)', implode(', ', $roles)));
|
||||||
|
|
||||||
/** @var Collection $dbRoles */
|
/** @var Collection $dbRoles */
|
||||||
$dbRoles = UserRole::whereIn('title', $roles)->get();
|
$dbRoles = UserRole::whereIn('title', $roles)->get();
|
||||||
if (0 === $dbRoles->count()) {
|
if (0 === $dbRoles->count()) {
|
||||||
app('log')->error(sprintf('Could not find role(s): %s. Probably migration mishap.', implode(', ', $roles)));
|
app('log')->error(sprintf('Could not find role(s): %s. Probably migration mishap.', implode(', ', $roles)));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$dbRolesIds = $dbRoles->pluck('id')->toArray();
|
$dbRolesIds = $dbRoles->pluck('id')->toArray();
|
||||||
$dbRolesTitles = $dbRoles->pluck('title')->toArray();
|
$dbRolesTitles = $dbRoles->pluck('title')->toArray();
|
||||||
|
|
||||||
/** @var Collection $groupMemberships */
|
/** @var Collection $groupMemberships */
|
||||||
$groupMemberships = $this->groupMemberships()->whereIn('user_role_id', $dbRolesIds)->where('user_group_id', $userGroup->id)->get();
|
$groupMemberships = $this->groupMemberships()->whereIn('user_role_id', $dbRolesIds)->where('user_group_id', $userGroup->id)->get();
|
||||||
if (0 === $groupMemberships->count()) {
|
if (0 === $groupMemberships->count()) {
|
||||||
app('log')->error(sprintf(
|
app('log')->error(sprintf(
|
||||||
'User #%d "%s" does not have roles %s in user group #%d "%s"',
|
'User #%d "%s" does not have roles %s in user group #%d "%s"',
|
||||||
$this->id,
|
$this->id,
|
||||||
$this->email,
|
$this->email,
|
||||||
implode(', ', $roles),
|
implode(', ', $roles),
|
||||||
$userGroup->id,
|
$userGroup->id,
|
||||||
$userGroup->title
|
$userGroup->title
|
||||||
));
|
));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
foreach ($groupMemberships as $membership) {
|
foreach ($groupMemberships as $membership) {
|
||||||
app('log')->debug(sprintf(
|
app('log')->debug(sprintf(
|
||||||
'User #%d "%s" has role "%s" in user group #%d "%s"',
|
'User #%d "%s" has role "%s" in user group #%d "%s"',
|
||||||
$this->id,
|
$this->id,
|
||||||
$this->email,
|
$this->email,
|
||||||
$membership->userRole->title,
|
$membership->userRole->title,
|
||||||
$userGroup->id,
|
$userGroup->id,
|
||||||
$userGroup->title
|
$userGroup->title
|
||||||
));
|
));
|
||||||
if (in_array($membership->userRole->title, $dbRolesTitles, true)) {
|
if (in_array($membership->userRole->title, $dbRolesTitles, true)) {
|
||||||
app('log')->debug(sprintf('Return true, found role "%s"', $membership->userRole->title));
|
app('log')->debug(sprintf('Return true, found role "%s"', $membership->userRole->title));
|
||||||
|
|
||||||
@ -299,13 +297,13 @@ class User extends Authenticatable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
app('log')->error(sprintf(
|
app('log')->error(sprintf(
|
||||||
'User #%d "%s" does not have roles %s in user group #%d "%s"',
|
'User #%d "%s" does not have roles %s in user group #%d "%s"',
|
||||||
$this->id,
|
$this->id,
|
||||||
$this->email,
|
$this->email,
|
||||||
implode(', ', $roles),
|
implode(', ', $roles),
|
||||||
$userGroup->id,
|
$userGroup->id,
|
||||||
$userGroup->title
|
$userGroup->title
|
||||||
));
|
));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -357,13 +355,13 @@ class User extends Authenticatable
|
|||||||
*/
|
*/
|
||||||
public function routeNotificationFor($driver, $notification = null)
|
public function routeNotificationFor($driver, $notification = null)
|
||||||
{
|
{
|
||||||
$method = 'routeNotificationFor' . Str::studly($driver);
|
$method = 'routeNotificationFor'.Str::studly($driver);
|
||||||
if (method_exists($this, $method)) {
|
if (method_exists($this, $method)) {
|
||||||
return $this->{$method}($notification); // @phpstan-ignore-line
|
return $this->{$method}($notification); // @phpstan-ignore-line
|
||||||
}
|
}
|
||||||
$email = $this->email;
|
$email = $this->email;
|
||||||
// see if user has alternative email address:
|
// see if user has alternative email address:
|
||||||
$pref = app('preferences')->getForUser($this, 'remote_guard_alt_email');
|
$pref = app('preferences')->getForUser($this, 'remote_guard_alt_email');
|
||||||
if (null !== $pref) {
|
if (null !== $pref) {
|
||||||
$email = $pref->data;
|
$email = $pref->data;
|
||||||
}
|
}
|
||||||
@ -400,36 +398,36 @@ class User extends Authenticatable
|
|||||||
$appToken = (string) app('fireflyconfig')->getEncrypted('pushover_app_token', '')->data;
|
$appToken = (string) app('fireflyconfig')->getEncrypted('pushover_app_token', '')->data;
|
||||||
$userToken = (string) app('fireflyconfig')->getEncrypted('pushover_user_token', '')->data;
|
$userToken = (string) app('fireflyconfig')->getEncrypted('pushover_user_token', '')->data;
|
||||||
|
|
||||||
if (property_exists($notification, 'type') && $notification->type === 'owner') {
|
if (property_exists($notification, 'type') && 'owner' === $notification->type) {
|
||||||
return PushoverReceiver::withUserKey($userToken)
|
return PushoverReceiver::withUserKey($userToken)
|
||||||
->withApplicationToken($appToken);
|
->withApplicationToken($appToken)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new FireflyException('No pushover token found.');
|
throw new FireflyException('No pushover token found.');
|
||||||
// return PushoverReceiver::withUserKey((string) config('services.pushover.user_token'))
|
// return PushoverReceiver::withUserKey((string) config('services.pushover.user_token'))
|
||||||
// ->withApplicationToken((string) config('services.pushover.token'));
|
// ->withApplicationToken((string) config('services.pushover.token'));
|
||||||
//return (string) config('services.pushover.token');
|
// return (string) config('services.pushover.token');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Route notifications for the Slack channel.
|
* Route notifications for the Slack channel.
|
||||||
*/
|
*/
|
||||||
public function routeNotificationForSlack(Notification $notification): ?string
|
public function routeNotificationForSlack(Notification $notification): ?string
|
||||||
{
|
{
|
||||||
// this check does not validate if the user is owner, Should be done by notification itself.
|
// this check does not validate if the user is owner, Should be done by notification itself.
|
||||||
$res = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
$res = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
|
||||||
if (is_array($res)) {
|
if (is_array($res)) {
|
||||||
$res = '';
|
$res = '';
|
||||||
}
|
}
|
||||||
$res = (string) $res;
|
$res = (string) $res;
|
||||||
|
|
||||||
if (property_exists($notification, 'type') && $notification->type === 'owner') {
|
if (property_exists($notification, 'type') && 'owner' === $notification->type) {
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not the best way to do this, but alas.
|
// not the best way to do this, but alas.
|
||||||
if ($notification instanceof UserRegistration) {
|
if ($notification instanceof UserRegistration) {
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
if ($notification instanceof VersionCheckResult) {
|
if ($notification instanceof VersionCheckResult) {
|
||||||
|
@ -813,14 +813,15 @@ class FireflyValidator extends Validator
|
|||||||
public function validateUniquePiggyBankForUser($attribute, $value, $parameters): bool
|
public function validateUniquePiggyBankForUser($attribute, $value, $parameters): bool
|
||||||
{
|
{
|
||||||
$exclude = $parameters[0] ?? null;
|
$exclude = $parameters[0] ?? null;
|
||||||
$query = PiggyBank
|
$query = PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||||
::leftJoin('account_piggy_bank','account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
|
||||||
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||||
->where('accounts.user_id', auth()->user()->id);
|
->where('accounts.user_id', auth()->user()->id)
|
||||||
|
;
|
||||||
if (null !== $exclude) {
|
if (null !== $exclude) {
|
||||||
$query->where('piggy_banks.id', '!=', (int) $exclude);
|
$query->where('piggy_banks.id', '!=', (int) $exclude);
|
||||||
}
|
}
|
||||||
$query->where('piggy_banks.name', $value);
|
$query->where('piggy_banks.name', $value);
|
||||||
|
|
||||||
return 0 === $query->get(['piggy_banks.*'])->count();
|
return 0 === $query->get(['piggy_banks.*'])->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,7 +428,7 @@ return [
|
|||||||
'transfers' => 'fa-exchange',
|
'transfers' => 'fa-exchange',
|
||||||
],
|
],
|
||||||
|
|
||||||
'bindables' => [
|
'bindables' => [
|
||||||
// models
|
// models
|
||||||
'account' => Account::class,
|
'account' => Account::class,
|
||||||
'attachment' => Attachment::class,
|
'attachment' => Attachment::class,
|
||||||
@ -486,7 +486,7 @@ return [
|
|||||||
'userGroupBill' => UserGroupBill::class,
|
'userGroupBill' => UserGroupBill::class,
|
||||||
'userGroup' => UserGroup::class,
|
'userGroup' => UserGroup::class,
|
||||||
],
|
],
|
||||||
'rule-actions' => [
|
'rule-actions' => [
|
||||||
'set_category' => SetCategory::class,
|
'set_category' => SetCategory::class,
|
||||||
'clear_category' => ClearCategory::class,
|
'clear_category' => ClearCategory::class,
|
||||||
'set_budget' => SetBudget::class,
|
'set_budget' => SetBudget::class,
|
||||||
@ -520,7 +520,7 @@ return [
|
|||||||
// 'set_foreign_amount' => SetForeignAmount::class,
|
// 'set_foreign_amount' => SetForeignAmount::class,
|
||||||
// 'set_foreign_currency' => SetForeignCurrency::class,
|
// 'set_foreign_currency' => SetForeignCurrency::class,
|
||||||
],
|
],
|
||||||
'context-rule-actions' => [
|
'context-rule-actions' => [
|
||||||
'set_category',
|
'set_category',
|
||||||
'set_budget',
|
'set_budget',
|
||||||
'add_tag',
|
'add_tag',
|
||||||
@ -539,16 +539,16 @@ return [
|
|||||||
'convert_transfer',
|
'convert_transfer',
|
||||||
],
|
],
|
||||||
|
|
||||||
'test-triggers' => [
|
'test-triggers' => [
|
||||||
'limit' => 10,
|
'limit' => 10,
|
||||||
'range' => 200,
|
'range' => 200,
|
||||||
],
|
],
|
||||||
|
|
||||||
// expected source types for each transaction type, in order of preference.
|
// expected source types for each transaction type, in order of preference.
|
||||||
'expected_source_types' => [
|
'expected_source_types' => [
|
||||||
'source' => [
|
'source' => [
|
||||||
TransactionTypeEnum::WITHDRAWAL->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
TransactionTypeEnum::WITHDRAWAL->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
||||||
TransactionTypeEnum::DEPOSIT->value => [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::CASH->value],
|
TransactionTypeEnum::DEPOSIT->value => [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::CASH->value],
|
||||||
TransactionTypeEnum::TRANSFER->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
TransactionTypeEnum::TRANSFER->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
||||||
TransactionTypeEnum::OPENING_BALANCE->value => [
|
TransactionTypeEnum::OPENING_BALANCE->value => [
|
||||||
AccountTypeEnum::INITIAL_BALANCE->value,
|
AccountTypeEnum::INITIAL_BALANCE->value,
|
||||||
@ -560,7 +560,7 @@ return [
|
|||||||
TransactionTypeEnum::RECONCILIATION->value => [AccountTypeEnum::RECONCILIATION->value, AccountTypeEnum::ASSET->value],
|
TransactionTypeEnum::RECONCILIATION->value => [AccountTypeEnum::RECONCILIATION->value, AccountTypeEnum::ASSET->value],
|
||||||
TransactionTypeEnum::LIABILITY_CREDIT->value => [AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
TransactionTypeEnum::LIABILITY_CREDIT->value => [AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
||||||
// in case no transaction type is known yet, it could be anything.
|
// in case no transaction type is known yet, it could be anything.
|
||||||
'none' => [
|
'none' => [
|
||||||
AccountTypeEnum::ASSET->value,
|
AccountTypeEnum::ASSET->value,
|
||||||
AccountTypeEnum::EXPENSE->value,
|
AccountTypeEnum::EXPENSE->value,
|
||||||
AccountTypeEnum::REVENUE->value,
|
AccountTypeEnum::REVENUE->value,
|
||||||
@ -577,7 +577,7 @@ return [
|
|||||||
AccountTypeEnum::EXPENSE->value,
|
AccountTypeEnum::EXPENSE->value,
|
||||||
AccountTypeEnum::CASH->value,
|
AccountTypeEnum::CASH->value,
|
||||||
],
|
],
|
||||||
TransactionTypeEnum::DEPOSIT->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
TransactionTypeEnum::DEPOSIT->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
||||||
TransactionTypeEnum::TRANSFER->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
TransactionTypeEnum::TRANSFER->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
||||||
TransactionTypeEnum::OPENING_BALANCE->value => [
|
TransactionTypeEnum::OPENING_BALANCE->value => [
|
||||||
AccountTypeEnum::INITIAL_BALANCE->value,
|
AccountTypeEnum::INITIAL_BALANCE->value,
|
||||||
@ -590,7 +590,7 @@ return [
|
|||||||
TransactionTypeEnum::LIABILITY_CREDIT->value => [AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
TransactionTypeEnum::LIABILITY_CREDIT->value => [AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'allowed_opposing_types' => [
|
'allowed_opposing_types' => [
|
||||||
'source' => [
|
'source' => [
|
||||||
AccountTypeEnum::ASSET->value => [
|
AccountTypeEnum::ASSET->value => [
|
||||||
AccountTypeEnum::ASSET->value,
|
AccountTypeEnum::ASSET->value,
|
||||||
@ -680,7 +680,7 @@ return [
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
// depending on the account type, return the allowed transaction types:
|
// depending on the account type, return the allowed transaction types:
|
||||||
'allowed_transaction_types' => [
|
'allowed_transaction_types' => [
|
||||||
'source' => [
|
'source' => [
|
||||||
AccountTypeEnum::ASSET->value => [
|
AccountTypeEnum::ASSET->value => [
|
||||||
TransactionTypeEnum::WITHDRAWAL->value,
|
TransactionTypeEnum::WITHDRAWAL->value,
|
||||||
@ -749,7 +749,7 @@ return [
|
|||||||
],
|
],
|
||||||
|
|
||||||
// having the source + dest will tell you the transaction type.
|
// having the source + dest will tell you the transaction type.
|
||||||
'account_to_transaction' => [
|
'account_to_transaction' => [
|
||||||
AccountTypeEnum::ASSET->value => [
|
AccountTypeEnum::ASSET->value => [
|
||||||
AccountTypeEnum::ASSET->value => TransactionTypeEnum::TRANSFER->value,
|
AccountTypeEnum::ASSET->value => TransactionTypeEnum::TRANSFER->value,
|
||||||
AccountTypeEnum::CASH->value => TransactionTypeEnum::WITHDRAWAL->value,
|
AccountTypeEnum::CASH->value => TransactionTypeEnum::WITHDRAWAL->value,
|
||||||
@ -814,14 +814,14 @@ return [
|
|||||||
],
|
],
|
||||||
|
|
||||||
// allowed source -> destination accounts.
|
// allowed source -> destination accounts.
|
||||||
'source_dests' => [
|
'source_dests' => [
|
||||||
TransactionTypeEnum::WITHDRAWAL->value => [
|
TransactionTypeEnum::WITHDRAWAL->value => [
|
||||||
AccountTypeEnum::ASSET->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::CASH->value],
|
AccountTypeEnum::ASSET->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::CASH->value],
|
||||||
AccountTypeEnum::LOAN->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::CASH->value],
|
AccountTypeEnum::LOAN->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::CASH->value],
|
||||||
AccountTypeEnum::DEBT->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::CASH->value],
|
AccountTypeEnum::DEBT->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::CASH->value],
|
||||||
AccountTypeEnum::MORTGAGE->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::CASH->value],
|
AccountTypeEnum::MORTGAGE->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::CASH->value],
|
||||||
],
|
],
|
||||||
TransactionTypeEnum::DEPOSIT->value => [
|
TransactionTypeEnum::DEPOSIT->value => [
|
||||||
AccountTypeEnum::REVENUE->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
AccountTypeEnum::REVENUE->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
||||||
AccountTypeEnum::CASH->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
AccountTypeEnum::CASH->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
||||||
AccountTypeEnum::LOAN->value => [AccountTypeEnum::ASSET->value],
|
AccountTypeEnum::LOAN->value => [AccountTypeEnum::ASSET->value],
|
||||||
@ -853,7 +853,7 @@ return [
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
// if you add fields to this array, don't forget to update the export routine (ExportDataGenerator).
|
// if you add fields to this array, don't forget to update the export routine (ExportDataGenerator).
|
||||||
'journal_meta_fields' => [
|
'journal_meta_fields' => [
|
||||||
// sepa
|
// sepa
|
||||||
'sepa_cc',
|
'sepa_cc',
|
||||||
'sepa_ct_op',
|
'sepa_ct_op',
|
||||||
@ -887,31 +887,31 @@ return [
|
|||||||
'recurrence_count',
|
'recurrence_count',
|
||||||
'recurrence_date',
|
'recurrence_date',
|
||||||
],
|
],
|
||||||
'webhooks' => [
|
'webhooks' => [
|
||||||
'max_attempts' => env('WEBHOOK_MAX_ATTEMPTS', 3),
|
'max_attempts' => env('WEBHOOK_MAX_ATTEMPTS', 3),
|
||||||
],
|
],
|
||||||
'can_have_virtual_amounts' => [AccountTypeEnum::ASSET->value],
|
'can_have_virtual_amounts' => [AccountTypeEnum::ASSET->value],
|
||||||
'can_have_opening_balance' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
'can_have_opening_balance' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
||||||
'dynamic_creation_allowed' => [
|
'dynamic_creation_allowed' => [
|
||||||
AccountTypeEnum::EXPENSE->value,
|
AccountTypeEnum::EXPENSE->value,
|
||||||
AccountTypeEnum::REVENUE->value,
|
AccountTypeEnum::REVENUE->value,
|
||||||
AccountTypeEnum::INITIAL_BALANCE->value,
|
AccountTypeEnum::INITIAL_BALANCE->value,
|
||||||
AccountTypeEnum::RECONCILIATION->value,
|
AccountTypeEnum::RECONCILIATION->value,
|
||||||
AccountTypeEnum::LIABILITY_CREDIT->value,
|
AccountTypeEnum::LIABILITY_CREDIT->value,
|
||||||
],
|
],
|
||||||
'valid_asset_fields' => ['account_role', 'account_number', 'currency_id', 'BIC', 'include_net_worth'],
|
'valid_asset_fields' => ['account_role', 'account_number', 'currency_id', 'BIC', 'include_net_worth'],
|
||||||
'valid_cc_fields' => ['account_role', 'cc_monthly_payment_date', 'cc_type', 'account_number', 'currency_id', 'BIC', 'include_net_worth'],
|
'valid_cc_fields' => ['account_role', 'cc_monthly_payment_date', 'cc_type', 'account_number', 'currency_id', 'BIC', 'include_net_worth'],
|
||||||
'valid_account_fields' => ['account_number', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth', 'liability_direction'],
|
'valid_account_fields' => ['account_number', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth', 'liability_direction'],
|
||||||
|
|
||||||
// dynamic date ranges are as follows:
|
// dynamic date ranges are as follows:
|
||||||
'dynamic_date_ranges' => ['last7', 'last30', 'last90', 'last365', 'MTD', 'QTD', 'YTD'],
|
'dynamic_date_ranges' => ['last7', 'last30', 'last90', 'last365', 'MTD', 'QTD', 'YTD'],
|
||||||
|
|
||||||
// only used in v1
|
// only used in v1
|
||||||
'allowed_sort_parameters' => ['order', 'name', 'iban'],
|
'allowed_sort_parameters' => ['order', 'name', 'iban'],
|
||||||
|
|
||||||
// preselected account lists possibilities:
|
// preselected account lists possibilities:
|
||||||
'preselected_accounts' => ['all', 'assets', 'liabilities'],
|
'preselected_accounts' => ['all', 'assets', 'liabilities'],
|
||||||
|
|
||||||
// allowed to store a piggy bank in:
|
// allowed to store a piggy bank in:
|
||||||
'piggy_bank_account_types' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
'piggy_bank_account_types' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value],
|
||||||
];
|
];
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* notifications.php
|
* notifications.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
@ -20,14 +21,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'channels' => [
|
'channels' => [
|
||||||
'email' => ['enabled' => true, 'ui_configurable' => 0,],
|
'email' => ['enabled' => true, 'ui_configurable' => 0],
|
||||||
'slack' => ['enabled' => true, 'ui_configurable' => 1,],
|
'slack' => ['enabled' => true, 'ui_configurable' => 1],
|
||||||
'ntfy' => ['enabled' => true, 'ui_configurable' => 1,],
|
'ntfy' => ['enabled' => true, 'ui_configurable' => 1],
|
||||||
'pushover' => ['enabled' => true, 'ui_configurable' => 1,],
|
'pushover' => ['enabled' => true, 'ui_configurable' => 1],
|
||||||
'gotify' => ['enabled' => false, 'ui_configurable' => 0,],
|
'gotify' => ['enabled' => false, 'ui_configurable' => 0],
|
||||||
'pushbullet' => ['enabled' => false, 'ui_configurable' => 0,],
|
'pushbullet' => ['enabled' => false, 'ui_configurable' => 0],
|
||||||
],
|
],
|
||||||
'notifications' => [
|
'notifications' => [
|
||||||
'user' => [
|
'user' => [
|
||||||
@ -49,13 +51,13 @@ return [
|
|||||||
'new_backup_codes' => ['enabled' => true, 'configurable' => false],
|
'new_backup_codes' => ['enabled' => true, 'configurable' => false],
|
||||||
],
|
],
|
||||||
'owner' => [
|
'owner' => [
|
||||||
//'invitation_created' => ['enabled' => true],
|
// 'invitation_created' => ['enabled' => true],
|
||||||
// 'some_notification' => ['enabled' => true],
|
// 'some_notification' => ['enabled' => true],
|
||||||
'admin_new_reg' => ['enabled' => true],
|
'admin_new_reg' => ['enabled' => true],
|
||||||
'user_new_reg' => ['enabled' => true],
|
'user_new_reg' => ['enabled' => true],
|
||||||
'new_version' => ['enabled' => true],
|
'new_version' => ['enabled' => true],
|
||||||
'invite_created' => ['enabled' => true],
|
'invite_created' => ['enabled' => true],
|
||||||
'invite_redeemed' => ['enabled' => true],
|
'invite_redeemed' => ['enabled' => true],
|
||||||
'unknown_user_attempt' => ['enabled' => true],
|
'unknown_user_attempt' => ['enabled' => true],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
// config for Wijourdil/NtfyNotificationChannel
|
// config for Wijourdil/NtfyNotificationChannel
|
||||||
return [
|
return [
|
||||||
|
|
||||||
'server' => 'https://ntfy.sh',
|
'server' => 'https://ntfy.sh',
|
||||||
'topic' => '',
|
'topic' => '',
|
||||||
'authentication' => [
|
'authentication' => [
|
||||||
'enabled' => false,
|
'enabled' => false,
|
||||||
'username' => '',
|
'username' => '',
|
||||||
'password' => '',
|
'password' => '',
|
||||||
],
|
],
|
||||||
|
@ -61,8 +61,8 @@ return [
|
|||||||
'mandrill' => [
|
'mandrill' => [
|
||||||
'secret' => env('MANDRILL_SECRET'),
|
'secret' => env('MANDRILL_SECRET'),
|
||||||
],
|
],
|
||||||
'pushover' => [
|
'pushover' => [
|
||||||
'token' => 'fake_token',
|
'token' => 'fake_token',
|
||||||
'user_token' => 'fake_token',
|
'user_token' => 'fake_token',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -1,31 +1,32 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class () extends Migration {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* Run the migrations.
|
* Run the migrations.
|
||||||
*/
|
*/
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
// make account_id nullable and the relation also nullable.
|
// make account_id nullable and the relation also nullable.
|
||||||
Schema::table('piggy_banks', static function (Blueprint $table) {
|
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
||||||
// 1. drop index
|
// 1. drop index
|
||||||
$table->dropForeign('piggy_banks_account_id_foreign');
|
$table->dropForeign('piggy_banks_account_id_foreign');
|
||||||
});
|
});
|
||||||
Schema::table('piggy_banks', static function (Blueprint $table) {
|
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
||||||
// 2. make column nullable.
|
// 2. make column nullable.
|
||||||
$table->unsignedInteger('account_id')->nullable()->change();
|
$table->unsignedInteger('account_id')->nullable()->change();
|
||||||
});
|
});
|
||||||
Schema::table('piggy_banks', static function (Blueprint $table) {
|
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
||||||
// 3. add currency
|
// 3. add currency
|
||||||
$table->integer('transaction_currency_id', false, true)->after('account_id');
|
$table->integer('transaction_currency_id', false, true)->after('account_id');
|
||||||
$table->foreign('transaction_currency_id','unique_currency')->references('id')->on('transaction_currencies')->onDelete('cascade');
|
$table->foreign('transaction_currency_id', 'unique_currency')->references('id')->on('transaction_currencies')->onDelete('cascade');
|
||||||
});
|
});
|
||||||
Schema::table('piggy_banks', static function (Blueprint $table) {
|
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
||||||
// 4. rename columns
|
// 4. rename columns
|
||||||
$table->renameColumn('targetamount', 'target_amount');
|
$table->renameColumn('targetamount', 'target_amount');
|
||||||
$table->renameColumn('startdate', 'start_date');
|
$table->renameColumn('startdate', 'start_date');
|
||||||
@ -33,13 +34,13 @@ return new class extends Migration
|
|||||||
$table->renameColumn('startdate_tz', 'start_date_tz');
|
$table->renameColumn('startdate_tz', 'start_date_tz');
|
||||||
$table->renameColumn('targetdate_tz', 'target_date_tz');
|
$table->renameColumn('targetdate_tz', 'target_date_tz');
|
||||||
});
|
});
|
||||||
Schema::table('piggy_banks', static function (Blueprint $table) {
|
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
||||||
// 5. add new index
|
// 5. add new index
|
||||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('set null');
|
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('set null');
|
||||||
});
|
});
|
||||||
|
|
||||||
// rename some fields in piggy bank reps.
|
// rename some fields in piggy bank reps.
|
||||||
Schema::table('piggy_bank_repetitions', static function (Blueprint $table) {
|
Schema::table('piggy_bank_repetitions', static function (Blueprint $table): void {
|
||||||
// 6. rename columns
|
// 6. rename columns
|
||||||
$table->renameColumn('currentamount', 'current_amount');
|
$table->renameColumn('currentamount', 'current_amount');
|
||||||
$table->renameColumn('startdate', 'start_date');
|
$table->renameColumn('startdate', 'start_date');
|
||||||
@ -49,14 +50,14 @@ return new class extends Migration
|
|||||||
});
|
});
|
||||||
|
|
||||||
// create table account_piggy_bank
|
// create table account_piggy_bank
|
||||||
Schema::create('account_piggy_bank', static function (Blueprint $table) {
|
Schema::create('account_piggy_bank', static function (Blueprint $table): void {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->integer('account_id', false, true);
|
$table->integer('account_id', false, true);
|
||||||
$table->integer('piggy_bank_id',false, true);
|
$table->integer('piggy_bank_id', false, true);
|
||||||
$table->decimal('current_amount', 32, 12)->default('0');
|
$table->decimal('current_amount', 32, 12)->default('0');
|
||||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||||
$table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade');
|
$table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade');
|
||||||
$table->unique(['account_id', 'piggy_bank_id'],'unique_piggy_save');
|
$table->unique(['account_id', 'piggy_bank_id'], 'unique_piggy_save');
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -66,7 +67,7 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down(): void
|
public function down(): void
|
||||||
{
|
{
|
||||||
Schema::table('piggy_banks', static function (Blueprint $table) {
|
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
||||||
// 1. drop account index again.
|
// 1. drop account index again.
|
||||||
$table->dropForeign('piggy_banks_account_id_foreign');
|
$table->dropForeign('piggy_banks_account_id_foreign');
|
||||||
|
|
||||||
@ -89,7 +90,7 @@ return new class extends Migration
|
|||||||
});
|
});
|
||||||
|
|
||||||
// rename some fields in piggy bank reps.
|
// rename some fields in piggy bank reps.
|
||||||
Schema::table('piggy_bank_repetitions', static function (Blueprint $table) {
|
Schema::table('piggy_bank_repetitions', static function (Blueprint $table): void {
|
||||||
// 6. rename columns
|
// 6. rename columns
|
||||||
$table->renameColumn('current_amount', 'currentamount');
|
$table->renameColumn('current_amount', 'currentamount');
|
||||||
$table->renameColumn('start_date', 'startdate');
|
$table->renameColumn('start_date', 'startdate');
|
||||||
|
@ -88,5 +88,5 @@ return [
|
|||||||
'mfa_disableMFA' => 'Disable multi-factor authentication',
|
'mfa_disableMFA' => 'Disable multi-factor authentication',
|
||||||
|
|
||||||
// notifications
|
// notifications
|
||||||
'notification_index' => 'Owner notifications',
|
'notification_index' => 'Owner notifications',
|
||||||
];
|
];
|
||||||
|
@ -26,160 +26,160 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
// common items
|
// common items
|
||||||
'greeting' => 'Hi there,',
|
'greeting' => 'Hi there,',
|
||||||
'closing' => 'Beep boop,',
|
'closing' => 'Beep boop,',
|
||||||
'signature' => 'The Firefly III Mail Robot',
|
'signature' => 'The Firefly III Mail Robot',
|
||||||
'footer_ps' => 'PS: This message was sent because a request from IP :ipAddress triggered it.',
|
'footer_ps' => 'PS: This message was sent because a request from IP :ipAddress triggered it.',
|
||||||
|
|
||||||
// admin test
|
// admin test
|
||||||
'admin_test_subject' => 'A test message from your Firefly III installation',
|
'admin_test_subject' => 'A test message from your Firefly III installation',
|
||||||
'admin_test_body' => 'This is a test message from your Firefly III instance. It was sent to :email.',
|
'admin_test_body' => 'This is a test message from your Firefly III instance. It was sent to :email.',
|
||||||
'admin_test_message' => 'This is a test message from your Firefly III instance over channel ":channel".',
|
'admin_test_message' => 'This is a test message from your Firefly III instance over channel ":channel".',
|
||||||
|
|
||||||
// Ignore this comment
|
// Ignore this comment
|
||||||
|
|
||||||
// invite
|
// invite
|
||||||
'invitation_created_subject' => 'An invitation has been created',
|
'invitation_created_subject' => 'An invitation has been created',
|
||||||
'invitation_created_body' => 'Admin user ":email" created a user invitation which can be used by whoever is behind email address ":invitee". The invite will be valid for 48hrs.',
|
'invitation_created_body' => 'Admin user ":email" created a user invitation which can be used by whoever is behind email address ":invitee". The invite will be valid for 48hrs.',
|
||||||
'invite_user_subject' => 'You\'ve been invited to create a Firefly III account.',
|
'invite_user_subject' => 'You\'ve been invited to create a Firefly III account.',
|
||||||
'invitation_introduction' => 'You\'ve been invited to create a Firefly III account on **:host**. Firefly III is a personal, self-hosted, private personal finance manager. All the cool kids are using it.',
|
'invitation_introduction' => 'You\'ve been invited to create a Firefly III account on **:host**. Firefly III is a personal, self-hosted, private personal finance manager. All the cool kids are using it.',
|
||||||
'invitation_invited_by' => 'You\'ve been invited by ":admin" and this invitation was sent to ":invitee". That\'s you, right?',
|
'invitation_invited_by' => 'You\'ve been invited by ":admin" and this invitation was sent to ":invitee". That\'s you, right?',
|
||||||
'invitation_url' => 'The invitation is valid for 48 hours and can be redeemed by surfing to [Firefly III](:url). Enjoy!',
|
'invitation_url' => 'The invitation is valid for 48 hours and can be redeemed by surfing to [Firefly III](:url). Enjoy!',
|
||||||
|
|
||||||
// new IP
|
// new IP
|
||||||
'login_from_new_ip' => 'New login on Firefly III',
|
'login_from_new_ip' => 'New login on Firefly III',
|
||||||
'slack_login_from_new_ip' => 'New Firefly III login from IP :ip (:host)',
|
'slack_login_from_new_ip' => 'New Firefly III login from IP :ip (:host)',
|
||||||
'new_ip_body' => 'Firefly III detected a new login on your account from an unknown IP address. If you never logged in from the IP address below, or it has been more than six months ago, Firefly III will warn you.',
|
'new_ip_body' => 'Firefly III detected a new login on your account from an unknown IP address. If you never logged in from the IP address below, or it has been more than six months ago, Firefly III will warn you.',
|
||||||
'new_ip_warning' => 'If you recognize this IP address or the login, you can ignore this message. If you didn\'t login, of if you have no idea what this is about, verify your password security, change it, and log out all other sessions. To do this, go to your profile page. Of course you have 2FA enabled already, right? Stay safe!',
|
'new_ip_warning' => 'If you recognize this IP address or the login, you can ignore this message. If you didn\'t login, of if you have no idea what this is about, verify your password security, change it, and log out all other sessions. To do this, go to your profile page. Of course you have 2FA enabled already, right? Stay safe!',
|
||||||
'ip_address' => 'IP address',
|
'ip_address' => 'IP address',
|
||||||
'host_name' => 'Host',
|
'host_name' => 'Host',
|
||||||
'date_time' => 'Date + time',
|
'date_time' => 'Date + time',
|
||||||
|
|
||||||
// access token created
|
// access token created
|
||||||
'access_token_created_subject' => 'A new access token was created',
|
'access_token_created_subject' => 'A new access token was created',
|
||||||
'access_token_created_body' => 'Somebody (hopefully you) just created a new Firefly III API Access Token for your user account.',
|
'access_token_created_body' => 'Somebody (hopefully you) just created a new Firefly III API Access Token for your user account.',
|
||||||
'access_token_created_explanation' => 'With this token, they can access **all** of your financial records through the Firefly III API.',
|
'access_token_created_explanation' => 'With this token, they can access **all** of your financial records through the Firefly III API.',
|
||||||
'access_token_created_revoke' => 'If this wasn\'t you, please revoke this token as soon as possible at :url',
|
'access_token_created_revoke' => 'If this wasn\'t you, please revoke this token as soon as possible at :url',
|
||||||
|
|
||||||
// unknown user login attempt
|
// unknown user login attempt
|
||||||
'unknown_user_subject' => 'An unknown user tried to log in',
|
'unknown_user_subject' => 'An unknown user tried to log in',
|
||||||
'unknown_user_body' => 'An unknown user tried to log in to Firefly III. The email address they used was ":address".',
|
'unknown_user_body' => 'An unknown user tried to log in to Firefly III. The email address they used was ":address".',
|
||||||
'unknown_user_message' => 'The email address they used was ":address".',
|
'unknown_user_message' => 'The email address they used was ":address".',
|
||||||
|
|
||||||
// registered
|
// registered
|
||||||
'registered_subject' => 'Welcome to Firefly III!',
|
'registered_subject' => 'Welcome to Firefly III!',
|
||||||
'registered_subject_admin' => 'A new user has registered',
|
'registered_subject_admin' => 'A new user has registered',
|
||||||
'admin_new_user_registered' => 'A new user has registered. User **:email** was given user ID #:id.',
|
'admin_new_user_registered' => 'A new user has registered. User **:email** was given user ID #:id.',
|
||||||
'registered_welcome' => 'Welcome to [Firefly III](:address). Your registration has made it, and this email is here to confirm it. Yay!',
|
'registered_welcome' => 'Welcome to [Firefly III](:address). Your registration has made it, and this email is here to confirm it. Yay!',
|
||||||
'registered_pw' => 'If you have forgotten your password already, please reset it using [the password reset tool](:address/password/reset).',
|
'registered_pw' => 'If you have forgotten your password already, please reset it using [the password reset tool](:address/password/reset).',
|
||||||
'registered_help' => 'There is a help-icon in the top right corner of each page. If you need help, click it!',
|
'registered_help' => 'There is a help-icon in the top right corner of each page. If you need help, click it!',
|
||||||
'registered_closing' => 'Enjoy!',
|
'registered_closing' => 'Enjoy!',
|
||||||
'registered_firefly_iii_link' => 'Firefly III:',
|
'registered_firefly_iii_link' => 'Firefly III:',
|
||||||
'registered_pw_reset_link' => 'Password reset:',
|
'registered_pw_reset_link' => 'Password reset:',
|
||||||
'registered_doc_link' => 'Documentation:',
|
'registered_doc_link' => 'Documentation:',
|
||||||
|
|
||||||
// Ignore this comment
|
// Ignore this comment
|
||||||
|
|
||||||
// new version
|
// new version
|
||||||
'new_version_email_subject' => 'A new Firefly III version is available',
|
'new_version_email_subject' => 'A new Firefly III version is available',
|
||||||
|
|
||||||
// email change
|
// email change
|
||||||
'email_change_subject' => 'Your Firefly III email address has changed',
|
'email_change_subject' => 'Your Firefly III email address has changed',
|
||||||
'email_change_body_to_new' => 'You or somebody with access to your Firefly III account has changed your email address. If you did not expect this message, please ignore and delete it.',
|
'email_change_body_to_new' => 'You or somebody with access to your Firefly III account has changed your email address. If you did not expect this message, please ignore and delete it.',
|
||||||
'email_change_body_to_old' => 'You or somebody with access to your Firefly III account has changed your email address. If you did not expect this to happen, you **must** follow the "undo"-link below to protect your account!',
|
'email_change_body_to_old' => 'You or somebody with access to your Firefly III account has changed your email address. If you did not expect this to happen, you **must** follow the "undo"-link below to protect your account!',
|
||||||
'email_change_ignore' => 'If you initiated this change, you may safely ignore this message.',
|
'email_change_ignore' => 'If you initiated this change, you may safely ignore this message.',
|
||||||
'email_change_old' => 'The old email address was: :email',
|
'email_change_old' => 'The old email address was: :email',
|
||||||
'email_change_old_strong' => 'The old email address was: **:email**',
|
'email_change_old_strong' => 'The old email address was: **:email**',
|
||||||
'email_change_new' => 'The new email address is: :email',
|
'email_change_new' => 'The new email address is: :email',
|
||||||
'email_change_new_strong' => 'The new email address is: **:email**',
|
'email_change_new_strong' => 'The new email address is: **:email**',
|
||||||
'email_change_instructions' => 'You cannot use Firefly III until you confirm this change. Please follow the link below to do so.',
|
'email_change_instructions' => 'You cannot use Firefly III until you confirm this change. Please follow the link below to do so.',
|
||||||
'email_change_undo_link' => 'To undo the change, follow this link:',
|
'email_change_undo_link' => 'To undo the change, follow this link:',
|
||||||
|
|
||||||
// OAuth token created
|
// OAuth token created
|
||||||
'oauth_created_subject' => 'A new OAuth client has been created',
|
'oauth_created_subject' => 'A new OAuth client has been created',
|
||||||
'oauth_created_body' => 'Somebody (hopefully you) just created a new Firefly III API OAuth Client for your user account. It\'s labeled ":name" and has callback URL `:url`.',
|
'oauth_created_body' => 'Somebody (hopefully you) just created a new Firefly III API OAuth Client for your user account. It\'s labeled ":name" and has callback URL `:url`.',
|
||||||
'oauth_created_explanation' => 'With this client, they can access **all** of your financial records through the Firefly III API.',
|
'oauth_created_explanation' => 'With this client, they can access **all** of your financial records through the Firefly III API.',
|
||||||
'oauth_created_undo' => 'If this wasn\'t you, please revoke this client as soon as possible at `:url`',
|
'oauth_created_undo' => 'If this wasn\'t you, please revoke this client as soon as possible at `:url`',
|
||||||
|
|
||||||
// reset password
|
// reset password
|
||||||
'reset_pw_subject' => 'Your password reset request',
|
'reset_pw_subject' => 'Your password reset request',
|
||||||
'reset_pw_instructions' => 'Somebody tried to reset your password. If it was you, please follow the link below to do so.',
|
'reset_pw_instructions' => 'Somebody tried to reset your password. If it was you, please follow the link below to do so.',
|
||||||
'reset_pw_warning' => '**PLEASE** verify that the link actually goes to the Firefly III you expect it to go!',
|
'reset_pw_warning' => '**PLEASE** verify that the link actually goes to the Firefly III you expect it to go!',
|
||||||
|
|
||||||
// error
|
// error
|
||||||
'error_subject' => 'Caught an error in Firefly III',
|
'error_subject' => 'Caught an error in Firefly III',
|
||||||
'error_intro' => 'Firefly III v:version ran into an error: <span style="font-family: monospace;">:errorMessage</span>.',
|
'error_intro' => 'Firefly III v:version ran into an error: <span style="font-family: monospace;">:errorMessage</span>.',
|
||||||
'error_type' => 'The error was of type ":class".',
|
'error_type' => 'The error was of type ":class".',
|
||||||
'error_timestamp' => 'The error occurred on/at: :time.',
|
'error_timestamp' => 'The error occurred on/at: :time.',
|
||||||
'error_location' => 'This error occurred in file "<span style="font-family: monospace;">:file</span>" on line :line with code :code.',
|
'error_location' => 'This error occurred in file "<span style="font-family: monospace;">:file</span>" on line :line with code :code.',
|
||||||
'error_user' => 'The error was encountered by user #:id, <a href="mailto::email">:email</a>.',
|
'error_user' => 'The error was encountered by user #:id, <a href="mailto::email">:email</a>.',
|
||||||
'error_no_user' => 'There was no user logged in for this error or no user was detected.',
|
'error_no_user' => 'There was no user logged in for this error or no user was detected.',
|
||||||
'error_ip' => 'The IP address related to this error is: :ip',
|
'error_ip' => 'The IP address related to this error is: :ip',
|
||||||
'error_url' => 'URL is: :url',
|
'error_url' => 'URL is: :url',
|
||||||
'error_user_agent' => 'User agent: :userAgent',
|
'error_user_agent' => 'User agent: :userAgent',
|
||||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||||
'error_github_html' => 'If you prefer, you can also open a new issue on <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
'error_github_html' => 'If you prefer, you can also open a new issue on <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||||
'error_github_text' => 'If you prefer, you can also open a new issue on https://github.com/firefly-iii/firefly-iii/issues.',
|
'error_github_text' => 'If you prefer, you can also open a new issue on https://github.com/firefly-iii/firefly-iii/issues.',
|
||||||
'error_stacktrace_below' => 'The full stacktrace is below:',
|
'error_stacktrace_below' => 'The full stacktrace is below:',
|
||||||
'error_headers' => 'The following headers may also be relevant:',
|
'error_headers' => 'The following headers may also be relevant:',
|
||||||
'error_post' => 'This was submitted by the user:',
|
'error_post' => 'This was submitted by the user:',
|
||||||
|
|
||||||
// Ignore this comment
|
// Ignore this comment
|
||||||
|
|
||||||
// report new journals
|
// report new journals
|
||||||
'new_journals_subject' => 'Firefly III has created a new transaction|Firefly III has created :count new transactions',
|
'new_journals_subject' => 'Firefly III has created a new transaction|Firefly III has created :count new transactions',
|
||||||
'new_journals_header' => 'Firefly III has created a transaction for you. You can find it in your Firefly III installation:|Firefly III has created :count transactions for you. You can find them in your Firefly III installation:',
|
'new_journals_header' => 'Firefly III has created a transaction for you. You can find it in your Firefly III installation:|Firefly III has created :count transactions for you. You can find them in your Firefly III installation:',
|
||||||
|
|
||||||
// bill warning
|
// bill warning
|
||||||
'bill_warning_subject_end_date' => 'Your bill ":name" is due to end in :diff days',
|
'bill_warning_subject_end_date' => 'Your bill ":name" is due to end in :diff days',
|
||||||
'bill_warning_subject_now_end_date' => 'Your bill ":name" is due to end TODAY',
|
'bill_warning_subject_now_end_date' => 'Your bill ":name" is due to end TODAY',
|
||||||
'bill_warning_subject_extension_date' => 'Your bill ":name" is due to be extended or cancelled in :diff days',
|
'bill_warning_subject_extension_date' => 'Your bill ":name" is due to be extended or cancelled in :diff days',
|
||||||
'bill_warning_subject_now_extension_date' => 'Your bill ":name" is due to be extended or cancelled TODAY',
|
'bill_warning_subject_now_extension_date' => 'Your bill ":name" is due to be extended or cancelled TODAY',
|
||||||
'bill_warning_end_date' => 'Your bill **":name"** is due to end on :date. This moment will pass in about **:diff days**.',
|
'bill_warning_end_date' => 'Your bill **":name"** is due to end on :date. This moment will pass in about **:diff days**.',
|
||||||
'bill_warning_extension_date' => 'Your bill **":name"** is due to be extended or cancelled on :date. This moment will pass in about **:diff days**.',
|
'bill_warning_extension_date' => 'Your bill **":name"** is due to be extended or cancelled on :date. This moment will pass in about **:diff days**.',
|
||||||
'bill_warning_end_date_zero' => 'Your bill **":name"** is due to end on :date. This moment will pass **TODAY!**',
|
'bill_warning_end_date_zero' => 'Your bill **":name"** is due to end on :date. This moment will pass **TODAY!**',
|
||||||
'bill_warning_extension_date_zero' => 'Your bill **":name"** is due to be extended or cancelled on :date. This moment will pass **TODAY!**',
|
'bill_warning_extension_date_zero' => 'Your bill **":name"** is due to be extended or cancelled on :date. This moment will pass **TODAY!**',
|
||||||
'bill_warning_please_action' => 'Please take the appropriate action.',
|
'bill_warning_please_action' => 'Please take the appropriate action.',
|
||||||
|
|
||||||
// user has enabled MFA
|
// user has enabled MFA
|
||||||
'enabled_mfa_subject' => 'You have enabled multi-factor authentication',
|
'enabled_mfa_subject' => 'You have enabled multi-factor authentication',
|
||||||
'enabled_mfa_slack' => 'You (:email) have enabled multi-factor authentication. Is this not correct? Check your settings!',
|
'enabled_mfa_slack' => 'You (:email) have enabled multi-factor authentication. Is this not correct? Check your settings!',
|
||||||
'have_enabled_mfa' => 'You have enabled multi-factor authentication on your Firefly III account ":email". This means that you will need to use an authenticator app to log in from now on.',
|
'have_enabled_mfa' => 'You have enabled multi-factor authentication on your Firefly III account ":email". This means that you will need to use an authenticator app to log in from now on.',
|
||||||
'enabled_mfa_warning' => 'If you did not enable this, please contact your administrator immediately or check out the Firefly III documentation.',
|
'enabled_mfa_warning' => 'If you did not enable this, please contact your administrator immediately or check out the Firefly III documentation.',
|
||||||
|
|
||||||
'disabled_mfa_subject' => 'You have disabled multi-factor authentication!',
|
'disabled_mfa_subject' => 'You have disabled multi-factor authentication!',
|
||||||
'disabled_mfa_slack' => 'You (:email) have disabled multi-factor authentication. Is this not correct? Check your settings!',
|
'disabled_mfa_slack' => 'You (:email) have disabled multi-factor authentication. Is this not correct? Check your settings!',
|
||||||
'have_disabled_mfa' => 'You have disabled multi-factor authentication on your Firefly III account ":email".',
|
'have_disabled_mfa' => 'You have disabled multi-factor authentication on your Firefly III account ":email".',
|
||||||
'disabled_mfa_warning' => 'If you did not disable this, please contact your administrator immediately or check out the Firefly III documentation.',
|
'disabled_mfa_warning' => 'If you did not disable this, please contact your administrator immediately or check out the Firefly III documentation.',
|
||||||
|
|
||||||
'new_backup_codes_subject' => 'You have generated new back-up codes',
|
'new_backup_codes_subject' => 'You have generated new back-up codes',
|
||||||
'new_backup_codes_slack' => 'You (:email) have generated new back-up codes. These can be used to login to Firefly III. Is this not correct? Check your settings!',
|
'new_backup_codes_slack' => 'You (:email) have generated new back-up codes. These can be used to login to Firefly III. Is this not correct? Check your settings!',
|
||||||
'new_backup_codes_intro' => 'You (:email) have generated new back-up codes. These can be used to login to Firefly III if you lose access to your authenticator app.',
|
'new_backup_codes_intro' => 'You (:email) have generated new back-up codes. These can be used to login to Firefly III if you lose access to your authenticator app.',
|
||||||
'new_backup_codes_warning' => 'Please store these codes in a safe place. If you lose them, you will not be able to log in to Firefly III. If you did not do this, please contact your administrator immediately or check out the Firefly III documentation.',
|
'new_backup_codes_warning' => 'Please store these codes in a safe place. If you lose them, you will not be able to log in to Firefly III. If you did not do this, please contact your administrator immediately or check out the Firefly III documentation.',
|
||||||
|
|
||||||
'used_backup_code_subject' => 'You have used a back-up code to login',
|
'used_backup_code_subject' => 'You have used a back-up code to login',
|
||||||
'used_backup_code_slack' => 'You (:email) have used a back-up code to login',
|
'used_backup_code_slack' => 'You (:email) have used a back-up code to login',
|
||||||
|
|
||||||
'used_backup_code_intro' => 'You (:email) have used a back-up code to login to Firefly III. You now have one less back-up code to login with. Please remove it from your list.',
|
'used_backup_code_intro' => 'You (:email) have used a back-up code to login to Firefly III. You now have one less back-up code to login with. Please remove it from your list.',
|
||||||
'used_backup_code_warning' => 'If you did not do this, please contact your administrator immediately or check out the Firefly III documentation.',
|
'used_backup_code_warning' => 'If you did not do this, please contact your administrator immediately or check out the Firefly III documentation.',
|
||||||
|
|
||||||
// few left:
|
// few left:
|
||||||
'mfa_few_backups_left_subject' => 'You have only :count backup code(s) left!',
|
'mfa_few_backups_left_subject' => 'You have only :count backup code(s) left!',
|
||||||
'mfa_few_backups_left_slack' => 'You (:email) have only :count backup code(s) left!',
|
'mfa_few_backups_left_slack' => 'You (:email) have only :count backup code(s) left!',
|
||||||
'few_backup_codes_intro' => 'You (:email) have used most of your backup codes, and now have only :count left. Please generate new ones as soon as possible.',
|
'few_backup_codes_intro' => 'You (:email) have used most of your backup codes, and now have only :count left. Please generate new ones as soon as possible.',
|
||||||
'few_backup_codes_warning' => 'Without backup codes, you cannot recover your MFA login if you lose access to your code generator.',
|
'few_backup_codes_warning' => 'Without backup codes, you cannot recover your MFA login if you lose access to your code generator.',
|
||||||
|
|
||||||
// NO left:
|
// NO left:
|
||||||
'mfa_no_backups_left_subject' => 'You have NO backup codes left!',
|
'mfa_no_backups_left_subject' => 'You have NO backup codes left!',
|
||||||
'mfa_no_backups_left_slack' => 'You (:email) NO backup codes left!',
|
'mfa_no_backups_left_slack' => 'You (:email) NO backup codes left!',
|
||||||
'no_backup_codes_intro' => 'You (:email) have used ALL of your backup codes. Please generate new ones as soon as possible.',
|
'no_backup_codes_intro' => 'You (:email) have used ALL of your backup codes. Please generate new ones as soon as possible.',
|
||||||
'no_backup_codes_warning' => 'Without backup codes, you cannot recover your MFA login if you lose access to your code generator.',
|
'no_backup_codes_warning' => 'Without backup codes, you cannot recover your MFA login if you lose access to your code generator.',
|
||||||
|
|
||||||
// many failed MFA attempts
|
// many failed MFA attempts
|
||||||
'mfa_many_failed_subject' => 'You have tried and failed to use multi-factor authentication :count times now!',
|
'mfa_many_failed_subject' => 'You have tried and failed to use multi-factor authentication :count times now!',
|
||||||
'mfa_many_failed_slack' => 'You (:email) have tried and failed to use multi-factor authentication :count times now. Is this not correct? Check your settings!',
|
'mfa_many_failed_slack' => 'You (:email) have tried and failed to use multi-factor authentication :count times now. Is this not correct? Check your settings!',
|
||||||
'mfa_many_failed_attempts_intro' => 'You (:email) have tried :count times to use a multi-factor authentication code, but these login attempts have failed. Are you sure you are using the right MFA code? Are you sure the time on the server is correct?',
|
'mfa_many_failed_attempts_intro' => 'You (:email) have tried :count times to use a multi-factor authentication code, but these login attempts have failed. Are you sure you are using the right MFA code? Are you sure the time on the server is correct?',
|
||||||
'mfa_many_failed_attempts_warning' => 'If you did not do this, please contact your administrator immediately or check out the Firefly III documentation.',
|
'mfa_many_failed_attempts_warning' => 'If you did not do this, please contact your administrator immediately or check out the Firefly III documentation.',
|
||||||
|
|
||||||
];
|
];
|
||||||
// Ignore this comment
|
// Ignore this comment
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -26,250 +26,250 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
// new user:
|
// new user:
|
||||||
'bank_name' => 'Bank name',
|
'bank_name' => 'Bank name',
|
||||||
'bank_balance' => 'Balance',
|
'bank_balance' => 'Balance',
|
||||||
'current_balance' => 'Current balance',
|
'current_balance' => 'Current balance',
|
||||||
'savings_balance' => 'Savings balance',
|
'savings_balance' => 'Savings balance',
|
||||||
'credit_card_limit' => 'Credit card limit',
|
'credit_card_limit' => 'Credit card limit',
|
||||||
'automatch' => 'Match automatically',
|
'automatch' => 'Match automatically',
|
||||||
'skip' => 'Skip',
|
'skip' => 'Skip',
|
||||||
'enabled' => 'Enabled',
|
'enabled' => 'Enabled',
|
||||||
'name' => 'Name',
|
'name' => 'Name',
|
||||||
'active' => 'Active',
|
'active' => 'Active',
|
||||||
'amount_min' => 'Minimum amount',
|
'amount_min' => 'Minimum amount',
|
||||||
'amount_max' => 'Maximum amount',
|
'amount_max' => 'Maximum amount',
|
||||||
'match' => 'Matches on',
|
'match' => 'Matches on',
|
||||||
'strict' => 'Strict mode',
|
'strict' => 'Strict mode',
|
||||||
'repeat_freq' => 'Repeats',
|
'repeat_freq' => 'Repeats',
|
||||||
'object_group' => 'Group',
|
'object_group' => 'Group',
|
||||||
'location' => 'Location',
|
'location' => 'Location',
|
||||||
'update_channel' => 'Update channel',
|
'update_channel' => 'Update channel',
|
||||||
'currency_id' => 'Currency',
|
'currency_id' => 'Currency',
|
||||||
'transaction_currency_id' => 'Currency',
|
'transaction_currency_id' => 'Currency',
|
||||||
'auto_budget_currency_id' => 'Currency',
|
'auto_budget_currency_id' => 'Currency',
|
||||||
'external_ip' => 'Your server\'s external IP',
|
'external_ip' => 'Your server\'s external IP',
|
||||||
'attachments' => 'Attachments',
|
'attachments' => 'Attachments',
|
||||||
'BIC' => 'BIC',
|
'BIC' => 'BIC',
|
||||||
'verify_password' => 'Verify password security',
|
'verify_password' => 'Verify password security',
|
||||||
'source_account' => 'Source account',
|
'source_account' => 'Source account',
|
||||||
'destination_account' => 'Destination account',
|
'destination_account' => 'Destination account',
|
||||||
'asset_destination_account' => 'Destination account',
|
'asset_destination_account' => 'Destination account',
|
||||||
'include_net_worth' => 'Include in net worth',
|
'include_net_worth' => 'Include in net worth',
|
||||||
'asset_source_account' => 'Source account',
|
'asset_source_account' => 'Source account',
|
||||||
'journal_description' => 'Description',
|
'journal_description' => 'Description',
|
||||||
'note' => 'Notes',
|
'note' => 'Notes',
|
||||||
'currency' => 'Currency',
|
'currency' => 'Currency',
|
||||||
'account_id' => 'Asset account',
|
'account_id' => 'Asset account',
|
||||||
'budget_id' => 'Budget',
|
'budget_id' => 'Budget',
|
||||||
'bill_id' => 'Bill',
|
'bill_id' => 'Bill',
|
||||||
'opening_balance' => 'Opening balance',
|
'opening_balance' => 'Opening balance',
|
||||||
'tagMode' => 'Tag mode',
|
'tagMode' => 'Tag mode',
|
||||||
'virtual_balance' => 'Virtual balance',
|
'virtual_balance' => 'Virtual balance',
|
||||||
|
|
||||||
// Ignore this comment
|
// Ignore this comment
|
||||||
|
|
||||||
'targetamount' => 'Target amount',
|
'targetamount' => 'Target amount',
|
||||||
'target_amount' => 'Target amount',
|
'target_amount' => 'Target amount',
|
||||||
'account_role' => 'Account role',
|
'account_role' => 'Account role',
|
||||||
'opening_balance_date' => 'Opening balance date',
|
'opening_balance_date' => 'Opening balance date',
|
||||||
'cc_type' => 'Credit card payment plan',
|
'cc_type' => 'Credit card payment plan',
|
||||||
'cc_monthly_payment_date' => 'Credit card monthly payment date',
|
'cc_monthly_payment_date' => 'Credit card monthly payment date',
|
||||||
'piggy_bank_id' => 'Piggy bank',
|
'piggy_bank_id' => 'Piggy bank',
|
||||||
'returnHere' => 'Return here',
|
'returnHere' => 'Return here',
|
||||||
'returnHereExplanation' => 'After storing, return here to create another one.',
|
'returnHereExplanation' => 'After storing, return here to create another one.',
|
||||||
'returnHereUpdateExplanation' => 'After updating, return here.',
|
'returnHereUpdateExplanation' => 'After updating, return here.',
|
||||||
'description' => 'Description',
|
'description' => 'Description',
|
||||||
'expense_account' => 'Expense account',
|
'expense_account' => 'Expense account',
|
||||||
'revenue_account' => 'Revenue account',
|
'revenue_account' => 'Revenue account',
|
||||||
'decimal_places' => 'Decimal places',
|
'decimal_places' => 'Decimal places',
|
||||||
'destination_amount' => 'Amount (destination)',
|
'destination_amount' => 'Amount (destination)',
|
||||||
'new_email_address' => 'New email address',
|
'new_email_address' => 'New email address',
|
||||||
'verification' => 'Verification',
|
'verification' => 'Verification',
|
||||||
'api_key' => 'API key',
|
'api_key' => 'API key',
|
||||||
'remember_me' => 'Remember me',
|
'remember_me' => 'Remember me',
|
||||||
'liability_type_id' => 'Liability type',
|
'liability_type_id' => 'Liability type',
|
||||||
'liability_type' => 'Liability type',
|
'liability_type' => 'Liability type',
|
||||||
'interest' => 'Interest',
|
'interest' => 'Interest',
|
||||||
'interest_period' => 'Interest period',
|
'interest_period' => 'Interest period',
|
||||||
'extension_date' => 'Extension date',
|
'extension_date' => 'Extension date',
|
||||||
'type' => 'Type',
|
'type' => 'Type',
|
||||||
'convert_Withdrawal' => 'Convert withdrawal',
|
'convert_Withdrawal' => 'Convert withdrawal',
|
||||||
'convert_Deposit' => 'Convert deposit',
|
'convert_Deposit' => 'Convert deposit',
|
||||||
'convert_Transfer' => 'Convert transfer',
|
'convert_Transfer' => 'Convert transfer',
|
||||||
'amount' => 'Amount',
|
'amount' => 'Amount',
|
||||||
'foreign_amount' => 'Foreign amount',
|
'foreign_amount' => 'Foreign amount',
|
||||||
'date' => 'Date',
|
'date' => 'Date',
|
||||||
'interest_date' => 'Interest date',
|
'interest_date' => 'Interest date',
|
||||||
'book_date' => 'Book date',
|
'book_date' => 'Book date',
|
||||||
'process_date' => 'Processing date',
|
'process_date' => 'Processing date',
|
||||||
'category' => 'Category',
|
'category' => 'Category',
|
||||||
'tags' => 'Tags',
|
'tags' => 'Tags',
|
||||||
'deletePermanently' => 'Delete permanently',
|
'deletePermanently' => 'Delete permanently',
|
||||||
'cancel' => 'Cancel',
|
'cancel' => 'Cancel',
|
||||||
'targetdate' => 'Target date',
|
'targetdate' => 'Target date',
|
||||||
'target_date' => 'Target date',
|
'target_date' => 'Target date',
|
||||||
'startdate' => 'Start date',
|
'startdate' => 'Start date',
|
||||||
'start_date' => 'Start date',
|
'start_date' => 'Start date',
|
||||||
'tag' => 'Tag',
|
'tag' => 'Tag',
|
||||||
'under' => 'Under',
|
'under' => 'Under',
|
||||||
'symbol' => 'Symbol',
|
'symbol' => 'Symbol',
|
||||||
'code' => 'Code',
|
'code' => 'Code',
|
||||||
'iban' => 'IBAN',
|
'iban' => 'IBAN',
|
||||||
'account_number' => 'Account number',
|
'account_number' => 'Account number',
|
||||||
'creditCardNumber' => 'Credit card number',
|
'creditCardNumber' => 'Credit card number',
|
||||||
'has_headers' => 'Headers',
|
'has_headers' => 'Headers',
|
||||||
'date_format' => 'Date format',
|
'date_format' => 'Date format',
|
||||||
'attachments[]' => 'Attachments',
|
'attachments[]' => 'Attachments',
|
||||||
'title' => 'Title',
|
'title' => 'Title',
|
||||||
'notes' => 'Notes',
|
'notes' => 'Notes',
|
||||||
'filename' => 'File name',
|
'filename' => 'File name',
|
||||||
'mime' => 'Mime type',
|
'mime' => 'Mime type',
|
||||||
'size' => 'Size',
|
'size' => 'Size',
|
||||||
'trigger' => 'Trigger',
|
'trigger' => 'Trigger',
|
||||||
'stop_processing' => 'Stop processing',
|
'stop_processing' => 'Stop processing',
|
||||||
'end_date' => 'End date',
|
'end_date' => 'End date',
|
||||||
'enddate' => 'End date',
|
'enddate' => 'End date',
|
||||||
'move_rules_before_delete' => 'Rule group',
|
'move_rules_before_delete' => 'Rule group',
|
||||||
'start' => 'Start of range',
|
'start' => 'Start of range',
|
||||||
'end' => 'End of range',
|
'end' => 'End of range',
|
||||||
'delete_account' => 'Delete account ":name"',
|
'delete_account' => 'Delete account ":name"',
|
||||||
'delete_webhook' => 'Delete webhook ":title"',
|
'delete_webhook' => 'Delete webhook ":title"',
|
||||||
'delete_bill' => 'Delete bill ":name"',
|
'delete_bill' => 'Delete bill ":name"',
|
||||||
'delete_budget' => 'Delete budget ":name"',
|
'delete_budget' => 'Delete budget ":name"',
|
||||||
'delete_category' => 'Delete category ":name"',
|
'delete_category' => 'Delete category ":name"',
|
||||||
'delete_currency' => 'Delete currency ":name"',
|
'delete_currency' => 'Delete currency ":name"',
|
||||||
'delete_journal' => 'Delete transaction with description ":description"',
|
'delete_journal' => 'Delete transaction with description ":description"',
|
||||||
'delete_attachment' => 'Delete attachment ":name"',
|
'delete_attachment' => 'Delete attachment ":name"',
|
||||||
'delete_rule' => 'Delete rule ":title"',
|
'delete_rule' => 'Delete rule ":title"',
|
||||||
'delete_rule_group' => 'Delete rule group ":title"',
|
'delete_rule_group' => 'Delete rule group ":title"',
|
||||||
'delete_link_type' => 'Delete link type ":name"',
|
'delete_link_type' => 'Delete link type ":name"',
|
||||||
'delete_user' => 'Delete user ":email"',
|
'delete_user' => 'Delete user ":email"',
|
||||||
'delete_recurring' => 'Delete recurring transaction ":title"',
|
'delete_recurring' => 'Delete recurring transaction ":title"',
|
||||||
'user_areYouSure' => 'If you delete user ":email", everything will be gone. There is no undo, undelete or anything. If you delete yourself, you will lose access to this instance of Firefly III.',
|
'user_areYouSure' => 'If you delete user ":email", everything will be gone. There is no undo, undelete or anything. If you delete yourself, you will lose access to this instance of Firefly III.',
|
||||||
'attachment_areYouSure' => 'Are you sure you want to delete the attachment named ":name"?',
|
'attachment_areYouSure' => 'Are you sure you want to delete the attachment named ":name"?',
|
||||||
'account_areYouSure' => 'Are you sure you want to delete the account named ":name"?',
|
'account_areYouSure' => 'Are you sure you want to delete the account named ":name"?',
|
||||||
'account_areYouSure_js' => 'Are you sure you want to delete the account named "{name}"?',
|
'account_areYouSure_js' => 'Are you sure you want to delete the account named "{name}"?',
|
||||||
'bill_areYouSure' => 'Are you sure you want to delete the bill named ":name"?',
|
'bill_areYouSure' => 'Are you sure you want to delete the bill named ":name"?',
|
||||||
'rule_areYouSure' => 'Are you sure you want to delete the rule titled ":title"?',
|
'rule_areYouSure' => 'Are you sure you want to delete the rule titled ":title"?',
|
||||||
'object_group_areYouSure' => 'Are you sure you want to delete the group titled ":title"?',
|
'object_group_areYouSure' => 'Are you sure you want to delete the group titled ":title"?',
|
||||||
'ruleGroup_areYouSure' => 'Are you sure you want to delete the rule group titled ":title"?',
|
'ruleGroup_areYouSure' => 'Are you sure you want to delete the rule group titled ":title"?',
|
||||||
'budget_areYouSure' => 'Are you sure you want to delete the budget named ":name"?',
|
'budget_areYouSure' => 'Are you sure you want to delete the budget named ":name"?',
|
||||||
'webhook_areYouSure' => 'Are you sure you want to delete the webhook named ":title"?',
|
'webhook_areYouSure' => 'Are you sure you want to delete the webhook named ":title"?',
|
||||||
'category_areYouSure' => 'Are you sure you want to delete the category named ":name"?',
|
'category_areYouSure' => 'Are you sure you want to delete the category named ":name"?',
|
||||||
'recurring_areYouSure' => 'Are you sure you want to delete the recurring transaction titled ":title"?',
|
'recurring_areYouSure' => 'Are you sure you want to delete the recurring transaction titled ":title"?',
|
||||||
'currency_areYouSure' => 'Are you sure you want to delete the currency named ":name"?',
|
'currency_areYouSure' => 'Are you sure you want to delete the currency named ":name"?',
|
||||||
'piggyBank_areYouSure' => 'Are you sure you want to delete the piggy bank named ":name"?',
|
'piggyBank_areYouSure' => 'Are you sure you want to delete the piggy bank named ":name"?',
|
||||||
'journal_areYouSure' => 'Are you sure you want to delete the transaction described ":description"?',
|
'journal_areYouSure' => 'Are you sure you want to delete the transaction described ":description"?',
|
||||||
'mass_journal_are_you_sure' => 'Are you sure you want to delete these transactions?',
|
'mass_journal_are_you_sure' => 'Are you sure you want to delete these transactions?',
|
||||||
|
|
||||||
// Ignore this comment
|
// Ignore this comment
|
||||||
|
|
||||||
'tag_areYouSure' => 'Are you sure you want to delete the tag ":tag"?',
|
'tag_areYouSure' => 'Are you sure you want to delete the tag ":tag"?',
|
||||||
'journal_link_areYouSure' => 'Are you sure you want to delete the link between <a href=":source_link">:source</a> and <a href=":destination_link">:destination</a>?',
|
'journal_link_areYouSure' => 'Are you sure you want to delete the link between <a href=":source_link">:source</a> and <a href=":destination_link">:destination</a>?',
|
||||||
'linkType_areYouSure' => 'Are you sure you want to delete the link type ":name" (":inward" / ":outward")?',
|
'linkType_areYouSure' => 'Are you sure you want to delete the link type ":name" (":inward" / ":outward")?',
|
||||||
'permDeleteWarning' => 'Deleting stuff from Firefly III is permanent and cannot be undone.',
|
'permDeleteWarning' => 'Deleting stuff from Firefly III is permanent and cannot be undone.',
|
||||||
'mass_make_selection' => 'You can still prevent items from being deleted by removing the checkbox.',
|
'mass_make_selection' => 'You can still prevent items from being deleted by removing the checkbox.',
|
||||||
'delete_all_permanently' => 'Delete selected permanently',
|
'delete_all_permanently' => 'Delete selected permanently',
|
||||||
'update_all_journals' => 'Update these transactions',
|
'update_all_journals' => 'Update these transactions',
|
||||||
'also_delete_transactions' => 'The only transaction connected to this account will be deleted as well.|All :count transactions connected to this account will be deleted as well.',
|
'also_delete_transactions' => 'The only transaction connected to this account will be deleted as well.|All :count transactions connected to this account will be deleted as well.',
|
||||||
'also_delete_transactions_js' => 'No transactions|The only transaction connected to this account will be deleted as well.|All {count} transactions connected to this account will be deleted as well.',
|
'also_delete_transactions_js' => 'No transactions|The only transaction connected to this account will be deleted as well.|All {count} transactions connected to this account will be deleted as well.',
|
||||||
'also_delete_connections' => 'The only transaction linked with this link type will lose this connection.|All :count transactions linked with this link type will lose their connection.',
|
'also_delete_connections' => 'The only transaction linked with this link type will lose this connection.|All :count transactions linked with this link type will lose their connection.',
|
||||||
'also_delete_rules' => 'The only rule connected to this rule group will be deleted as well.|All :count rules connected to this rule group will be deleted as well.',
|
'also_delete_rules' => 'The only rule connected to this rule group will be deleted as well.|All :count rules connected to this rule group will be deleted as well.',
|
||||||
'also_delete_piggyBanks' => 'The only piggy bank connected to this account will be deleted as well.|All :count piggy bank connected to this account will be deleted as well.',
|
'also_delete_piggyBanks' => 'The only piggy bank connected to this account will be deleted as well.|All :count piggy bank connected to this account will be deleted as well.',
|
||||||
'also_delete_piggyBanks_js' => 'No piggy banks|The only piggy bank connected to this account will be deleted as well.|All {count} piggy banks connected to this account will be deleted as well.',
|
'also_delete_piggyBanks_js' => 'No piggy banks|The only piggy bank connected to this account will be deleted as well.|All {count} piggy banks connected to this account will be deleted as well.',
|
||||||
'not_delete_piggy_banks' => 'The piggy bank connected to this group will not be deleted.|The :count piggy banks connected to this group will not be deleted.',
|
'not_delete_piggy_banks' => 'The piggy bank connected to this group will not be deleted.|The :count piggy banks connected to this group will not be deleted.',
|
||||||
'bill_keep_transactions' => 'The only transaction connected to this bill will not be deleted.|All :count transactions connected to this bill will be spared deletion.',
|
'bill_keep_transactions' => 'The only transaction connected to this bill will not be deleted.|All :count transactions connected to this bill will be spared deletion.',
|
||||||
'budget_keep_transactions' => 'The only transaction connected to this budget will not be deleted.|All :count transactions connected to this budget will be spared deletion.',
|
'budget_keep_transactions' => 'The only transaction connected to this budget will not be deleted.|All :count transactions connected to this budget will be spared deletion.',
|
||||||
'category_keep_transactions' => 'The only transaction connected to this category will not be deleted.|All :count transactions connected to this category will be spared deletion.',
|
'category_keep_transactions' => 'The only transaction connected to this category will not be deleted.|All :count transactions connected to this category will be spared deletion.',
|
||||||
'recurring_keep_transactions' => 'The only transaction created by this recurring transaction will not be deleted.|All :count transactions created by this recurring transaction will be spared deletion.',
|
'recurring_keep_transactions' => 'The only transaction created by this recurring transaction will not be deleted.|All :count transactions created by this recurring transaction will be spared deletion.',
|
||||||
'tag_keep_transactions' => 'The only transaction connected to this tag will not be deleted.|All :count transactions connected to this tag will be spared deletion.',
|
'tag_keep_transactions' => 'The only transaction connected to this tag will not be deleted.|All :count transactions connected to this tag will be spared deletion.',
|
||||||
'check_for_updates' => 'Check for updates',
|
'check_for_updates' => 'Check for updates',
|
||||||
'liability_direction' => 'Liability in/out',
|
'liability_direction' => 'Liability in/out',
|
||||||
'delete_object_group' => 'Delete group ":title"',
|
'delete_object_group' => 'Delete group ":title"',
|
||||||
'email' => 'Email address',
|
'email' => 'Email address',
|
||||||
'password' => 'Password',
|
'password' => 'Password',
|
||||||
'password_confirmation' => 'Password (again)',
|
'password_confirmation' => 'Password (again)',
|
||||||
'blocked' => 'Is blocked?',
|
'blocked' => 'Is blocked?',
|
||||||
'blocked_code' => 'Reason for block',
|
'blocked_code' => 'Reason for block',
|
||||||
'login_name' => 'Login',
|
'login_name' => 'Login',
|
||||||
'is_owner' => 'Is admin?',
|
'is_owner' => 'Is admin?',
|
||||||
'url' => 'URL',
|
'url' => 'URL',
|
||||||
'bill_end_date' => 'End date',
|
'bill_end_date' => 'End date',
|
||||||
|
|
||||||
// import
|
// import
|
||||||
'apply_rules' => 'Apply rules',
|
'apply_rules' => 'Apply rules',
|
||||||
'artist' => 'Artist',
|
'artist' => 'Artist',
|
||||||
'album' => 'Album',
|
'album' => 'Album',
|
||||||
'song' => 'Song',
|
'song' => 'Song',
|
||||||
|
|
||||||
// admin
|
// admin
|
||||||
'domain' => 'Domain',
|
'domain' => 'Domain',
|
||||||
'single_user_mode' => 'Disable user registration',
|
'single_user_mode' => 'Disable user registration',
|
||||||
'is_demo_site' => 'Is demo site',
|
'is_demo_site' => 'Is demo site',
|
||||||
|
|
||||||
// import
|
// import
|
||||||
'configuration_file' => 'Configuration file',
|
'configuration_file' => 'Configuration file',
|
||||||
'csv_comma' => 'A comma (,)',
|
'csv_comma' => 'A comma (,)',
|
||||||
'csv_semicolon' => 'A semicolon (;)',
|
'csv_semicolon' => 'A semicolon (;)',
|
||||||
'csv_tab' => 'A tab (invisible)',
|
'csv_tab' => 'A tab (invisible)',
|
||||||
'csv_delimiter' => 'CSV field delimiter',
|
'csv_delimiter' => 'CSV field delimiter',
|
||||||
'client_id' => 'Client ID',
|
'client_id' => 'Client ID',
|
||||||
'app_id' => 'App ID',
|
'app_id' => 'App ID',
|
||||||
'secret' => 'Secret',
|
'secret' => 'Secret',
|
||||||
'public_key' => 'Public key',
|
'public_key' => 'Public key',
|
||||||
'country_code' => 'Country code',
|
'country_code' => 'Country code',
|
||||||
'provider_code' => 'Bank or data-provider',
|
'provider_code' => 'Bank or data-provider',
|
||||||
'fints_url' => 'FinTS API URL',
|
'fints_url' => 'FinTS API URL',
|
||||||
'fints_port' => 'Port',
|
'fints_port' => 'Port',
|
||||||
'fints_bank_code' => 'Bank code',
|
'fints_bank_code' => 'Bank code',
|
||||||
'fints_username' => 'Username',
|
'fints_username' => 'Username',
|
||||||
'fints_password' => 'PIN / Password',
|
'fints_password' => 'PIN / Password',
|
||||||
'fints_account' => 'FinTS account',
|
'fints_account' => 'FinTS account',
|
||||||
'local_account' => 'Firefly III account',
|
'local_account' => 'Firefly III account',
|
||||||
|
|
||||||
// Ignore this comment
|
// Ignore this comment
|
||||||
|
|
||||||
'from_date' => 'Date from',
|
'from_date' => 'Date from',
|
||||||
'to_date' => 'Date to',
|
'to_date' => 'Date to',
|
||||||
'due_date' => 'Due date',
|
'due_date' => 'Due date',
|
||||||
'payment_date' => 'Payment date',
|
'payment_date' => 'Payment date',
|
||||||
'invoice_date' => 'Invoice date',
|
'invoice_date' => 'Invoice date',
|
||||||
'internal_reference' => 'Internal reference',
|
'internal_reference' => 'Internal reference',
|
||||||
'inward' => 'Inward description',
|
'inward' => 'Inward description',
|
||||||
'outward' => 'Outward description',
|
'outward' => 'Outward description',
|
||||||
'rule_group_id' => 'Rule group',
|
'rule_group_id' => 'Rule group',
|
||||||
'transaction_description' => 'Transaction description',
|
'transaction_description' => 'Transaction description',
|
||||||
'first_date' => 'First date',
|
'first_date' => 'First date',
|
||||||
'transaction_type' => 'Transaction type',
|
'transaction_type' => 'Transaction type',
|
||||||
'repeat_until' => 'Repeat until',
|
'repeat_until' => 'Repeat until',
|
||||||
'recurring_description' => 'Recurring transaction description',
|
'recurring_description' => 'Recurring transaction description',
|
||||||
'repetition_type' => 'Type of repetition',
|
'repetition_type' => 'Type of repetition',
|
||||||
'foreign_currency_id' => 'Foreign currency',
|
'foreign_currency_id' => 'Foreign currency',
|
||||||
'repetition_end' => 'Repetition ends',
|
'repetition_end' => 'Repetition ends',
|
||||||
'repetitions' => 'Repetitions',
|
'repetitions' => 'Repetitions',
|
||||||
'calendar' => 'Calendar',
|
'calendar' => 'Calendar',
|
||||||
'weekend' => 'Weekend',
|
'weekend' => 'Weekend',
|
||||||
'client_secret' => 'Client secret',
|
'client_secret' => 'Client secret',
|
||||||
'withdrawal_destination_id' => 'Destination account',
|
'withdrawal_destination_id' => 'Destination account',
|
||||||
'deposit_source_id' => 'Source account',
|
'deposit_source_id' => 'Source account',
|
||||||
'expected_on' => 'Expected on',
|
'expected_on' => 'Expected on',
|
||||||
'paid' => 'Paid',
|
'paid' => 'Paid',
|
||||||
'auto_budget_type' => 'Auto-budget',
|
'auto_budget_type' => 'Auto-budget',
|
||||||
'auto_budget_amount' => 'Auto-budget amount',
|
'auto_budget_amount' => 'Auto-budget amount',
|
||||||
'auto_budget_period' => 'Auto-budget period',
|
'auto_budget_period' => 'Auto-budget period',
|
||||||
'collected' => 'Collected',
|
'collected' => 'Collected',
|
||||||
'submitted' => 'Submitted',
|
'submitted' => 'Submitted',
|
||||||
'key' => 'Key',
|
'key' => 'Key',
|
||||||
'value' => 'Content of record',
|
'value' => 'Content of record',
|
||||||
'webhook_delivery' => 'Delivery',
|
'webhook_delivery' => 'Delivery',
|
||||||
'webhook_response' => 'Response',
|
'webhook_response' => 'Response',
|
||||||
'webhook_trigger' => 'Trigger',
|
'webhook_trigger' => 'Trigger',
|
||||||
'pushover_app_token' => 'Pushover app token',
|
'pushover_app_token' => 'Pushover app token',
|
||||||
'pushover_user_token' => 'Pushover user token',
|
'pushover_user_token' => 'Pushover user token',
|
||||||
'ntfy_server' => 'Ntfy server',
|
'ntfy_server' => 'Ntfy server',
|
||||||
'ntfy_topic' => 'Ntfy topic',
|
'ntfy_topic' => 'Ntfy topic',
|
||||||
'ntfy_auth' => 'Ntfy authentication enabled',
|
'ntfy_auth' => 'Ntfy authentication enabled',
|
||||||
'ntfy_user' => 'Ntfy username',
|
'ntfy_user' => 'Ntfy username',
|
||||||
'ntfy_pass' => 'Ntfy password',
|
'ntfy_pass' => 'Ntfy password',
|
||||||
];
|
];
|
||||||
// Ignore this comment
|
// Ignore this comment
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'invalid_account_type' => 'A piggy bank can only be linked to asset accounts and liabilities',
|
'invalid_account_type' => 'A piggy bank can only be linked to asset accounts and liabilities',
|
||||||
'invalid_account_currency' => 'This account does not use the currency you have selected',
|
'invalid_account_currency' => 'This account does not use the currency you have selected',
|
||||||
'current_amount_too_much' => 'The combined amount in "current_amount" cannot exceed the "target_amount".',
|
'current_amount_too_much' => 'The combined amount in "current_amount" cannot exceed the "target_amount".',
|
||||||
'filter_must_be_in' => 'Filter ":filter" must be one of: :values',
|
'filter_must_be_in' => 'Filter ":filter" must be one of: :values',
|
||||||
'filter_not_string' => 'Filter ":filter" is expected to be a string of text',
|
'filter_not_string' => 'Filter ":filter" is expected to be a string of text',
|
||||||
'bad_api_filter' => 'This API endpoint does not support ":filter" as a filter.',
|
'bad_api_filter' => 'This API endpoint does not support ":filter" as a filter.',
|
||||||
|
Loading…
Reference in New Issue
Block a user