mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-11-02 12:15:55 +00:00
🤖 Auto commit for release 'develop' on 2025-09-07
This commit is contained in:
@@ -200,18 +200,18 @@ class BudgetController extends Controller
|
||||
return $return;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * When no budget limits are present, the expenses of the whole period are collected and grouped.
|
||||
// * This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
|
||||
// *
|
||||
// * @throws FireflyException
|
||||
// */
|
||||
// private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array
|
||||
// {
|
||||
// $spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget]));
|
||||
//
|
||||
// return $this->processExpenses($budget->id, $spent, $start, $end);
|
||||
// }
|
||||
// /**
|
||||
// * When no budget limits are present, the expenses of the whole period are collected and grouped.
|
||||
// * This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
|
||||
// *
|
||||
// * @throws FireflyException
|
||||
// */
|
||||
// private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array
|
||||
// {
|
||||
// $spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget]));
|
||||
//
|
||||
// return $this->processExpenses($budget->id, $spent, $start, $end);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return
|
||||
@@ -257,59 +257,59 @@ class BudgetController extends Controller
|
||||
return $return;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Function that processes each budget limit (per budget).
|
||||
// *
|
||||
// * If you have a budget limit in EUR, only transactions in EUR will be considered.
|
||||
// * If you have a budget limit in GBP, only transactions in GBP will be considered.
|
||||
// *
|
||||
// * If you have a budget limit in EUR, and a transaction in GBP, it will not be considered for the EUR budget limit.
|
||||
// *
|
||||
// * @throws FireflyException
|
||||
// */
|
||||
// private function budgetLimits(Budget $budget, Collection $limits): array
|
||||
// {
|
||||
// Log::debug(sprintf('Now in budgetLimits(#%d)', $budget->id));
|
||||
// $data = [];
|
||||
//
|
||||
// /** @var BudgetLimit $limit */
|
||||
// foreach ($limits as $limit) {
|
||||
// $data = array_merge($data, $this->processLimit($budget, $limit));
|
||||
// }
|
||||
//
|
||||
// return $data;
|
||||
// }
|
||||
// /**
|
||||
// * Function that processes each budget limit (per budget).
|
||||
// *
|
||||
// * If you have a budget limit in EUR, only transactions in EUR will be considered.
|
||||
// * If you have a budget limit in GBP, only transactions in GBP will be considered.
|
||||
// *
|
||||
// * If you have a budget limit in EUR, and a transaction in GBP, it will not be considered for the EUR budget limit.
|
||||
// *
|
||||
// * @throws FireflyException
|
||||
// */
|
||||
// private function budgetLimits(Budget $budget, Collection $limits): array
|
||||
// {
|
||||
// Log::debug(sprintf('Now in budgetLimits(#%d)', $budget->id));
|
||||
// $data = [];
|
||||
//
|
||||
// /** @var BudgetLimit $limit */
|
||||
// foreach ($limits as $limit) {
|
||||
// $data = array_merge($data, $this->processLimit($budget, $limit));
|
||||
// }
|
||||
//
|
||||
// return $data;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @throws FireflyException
|
||||
// */
|
||||
// private function processLimit(Budget $budget, BudgetLimit $limit): array
|
||||
// {
|
||||
// Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
|
||||
// $end = clone $limit->end_date;
|
||||
// $end->endOfDay();
|
||||
// $spent = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget]));
|
||||
// $limitCurrencyId = $limit->transaction_currency_id;
|
||||
//
|
||||
// /** @var array $entry */
|
||||
// // only spent the entry where the entry's currency matches the budget limit's currency
|
||||
// // so $filtered will only have 1 or 0 entries
|
||||
// $filtered = array_filter($spent, fn ($entry) => $entry['currency_id'] === $limitCurrencyId);
|
||||
// $result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
|
||||
// if (1 === count($result)) {
|
||||
// $compare = bccomp($limit->amount, (string)app('steam')->positive($result[$limitCurrencyId]['spent']));
|
||||
// $result[$limitCurrencyId]['budgeted'] = $limit->amount;
|
||||
// if (1 === $compare) {
|
||||
// // convert this amount into the primary currency:
|
||||
// $result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']);
|
||||
// }
|
||||
// if ($compare <= 0) {
|
||||
// $result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return $result;
|
||||
// }
|
||||
// /**
|
||||
// * @throws FireflyException
|
||||
// */
|
||||
// private function processLimit(Budget $budget, BudgetLimit $limit): array
|
||||
// {
|
||||
// Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
|
||||
// $end = clone $limit->end_date;
|
||||
// $end->endOfDay();
|
||||
// $spent = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget]));
|
||||
// $limitCurrencyId = $limit->transaction_currency_id;
|
||||
//
|
||||
// /** @var array $entry */
|
||||
// // only spent the entry where the entry's currency matches the budget limit's currency
|
||||
// // so $filtered will only have 1 or 0 entries
|
||||
// $filtered = array_filter($spent, fn ($entry) => $entry['currency_id'] === $limitCurrencyId);
|
||||
// $result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
|
||||
// if (1 === count($result)) {
|
||||
// $compare = bccomp($limit->amount, (string)app('steam')->positive($result[$limitCurrencyId]['spent']));
|
||||
// $result[$limitCurrencyId]['budgeted'] = $limit->amount;
|
||||
// if (1 === $compare) {
|
||||
// // convert this amount into the primary currency:
|
||||
// $result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']);
|
||||
// }
|
||||
// if ($compare <= 0) {
|
||||
// $result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return $result;
|
||||
// }
|
||||
|
||||
private function filterLimit(int $currencyId, Collection $limits): ?BudgetLimit
|
||||
{
|
||||
|
||||
@@ -147,7 +147,7 @@ abstract class Controller extends BaseController
|
||||
}
|
||||
if (null !== $value) {
|
||||
$value = (int)$value;
|
||||
$value = min(max(1, $value), 2 ** 16);
|
||||
$value = min(max(1, $value), 2 ** 16);
|
||||
$bag->set($integer, $value);
|
||||
}
|
||||
if (null === $value
|
||||
@@ -165,7 +165,7 @@ abstract class Controller extends BaseController
|
||||
|
||||
// sort fields:
|
||||
return $bag;
|
||||
//return $this->getSortParameters($bag);
|
||||
// return $this->getSortParameters($bag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@ use Illuminate\Http\JsonResponse;
|
||||
/**
|
||||
* Class TagController
|
||||
*/
|
||||
class TagController extends Controller
|
||||
class TagController extends Controller
|
||||
{
|
||||
private TagRepositoryInterface $repository;
|
||||
|
||||
|
||||
@@ -114,8 +114,8 @@ class ShowController extends Controller
|
||||
public function show(AvailableBudget $availableBudget): JsonResponse
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
// $start = $this->parameters->get('start');
|
||||
// $end = $this->parameters->get('end');
|
||||
// $start = $this->parameters->get('start');
|
||||
// $end = $this->parameters->get('end');
|
||||
|
||||
/** @var AvailableBudgetTransformer $transformer */
|
||||
$transformer = app(AvailableBudgetTransformer::class);
|
||||
@@ -126,8 +126,8 @@ class ShowController extends Controller
|
||||
$admin = auth()->user();
|
||||
$enrichment = new AvailableBudgetEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
// $enrichment->setStart($start);
|
||||
// $enrichment->setEnd($end);
|
||||
// $enrichment->setStart($start);
|
||||
// $enrichment->setEnd($end);
|
||||
$availableBudget = $enrichment->enrichSingle($availableBudget);
|
||||
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ class ShowController extends Controller
|
||||
$enrichment->setUser($admin);
|
||||
$enrichment->setStart($this->parameters->get('start'));
|
||||
$enrichment->setEnd($this->parameters->get('end'));
|
||||
|
||||
/** @var Budget $budget */
|
||||
$budget = $enrichment->enrichSingle($budget);
|
||||
|
||||
|
||||
@@ -30,9 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\RecurrenceTransaction;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
|
||||
@@ -156,7 +156,7 @@ class ConfigurationController extends Controller
|
||||
}
|
||||
|
||||
// fallback
|
||||
$data = [
|
||||
$data = [
|
||||
'title' => $configKey,
|
||||
'value' => config($shortKey),
|
||||
'editable' => false,
|
||||
@@ -176,7 +176,7 @@ class ConfigurationController extends Controller
|
||||
*/
|
||||
public function update(UpdateRequest $request, string $name): JsonResponse
|
||||
{
|
||||
$rules = ['value' => 'required'];
|
||||
$rules = ['value' => 'required'];
|
||||
if (!$this->repository->hasRole(auth()->user(), 'owner')) {
|
||||
$messages = ['value' => '200005: You need the "owner" role to do this.'];
|
||||
Validator::make([], $rules, $messages)->validate();
|
||||
|
||||
@@ -77,6 +77,7 @@ class UpdateController extends Controller
|
||||
$admin = auth()->user();
|
||||
$enrichment = new WebhookEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
|
||||
/** @var Webhook $webhook */
|
||||
$webhook = $enrichment->enrichSingle($webhook);
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ namespace FireflyIII\Api\V1\Requests\Models\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Rules\IsValidSortInstruction;
|
||||
use FireflyIII\Support\Facades\Preferences;
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
@@ -55,7 +54,7 @@ class ShowRequest extends FormRequest
|
||||
return [
|
||||
'type' => $this->convertString('type', 'all'),
|
||||
'limit' => $limit,
|
||||
'sort' => $this->convertSortParameters('sort',Account::class),
|
||||
'sort' => $this->convertSortParameters('sort', Account::class),
|
||||
'page' => $page,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -302,10 +302,10 @@ class CorrectsUnevenAmount extends Command
|
||||
|
||||
private function isBetweenAssetAndLiability(TransactionJournal $journal): bool
|
||||
{
|
||||
/** @var Transaction|null $sourceTransaction */
|
||||
/** @var null|Transaction $sourceTransaction */
|
||||
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
|
||||
/** @var Transaction|null $destinationTransaction */
|
||||
/** @var null|Transaction $destinationTransaction */
|
||||
$destinationTransaction = $journal->transactions()->where('amount', '>', 0)->first();
|
||||
if (null === $sourceTransaction || null === $destinationTransaction) {
|
||||
Log::warning('Either transaction is false, stop.');
|
||||
|
||||
@@ -60,6 +60,7 @@ class RecalculatesRunningBalance extends Command
|
||||
return 0;
|
||||
}
|
||||
$this->friendlyWarning('This command has been disabled.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,12 +25,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use function Safe\file_put_contents;
|
||||
use function Safe\json_encode;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Console\Command\Command as CommandAlias;
|
||||
|
||||
use function Safe\file_put_contents;
|
||||
use function Safe\json_encode;
|
||||
|
||||
class ResetsErrorMailLimit extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -37,7 +37,7 @@ class ActuallyLoggedIn extends Event
|
||||
|
||||
public User $user;
|
||||
|
||||
public function __construct(null|Authenticatable|User $user)
|
||||
public function __construct(Authenticatable|User|null $user)
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
||||
@@ -35,7 +35,7 @@ class DisabledMFA extends Event
|
||||
|
||||
public User $user;
|
||||
|
||||
public function __construct(null|Authenticatable|User $user)
|
||||
public function __construct(Authenticatable|User|null $user)
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
||||
@@ -35,7 +35,7 @@ class EnabledMFA extends Event
|
||||
|
||||
public User $user;
|
||||
|
||||
public function __construct(null|Authenticatable|User $user)
|
||||
public function __construct(Authenticatable|User|null $user)
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
||||
@@ -35,7 +35,7 @@ class MFABackupFewLeft extends Event
|
||||
|
||||
public User $user;
|
||||
|
||||
public function __construct(null|Authenticatable|User $user, public int $count)
|
||||
public function __construct(Authenticatable|User|null $user, public int $count)
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
||||
@@ -35,7 +35,7 @@ class MFABackupNoLeft extends Event
|
||||
|
||||
public User $user;
|
||||
|
||||
public function __construct(null|Authenticatable|User $user)
|
||||
public function __construct(Authenticatable|User|null $user)
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
||||
@@ -35,7 +35,7 @@ class MFAManyFailedAttempts extends Event
|
||||
|
||||
public User $user;
|
||||
|
||||
public function __construct(null|Authenticatable|User $user, public int $count)
|
||||
public function __construct(Authenticatable|User|null $user, public int $count)
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
||||
@@ -35,7 +35,7 @@ class MFANewBackupCodes extends Event
|
||||
|
||||
public User $user;
|
||||
|
||||
public function __construct(null|Authenticatable|User $user)
|
||||
public function __construct(Authenticatable|User|null $user)
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
||||
@@ -35,7 +35,7 @@ class MFAUsedBackupCode extends Event
|
||||
|
||||
public User $user;
|
||||
|
||||
public function __construct(null|Authenticatable|User $user)
|
||||
public function __construct(Authenticatable|User|null $user)
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
||||
@@ -35,7 +35,7 @@ class UserAttemptedLogin extends Event
|
||||
|
||||
public User $user;
|
||||
|
||||
public function __construct(null|Authenticatable|User $user)
|
||||
public function __construct(Authenticatable|User|null $user)
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
||||
@@ -184,6 +184,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
if ($model instanceof Budget) {
|
||||
$enrichment = new BudgetEnrichment();
|
||||
$enrichment->setUser($model->user);
|
||||
|
||||
/** @var Budget $model */
|
||||
$model = $enrichment->enrichSingle($model);
|
||||
$transformer = new BudgetTransformer();
|
||||
@@ -197,6 +198,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
$parameters = new ParameterBag();
|
||||
$parameters->set('start', $model->start_date);
|
||||
$parameters->set('end', $model->end_date);
|
||||
|
||||
/** @var BudgetLimit $model */
|
||||
$model = $enrichment->enrichSingle($model);
|
||||
$transformer = new BudgetLimitTransformer();
|
||||
|
||||
@@ -140,10 +140,10 @@ class AdminEventHandler
|
||||
|
||||
break;
|
||||
|
||||
// case 'ntfy':
|
||||
// $class = OwnerTestNotificationNtfy::class;
|
||||
//
|
||||
// break;
|
||||
// case 'ntfy':
|
||||
// $class = OwnerTestNotificationNtfy::class;
|
||||
//
|
||||
// break;
|
||||
|
||||
case 'pushover':
|
||||
$class = OwnerTestNotificationPushover::class;
|
||||
|
||||
@@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use function Safe\json_encode;
|
||||
use Exception;
|
||||
use FireflyIII\Events\Model\Bill\WarnUserAboutBill;
|
||||
use FireflyIII\Events\Model\Bill\WarnUserAboutOverdueSubscriptions;
|
||||
@@ -35,6 +34,8 @@ use FireflyIII\Support\Facades\Preferences;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
||||
use function Safe\json_encode;
|
||||
|
||||
/**
|
||||
* Class BillEventHandler
|
||||
*/
|
||||
|
||||
@@ -411,10 +411,10 @@ class UserEventHandler
|
||||
|
||||
break;
|
||||
|
||||
// case 'ntfy':
|
||||
// $class = UserTestNotificationNtfy::class;
|
||||
//
|
||||
// break;
|
||||
// case 'ntfy':
|
||||
// $class = UserTestNotificationNtfy::class;
|
||||
//
|
||||
// break;
|
||||
|
||||
case 'pushover':
|
||||
$class = UserTestNotificationPushover::class;
|
||||
|
||||
@@ -128,6 +128,7 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
public function saveAttachmentFromApi(Attachment $attachment, string $content): bool
|
||||
{
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
|
||||
try {
|
||||
$resource = tmpfile();
|
||||
} catch (FilesystemException $e) {
|
||||
@@ -144,6 +145,7 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
|
||||
$path = stream_get_meta_data($resource)['uri'];
|
||||
Log::debug(sprintf('Path is %s', $path));
|
||||
|
||||
try {
|
||||
$result = fwrite($resource, $content);
|
||||
} catch (FilesystemException $e) {
|
||||
@@ -152,6 +154,7 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
return false;
|
||||
}
|
||||
Log::debug(sprintf('Wrote %d bytes to temp file.', $result));
|
||||
|
||||
try {
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
} catch (FileinfoException $e) {
|
||||
@@ -175,7 +178,7 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
$this->uploadDisk->put($file, $content);
|
||||
|
||||
// update attachment.
|
||||
$attachment->md5 = md5_file($path);
|
||||
$attachment->md5 = md5_file($path);
|
||||
$attachment->mime = $mime;
|
||||
$attachment->size = strlen($content);
|
||||
$attachment->uploaded = true;
|
||||
@@ -237,7 +240,7 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
$attachment = new Attachment(); // create Attachment object.
|
||||
$attachment->user()->associate($user);
|
||||
$attachment->attachable()->associate($model);
|
||||
$attachment->md5 = md5_file($file->getRealPath());
|
||||
$attachment->md5 = md5_file($file->getRealPath());
|
||||
$attachment->filename = $file->getClientOriginalName();
|
||||
$attachment->mime = $file->getMimeType();
|
||||
$attachment->size = $file->getSize();
|
||||
|
||||
@@ -116,7 +116,7 @@ class NetWorth implements NetWorthInterface
|
||||
return $netWorth;
|
||||
}
|
||||
|
||||
public function setUser(null|Authenticatable|User $user): void
|
||||
public function setUser(Authenticatable|User|null $user): void
|
||||
{
|
||||
if (!$user instanceof User) {
|
||||
return;
|
||||
|
||||
@@ -46,7 +46,7 @@ interface NetWorthInterface
|
||||
*/
|
||||
public function byAccounts(Collection $accounts, Carbon $date): array;
|
||||
|
||||
public function setUser(null|Authenticatable|User $user): void;
|
||||
public function setUser(Authenticatable|User|null $user): void;
|
||||
|
||||
public function setUserGroup(UserGroup $userGroup): void;
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class NotificationController extends Controller
|
||||
}
|
||||
$forcedAvailability['ntfy'] = '' !== $ntfyTopic;
|
||||
$forcedAvailability['pushover'] = '' !== $pushoverAppToken && '' !== $pushoverUserToken;
|
||||
$forcedAvailability['slack'] = '' !== $slackUrl;
|
||||
$forcedAvailability['slack'] = '' !== $slackUrl;
|
||||
|
||||
return view(
|
||||
'settings.notifications.index',
|
||||
|
||||
@@ -33,8 +33,8 @@ use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
|
||||
use Safe\Exceptions\UrlException;
|
||||
|
||||
use function Safe\parse_url;
|
||||
|
||||
/**
|
||||
@@ -107,12 +107,12 @@ class ForgotPasswordController extends Controller
|
||||
try {
|
||||
$configuredHost = parse_url((string)config('app.url'), PHP_URL_HOST);
|
||||
} catch (UrlException $e) {
|
||||
throw new FireflyException('Please set a valid and correct Firefly III URL in the APP_URL environment variable.',0, $e);
|
||||
throw new FireflyException('Please set a valid and correct Firefly III URL in the APP_URL environment variable.', 0, $e);
|
||||
}
|
||||
if (!is_string( $configuredHost)) {
|
||||
if (!is_string($configuredHost)) {
|
||||
throw new FireflyException('Please set a valid and correct Firefly III URL in the APP_URL environment variable.');
|
||||
}
|
||||
$host = request()->host();
|
||||
$host = request()->host();
|
||||
if ($configuredHost !== $host) {
|
||||
Log::error(sprintf('Host header is "%s", APP_URL is "%s".', $host, $configuredHost));
|
||||
|
||||
|
||||
@@ -69,14 +69,14 @@ class CreateController extends Controller
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
$periods = [];
|
||||
$periods = [];
|
||||
|
||||
/** @var array $billPeriods */
|
||||
$billPeriods = config('firefly.bill_periods');
|
||||
$billPeriods = config('firefly.bill_periods');
|
||||
foreach ($billPeriods as $current) {
|
||||
$periods[$current] = (string) trans('firefly.repeat_freq_'.$current);
|
||||
}
|
||||
$subTitle = (string) trans('firefly.create_new_bill');
|
||||
$subTitle = (string) trans('firefly.create_new_bill');
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (true !== session('bills.create.fromStore')) {
|
||||
|
||||
@@ -117,7 +117,7 @@ class BudgetReportController extends Controller
|
||||
];
|
||||
|
||||
$amount = Steam::positive($journal['amount']);
|
||||
$result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
|
||||
$result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,7 +147,7 @@ class BudgetReportController extends Controller
|
||||
];
|
||||
|
||||
$amount = Steam::positive($journal['amount']);
|
||||
$result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
|
||||
$result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,7 +235,7 @@ class BudgetReportController extends Controller
|
||||
];
|
||||
|
||||
$amount = Steam::positive($journal['amount']);
|
||||
$result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
|
||||
$result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,8 +95,8 @@ abstract class Controller extends BaseController
|
||||
View::share('logoutUrl', $logoutUrl);
|
||||
|
||||
// upload size
|
||||
$maxFileSize = Steam::phpBytes( ini_get('upload_max_filesize'));
|
||||
$maxPostSize = Steam::phpBytes( ini_get('post_max_size'));
|
||||
$maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize'));
|
||||
$maxPostSize = Steam::phpBytes(ini_get('post_max_size'));
|
||||
$uploadSize = min($maxFileSize, $maxPostSize);
|
||||
View::share('uploadSize', $uploadSize);
|
||||
|
||||
|
||||
@@ -175,8 +175,8 @@ class DebugController extends Controller
|
||||
|
||||
private function getSystemInformation(): array
|
||||
{
|
||||
$maxFileSize = Steam::phpBytes( ini_get('upload_max_filesize'));
|
||||
$maxPostSize = Steam::phpBytes( ini_get('post_max_size'));
|
||||
$maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize'));
|
||||
$maxPostSize = Steam::phpBytes(ini_get('post_max_size'));
|
||||
$drivers = DB::availableDrivers();
|
||||
$currentDriver = DB::getDriverName();
|
||||
|
||||
@@ -208,7 +208,7 @@ class DebugController extends Controller
|
||||
|
||||
try {
|
||||
if (file_exists('/var/www/counter-main.txt')) {
|
||||
$return['build'] = trim( file_get_contents('/var/www/counter-main.txt'));
|
||||
$return['build'] = trim(file_get_contents('/var/www/counter-main.txt'));
|
||||
app('log')->debug(sprintf('build is now "%s"', $return['build']));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
@@ -218,7 +218,7 @@ class DebugController extends Controller
|
||||
|
||||
try {
|
||||
if (file_exists('/var/www/build-date-main.txt')) {
|
||||
$return['build_date'] = trim( file_get_contents('/var/www/build-date-main.txt'));
|
||||
$return['build_date'] = trim(file_get_contents('/var/www/build-date-main.txt'));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
app('log')->debug('Could not check build date, but thats ok.');
|
||||
|
||||
@@ -82,6 +82,7 @@ class ShowController extends Controller
|
||||
$admin = auth()->user();
|
||||
$enrichment = new PiggyBankEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
|
||||
/** @var PiggyBank $piggyBank */
|
||||
$piggyBank = $enrichment->enrichSingle($piggyBank);
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ class CreateController extends Controller
|
||||
app('view')->share('title', (string) trans('firefly.recurrences'));
|
||||
app('view')->share('subTitle', (string) trans('firefly.create_new_recurrence'));
|
||||
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->budgetRepos = app(BudgetRepositoryInterface::class);
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->budgetRepos = app(BudgetRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->billRepository = app(BillRepositoryInterface::class);
|
||||
|
||||
@@ -115,7 +115,7 @@ class CreateController extends Controller
|
||||
|
||||
return view(
|
||||
'recurring.create',
|
||||
compact('tomorrow', 'oldRepetitionType', 'bills', 'weekendResponses', 'preFilled', 'repetitionEnds', 'budgets')
|
||||
compact('tomorrow', 'oldRepetitionType', 'bills', 'weekendResponses', 'preFilled', 'repetitionEnds', 'budgets')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,8 +70,8 @@ class EditController extends Controller
|
||||
app('view')->share('title', (string) trans('firefly.recurrences'));
|
||||
app('view')->share('subTitle', (string) trans('firefly.recurrences'));
|
||||
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->budgetRepos = app(BudgetRepositoryInterface::class);
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->budgetRepos = app(BudgetRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->billRepository = app(BillRepositoryInterface::class);
|
||||
|
||||
@@ -100,6 +100,7 @@ class EditController extends Controller
|
||||
$admin = auth()->user();
|
||||
$enrichment = new RecurringEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
|
||||
/** @var Recurrence $recurrence */
|
||||
$recurrence = $enrichment->enrichSingle($recurrence);
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ class ShowController extends Controller
|
||||
$admin = auth()->user();
|
||||
$enrichment = new RecurringEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
|
||||
/** @var Recurrence $recurrence */
|
||||
$recurrence = $enrichment->enrichSingle($recurrence);
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ class TriggerController extends Controller
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function trigger(Recurrence $recurrence, TriggerRecurrenceRequest $request): RedirectResponse
|
||||
{
|
||||
$all = $request->getAll();
|
||||
|
||||
@@ -338,7 +338,7 @@ class ConvertController extends Controller
|
||||
'type' => $transactionType->type,
|
||||
];
|
||||
|
||||
/** @var Transaction|null $sourceTransaction */
|
||||
/** @var null|Transaction $sourceTransaction */
|
||||
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
$amount = $sourceTransaction->amount ?? '0';
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ class ShowController extends Controller
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($admin)->setTransactionGroup($transactionGroup)->withAPIInformation();
|
||||
|
||||
/** @var TransactionGroup|null $selectedGroup */
|
||||
/** @var null|TransactionGroup $selectedGroup */
|
||||
$selectedGroup = $collector->getGroups()->first();
|
||||
if (null === $selectedGroup) {
|
||||
throw new NotFoundHttpException();
|
||||
@@ -119,6 +119,7 @@ class ShowController extends Controller
|
||||
// enrich
|
||||
$enrichment = new TransactionGroupEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
|
||||
/** @var array $selectedGroup */
|
||||
$selectedGroup = $enrichment->enrichSingle($selectedGroup);
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
||||
|
||||
@@ -129,7 +129,7 @@ class MailError extends Job implements ShouldQueue
|
||||
}
|
||||
if (file_exists($file)) {
|
||||
Log::debug(sprintf('Read file in "%s"', $file));
|
||||
$limits = json_decode( file_get_contents($file), true);
|
||||
$limits = json_decode(file_get_contents($file), true);
|
||||
}
|
||||
// limit reached?
|
||||
foreach ($types as $type => $info) {
|
||||
|
||||
@@ -171,6 +171,7 @@ class WarnAboutBills implements ShouldQueue
|
||||
$enrichment->setUser($bill->user);
|
||||
$enrichment->setStart($start);
|
||||
$enrichment->setEnd($end);
|
||||
|
||||
/** @var Bill $single */
|
||||
$single = $enrichment->enrichSingle($bill);
|
||||
|
||||
|
||||
@@ -45,9 +45,9 @@ class InvitationMail extends Mailable
|
||||
*/
|
||||
public function __construct(public string $invitee, public string $admin, public string $url)
|
||||
{
|
||||
$host = parse_url($this->url, PHP_URL_HOST);
|
||||
if(is_array($host)) {
|
||||
$host ='';
|
||||
$host = parse_url($this->url, PHP_URL_HOST);
|
||||
if (is_array($host)) {
|
||||
$host = '';
|
||||
}
|
||||
$this->host = (string) $host;
|
||||
}
|
||||
|
||||
@@ -68,21 +68,21 @@ class UnknownUserLoginAttempt extends Notification
|
||||
;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
// */
|
||||
//
|
||||
// public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
// $message = new Message();
|
||||
// $ip = Request::ip();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.unknown_user_subject'));
|
||||
// $message->body((string) trans('email.unknown_user_message', ['address' => $this->address, 'ip' => $ip]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// /**
|
||||
// * @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
// */
|
||||
//
|
||||
// public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
// $message = new Message();
|
||||
// $ip = Request::ip();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.unknown_user_subject'));
|
||||
// $message->body((string) trans('email.unknown_user_message', ['address' => $this->address, 'ip' => $ip]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -73,20 +73,20 @@ class UserInvitation extends Notification
|
||||
;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
// */
|
||||
// public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||
// {
|
||||
// Log::debug('Now in toNtfy() for UserInvitation');
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $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]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// /**
|
||||
// * @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
// */
|
||||
// public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||
// {
|
||||
// Log::debug('Now in toNtfy() for UserInvitation');
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $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]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -72,20 +72,20 @@ class UserRegistration extends Notification
|
||||
;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
// */
|
||||
// public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||
// {
|
||||
// Log::debug('Now in toNtfy() for (Admin) UserRegistration');
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $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]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// /**
|
||||
// * @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
// */
|
||||
// public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||
// {
|
||||
// Log::debug('Now in toNtfy() for (Admin) UserRegistration');
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $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]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -64,20 +64,20 @@ class VersionCheckResult extends Notification
|
||||
;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
// */
|
||||
// public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||
// {
|
||||
// Log::debug('Now in toNtfy() for VersionCheckResult');
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.new_version_email_subject'));
|
||||
// $message->body($this->message);
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// /**
|
||||
// * @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
// */
|
||||
// public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||
// {
|
||||
// Log::debug('Now in toNtfy() for VersionCheckResult');
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.new_version_email_subject'));
|
||||
// $message->body($this->message);
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -28,7 +28,8 @@ use FireflyIII\Support\Notifications\UrlValidator;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use NotificationChannels\Pushover\PushoverChannel;
|
||||
//use Wijourdil\NtfyNotificationChannel\Channels\NtfyChannel;
|
||||
|
||||
// use Wijourdil\NtfyNotificationChannel\Channels\NtfyChannel;
|
||||
|
||||
class ReturnsAvailableChannels
|
||||
{
|
||||
@@ -58,16 +59,16 @@ class ReturnsAvailableChannels
|
||||
}
|
||||
}
|
||||
|
||||
// if (true === config('notifications.channels.ntfy.enabled', false)) {
|
||||
// // validate presence of of Ntfy settings.
|
||||
// if ('' !== (string) app('fireflyconfig')->getEncrypted('ntfy_topic', '')->data) {
|
||||
// Log::debug('Enabled ntfy.');
|
||||
// $channels[] = NtfyChannel::class;
|
||||
// }
|
||||
// if ('' === (string) app('fireflyconfig')->getEncrypted('ntfy_topic', '')->data) {
|
||||
// Log::warning('No topic name for Ntfy, channel is disabled.');
|
||||
// }
|
||||
// }
|
||||
// if (true === config('notifications.channels.ntfy.enabled', false)) {
|
||||
// // validate presence of of Ntfy settings.
|
||||
// if ('' !== (string) app('fireflyconfig')->getEncrypted('ntfy_topic', '')->data) {
|
||||
// Log::debug('Enabled ntfy.');
|
||||
// $channels[] = NtfyChannel::class;
|
||||
// }
|
||||
// if ('' === (string) app('fireflyconfig')->getEncrypted('ntfy_topic', '')->data) {
|
||||
// Log::warning('No topic name for Ntfy, channel is disabled.');
|
||||
// }
|
||||
// }
|
||||
|
||||
// pushover
|
||||
if (true === config('notifications.channels.pushover.enabled', false)) {
|
||||
@@ -99,17 +100,17 @@ class ReturnsAvailableChannels
|
||||
}
|
||||
}
|
||||
|
||||
// // validate presence of of Ntfy settings.
|
||||
// if (true === config('notifications.channels.nfy.enabled', false)) {
|
||||
// $ntfyTopic = (string) app('preferences')->getEncryptedForUser($user, 'ntfy_topic', '')->data;
|
||||
// if ('' !== $ntfyTopic) {
|
||||
// Log::debug(sprintf('Enabled ntfy, "%s"', $ntfyTopic));
|
||||
// $channels[] = NtfyChannel::class;
|
||||
// }
|
||||
// if ('' === (string) app('preferences')->getEncryptedForUser($user, 'ntfy_topic', '')->data) {
|
||||
// Log::warning('No topic name for Ntfy, channel is disabled.');
|
||||
// }
|
||||
// }
|
||||
// // validate presence of of Ntfy settings.
|
||||
// if (true === config('notifications.channels.nfy.enabled', false)) {
|
||||
// $ntfyTopic = (string) app('preferences')->getEncryptedForUser($user, 'ntfy_topic', '')->data;
|
||||
// if ('' !== $ntfyTopic) {
|
||||
// Log::debug(sprintf('Enabled ntfy, "%s"', $ntfyTopic));
|
||||
// $channels[] = NtfyChannel::class;
|
||||
// }
|
||||
// if ('' === (string) app('preferences')->getEncryptedForUser($user, 'ntfy_topic', '')->data) {
|
||||
// Log::warning('No topic name for Ntfy, channel is disabled.');
|
||||
// }
|
||||
// }
|
||||
|
||||
// pushover
|
||||
if (true === config('notifications.channels.slack.enabled', false)) {
|
||||
|
||||
@@ -65,16 +65,16 @@ class DisabledMFANotification extends Notification
|
||||
return new MailMessage()->markdown('emails.security.disabled-mfa', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.disabled_mfa_subject'));
|
||||
// $message->body((string) trans('email.disabled_mfa_slack', ['email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.disabled_mfa_subject'));
|
||||
// $message->body((string) trans('email.disabled_mfa_slack', ['email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -65,16 +65,16 @@ class EnabledMFANotification extends Notification
|
||||
return new MailMessage()->markdown('emails.security.enabled-mfa', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.enabled_mfa_subject'));
|
||||
// $message->body((string) trans('email.enabled_mfa_slack', ['email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.enabled_mfa_subject'));
|
||||
// $message->body((string) trans('email.enabled_mfa_slack', ['email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -65,16 +65,16 @@ class MFABackupFewLeftNotification extends Notification
|
||||
return new MailMessage()->markdown('emails.security.few-backup-codes', ['user' => $this->user, 'count' => $this->count, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.mfa_few_backups_left_subject'));
|
||||
// $message->body((string) trans('email.mfa_few_backups_left_slack', ['email' => $this->user->email, 'count' => $this->count]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.mfa_few_backups_left_subject'));
|
||||
// $message->body((string) trans('email.mfa_few_backups_left_slack', ['email' => $this->user->email, 'count' => $this->count]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -65,16 +65,16 @@ class MFABackupNoLeftNotification extends Notification
|
||||
return new MailMessage()->markdown('emails.security.no-backup-codes', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.mfa_no_backups_left_subject'));
|
||||
// $message->body((string) trans('email.mfa_no_backups_left_slack', ['email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.mfa_no_backups_left_subject'));
|
||||
// $message->body((string) trans('email.mfa_no_backups_left_slack', ['email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -62,16 +62,16 @@ class MFAManyFailedAttemptsNotification extends Notification
|
||||
return new MailMessage()->markdown('emails.security.many-failed-attempts', ['user' => $this->user, 'count' => $this->count, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.mfa_many_failed_subject'));
|
||||
// $message->body((string) trans('email.mfa_many_failed_slack', ['email' => $this->user->email, 'count' => $this->count]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.mfa_many_failed_subject'));
|
||||
// $message->body((string) trans('email.mfa_many_failed_slack', ['email' => $this->user->email, 'count' => $this->count]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -65,16 +65,16 @@ class MFAUsedBackupCodeNotification extends Notification
|
||||
return new MailMessage()->markdown('emails.security.used-backup-code', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.used_backup_code_subject'));
|
||||
// $message->body((string) trans('email.used_backup_code_slack', ['email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.used_backup_code_subject'));
|
||||
// $message->body((string) trans('email.used_backup_code_slack', ['email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -65,16 +65,16 @@ class NewBackupCodesNotification extends Notification
|
||||
return new MailMessage()->markdown('emails.security.new-backup-codes', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.new_backup_codes_subject'));
|
||||
// $message->body((string) trans('email.new_backup_codes_slack', ['email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.new_backup_codes_subject'));
|
||||
// $message->body((string) trans('email.new_backup_codes_slack', ['email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -63,17 +63,17 @@ class UserFailedLoginAttempt extends Notification
|
||||
return new MailMessage()->markdown('emails.security.failed-login', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $ip = Request::ip();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.failed_login_subject'));
|
||||
// $message->body((string) trans('email.failed_login_message', ['ip' => $ip, 'email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $ip = Request::ip();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.failed_login_subject'));
|
||||
// $message->body((string) trans('email.failed_login_message', ['ip' => $ip, 'email' => $this->user->email]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -49,20 +49,20 @@ class OwnerTestNotificationNtfy extends Notification
|
||||
];
|
||||
}
|
||||
|
||||
// public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.admin_test_subject'));
|
||||
// $message->body((string) trans('email.admin_test_message', ['channel' => 'ntfy']));
|
||||
// $message->tags(['white_check_mark']);
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(OwnerNotifiable $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.admin_test_subject'));
|
||||
// $message->body((string) trans('email.admin_test_message', ['channel' => 'ntfy']));
|
||||
// $message->tags(['white_check_mark']);
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
// public function via(OwnerNotifiable $notifiable): array
|
||||
// {
|
||||
// return [NtfyChannel::class];
|
||||
// }
|
||||
// public function via(OwnerNotifiable $notifiable): array
|
||||
// {
|
||||
// return [NtfyChannel::class];
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -49,20 +49,20 @@ class UserTestNotificationNtfy extends Notification
|
||||
];
|
||||
}
|
||||
|
||||
// public function toNtfy(User $user): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $user);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.admin_test_subject'));
|
||||
// $message->body((string) trans('email.admin_test_message', ['channel' => 'ntfy']));
|
||||
// $message->tags(['white_check_mark']);
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $user): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $user);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.admin_test_subject'));
|
||||
// $message->body((string) trans('email.admin_test_message', ['channel' => 'ntfy']));
|
||||
// $message->tags(['white_check_mark']);
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
// public function via(User $user): array
|
||||
// {
|
||||
// return [NtfyChannel::class];
|
||||
// }
|
||||
// public function via(User $user): array
|
||||
// {
|
||||
// return [NtfyChannel::class];
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -73,16 +73,16 @@ class BillReminder extends Notification
|
||||
return (string) trans(sprintf('email.bill_warning_subject_%s', $this->field), ['diff' => $this->diff, 'name' => $this->bill->name]);
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title($this->getSubject());
|
||||
// $message->body((string) trans('email.bill_warning_please_action'));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title($this->getSubject());
|
||||
// $message->body((string) trans('email.bill_warning_please_action'));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -68,16 +68,16 @@ class NewAccessToken extends Notification
|
||||
;
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.access_token_created_subject'));
|
||||
// $message->body((string) trans('email.access_token_created_body'));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.access_token_created_subject'));
|
||||
// $message->body((string) trans('email.access_token_created_body'));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -65,15 +65,15 @@ class RuleActionFailed extends Notification
|
||||
];
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->body($this->message);
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->body($this->message);
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -65,18 +65,18 @@ class UserLogin extends Notification
|
||||
;
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $ip = Request::ip();
|
||||
// $host = Steam::getHostName($ip);
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.login_from_new_ip'));
|
||||
// $message->body((string) trans('email.slack_login_from_new_ip', ['ip' => $ip, 'host' => $host]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $ip = Request::ip();
|
||||
// $host = Steam::getHostName($ip);
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->title((string) trans('email.login_from_new_ip'));
|
||||
// $message->body((string) trans('email.slack_login_from_new_ip', ['ip' => $ip, 'host' => $host]));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -70,15 +70,15 @@ class UserNewPassword extends Notification
|
||||
;
|
||||
}
|
||||
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->body((string) trans('email.reset_pw_message'));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
// public function toNtfy(User $notifiable): Message
|
||||
// {
|
||||
// $settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
// $message = new Message();
|
||||
// $message->topic($settings['ntfy_topic']);
|
||||
// $message->body((string) trans('email.reset_pw_message'));
|
||||
//
|
||||
// return $message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
|
||||
@@ -478,18 +478,18 @@ class AccountRepository implements AccountRepositoryInterface, UserGroupInterfac
|
||||
|
||||
public function getAccountsByType(array $types, ?array $sort = []): Collection
|
||||
{
|
||||
$res = array_intersect([AccountTypeEnum::ASSET->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value], $types);
|
||||
$query = $this->user->accounts();
|
||||
$res = array_intersect([AccountTypeEnum::ASSET->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value], $types);
|
||||
$query = $this->user->accounts();
|
||||
if (0 !== count($types)) {
|
||||
$query->accountTypeIn($types);
|
||||
}
|
||||
|
||||
// add sort parameters
|
||||
$allowed = config('firefly.allowed_db_sort_parameters.Account', []);
|
||||
$sorted = 0;
|
||||
$sorted = 0;
|
||||
if (0 !== count($sort)) {
|
||||
foreach ($sort as $param) {
|
||||
if(in_array($param[0], $allowed, true)) {
|
||||
if (in_array($param[0], $allowed, true)) {
|
||||
$query->orderBy($param[0], $param[1]);
|
||||
++$sorted;
|
||||
}
|
||||
|
||||
@@ -115,12 +115,13 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface, UserGroupInterf
|
||||
public function getJournalLinks(?LinkType $linkType = null): Collection
|
||||
{
|
||||
$query = TransactionJournalLink::with(['source', 'destination'])
|
||||
->leftJoin('transaction_journals as source_journals', 'journal_links.source_id', '=', 'source_journals.id')
|
||||
->leftJoin('transaction_journals as dest_journals', 'journal_links.destination_id', '=', 'dest_journals.id')
|
||||
->where('source_journals.user_id', $this->user->id)
|
||||
->where('dest_journals.user_id', $this->user->id)
|
||||
->whereNull('source_journals.deleted_at')
|
||||
->whereNull('dest_journals.deleted_at');
|
||||
->leftJoin('transaction_journals as source_journals', 'journal_links.source_id', '=', 'source_journals.id')
|
||||
->leftJoin('transaction_journals as dest_journals', 'journal_links.destination_id', '=', 'dest_journals.id')
|
||||
->where('source_journals.user_id', $this->user->id)
|
||||
->where('dest_journals.user_id', $this->user->id)
|
||||
->whereNull('source_journals.deleted_at')
|
||||
->whereNull('dest_journals.deleted_at')
|
||||
;
|
||||
|
||||
if ($linkType instanceof LinkType) {
|
||||
$query->where('journal_links.link_type_id', $linkType->id);
|
||||
@@ -149,7 +150,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface, UserGroupInterf
|
||||
$merged = $outward->merge($inward);
|
||||
|
||||
return $merged->filter(
|
||||
static fn(TransactionJournalLink $link) => null !== $link->source && null !== $link->destination
|
||||
static fn (TransactionJournalLink $link) => null !== $link->source && null !== $link->destination
|
||||
);
|
||||
}
|
||||
|
||||
@@ -188,7 +189,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface, UserGroupInterf
|
||||
return $existing;
|
||||
}
|
||||
|
||||
$link = new TransactionJournalLink();
|
||||
$link = new TransactionJournalLink();
|
||||
$link->linkType()->associate($linkType);
|
||||
if ('inward' === $information['direction']) {
|
||||
app('log')->debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->inward, $inward->id, $outward->id));
|
||||
@@ -229,8 +230,9 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface, UserGroupInterf
|
||||
public function findSpecificLink(LinkType $linkType, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink
|
||||
{
|
||||
return TransactionJournalLink::where('link_type_id', $linkType->id)
|
||||
->where('source_id', $inward->id)
|
||||
->where('destination_id', $outward->id)->first();
|
||||
->where('source_id', $inward->id)
|
||||
->where('destination_id', $outward->id)->first()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,7 +294,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface, UserGroupInterf
|
||||
$journalLink->refresh();
|
||||
}
|
||||
|
||||
$journalLink->link_type_id = $data['link_type_id'] ?? $journalLink->link_type_id;
|
||||
$journalLink->link_type_id = $data['link_type_id'] ?? $journalLink->link_type_id;
|
||||
$journalLink->save();
|
||||
if (array_key_exists('notes', $data) && null !== $data['notes']) {
|
||||
$this->setNoteText($journalLink, $data['notes']);
|
||||
|
||||
@@ -241,7 +241,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface, UserGroupInte
|
||||
Log::debug(sprintf('Will add/remove %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
|
||||
|
||||
// if the amount is positive, make sure it fits in piggy bank:
|
||||
if (1 === bccomp($amount, '0') && -1 === bccomp( $room, $amount)) {
|
||||
if (1 === bccomp($amount, '0') && -1 === bccomp($room, $amount)) {
|
||||
// amount is positive and $room is smaller than $amount
|
||||
Log::debug(sprintf('Room in piggy bank for extra money is %f', $room));
|
||||
Log::debug(sprintf('There is NO room to add %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
|
||||
@@ -259,7 +259,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface, UserGroupInte
|
||||
return $compare;
|
||||
}
|
||||
|
||||
return $amount;
|
||||
return $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -272,9 +272,9 @@ class TagRepository implements TagRepositoryInterface, UserGroupInterface
|
||||
$amount = Steam::positive((string) $journal['amount']);
|
||||
$type = $journal['transaction_type_type'];
|
||||
if (TransactionTypeEnum::WITHDRAWAL->value === $type) {
|
||||
$amount = bcmul( $amount, '-1');
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
$sums[$currencyId][$type] = bcadd((string) $sums[$currencyId][$type], $amount);
|
||||
$sums[$currencyId][$type] = bcadd((string) $sums[$currencyId][$type], $amount);
|
||||
|
||||
$foreignCurrencyId = $journal['foreign_currency_id'];
|
||||
if (null !== $foreignCurrencyId && 0 !== $foreignCurrencyId) {
|
||||
@@ -292,7 +292,7 @@ class TagRepository implements TagRepositoryInterface, UserGroupInterface
|
||||
// add foreign amount to correct type:
|
||||
$amount = Steam::positive((string) $journal['foreign_amount']);
|
||||
if (TransactionTypeEnum::WITHDRAWAL->value === $type) {
|
||||
$amount = bcmul( $amount, '-1');
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
$sums[$foreignCurrencyId][$type] = bcadd((string) $sums[$foreignCurrencyId][$type], $amount);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
use function Safe\json_decode;
|
||||
|
||||
/**
|
||||
@@ -143,21 +144,22 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
{
|
||||
$repository = app(AttachmentRepositoryInterface::class);
|
||||
$repository->setUser($this->user);
|
||||
$journals = $group->transactionJournals->pluck('id')->toArray();
|
||||
$set = Attachment::whereIn('attachable_id', $journals)
|
||||
->where('attachable_type', TransactionJournal::class)
|
||||
->where('uploaded', true)
|
||||
->whereNull('deleted_at')->get();
|
||||
$journals = $group->transactionJournals->pluck('id')->toArray();
|
||||
$set = Attachment::whereIn('attachable_id', $journals)
|
||||
->where('attachable_type', TransactionJournal::class)
|
||||
->where('uploaded', true)
|
||||
->whereNull('deleted_at')->get()
|
||||
;
|
||||
|
||||
$result = [];
|
||||
$result = [];
|
||||
|
||||
/** @var Attachment $attachment */
|
||||
foreach ($set as $attachment) {
|
||||
$journalId = $attachment->attachable_id;
|
||||
$result[$journalId] ??= [];
|
||||
$current = $attachment->toArray();
|
||||
$current['file_exists'] = true;
|
||||
$current['notes'] = $repository->getNoteText($attachment);
|
||||
$journalId = $attachment->attachable_id;
|
||||
$result[$journalId] ??= [];
|
||||
$current = $attachment->toArray();
|
||||
$current['file_exists'] = true;
|
||||
$current['notes'] = $repository->getNoteText($attachment);
|
||||
// already determined that this attachable is a TransactionJournal.
|
||||
$current['journal_title'] = $attachment->attachable->description;
|
||||
$result[$journalId][] = $current;
|
||||
@@ -173,8 +175,9 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
{
|
||||
/** @var null|Note $note */
|
||||
$note = Note::where('noteable_id', $journalId)
|
||||
->where('noteable_type', TransactionJournal::class)
|
||||
->first();
|
||||
->where('noteable_type', TransactionJournal::class)
|
||||
->first()
|
||||
;
|
||||
if (null === $note) {
|
||||
return null;
|
||||
}
|
||||
@@ -195,13 +198,14 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
$q->orWhereIn('destination_id', $journals);
|
||||
}
|
||||
)
|
||||
->with(['source', 'destination', 'source.transactions'])
|
||||
->leftJoin('link_types', 'link_types.id', '=', 'journal_links.link_type_id')
|
||||
->get(['journal_links.*', 'link_types.inward', 'link_types.outward', 'link_types.editable']);
|
||||
->with(['source', 'destination', 'source.transactions'])
|
||||
->leftJoin('link_types', 'link_types.id', '=', 'journal_links.link_type_id')
|
||||
->get(['journal_links.*', 'link_types.inward', 'link_types.outward', 'link_types.editable'])
|
||||
;
|
||||
|
||||
/** @var TransactionJournalLink $entry */
|
||||
foreach ($set as $entry) {
|
||||
$journalId = in_array($entry->source_id, $journals, true) ? $entry->source_id : $entry->destination_id;
|
||||
$journalId = in_array($entry->source_id, $journals, true) ? $entry->source_id : $entry->destination_id;
|
||||
$return[$journalId] ??= [];
|
||||
|
||||
// phpstan: the editable field is provided by the query.
|
||||
@@ -247,6 +251,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
if (TransactionTypeEnum::WITHDRAWAL->value === $type) {
|
||||
return Amount::formatAnything($currency, app('steam')->negative($amount));
|
||||
}
|
||||
|
||||
return Amount::formatAnything($currency, $amount);
|
||||
}
|
||||
|
||||
@@ -262,13 +267,14 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
return '';
|
||||
}
|
||||
|
||||
$currency = $transaction->foreignCurrency;
|
||||
$type = $journal->transactionType->type;
|
||||
$amount = app('steam')->positive($transaction->foreign_amount);
|
||||
$currency = $transaction->foreignCurrency;
|
||||
$type = $journal->transactionType->type;
|
||||
$amount = app('steam')->positive($transaction->foreign_amount);
|
||||
if (TransactionTypeEnum::WITHDRAWAL->value === $type) {
|
||||
return Amount::formatAnything($currency, app('steam')->negative($amount));
|
||||
}
|
||||
return Amount::formatAnything($currency, $amount);
|
||||
|
||||
return Amount::formatAnything($currency, $amount);
|
||||
}
|
||||
|
||||
public function getLocation(int $journalId): ?Location
|
||||
@@ -288,10 +294,11 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
public function getMetaDateFields(int $journalId, array $fields): NullArrayObject
|
||||
{
|
||||
$query = DB::table('journal_meta')
|
||||
->where('transaction_journal_id', $journalId)
|
||||
->whereIn('name', $fields)
|
||||
->whereNull('deleted_at')
|
||||
->get(['name', 'data']);
|
||||
->where('transaction_journal_id', $journalId)
|
||||
->whereIn('name', $fields)
|
||||
->whereNull('deleted_at')
|
||||
->get(['name', 'data'])
|
||||
;
|
||||
$return = [];
|
||||
|
||||
foreach ($query as $row) {
|
||||
@@ -307,10 +314,11 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
public function getMetaFields(int $journalId, array $fields): NullArrayObject
|
||||
{
|
||||
$query = DB::table('journal_meta')
|
||||
->where('transaction_journal_id', $journalId)
|
||||
->whereIn('name', $fields)
|
||||
->whereNull('deleted_at')
|
||||
->get(['name', 'data']);
|
||||
->where('transaction_journal_id', $journalId)
|
||||
->whereIn('name', $fields)
|
||||
->whereNull('deleted_at')
|
||||
->get(['name', 'data'])
|
||||
;
|
||||
$return = [];
|
||||
|
||||
foreach ($query as $row) {
|
||||
@@ -331,8 +339,9 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
$journals = $group->transactionJournals->pluck('id')->toArray();
|
||||
$currency = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
|
||||
$data = PiggyBankEvent::whereIn('transaction_journal_id', $journals)
|
||||
->with('piggyBank', 'piggyBank.account')
|
||||
->get(['piggy_bank_events.*']);
|
||||
->with('piggyBank', 'piggyBank.account')
|
||||
->get(['piggy_bank_events.*'])
|
||||
;
|
||||
|
||||
/** @var PiggyBankEvent $row */
|
||||
foreach ($data as $row) {
|
||||
@@ -340,13 +349,14 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
continue;
|
||||
}
|
||||
// get currency preference.
|
||||
$currencyPreference = AccountMeta::where('account_id', $row->piggyBank->account_id)
|
||||
->where('name', 'currency_id')
|
||||
->first();
|
||||
$currencyPreference = AccountMeta::where('account_id', $row->piggyBank->account_id)
|
||||
->where('name', 'currency_id')
|
||||
->first()
|
||||
;
|
||||
if (null !== $currencyPreference) {
|
||||
$currency = TransactionCurrency::where('id', $currencyPreference->data)->first();
|
||||
}
|
||||
$journalId = $row->transaction_journal_id;
|
||||
$journalId = $row->transaction_journal_id;
|
||||
$return[$journalId] ??= [];
|
||||
|
||||
$return[$journalId][] = [
|
||||
@@ -373,10 +383,11 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
public function getTags(int $journalId): array
|
||||
{
|
||||
$result = DB::table('tag_transaction_journal')
|
||||
->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id')
|
||||
->where('tag_transaction_journal.transaction_journal_id', $journalId)
|
||||
->orderBy('tags.tag', 'ASC')
|
||||
->get(['tags.tag']);
|
||||
->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id')
|
||||
->where('tag_transaction_journal.transaction_journal_id', $journalId)
|
||||
->orderBy('tags.tag', 'ASC')
|
||||
->get(['tags.tag'])
|
||||
;
|
||||
|
||||
return $result->pluck('tag')->toArray();
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ class UserRepository implements UserRepositoryInterface
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function hasRole(null|Authenticatable|User $user, string $role): bool
|
||||
public function hasRole(Authenticatable|User|null $user, string $role): bool
|
||||
{
|
||||
if (!$user instanceof Authenticatable) {
|
||||
return false;
|
||||
@@ -270,7 +270,7 @@ class UserRepository implements UserRepositoryInterface
|
||||
return $collection;
|
||||
}
|
||||
|
||||
public function inviteUser(null|Authenticatable|User $user, string $email): InvitedUser
|
||||
public function inviteUser(Authenticatable|User|null $user, string $email): InvitedUser
|
||||
{
|
||||
if (!$user instanceof User) {
|
||||
throw new FireflyException('User is not a User object.');
|
||||
|
||||
@@ -105,9 +105,9 @@ interface UserRepositoryInterface
|
||||
|
||||
public function getUserGroups(User $user): Collection;
|
||||
|
||||
public function hasRole(null|Authenticatable|User $user, string $role): bool;
|
||||
public function hasRole(Authenticatable|User|null $user, string $role): bool;
|
||||
|
||||
public function inviteUser(null|Authenticatable|User $user, string $email): InvitedUser;
|
||||
public function inviteUser(Authenticatable|User|null $user, string $email): InvitedUser;
|
||||
|
||||
public function redeemCode(string $code): void;
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* IsValidSortInstruction.php
|
||||
* Copyright (c) 2025 james@firefly-iii.org
|
||||
@@ -35,21 +37,24 @@ class IsValidSortInstruction implements ValidationRule
|
||||
|
||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||
{
|
||||
$shortClass = str_replace('FireflyIII\\Models\\', '', $this->class);
|
||||
$shortClass = str_replace('FireflyIII\Models\\', '', $this->class);
|
||||
if (!is_string($value)) {
|
||||
$fail('validation.invalid_sort_instruction')->translate(['object' => $shortClass]);
|
||||
|
||||
return;
|
||||
}
|
||||
$validParameters = config(sprintf('firefly.allowed_sort_parameters.%s', $shortClass));
|
||||
if (!is_array($validParameters)) {
|
||||
$fail('validation.no_sort_instructions')->translate(['object' => $shortClass]);
|
||||
|
||||
return;
|
||||
}
|
||||
$parts = explode(',', $value);
|
||||
$parts = explode(',', $value);
|
||||
foreach ($parts as $i => $part) {
|
||||
$part = trim($part);
|
||||
if (strlen($part) < 2) {
|
||||
$fail('validation.invalid_sort_instruction_index')->translate(['index' => $i, 'object' => $shortClass]);
|
||||
|
||||
return;
|
||||
}
|
||||
if ('-' === $part[0]) {
|
||||
@@ -57,6 +62,7 @@ class IsValidSortInstruction implements ValidationRule
|
||||
}
|
||||
if (!in_array($part, $validParameters, true)) {
|
||||
$fail('validation.invalid_sort_instruction_index')->translate(['index' => $i, 'object' => $shortClass]);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -780,10 +780,10 @@ class JournalUpdateService
|
||||
|
||||
private function isBetweenAssetAndLiability(): bool
|
||||
{
|
||||
/** @var Transaction|null $sourceTransaction */
|
||||
/** @var null|Transaction $sourceTransaction */
|
||||
$sourceTransaction = $this->transactionJournal->transactions()->where('amount', '<', 0)->first();
|
||||
|
||||
/** @var Transaction|null $destinationTransaction */
|
||||
/** @var null|Transaction $destinationTransaction */
|
||||
$destinationTransaction = $this->transactionJournal->transactions()->where('amount', '>', 0)->first();
|
||||
if (null === $sourceTransaction || null === $destinationTransaction) {
|
||||
Log::warning('Either transaction is false, stop.');
|
||||
|
||||
@@ -139,14 +139,14 @@ class RemoteUserGuard implements Guard
|
||||
/**
|
||||
* @SuppressWarnings("PHPMD.ShortMethodName")
|
||||
*/
|
||||
public function id(): null|int|string
|
||||
public function id(): int|string|null
|
||||
{
|
||||
Log::debug(sprintf('Now at %s', __METHOD__));
|
||||
|
||||
return $this->user?->id;
|
||||
}
|
||||
|
||||
public function setUser(null|Authenticatable|User $user): void // @phpstan-ignore-line
|
||||
public function setUser(Authenticatable|User|null $user): void // @phpstan-ignore-line
|
||||
{
|
||||
Log::debug(sprintf('Now at %s', __METHOD__));
|
||||
if ($user instanceof User) {
|
||||
|
||||
@@ -23,7 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Facades;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class Navigation extends Facade
|
||||
|
||||
@@ -144,9 +144,10 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
|
||||
private function collectMetaData(): void
|
||||
{
|
||||
$set = AccountMeta::whereIn('name', ['is_multi_currency', 'include_net_worth', 'currency_id', 'account_role', 'account_number', 'BIC', 'liability_direction', 'interest', 'interest_period', 'current_debt'])
|
||||
->whereIn('account_id', $this->ids)
|
||||
->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data'])->toArray();
|
||||
$set = AccountMeta::whereIn('name', ['is_multi_currency', 'include_net_worth', 'currency_id', 'account_role', 'account_number', 'BIC', 'liability_direction', 'interest', 'interest_period', 'current_debt'])
|
||||
->whereIn('account_id', $this->ids)
|
||||
->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data'])->toArray()
|
||||
;
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($set as $entry) {
|
||||
@@ -172,9 +173,10 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
private function collectNotes(): void
|
||||
{
|
||||
$notes = Note::query()->whereIn('noteable_id', $this->ids)
|
||||
->whereNotNull('notes.text')
|
||||
->where('notes.text', '!=', '')
|
||||
->where('noteable_type', Account::class)->get(['notes.noteable_id', 'notes.text'])->toArray();
|
||||
->whereNotNull('notes.text')
|
||||
->where('notes.text', '!=', '')
|
||||
->where('noteable_type', Account::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
|
||||
;
|
||||
foreach ($notes as $note) {
|
||||
$this->notes[(int)$note['noteable_id']] = (string)$note['text'];
|
||||
}
|
||||
@@ -184,14 +186,15 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
private function collectLocations(): void
|
||||
{
|
||||
$locations = Location::query()->whereIn('locatable_id', $this->ids)
|
||||
->where('locatable_type', Account::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray();
|
||||
->where('locatable_type', Account::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray()
|
||||
;
|
||||
foreach ($locations as $location) {
|
||||
$this->locations[(int)$location['locatable_id']]
|
||||
= [
|
||||
'latitude' => (float)$location['latitude'],
|
||||
'longitude' => (float)$location['longitude'],
|
||||
'zoom_level' => (int)$location['zoom_level'],
|
||||
];
|
||||
'latitude' => (float)$location['latitude'],
|
||||
'longitude' => (float)$location['longitude'],
|
||||
'zoom_level' => (int)$location['zoom_level'],
|
||||
];
|
||||
}
|
||||
Log::debug(sprintf('Enrich with %d locations(s)', count($this->locations)));
|
||||
}
|
||||
@@ -206,19 +209,20 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
->setUserGroup($this->userGroup)
|
||||
->setAccounts($this->collection)
|
||||
->withAccountInformation()
|
||||
->setTypes([TransactionTypeEnum::OPENING_BALANCE->value]);
|
||||
$journals = $collector->getExtractedJournals();
|
||||
->setTypes([TransactionTypeEnum::OPENING_BALANCE->value])
|
||||
;
|
||||
$journals = $collector->getExtractedJournals();
|
||||
foreach ($journals as $journal) {
|
||||
$this->openingBalances[(int)$journal['source_account_id']]
|
||||
= [
|
||||
'amount' => Steam::negative($journal['amount']),
|
||||
'date' => $journal['date'],
|
||||
];
|
||||
'amount' => Steam::negative($journal['amount']),
|
||||
'date' => $journal['date'],
|
||||
];
|
||||
$this->openingBalances[(int)$journal['destination_account_id']]
|
||||
= [
|
||||
'amount' => Steam::positive($journal['amount']),
|
||||
'date' => $journal['date'],
|
||||
];
|
||||
'amount' => Steam::positive($journal['amount']),
|
||||
'date' => $journal['date'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,9 +240,9 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
private function appendCollectedData(): void
|
||||
{
|
||||
$this->collection = $this->collection->map(function (Account $item) {
|
||||
$id = (int)$item->id;
|
||||
$item->full_account_type = $this->accountTypes[(int)$item->account_type_id] ?? null;
|
||||
$meta = [
|
||||
$id = (int)$item->id;
|
||||
$item->full_account_type = $this->accountTypes[(int)$item->account_type_id] ?? null;
|
||||
$meta = [
|
||||
'currency' => null,
|
||||
'location' => [
|
||||
'latitude' => null,
|
||||
@@ -285,30 +289,30 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
|
||||
// add balances
|
||||
// get currencies:
|
||||
$currency = $this->primaryCurrency; // assume primary currency
|
||||
$currency = $this->primaryCurrency; // assume primary currency
|
||||
if (null !== $meta['currency']) {
|
||||
$currency = $meta['currency'];
|
||||
}
|
||||
|
||||
// get the current balance:
|
||||
$date = $this->getDate();
|
||||
$date = $this->getDate();
|
||||
// $finalBalance = Steam::finalAccountBalance($item, $date, $this->primaryCurrency, $this->convertToPrimary);
|
||||
$finalBalance = $this->balances[$id];
|
||||
$balanceDifference = $this->getBalanceDifference($id, $currency);
|
||||
$finalBalance = $this->balances[$id];
|
||||
$balanceDifference = $this->getBalanceDifference($id, $currency);
|
||||
Log::debug(sprintf('Call finalAccountBalance(%s) with date/time "%s"', var_export($this->convertToPrimary, true), $date->toIso8601String()), $finalBalance);
|
||||
|
||||
// collect current balances:
|
||||
$currentBalance = Steam::bcround($finalBalance[$currency->code] ?? '0', $currency->decimal_places);
|
||||
$openingBalance = Steam::bcround($meta['opening_balance_amount'] ?? '0', $currency->decimal_places);
|
||||
$virtualBalance = Steam::bcround($item->virtual_balance ?? '0', $currency->decimal_places);
|
||||
$debtAmount = $meta['current_debt'] ?? null;
|
||||
$currentBalance = Steam::bcround($finalBalance[$currency->code] ?? '0', $currency->decimal_places);
|
||||
$openingBalance = Steam::bcround($meta['opening_balance_amount'] ?? '0', $currency->decimal_places);
|
||||
$virtualBalance = Steam::bcround($item->virtual_balance ?? '0', $currency->decimal_places);
|
||||
$debtAmount = $meta['current_debt'] ?? null;
|
||||
|
||||
// set some pc_ default values to NULL:
|
||||
$pcCurrentBalance = null;
|
||||
$pcOpeningBalance = null;
|
||||
$pcVirtualBalance = null;
|
||||
$pcDebtAmount = null;
|
||||
$pcBalanceDifference = null;
|
||||
$pcCurrentBalance = null;
|
||||
$pcOpeningBalance = null;
|
||||
$pcVirtualBalance = null;
|
||||
$pcDebtAmount = null;
|
||||
$pcBalanceDifference = null;
|
||||
|
||||
// convert to primary currency if needed:
|
||||
if ($this->convertToPrimary && $currency->id !== $this->primaryCurrency->id) {
|
||||
@@ -347,7 +351,7 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
'pc_balance_difference' => $pcBalanceDifference,
|
||||
];
|
||||
// end add balances
|
||||
$item->meta = $meta;
|
||||
$item->meta = $meta;
|
||||
|
||||
return $item;
|
||||
});
|
||||
@@ -369,12 +373,13 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
|
||||
private function collectObjectGroups(): void
|
||||
{
|
||||
$set = DB::table('object_groupables')
|
||||
->whereIn('object_groupable_id', $this->ids)
|
||||
->where('object_groupable_type', Account::class)
|
||||
->get(['object_groupable_id', 'object_group_id']);
|
||||
$set = DB::table('object_groupables')
|
||||
->whereIn('object_groupable_id', $this->ids)
|
||||
->where('object_groupable_type', Account::class)
|
||||
->get(['object_groupable_id', 'object_group_id'])
|
||||
;
|
||||
|
||||
$ids = array_unique($set->pluck('object_group_id')->toArray());
|
||||
$ids = array_unique($set->pluck('object_group_id')->toArray());
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$this->mappedObjects[(int)$entry->object_groupable_id] = (int)$entry->object_group_id;
|
||||
@@ -426,8 +431,8 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
if (0 === count($startBalance) || 0 === count($endBalance)) {
|
||||
return null;
|
||||
}
|
||||
$start = $startBalance[$currency->code] ?? '0';
|
||||
$end = $endBalance[$currency->code] ?? '0';
|
||||
$start = $startBalance[$currency->code] ?? '0';
|
||||
$end = $endBalance[$currency->code] ?? '0';
|
||||
|
||||
return bcsub($end, $start);
|
||||
}
|
||||
@@ -440,22 +445,25 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
private function sortData(): void
|
||||
{
|
||||
$dbParams = config('firefly.allowed_db_sort_parameters.Account', []);
|
||||
|
||||
/** @var array $parameter */
|
||||
foreach ($this->sort as $parameter) {
|
||||
if (in_array($parameter[0], $dbParams, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($parameter[0]) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Account enrichment cannot sort on field "%s"', $parameter[0]));
|
||||
|
||||
case 'current_balance':
|
||||
case 'pc_current_balance':
|
||||
$this->collection = $this->collection->sortBy(static function (Account $account) use ($parameter) {
|
||||
return $account->meta['balances'][$parameter[0]] ?? '0';
|
||||
}, SORT_NUMERIC, 'desc' === $parameter[1]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -55,10 +55,9 @@ class AvailableBudgetEnrichment implements EnrichmentInterface
|
||||
private readonly OperationsRepositoryInterface $opsRepository;
|
||||
private readonly BudgetRepositoryInterface $repository;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
//$this->primaryCurrency = Amount::getPrimaryCurrency();
|
||||
// $this->primaryCurrency = Amount::getPrimaryCurrency();
|
||||
$this->convertToPrimary = Amount::convertToPrimary();
|
||||
$this->noBudgetRepository = app(NoBudgetRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
|
||||
@@ -30,10 +30,8 @@ use FireflyIII\Models\AutoBudget;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -56,9 +54,7 @@ class BudgetEnrichment implements EnrichmentInterface
|
||||
private array $objectGroups = [];
|
||||
private array $mappedObjects = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
public function __construct() {}
|
||||
|
||||
public function enrich(Collection $collection): Collection
|
||||
{
|
||||
|
||||
@@ -55,8 +55,8 @@ class PiggyBankEnrichment implements EnrichmentInterface
|
||||
private array $mappedObjects = [];
|
||||
private TransactionCurrency $primaryCurrency;
|
||||
private array $amounts = [];
|
||||
private array $accounts= [];
|
||||
private array $objectGroups= [];
|
||||
private array $accounts = [];
|
||||
private array $objectGroups = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
@@ -25,7 +25,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\JsonApi\Enrichments;
|
||||
|
||||
use function Safe\json_decode;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Enums\RecurrenceRepetitionWeekend;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
@@ -53,11 +52,13 @@ use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use function Safe\json_decode;
|
||||
|
||||
class RecurringEnrichment implements EnrichmentInterface
|
||||
{
|
||||
private Collection $collection;
|
||||
private array $ids = [];
|
||||
// private array $transactionTypeIds = [];
|
||||
// private array $transactionTypeIds = [];
|
||||
// private array $transactionTypes = [];
|
||||
private array $notes = [];
|
||||
private array $repetitions = [];
|
||||
@@ -122,10 +123,10 @@ class RecurringEnrichment implements EnrichmentInterface
|
||||
{
|
||||
/** @var Recurrence $recurrence */
|
||||
foreach ($this->collection as $recurrence) {
|
||||
$id = (int)$recurrence->id;
|
||||
// $typeId = (int)$recurrence->transaction_type_id;
|
||||
$this->ids[] = $id;
|
||||
//$this->transactionTypeIds[$id] = $typeId;
|
||||
$id = (int)$recurrence->id;
|
||||
// $typeId = (int)$recurrence->transaction_type_id;
|
||||
$this->ids[] = $id;
|
||||
// $this->transactionTypeIds[$id] = $typeId;
|
||||
}
|
||||
$this->ids = array_unique($this->ids);
|
||||
|
||||
@@ -146,7 +147,7 @@ class RecurringEnrichment implements EnrichmentInterface
|
||||
|
||||
/** @var RecurrenceRepetition $repetition */
|
||||
foreach ($set as $repetition) {
|
||||
$recurrence = $this->collection->filter(fn(Recurrence $item) => (int)$item->id === (int)$repetition->recurrence_id)->first();
|
||||
$recurrence = $this->collection->filter(fn (Recurrence $item) => (int)$item->id === (int)$repetition->recurrence_id)->first();
|
||||
$fromDate = clone ($recurrence->latest_date ?? $recurrence->first_date);
|
||||
$id = (int)$repetition->recurrence_id;
|
||||
$repId = (int)$repetition->id;
|
||||
|
||||
@@ -28,7 +28,6 @@ namespace FireflyIII\Support\JsonApi\Enrichments;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonInterface;
|
||||
use Carbon\Exceptions\InvalidFormatException;
|
||||
use Carbon\Exceptions\ParseErrorException;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
@@ -87,11 +86,11 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
||||
$paidDates = $this->paidDates;
|
||||
$payDates = $this->payDates;
|
||||
$this->collection = $this->collection->map(function (Bill $item) use ($notes, $objectGroups, $paidDates, $payDates) {
|
||||
$id = (int)$item->id;
|
||||
$currency = $item->transactionCurrency;
|
||||
$nem = $this->getNextExpectedMatch($payDates[$id] ?? []);
|
||||
$id = (int)$item->id;
|
||||
$currency = $item->transactionCurrency;
|
||||
$nem = $this->getNextExpectedMatch($payDates[$id] ?? []);
|
||||
|
||||
$meta = [
|
||||
$meta = [
|
||||
'notes' => null,
|
||||
'object_group_id' => null,
|
||||
'object_group_title' => null,
|
||||
@@ -102,7 +101,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
||||
'nem' => $nem,
|
||||
'nem_diff' => $this->getNextExpectedMatchDiff($nem, $payDates[$id] ?? []),
|
||||
];
|
||||
$amounts = [
|
||||
$amounts = [
|
||||
'amount_min' => Steam::bcround($item->amount_min, $currency->decimal_places),
|
||||
'amount_max' => Steam::bcround($item->amount_max, $currency->decimal_places),
|
||||
'average' => Steam::bcround(bcdiv(bcadd($item->amount_min, $item->amount_max), '2'), $currency->decimal_places),
|
||||
@@ -155,9 +154,10 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
||||
private function collectNotes(): void
|
||||
{
|
||||
$notes = Note::query()->whereIn('noteable_id', $this->subscriptionIds)
|
||||
->whereNotNull('notes.text')
|
||||
->where('notes.text', '!=', '')
|
||||
->where('noteable_type', Bill::class)->get(['notes.noteable_id', 'notes.text'])->toArray();
|
||||
->whereNotNull('notes.text')
|
||||
->where('notes.text', '!=', '')
|
||||
->where('noteable_type', Bill::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
|
||||
;
|
||||
foreach ($notes as $note) {
|
||||
$this->notes[(int)$note['noteable_id']] = (string)$note['text'];
|
||||
}
|
||||
@@ -186,12 +186,13 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
||||
|
||||
private function collectObjectGroups(): void
|
||||
{
|
||||
$set = DB::table('object_groupables')
|
||||
->whereIn('object_groupable_id', $this->subscriptionIds)
|
||||
->where('object_groupable_type', Bill::class)
|
||||
->get(['object_groupable_id', 'object_group_id']);
|
||||
$set = DB::table('object_groupables')
|
||||
->whereIn('object_groupable_id', $this->subscriptionIds)
|
||||
->where('object_groupable_type', Bill::class)
|
||||
->get(['object_groupable_id', 'object_group_id'])
|
||||
;
|
||||
|
||||
$ids = array_unique($set->pluck('object_group_id')->toArray());
|
||||
$ids = array_unique($set->pluck('object_group_id')->toArray());
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$this->mappedObjects[(int)$entry->object_groupable_id] = (int)$entry->object_group_id;
|
||||
@@ -219,13 +220,13 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
||||
// 2023-07-18 this particular date is used to search for the last paid date.
|
||||
// 2023-07-18 the cloned $searchDate is used to grab the correct transactions.
|
||||
/** @var Carbon $start */
|
||||
$start = clone $this->start;
|
||||
$searchStart = clone $start;
|
||||
$start = clone $this->start;
|
||||
$searchStart = clone $start;
|
||||
$start->subDay();
|
||||
|
||||
/** @var Carbon $end */
|
||||
$end = clone $this->end;
|
||||
$searchEnd = clone $end;
|
||||
$end = clone $this->end;
|
||||
$searchEnd = clone $end;
|
||||
|
||||
// move the search dates to the start of the day.
|
||||
$searchStart->startOfDay();
|
||||
@@ -234,13 +235,13 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
||||
Log::debug(sprintf('Search parameters are: start: %s, end: %s', $searchStart->format('Y-m-d H:i:s'), $searchEnd->format('Y-m-d H:i:s')));
|
||||
|
||||
// Get from database when bills were paid.
|
||||
$set = $this->user->transactionJournals()
|
||||
->whereIn('bill_id', $this->subscriptionIds)
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('transaction_currencies AS currency', 'currency.id', '=', 'transactions.transaction_currency_id')
|
||||
->leftJoin('transaction_currencies AS foreign_currency', 'foreign_currency.id', '=', 'transactions.foreign_currency_id')
|
||||
->where('transactions.amount', '>', 0)
|
||||
->before($searchEnd)->after($searchStart)->get(
|
||||
$set = $this->user->transactionJournals()
|
||||
->whereIn('bill_id', $this->subscriptionIds)
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('transaction_currencies AS currency', 'currency.id', '=', 'transactions.transaction_currency_id')
|
||||
->leftJoin('transaction_currencies AS foreign_currency', 'foreign_currency.id', '=', 'transactions.foreign_currency_id')
|
||||
->where('transactions.amount', '>', 0)
|
||||
->before($searchEnd)->after($searchStart)->get(
|
||||
[
|
||||
'transaction_journals.id',
|
||||
'transaction_journals.date',
|
||||
@@ -257,26 +258,27 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
||||
'transactions.amount',
|
||||
'transactions.foreign_amount',
|
||||
]
|
||||
);
|
||||
)
|
||||
;
|
||||
Log::debug(sprintf('Count %d entries in set', $set->count()));
|
||||
|
||||
// for each bill, do a loop.
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter = new ExchangeRateConverter();
|
||||
|
||||
/** @var Bill $subscription */
|
||||
foreach ($this->collection as $subscription) {
|
||||
// Grab from array the most recent payment. If none exist, fall back to the start date and pretend *that* was the last paid date.
|
||||
Log::debug(sprintf('Grab last paid date from function, return %s if it comes up with nothing.', $start->format('Y-m-d')));
|
||||
$lastPaidDate = $this->lastPaidDate($subscription, $set, $start);
|
||||
$lastPaidDate = $this->lastPaidDate($subscription, $set, $start);
|
||||
Log::debug(sprintf('Result of lastPaidDate is %s', $lastPaidDate->format('Y-m-d')));
|
||||
|
||||
// At this point the "next match" is exactly after the last time the bill was paid.
|
||||
$result = [];
|
||||
$filtered = $set->filter(function (TransactionJournal $journal) use ($subscription) {
|
||||
$result = [];
|
||||
$filtered = $set->filter(function (TransactionJournal $journal) use ($subscription) {
|
||||
return (int)$journal->bill_id === (int)$subscription->id;
|
||||
});
|
||||
foreach ($filtered as $entry) {
|
||||
$array = [
|
||||
$array = [
|
||||
'transaction_group_id' => (string)$entry->transaction_group_id,
|
||||
'transaction_journal_id' => (string)$entry->id,
|
||||
'date' => $entry->date->toAtomString(),
|
||||
@@ -352,7 +354,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
||||
return $default;
|
||||
}
|
||||
|
||||
$latest = $filtered->first()->date;
|
||||
$latest = $filtered->first()->date;
|
||||
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($filtered as $journal) {
|
||||
@@ -398,12 +400,12 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
||||
|
||||
/** @var Bill $subscription */
|
||||
foreach ($this->collection as $subscription) {
|
||||
$id = (int)$subscription->id;
|
||||
$lastPaidDate = $this->getLastPaidDate($this->paidDates[$id] ?? []);
|
||||
$payDates = $this->calculator->getPayDates($this->start, $this->end, $subscription->date, $subscription->repeat_freq, $subscription->skip, $lastPaidDate);
|
||||
$payDatesFormatted = [];
|
||||
$id = (int)$subscription->id;
|
||||
$lastPaidDate = $this->getLastPaidDate($this->paidDates[$id] ?? []);
|
||||
$payDates = $this->calculator->getPayDates($this->start, $this->end, $subscription->date, $subscription->repeat_freq, $subscription->skip, $lastPaidDate);
|
||||
$payDatesFormatted = [];
|
||||
foreach ($payDates as $string) {
|
||||
$date = Carbon::createFromFormat('!Y-m-d', $string, config('app.timezone'));
|
||||
$date = Carbon::createFromFormat('!Y-m-d', $string, config('app.timezone'));
|
||||
if (!$date instanceof Carbon) {
|
||||
$date = today(config('app.timezone'));
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ class Preferences
|
||||
;
|
||||
}
|
||||
|
||||
public function get(string $name, null|array|bool|int|string $default = null): ?Preference
|
||||
public function get(string $name, array|bool|int|string|null $default = null): ?Preference
|
||||
{
|
||||
/** @var null|User $user */
|
||||
$user = auth()->user();
|
||||
@@ -71,7 +71,7 @@ class Preferences
|
||||
return $this->getForUser($user, $name, $default);
|
||||
}
|
||||
|
||||
public function getForUser(User $user, string $name, null|array|bool|int|string $default = null): ?Preference
|
||||
public function getForUser(User $user, string $name, array|bool|int|string|null $default = null): ?Preference
|
||||
{
|
||||
// Log::debug(sprintf('getForUser(#%d, "%s")', $user->id, $name));
|
||||
// don't care about user group ID, except for some specific preferences.
|
||||
@@ -135,7 +135,7 @@ class Preferences
|
||||
Cache::put($key, '', 5);
|
||||
}
|
||||
|
||||
public function setForUser(User $user, string $name, null|array|bool|int|string $value): Preference
|
||||
public function setForUser(User $user, string $name, array|bool|int|string|null $value): Preference
|
||||
{
|
||||
$fullName = sprintf('preference%s%s', $user->id, $name);
|
||||
$userGroupId = $this->getUserGroupId($user, $name);
|
||||
@@ -240,7 +240,7 @@ class Preferences
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getEncryptedForUser(User $user, string $name, null|array|bool|int|string $default = null): ?Preference
|
||||
public function getEncryptedForUser(User $user, string $name, array|bool|int|string|null $default = null): ?Preference
|
||||
{
|
||||
$result = $this->getForUser($user, $name, $default);
|
||||
if ('' === $result->data) {
|
||||
@@ -265,7 +265,7 @@ class Preferences
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getFresh(string $name, null|array|bool|int|string $default = null): ?Preference
|
||||
public function getFresh(string $name, array|bool|int|string|null $default = null): ?Preference
|
||||
{
|
||||
/** @var null|User $user */
|
||||
$user = auth()->user();
|
||||
@@ -313,7 +313,7 @@ class Preferences
|
||||
Session::forget('first');
|
||||
}
|
||||
|
||||
public function set(string $name, null|array|bool|int|string $value): Preference
|
||||
public function set(string $name, array|bool|int|string|null $value): Preference
|
||||
{
|
||||
/** @var null|User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
@@ -37,7 +37,7 @@ interface UserGroupInterface
|
||||
|
||||
public function getUserGroup(): ?UserGroup;
|
||||
|
||||
public function setUser(null|Authenticatable|User $user): void;
|
||||
public function setUser(Authenticatable|User|null $user): void;
|
||||
|
||||
public function setUserGroup(UserGroup $userGroup): void;
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ trait UserGroupTrait
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function setUser(null|Authenticatable|User $user): void
|
||||
public function setUser(Authenticatable|User|null $user): void
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
||||
@@ -31,6 +31,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use function Safe\preg_replace;
|
||||
|
||||
/**
|
||||
@@ -105,14 +106,15 @@ trait ConvertsDataTypes
|
||||
$parts = explode(',', $parameter);
|
||||
$sortParameters = [];
|
||||
foreach ($parts as $part) {
|
||||
$part = trim($part);
|
||||
$direction = 'asc';
|
||||
$part = trim($part);
|
||||
$direction = 'asc';
|
||||
if ('-' === $part[0]) {
|
||||
$part = substr($part, 1);
|
||||
$direction = 'desc';
|
||||
}
|
||||
$sortParameters[] = [$part, $direction];
|
||||
}
|
||||
|
||||
return $sortParameters;
|
||||
}
|
||||
|
||||
@@ -434,7 +436,7 @@ trait ConvertsDataTypes
|
||||
if (!is_array($entry)) {
|
||||
continue;
|
||||
}
|
||||
$amount = null;
|
||||
$amount = null;
|
||||
if (array_key_exists('current_amount', $entry)) {
|
||||
$amount = $this->clearString((string)($entry['current_amount'] ?? '0'));
|
||||
if (null === $entry['current_amount']) {
|
||||
|
||||
@@ -137,7 +137,7 @@ class AccountSearch implements GenericSearchInterface
|
||||
$this->types = $types;
|
||||
}
|
||||
|
||||
public function setUser(null|Authenticatable|User $user): void
|
||||
public function setUser(Authenticatable|User|null $user): void
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
||||
@@ -116,9 +116,10 @@ class AmountFormat extends AbstractExtension
|
||||
'formatAmountBySymbol',
|
||||
static function (string $amount, ?string $symbol, ?int $decimalPlaces = null, ?bool $coloured = null): string {
|
||||
|
||||
if(null === $symbol) {
|
||||
$message = sprintf('formatAmountBySymbol("%s", %s, %d, %s) was called without a symbol. Please browse to /flush to clear your cache.', $amount,var_export($symbol, true), $decimalPlaces, var_export($coloured, true));
|
||||
if (null === $symbol) {
|
||||
$message = sprintf('formatAmountBySymbol("%s", %s, %d, %s) was called without a symbol. Please browse to /flush to clear your cache.', $amount, var_export($symbol, true), $decimalPlaces, var_export($coloured, true));
|
||||
Log::error($message);
|
||||
|
||||
throw new FireflyException($message);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ use Override;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
use function Safe\parse_url;
|
||||
|
||||
/**
|
||||
@@ -70,14 +71,14 @@ class General extends AbstractExtension
|
||||
}
|
||||
|
||||
/** @var Carbon $date */
|
||||
$date = session('end', today(config('app.timezone'))->endOfMonth());
|
||||
$date = session('end', today(config('app.timezone'))->endOfMonth());
|
||||
Log::debug(sprintf('twig balance: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
|
||||
$info = Steam::finalAccountBalance($account, $date);
|
||||
$currency = Steam::getAccountCurrency($account);
|
||||
$primary = Amount::getPrimaryCurrency();
|
||||
$convertToPrimary = Amount::convertToPrimary();
|
||||
$usePrimary = $convertToPrimary && $primary->id !== $currency->id;
|
||||
$currency ??= $primary;
|
||||
$currency ??= $primary;
|
||||
$strings = [];
|
||||
foreach ($info as $key => $balance) {
|
||||
if ('balance' === $key) {
|
||||
@@ -118,15 +119,15 @@ class General extends AbstractExtension
|
||||
static function (int $size): string {
|
||||
// less than one GB, more than one MB
|
||||
if ($size < (1024 * 1024 * 2014) && $size >= (1024 * 1024)) {
|
||||
return round($size / (1024 * 1024), 2) . ' MB';
|
||||
return round($size / (1024 * 1024), 2).' MB';
|
||||
}
|
||||
|
||||
// less than one MB
|
||||
if ($size < (1024 * 1024)) {
|
||||
return round($size / 1024, 2) . ' KB';
|
||||
return round($size / 1024, 2).' KB';
|
||||
}
|
||||
|
||||
return $size . ' bytes';
|
||||
return $size.' bytes';
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -140,7 +141,7 @@ class General extends AbstractExtension
|
||||
{
|
||||
return new TwigFilter(
|
||||
'mimeIcon',
|
||||
static fn(string $string): string => match ($string) {
|
||||
static fn (string $string): string => match ($string) {
|
||||
'application/pdf' => 'fa-file-pdf-o',
|
||||
'image/webp', 'image/png', 'image/jpeg', 'image/svg+xml', 'image/heic', 'image/heic-sequence', 'application/vnd.oasis.opendocument.image' => 'fa-file-image-o',
|
||||
'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'application/x-iwork-pages-sffpages', 'application/vnd.sun.xml.writer', 'application/vnd.sun.xml.writer.template', 'application/vnd.sun.xml.writer.global', 'application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global', 'application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.text-template', 'application/vnd.oasis.opendocument.text-web', 'application/vnd.oasis.opendocument.text-master' => 'fa-file-word-o',
|
||||
@@ -213,7 +214,7 @@ class General extends AbstractExtension
|
||||
{
|
||||
return new TwigFunction(
|
||||
'phpdate',
|
||||
static fn(string $str): string => date($str)
|
||||
static fn (string $str): string => date($str)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -269,7 +270,7 @@ class General extends AbstractExtension
|
||||
'activeRoutePartialObjectType',
|
||||
static function ($context): string {
|
||||
[, $route, $objectType] = func_get_args();
|
||||
$activeObjectType = $context['objectType'] ?? false;
|
||||
$activeObjectType = $context['objectType'] ?? false;
|
||||
|
||||
if ($objectType === $activeObjectType
|
||||
&& false !== stripos(
|
||||
@@ -375,7 +376,7 @@ class General extends AbstractExtension
|
||||
{
|
||||
return new TwigFunction(
|
||||
'carbonize',
|
||||
static fn(string $date): Carbon => new Carbon($date, config('app.timezone'))
|
||||
static fn (string $date): Carbon => new Carbon($date, config('app.timezone'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user