mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2026-08-17 16:35:20 -05:00
🤖 Auto commit for release 'develop' on 2026-01-25
This commit is contained in:
Generated
+30
-30
@@ -1252,16 +1252,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v8.0.3",
|
||||
"version": "v8.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "6145b304a5c1ea0bdbd0b04d297a5864f9a7d587"
|
||||
"reference": "ace03c4cf9805080ff40cbeec69fca180c339a3b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/6145b304a5c1ea0bdbd0b04d297a5864f9a7d587",
|
||||
"reference": "6145b304a5c1ea0bdbd0b04d297a5864f9a7d587",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/ace03c4cf9805080ff40cbeec69fca180c339a3b",
|
||||
"reference": "ace03c4cf9805080ff40cbeec69fca180c339a3b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1318,7 +1318,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v8.0.3"
|
||||
"source": "https://github.com/symfony/console/tree/v8.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1338,7 +1338,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-23T14:52:06+00:00"
|
||||
"time": "2026-01-13T13:06:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
@@ -1409,16 +1409,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v8.0.0",
|
||||
"version": "v8.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "573f95783a2ec6e38752979db139f09fec033f03"
|
||||
"reference": "99301401da182b6cfaa4700dbe9987bb75474b47"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/573f95783a2ec6e38752979db139f09fec033f03",
|
||||
"reference": "573f95783a2ec6e38752979db139f09fec033f03",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/99301401da182b6cfaa4700dbe9987bb75474b47",
|
||||
"reference": "99301401da182b6cfaa4700dbe9987bb75474b47",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1470,7 +1470,7 @@
|
||||
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v8.0.0"
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v8.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1490,7 +1490,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-10-30T14:17:19+00:00"
|
||||
"time": "2026-01-05T11:45:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher-contracts",
|
||||
@@ -1640,16 +1640,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v8.0.3",
|
||||
"version": "v8.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12"
|
||||
"reference": "42e48eb02e07d5f3771d194d67da117eb824c8c1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/dd3a2953570a283a2ba4e17063bb98c734cf5b12",
|
||||
"reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/42e48eb02e07d5f3771d194d67da117eb824c8c1",
|
||||
"reference": "42e48eb02e07d5f3771d194d67da117eb824c8c1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1684,7 +1684,7 @@
|
||||
"description": "Finds files and directories via an intuitive fluent interface",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/finder/tree/v8.0.3"
|
||||
"source": "https://github.com/symfony/finder/tree/v8.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1704,7 +1704,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-23T14:52:06+00:00"
|
||||
"time": "2026-01-12T12:37:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
@@ -2358,16 +2358,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v8.0.3",
|
||||
"version": "v8.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "0cbbd88ec836f8757641c651bb995335846abb78"
|
||||
"reference": "10df72602d88c0a3fa685b822976a052611dd607"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/0cbbd88ec836f8757641c651bb995335846abb78",
|
||||
"reference": "0cbbd88ec836f8757641c651bb995335846abb78",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/10df72602d88c0a3fa685b822976a052611dd607",
|
||||
"reference": "10df72602d88c0a3fa685b822976a052611dd607",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2399,7 +2399,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v8.0.3"
|
||||
"source": "https://github.com/symfony/process/tree/v8.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2419,7 +2419,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-19T10:01:18+00:00"
|
||||
"time": "2026-01-23T11:07:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
@@ -2576,16 +2576,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v8.0.1",
|
||||
"version": "v8.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc"
|
||||
"reference": "758b372d6882506821ed666032e43020c4f57194"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/ba65a969ac918ce0cc3edfac6cdde847eba231dc",
|
||||
"reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/758b372d6882506821ed666032e43020c4f57194",
|
||||
"reference": "758b372d6882506821ed666032e43020c4f57194",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2642,7 +2642,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v8.0.1"
|
||||
"source": "https://github.com/symfony/string/tree/v8.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2662,7 +2662,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-01T09:13:36+00:00"
|
||||
"time": "2026-01-12T12:37:40+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
||||
@@ -158,7 +158,10 @@ class TagController extends Controller
|
||||
'currency_id' => (string) $foreignCurrencyId,
|
||||
'currency_code' => $journal['foreign_currency_code'],
|
||||
];
|
||||
$response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount']));
|
||||
$response[$foreignKey]['difference'] = bcadd(
|
||||
(string) $response[$foreignKey]['difference'],
|
||||
Steam::positive($journal['foreign_amount'])
|
||||
);
|
||||
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,10 @@ class TagController extends Controller
|
||||
'currency_id' => (string) $foreignCurrencyId,
|
||||
'currency_code' => $journal['foreign_currency_code'],
|
||||
];
|
||||
$response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount']));
|
||||
$response[$foreignKey]['difference'] = bcadd(
|
||||
(string) $response[$foreignKey]['difference'],
|
||||
Steam::positive($journal['foreign_amount'])
|
||||
);
|
||||
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,9 +88,9 @@ class StoreController extends Controller
|
||||
public function store(StoreRequest $request): JsonResponse
|
||||
{
|
||||
Log::debug('Now in API StoreController::store()');
|
||||
$data = $request->getAll();
|
||||
$data['user'] = auth()->user();
|
||||
$data['user_group'] = $this->userGroup;
|
||||
$data = $request->getAll();
|
||||
$data['user'] = auth()->user();
|
||||
$data['user_group'] = $this->userGroup;
|
||||
|
||||
Log::channel('audit')->info('Store new transaction over API.', $data);
|
||||
|
||||
@@ -110,21 +110,21 @@ class StoreController extends Controller
|
||||
throw new ValidationException($validator);
|
||||
}
|
||||
Preferences::mark();
|
||||
$flags = new TransactionGroupEventFlags();
|
||||
$flags->applyRules = $data['apply_rules'] ?? true;
|
||||
$flags->fireWebhooks = $data['fire_webhooks'] ?? true;
|
||||
$flags = new TransactionGroupEventFlags();
|
||||
$flags->applyRules = $data['apply_rules'] ?? true;
|
||||
$flags->fireWebhooks = $data['fire_webhooks'] ?? true;
|
||||
$flags->batchSubmission = $data['batch_submission'] ?? false;
|
||||
Log::debug('CreatedSingleTransactionGroup');
|
||||
event(new CreatedSingleTransactionGroup($transactionGroup, $flags));
|
||||
|
||||
$manager = $this->getManager();
|
||||
$manager = $this->getManager();
|
||||
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
$admin = auth()->user();
|
||||
|
||||
// use new group collector:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector
|
||||
->setUser($admin)
|
||||
->setUserGroup($this->userGroup)
|
||||
@@ -134,20 +134,20 @@ class StoreController extends Controller
|
||||
->withAPIInformation()
|
||||
;
|
||||
|
||||
$selectedGroup = $collector->getGroups()->first();
|
||||
$selectedGroup = $collector->getGroups()->first();
|
||||
if (null === $selectedGroup) {
|
||||
throw HttpException::fromStatusCode(410, '200032: Cannot find transaction. Possibly, a rule deleted this transaction after its creation.');
|
||||
}
|
||||
|
||||
// enrich
|
||||
$enrichment = new TransactionGroupEnrichment();
|
||||
$enrichment = new TransactionGroupEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
$selectedGroup = $enrichment->enrichSingle($selectedGroup);
|
||||
$selectedGroup = $enrichment->enrichSingle($selectedGroup);
|
||||
|
||||
/** @var TransactionGroupTransformer $transformer */
|
||||
$transformer = app(TransactionGroupTransformer::class);
|
||||
$transformer = app(TransactionGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
$resource = new Item($selectedGroup, $transformer, 'transactions');
|
||||
$resource = new Item($selectedGroup, $transformer, 'transactions');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class StoreRequest extends FormRequest
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
$fields = ['order' => ['order', 'convertInteger']];
|
||||
$fields = ['order' => ['order', 'convertInteger']];
|
||||
$data = $this->getAllData($fields);
|
||||
$data['name'] = $this->convertString('name');
|
||||
$data['accounts'] = $this->parseAccounts($this->get('accounts'));
|
||||
|
||||
@@ -64,7 +64,7 @@ class StoreRequest extends FormRequest
|
||||
return [
|
||||
'group_title' => $this->convertString('group_title'),
|
||||
'error_if_duplicate_hash' => $this->boolean('error_if_duplicate_hash'),
|
||||
'batch_submission' => $this->boolean('batch_submission'),
|
||||
'batch_submission' => $this->boolean('batch_submission'),
|
||||
'apply_rules' => $this->boolean('apply_rules', true),
|
||||
'fire_webhooks' => $this->boolean('fire_webhooks', true),
|
||||
'transactions' => $this->getTransactionData(),
|
||||
|
||||
@@ -113,9 +113,7 @@ class UpdateRequest extends FormRequest
|
||||
];
|
||||
$this->booleanFields = ['reconciled'];
|
||||
$this->arrayFields = ['tags'];
|
||||
$data = [
|
||||
'batch_submission' => false,
|
||||
];
|
||||
$data = ['batch_submission' => false];
|
||||
if ($this->has('transactions')) {
|
||||
$data['transactions'] = $this->getTransactionData();
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ class CorrectsMetaDataFields extends Command
|
||||
|
||||
private function rename(string $original, string $update): void
|
||||
{
|
||||
$total = DB::table('journal_meta')->where('name', '=', $original)->update(['name' => $update]);
|
||||
$total = DB::table('journal_meta')->where('name', '=', $original)->update(['name' => $update]);
|
||||
$this->count += $total;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +295,11 @@ class UpgradesTransferCurrencies extends Command
|
||||
{
|
||||
if (null === $this->sourceTransaction->transaction_currency_id && $this->sourceCurrency instanceof TransactionCurrency) {
|
||||
$this->sourceTransaction->transaction_currency_id = $this->sourceCurrency->id;
|
||||
$message = sprintf('Transaction #%d has no currency setting, now set to %s.', $this->sourceTransaction->id, $this->sourceCurrency->code);
|
||||
$message = sprintf(
|
||||
'Transaction #%d has no currency setting, now set to %s.',
|
||||
$this->sourceTransaction->id,
|
||||
$this->sourceCurrency->code
|
||||
);
|
||||
$this->friendlyInfo($message);
|
||||
++$this->count;
|
||||
$this->sourceTransaction->save();
|
||||
@@ -335,7 +339,11 @@ class UpgradesTransferCurrencies extends Command
|
||||
{
|
||||
if (null === $this->destinationTransaction->transaction_currency_id && $this->destinationCurrency instanceof TransactionCurrency) {
|
||||
$this->destinationTransaction->transaction_currency_id = $this->destinationCurrency->id;
|
||||
$message = sprintf('Transaction #%d has no currency setting, now set to %s.', $this->destinationTransaction->id, $this->destinationCurrency->code);
|
||||
$message = sprintf(
|
||||
'Transaction #%d has no currency setting, now set to %s.',
|
||||
$this->destinationTransaction->id,
|
||||
$this->destinationCurrency->code
|
||||
);
|
||||
$this->friendlyInfo($message);
|
||||
++$this->count;
|
||||
$this->destinationTransaction->save();
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* CreatedSingleTransactionGroup.php
|
||||
* Copyright (c) 2026 james@firefly-iii.org
|
||||
@@ -33,8 +36,10 @@ class CreatedSingleTransactionGroup extends Event
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct(public TransactionGroup $transactionGroup, public TransactionGroupEventFlags $flags) {
|
||||
public function __construct(
|
||||
public TransactionGroup $transactionGroup,
|
||||
public TransactionGroupEventFlags $flags
|
||||
) {
|
||||
Log::debug(__METHOD__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* CreatedTransactionGroupBatch.php
|
||||
* Copyright (c) 2026 james@firefly-iii.org
|
||||
@@ -32,5 +35,8 @@ class CreatedTransactionGroupInBatch extends Event
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct(public Collection $collection, public array $flags) {}
|
||||
public function __construct(
|
||||
public Collection $collection,
|
||||
public array $flags
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* TransactionGroupEventFlags.php
|
||||
* Copyright (c) 2026 james@firefly-iii.org
|
||||
@@ -23,9 +26,8 @@ namespace FireflyIII\Events\Model\TransactionGroup;
|
||||
|
||||
class TransactionGroupEventFlags
|
||||
{
|
||||
public bool $applyRules = true;
|
||||
public bool $fireWebhooks = true;
|
||||
public bool $batchSubmission = false;
|
||||
public bool $applyRules = true;
|
||||
public bool $fireWebhooks = true;
|
||||
public bool $batchSubmission = false;
|
||||
public bool $recalculateCredit = true;
|
||||
|
||||
}
|
||||
|
||||
@@ -32,5 +32,7 @@ class NewInvitationCreated extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public function __construct(public InvitedUser $invitee) {}
|
||||
public function __construct(
|
||||
public InvitedUser $invitee
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -37,5 +37,9 @@ class StoredTransactionGroup extends Event
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct(public TransactionGroup $transactionGroup, public bool $applyRules, public bool $fireWebhooks) {}
|
||||
public function __construct(
|
||||
public TransactionGroup $transactionGroup,
|
||||
public bool $applyRules,
|
||||
public bool $fireWebhooks
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ use FireflyIII\Validation\AccountValidator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use JsonException;
|
||||
|
||||
use function Safe\json_encode;
|
||||
|
||||
/**
|
||||
@@ -66,17 +67,17 @@ class TransactionJournalFactory
|
||||
{
|
||||
use JournalServiceTrait;
|
||||
|
||||
private AccountRepositoryInterface $accountRepository;
|
||||
private AccountValidator $accountValidator;
|
||||
private BillRepositoryInterface $billRepository;
|
||||
private CurrencyRepositoryInterface $currencyRepository;
|
||||
private bool $errorOnHash = false;
|
||||
private array $fields;
|
||||
private PiggyBankEventFactory $piggyEventFactory;
|
||||
private PiggyBankRepositoryInterface $piggyRepository;
|
||||
private AccountRepositoryInterface $accountRepository;
|
||||
private AccountValidator $accountValidator;
|
||||
private BillRepositoryInterface $billRepository;
|
||||
private CurrencyRepositoryInterface $currencyRepository;
|
||||
private bool $errorOnHash = false;
|
||||
private array $fields;
|
||||
private PiggyBankEventFactory $piggyEventFactory;
|
||||
private PiggyBankRepositoryInterface $piggyRepository;
|
||||
private TransactionTypeRepositoryInterface $typeRepository;
|
||||
private User $user;
|
||||
private UserGroup $userGroup;
|
||||
private User $user;
|
||||
private UserGroup $userGroup;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -108,11 +109,11 @@ class TransactionJournalFactory
|
||||
{
|
||||
Log::debug('Now in TransactionJournalFactory::create()');
|
||||
// convert to special object.
|
||||
//$dataObject = new NullArrayObject($data);
|
||||
// $dataObject = new NullArrayObject($data);
|
||||
|
||||
Log::debug('Start of TransactionJournalFactory::create()');
|
||||
$collection = new Collection();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
$collection = new Collection();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
if (0 === count($transactions)) {
|
||||
Log::error('There are no transactions in the array, the TransactionJournalFactory cannot continue.');
|
||||
|
||||
@@ -125,7 +126,7 @@ class TransactionJournalFactory
|
||||
foreach ($transactions as $index => $row) {
|
||||
$row['batch_submission'] = $batchSubmission;
|
||||
Log::debug(sprintf('Now creating journal %d/%d', $index + 1, count($transactions)));
|
||||
$journal = $this->createJournal($row);
|
||||
$journal = $this->createJournal($row);
|
||||
if ($journal instanceof TransactionJournal) {
|
||||
$collection->push($journal);
|
||||
}
|
||||
@@ -169,18 +170,18 @@ class TransactionJournalFactory
|
||||
$this->errorIfDuplicate($row['import_hash_v2']);
|
||||
|
||||
// Some basic fields
|
||||
$type = $this->typeRepository->findTransactionType(null, $row['type']);
|
||||
$carbon = $row['date'] ?? today(config('app.timezone'));
|
||||
$order = $row['order'] ?? 0;
|
||||
$type = $this->typeRepository->findTransactionType(null, $row['type']);
|
||||
$carbon = $row['date'] ?? today(config('app.timezone'));
|
||||
$order = $row['order'] ?? 0;
|
||||
|
||||
Log::debug('Find currency or return default.');
|
||||
$currency = $this->currencyRepository->findCurrency((int)$row['currency_id'], $row['currency_code']);
|
||||
$currency = $this->currencyRepository->findCurrency((int) $row['currency_id'], $row['currency_code']);
|
||||
Log::debug('Find foreign currency or return NULL.');
|
||||
|
||||
$foreignCurrency = $this->currencyRepository->findCurrencyNull($row['foreign_currency_id'], $row['foreign_currency_code']);
|
||||
$bill = $this->billRepository->findBill((int)$row['bill_id'], $row['bill_name']);
|
||||
$billId = TransactionTypeEnum::WITHDRAWAL->value === $type->type && $bill instanceof Bill ? $bill->id : null;
|
||||
$description = (string)$row['description'];
|
||||
$foreignCurrency = $this->currencyRepository->findCurrencyNull($row['foreign_currency_id'], $row['foreign_currency_code']);
|
||||
$bill = $this->billRepository->findBill((int) $row['bill_id'], $row['bill_name']);
|
||||
$billId = TransactionTypeEnum::WITHDRAWAL->value === $type->type && $bill instanceof Bill ? $bill->id : null;
|
||||
$description = (string) $row['description'];
|
||||
|
||||
// Manipulate basic fields
|
||||
$carbon->setTimezone(config('app.timezone'));
|
||||
@@ -202,7 +203,7 @@ class TransactionJournalFactory
|
||||
}
|
||||
|
||||
/** create or get source and destination accounts */
|
||||
$sourceInfo = [
|
||||
$sourceInfo = [
|
||||
'id' => $row['source_id'],
|
||||
'name' => $row['source_name'],
|
||||
'iban' => $row['source_iban'],
|
||||
@@ -211,7 +212,7 @@ class TransactionJournalFactory
|
||||
'currency_id' => $currency->id,
|
||||
];
|
||||
|
||||
$destInfo = [
|
||||
$destInfo = [
|
||||
'id' => $row['destination_id'],
|
||||
'name' => $row['destination_name'],
|
||||
'iban' => $row['destination_iban'],
|
||||
@@ -221,8 +222,8 @@ class TransactionJournalFactory
|
||||
];
|
||||
Log::debug('Source info:', $sourceInfo);
|
||||
Log::debug('Destination info:', $destInfo);
|
||||
$destinationAccount = null;
|
||||
$sourceAccount = null;
|
||||
$destinationAccount = null;
|
||||
$sourceAccount = null;
|
||||
if (TransactionTypeEnum::DEPOSIT->value === $type->type) {
|
||||
Log::debug('Transaction type is deposit, start with destination first.');
|
||||
$destinationAccount = $this->getAccount($type->type, 'destination', $destInfo);
|
||||
@@ -247,38 +248,38 @@ class TransactionJournalFactory
|
||||
[$sourceAccount, $destinationAccount] = $this->reconciliationSanityCheck($sourceAccount, $destinationAccount);
|
||||
}
|
||||
|
||||
$currency = $this->getCurrencyByAccount($type->type, $currency, $sourceAccount, $destinationAccount);
|
||||
$foreignCurrency = $this->compareCurrencies($currency, $foreignCurrency);
|
||||
$foreignCurrency = $this->getForeignByAccount($type->type, $foreignCurrency, $destinationAccount);
|
||||
$description = $this->getDescription($description);
|
||||
$currency = $this->getCurrencyByAccount($type->type, $currency, $sourceAccount, $destinationAccount);
|
||||
$foreignCurrency = $this->compareCurrencies($currency, $foreignCurrency);
|
||||
$foreignCurrency = $this->getForeignByAccount($type->type, $foreignCurrency, $destinationAccount);
|
||||
$description = $this->getDescription($description);
|
||||
|
||||
Log::debug(sprintf(
|
||||
'Currency is #%d "%s", foreign currency is #%d "%s"',
|
||||
$currency->id,
|
||||
$currency->code,
|
||||
$foreignCurrency?->id,
|
||||
$foreignCurrency?->code
|
||||
));
|
||||
'Currency is #%d "%s", foreign currency is #%d "%s"',
|
||||
$currency->id,
|
||||
$currency->code,
|
||||
$foreignCurrency?->id,
|
||||
$foreignCurrency?->code
|
||||
));
|
||||
Log::debug(sprintf('Date: %s (%s)', $carbon->toW3cString(), $carbon->getTimezone()->getName()));
|
||||
|
||||
/** Create a basic journal. */
|
||||
$journal = TransactionJournal::create([
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->userGroup->id,
|
||||
'transaction_type_id' => $type->id,
|
||||
'bill_id' => $billId,
|
||||
'transaction_currency_id' => $currency->id,
|
||||
'description' => substr($description, 0, 1000),
|
||||
'date' => $carbon,
|
||||
'date_tz' => $carbon->format('e'),
|
||||
'order' => $order,
|
||||
'tag_count' => 0,
|
||||
'completed' => !$row['batch_submission'],
|
||||
]);
|
||||
$journal = TransactionJournal::create([
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->userGroup->id,
|
||||
'transaction_type_id' => $type->id,
|
||||
'bill_id' => $billId,
|
||||
'transaction_currency_id' => $currency->id,
|
||||
'description' => substr($description, 0, 1000),
|
||||
'date' => $carbon,
|
||||
'date_tz' => $carbon->format('e'),
|
||||
'order' => $order,
|
||||
'tag_count' => 0,
|
||||
'completed' => !$row['batch_submission'],
|
||||
]);
|
||||
Log::debug(sprintf('Created new journal #%d: "%s"', $journal->id, $journal->description));
|
||||
|
||||
/** Create two transactions. */
|
||||
$transactionFactory = app(TransactionFactory::class);
|
||||
$transactionFactory = app(TransactionFactory::class);
|
||||
$transactionFactory->setJournal($journal);
|
||||
$transactionFactory->setAccount($sourceAccount);
|
||||
$transactionFactory->setCurrency($currency);
|
||||
@@ -287,7 +288,7 @@ class TransactionJournalFactory
|
||||
$transactionFactory->setReconciled($row['reconciled'] ?? false);
|
||||
|
||||
try {
|
||||
$negative = $transactionFactory->createNegative((string)$row['amount'], (string)$row['foreign_amount']);
|
||||
$negative = $transactionFactory->createNegative((string) $row['amount'], (string) $row['foreign_amount']);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error(sprintf('Exception creating negative transaction: %s', $e->getMessage()));
|
||||
$this->forceDeleteOnError(new Collection()->push($journal));
|
||||
@@ -296,7 +297,7 @@ class TransactionJournalFactory
|
||||
}
|
||||
|
||||
/** @var TransactionFactory $transactionFactory */
|
||||
$transactionFactory = app(TransactionFactory::class);
|
||||
$transactionFactory = app(TransactionFactory::class);
|
||||
$transactionFactory->setJournal($journal);
|
||||
$transactionFactory->setAccount($destinationAccount);
|
||||
$transactionFactory->setAccountInformation($destInfo);
|
||||
@@ -308,8 +309,8 @@ class TransactionJournalFactory
|
||||
// Firefly III will save the foreign currency information in such a way that both
|
||||
// asset accounts can look at the "amount" and "transaction_currency_id" column and
|
||||
// see the currency they expect to see.
|
||||
$amount = (string)$row['amount'];
|
||||
$foreignAmount = (string)$row['foreign_amount'];
|
||||
$amount = (string) $row['amount'];
|
||||
$foreignAmount = (string) $row['foreign_amount'];
|
||||
if (
|
||||
$foreignCurrency instanceof TransactionCurrency
|
||||
&& $foreignCurrency->id !== $currency->id
|
||||
@@ -317,8 +318,8 @@ class TransactionJournalFactory
|
||||
) {
|
||||
$transactionFactory->setCurrency($foreignCurrency);
|
||||
$transactionFactory->setForeignCurrency($currency);
|
||||
$amount = (string)$row['foreign_amount'];
|
||||
$foreignAmount = (string)$row['amount'];
|
||||
$amount = (string) $row['foreign_amount'];
|
||||
$foreignAmount = (string) $row['amount'];
|
||||
Log::debug('Swap primary/foreign amounts in transfer for new save method.');
|
||||
}
|
||||
|
||||
@@ -377,17 +378,18 @@ class TransactionJournalFactory
|
||||
|
||||
/** @var null|TransactionJournalMeta $result */
|
||||
$result = TransactionJournalMeta::withTrashed()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
|
||||
->whereNotNull('transaction_journals.id')
|
||||
->where('transaction_journals.user_id', $this->user->id)
|
||||
->where('data', json_encode($hash, JSON_THROW_ON_ERROR))
|
||||
->with(['transactionJournal', 'transactionJournal.transactionGroup'])
|
||||
->first(['journal_meta.*']);
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
|
||||
->whereNotNull('transaction_journals.id')
|
||||
->where('transaction_journals.user_id', $this->user->id)
|
||||
->where('data', json_encode($hash, JSON_THROW_ON_ERROR))
|
||||
->with(['transactionJournal', 'transactionJournal.transactionGroup'])
|
||||
->first(['journal_meta.*'])
|
||||
;
|
||||
if (null !== $result) {
|
||||
Log::warning(sprintf('Found a duplicate in errorIfDuplicate because hash %s is not unique!', $hash));
|
||||
$journal = $result->transactionJournal()->withTrashed()->first();
|
||||
$group = $journal?->transactionGroup()->withTrashed()->first();
|
||||
$groupId = (int)$group?->id;
|
||||
$groupId = (int) $group?->id;
|
||||
|
||||
throw new DuplicateTransactionException(sprintf('Duplicate of transaction #%d.', $groupId));
|
||||
}
|
||||
@@ -399,18 +401,18 @@ class TransactionJournalFactory
|
||||
private function validateAccounts(array $data): void
|
||||
{
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
$transactionType = $data['type'] ?? 'invalid';
|
||||
$transactionType = $data['type'] ?? 'invalid';
|
||||
$this->accountValidator->setUser($this->user);
|
||||
$this->accountValidator->setTransactionType($transactionType);
|
||||
|
||||
// validate source account.
|
||||
$array = [
|
||||
'id' => null !== $data['source_id'] ? (int)$data['source_id'] : null,
|
||||
'name' => null !== $data['source_name'] ? (string)$data['source_name'] : null,
|
||||
'iban' => null !== $data['source_iban'] ? (string)$data['source_iban'] : null,
|
||||
'number' => null !== $data['source_number'] ? (string)$data['source_number'] : null,
|
||||
$array = [
|
||||
'id' => null !== $data['source_id'] ? (int) $data['source_id'] : null,
|
||||
'name' => null !== $data['source_name'] ? (string) $data['source_name'] : null,
|
||||
'iban' => null !== $data['source_iban'] ? (string) $data['source_iban'] : null,
|
||||
'number' => null !== $data['source_number'] ? (string) $data['source_number'] : null,
|
||||
];
|
||||
$validSource = $this->accountValidator->validateSource($array);
|
||||
$validSource = $this->accountValidator->validateSource($array);
|
||||
|
||||
// do something with result:
|
||||
if (false === $validSource) {
|
||||
@@ -419,11 +421,11 @@ class TransactionJournalFactory
|
||||
Log::debug('Source seems valid.');
|
||||
|
||||
// validate destination account
|
||||
$array = [
|
||||
'id' => null !== $data['destination_id'] ? (int)$data['destination_id'] : null,
|
||||
'name' => null !== $data['destination_name'] ? (string)$data['destination_name'] : null,
|
||||
'iban' => null !== $data['destination_iban'] ? (string)$data['destination_iban'] : null,
|
||||
'number' => null !== $data['destination_number'] ? (string)$data['destination_number'] : null,
|
||||
$array = [
|
||||
'id' => null !== $data['destination_id'] ? (int) $data['destination_id'] : null,
|
||||
'name' => null !== $data['destination_name'] ? (string) $data['destination_name'] : null,
|
||||
'iban' => null !== $data['destination_iban'] ? (string) $data['destination_iban'] : null,
|
||||
'number' => null !== $data['destination_number'] ? (string) $data['destination_number'] : null,
|
||||
];
|
||||
|
||||
$validDestination = $this->accountValidator->validateDestination($array);
|
||||
@@ -508,7 +510,7 @@ class TransactionJournalFactory
|
||||
// return user's default:
|
||||
return Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
|
||||
}
|
||||
$result = $preference ?? $currency;
|
||||
$result = $preference ?? $currency;
|
||||
Log::debug(sprintf('Currency is now #%d (%s) because of account #%d (%s)', $result->id, $result->code, $account->id, $account->name));
|
||||
|
||||
return $result;
|
||||
@@ -578,7 +580,7 @@ class TransactionJournalFactory
|
||||
{
|
||||
Log::debug('Will now store piggy event.');
|
||||
|
||||
$piggyBank = $this->piggyRepository->findPiggyBank((int)$data['piggy_bank_id'], $data['piggy_bank_name']);
|
||||
$piggyBank = $this->piggyRepository->findPiggyBank((int) $data['piggy_bank_id'], $data['piggy_bank_name']);
|
||||
|
||||
if ($piggyBank instanceof PiggyBank) {
|
||||
$this->piggyEventFactory->create($journal, $piggyBank);
|
||||
@@ -598,7 +600,7 @@ class TransactionJournalFactory
|
||||
|
||||
protected function storeMeta(TransactionJournal $journal, array $data, string $field): void
|
||||
{
|
||||
$set = ['journal' => $journal, 'name' => $field, 'data' => (string)($data[$field] ?? '')];
|
||||
$set = ['journal' => $journal, 'name' => $field, 'data' => (string) ($data[$field] ?? '')];
|
||||
if (array_key_exists($field, $data) && $data[$field] instanceof Carbon) {
|
||||
$data[$field]->setTimezone(config('app.timezone'));
|
||||
Log::debug(sprintf('%s Date: %s (%s)', $field, $data[$field], $data[$field]->timezone->getName()));
|
||||
|
||||
@@ -55,8 +55,8 @@ class StoredGroupEventHandler
|
||||
|
||||
public function triggerRulesManually(TriggeredStoredTransactionGroup $event): void
|
||||
{
|
||||
// $newEvent = new StoredTransactionGroup($event->transactionGroup, true, false);
|
||||
// $this->processRules($newEvent, $event->ruleGroup);
|
||||
// $newEvent = new StoredTransactionGroup($event->transactionGroup, true, false);
|
||||
// $this->processRules($newEvent, $event->ruleGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Handlers\Observer;
|
||||
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
|
||||
@@ -23,7 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Admin;
|
||||
|
||||
|
||||
use FireflyIII\Events\Security\System\NewInvitationCreated;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
|
||||
@@ -167,7 +167,7 @@ class LoginController extends Controller
|
||||
*/
|
||||
protected function sendFailedLoginResponse(Request $request): void
|
||||
{
|
||||
$exception = ValidationException::withMessages([$this->username() => [trans('auth.failed')]]);
|
||||
$exception = ValidationException::withMessages([$this->username() => [trans('auth.failed')]]);
|
||||
$exception->redirectTo = route('login');
|
||||
|
||||
throw $exception;
|
||||
|
||||
@@ -192,7 +192,10 @@ class IndexController extends Controller
|
||||
if (count($bill['paid_dates']) < count($bill['pay_dates'])) {
|
||||
$count = count($bill['pay_dates']) - count($bill['paid_dates']);
|
||||
if ($count > 0) {
|
||||
$avg = bcdiv(bcadd((string) $bill['amount_min'], (string) $bill['amount_max']), '2');
|
||||
$avg = bcdiv(
|
||||
bcadd((string) $bill['amount_min'], (string) $bill['amount_max']),
|
||||
'2'
|
||||
);
|
||||
$avg = bcmul($avg, (string) $count);
|
||||
$sums[$groupOrder][$currencyId]['total_left_to_pay'] = bcadd($sums[$groupOrder][$currencyId]['total_left_to_pay'], $avg);
|
||||
Log::debug(
|
||||
|
||||
@@ -197,7 +197,13 @@ class BudgetLimitController extends Controller
|
||||
if ($request->expectsJson()) {
|
||||
$array = $limit->toArray();
|
||||
// add some extra metadata:
|
||||
$spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection()->push($budget), $currency);
|
||||
$spentArr = $this->opsRepository->sumExpenses(
|
||||
$limit->start_date,
|
||||
$limit->end_date,
|
||||
null,
|
||||
new Collection()->push($budget),
|
||||
$currency
|
||||
);
|
||||
$array['spent'] = $spentArr[$currency->id]['sum'] ?? '0';
|
||||
$array['left_formatted'] = Amount::formatAnything($limit->transactionCurrency, bcadd($array['spent'], (string) $array['amount']));
|
||||
$array['amount_formatted'] = Amount::formatAnything($limit->transactionCurrency, $limit['amount']);
|
||||
|
||||
@@ -73,7 +73,7 @@ class BillController extends Controller
|
||||
*/
|
||||
foreach ($paid as $info) {
|
||||
$amount = $info['sum'];
|
||||
$label = (string) trans('firefly.paid_in_currency', ['currency' => $info['name']]);
|
||||
$label = (string) trans('firefly.paid_in_currency', ['currency' => $info['name']]);
|
||||
$chartData[$label] = ['amount' => $amount, 'currency_symbol' => $info['symbol'], 'currency_code' => $info['code']];
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class BillController extends Controller
|
||||
*/
|
||||
foreach ($unpaid as $info) {
|
||||
$amount = $info['sum'];
|
||||
$label = (string) trans('firefly.unpaid_in_currency', ['currency' => $info['name']]);
|
||||
$label = (string) trans('firefly.unpaid_in_currency', ['currency' => $info['name']]);
|
||||
$chartData[$label] = ['amount' => $amount, 'currency_symbol' => $info['symbol'], 'currency_code' => $info['code']];
|
||||
}
|
||||
|
||||
|
||||
@@ -539,7 +539,13 @@ class BudgetController extends Controller
|
||||
}
|
||||
|
||||
// get spent amount in this period for this currency.
|
||||
$sum = $this->opsRepository->sumExpenses($currentStart, $currentEnd, $accounts, new Collection()->push($budget), $currency);
|
||||
$sum = $this->opsRepository->sumExpenses(
|
||||
$currentStart,
|
||||
$currentEnd,
|
||||
$accounts,
|
||||
new Collection()->push($budget),
|
||||
$currency
|
||||
);
|
||||
$amount = Steam::positive($sum[$currency->id]['sum'] ?? '0');
|
||||
$chartData[0]['entries'][$title] = Steam::bcround($amount, $currency->decimal_places);
|
||||
|
||||
|
||||
@@ -76,7 +76,11 @@ class TransactionController extends Controller
|
||||
foreach ($result as $journal) {
|
||||
$budget = $journal['budget_name'] ?? (string) trans('firefly.no_budget');
|
||||
$title = sprintf('%s (%s)', $budget, $journal['currency_symbol']);
|
||||
$data[$title] ??= ['amount' => '0', 'currency_symbol' => $journal['currency_symbol'], 'currency_code' => $journal['currency_code']];
|
||||
$data[$title] ??= [
|
||||
'amount' => '0',
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
];
|
||||
$data[$title]['amount'] = bcadd($data[$title]['amount'], (string) $journal['amount']);
|
||||
}
|
||||
$chart = $this->generator->multiCurrencyPieChart($data);
|
||||
@@ -122,7 +126,11 @@ class TransactionController extends Controller
|
||||
foreach ($result as $journal) {
|
||||
$category = $journal['category_name'] ?? (string) trans('firefly.no_category');
|
||||
$title = sprintf('%s (%s)', $category, $journal['currency_symbol']);
|
||||
$data[$title] ??= ['amount' => '0', 'currency_symbol' => $journal['currency_symbol'], 'currency_code' => $journal['currency_code']];
|
||||
$data[$title] ??= [
|
||||
'amount' => '0',
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
];
|
||||
$data[$title]['amount'] = bcadd($data[$title]['amount'], (string) $journal['amount']);
|
||||
}
|
||||
$chart = $this->generator->multiCurrencyPieChart($data);
|
||||
@@ -168,7 +176,11 @@ class TransactionController extends Controller
|
||||
foreach ($result as $journal) {
|
||||
$name = $journal['destination_account_name'];
|
||||
$title = sprintf('%s (%s)', $name, $journal['currency_symbol']);
|
||||
$data[$title] ??= ['amount' => '0', 'currency_symbol' => $journal['currency_symbol'], 'currency_code' => $journal['currency_code']];
|
||||
$data[$title] ??= [
|
||||
'amount' => '0',
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
];
|
||||
$data[$title]['amount'] = bcadd($data[$title]['amount'], (string) $journal['amount']);
|
||||
}
|
||||
$chart = $this->generator->multiCurrencyPieChart($data);
|
||||
@@ -214,7 +226,11 @@ class TransactionController extends Controller
|
||||
foreach ($result as $journal) {
|
||||
$name = $journal['source_account_name'];
|
||||
$title = sprintf('%s (%s)', $name, $journal['currency_symbol']);
|
||||
$data[$title] ??= ['amount' => '0', 'currency_symbol' => $journal['currency_symbol'], 'currency_code' => $journal['currency_code']];
|
||||
$data[$title] ??= [
|
||||
'amount' => '0',
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
];
|
||||
$data[$title]['amount'] = bcadd($data[$title]['amount'], (string) $journal['amount']);
|
||||
}
|
||||
$chart = $this->generator->multiCurrencyPieChart($data);
|
||||
|
||||
@@ -95,7 +95,11 @@ class CategoryController extends Controller
|
||||
'categories' => [],
|
||||
];
|
||||
|
||||
$report[$sourceAccountId]['currencies'][$currencyId]['categories'][$category['id']] ??= ['spent' => '0', 'earned' => '0', 'sum' => '0'];
|
||||
$report[$sourceAccountId]['currencies'][$currencyId]['categories'][$category['id']] ??= [
|
||||
'spent' => '0',
|
||||
'earned' => '0',
|
||||
'sum' => '0',
|
||||
];
|
||||
$report[$sourceAccountId]['currencies'][$currencyId]['categories'][$category['id']]['spent'] = bcadd(
|
||||
$report[$sourceAccountId]['currencies'][$currencyId]['categories'][$category['id']]['spent'],
|
||||
(string) $journal['amount']
|
||||
@@ -122,7 +126,11 @@ class CategoryController extends Controller
|
||||
'currency_decimal_places' => $currency['currency_decimal_places'],
|
||||
'categories' => [],
|
||||
];
|
||||
$report[$destinationId]['currencies'][$currencyId]['categories'][$category['id']] ??= ['spent' => '0', 'earned' => '0', 'sum' => '0'];
|
||||
$report[$destinationId]['currencies'][$currencyId]['categories'][$category['id']] ??= [
|
||||
'spent' => '0',
|
||||
'earned' => '0',
|
||||
'sum' => '0',
|
||||
];
|
||||
$report[$destinationId]['currencies'][$currencyId]['categories'][$category['id']]['earned'] = bcadd(
|
||||
$report[$destinationId]['currencies'][$currencyId]['categories'][$category['id']]['earned'],
|
||||
(string) $journal['amount']
|
||||
|
||||
@@ -77,7 +77,7 @@ class CreateController extends Controller
|
||||
$newGroup = $service->cloneGroup($group);
|
||||
|
||||
// event!
|
||||
$flags = new TransactionGroupEventFlags();
|
||||
$flags = new TransactionGroupEventFlags();
|
||||
event(new CreatedSingleTransactionGroup($group, $flags));
|
||||
// event(new StoredTransactionGroup($newGroup, true, true));
|
||||
|
||||
@@ -110,29 +110,29 @@ class CreateController extends Controller
|
||||
{
|
||||
Preferences::mark();
|
||||
|
||||
$sourceId = (int) request()->get('source');
|
||||
$destinationId = (int) request()->get('destination');
|
||||
$sourceId = (int) request()->get('source');
|
||||
$destinationId = (int) request()->get('destination');
|
||||
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$cash = $accountRepository->getCashAccount();
|
||||
$preFilled = session()->has('preFilled') ? session('preFilled') : [];
|
||||
$subTitle = (string) trans(sprintf('breadcrumbs.create_%s', strtolower((string) $objectType)));
|
||||
$subTitleIcon = 'fa-plus';
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$cash = $accountRepository->getCashAccount();
|
||||
$preFilled = session()->has('preFilled') ? session('preFilled') : [];
|
||||
$subTitle = (string) trans(sprintf('breadcrumbs.create_%s', strtolower((string) $objectType)));
|
||||
$subTitleIcon = 'fa-plus';
|
||||
|
||||
/** @var null|array $optionalFields */
|
||||
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
|
||||
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
|
||||
$accountToTypes = config('firefly.account_to_transaction');
|
||||
$previousUrl = $this->rememberPreviousUrl('transactions.create.url');
|
||||
$parts = parse_url((string) $previousUrl);
|
||||
$search = sprintf('?%s', $parts['query'] ?? '');
|
||||
$previousUrl = str_replace($search, '', $previousUrl);
|
||||
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
|
||||
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
|
||||
$accountToTypes = config('firefly.account_to_transaction');
|
||||
$previousUrl = $this->rememberPreviousUrl('transactions.create.url');
|
||||
$parts = parse_url((string) $previousUrl);
|
||||
$search = sprintf('?%s', $parts['query'] ?? '');
|
||||
$previousUrl = str_replace($search, '', $previousUrl);
|
||||
if (!is_array($optionalFields)) {
|
||||
$optionalFields = [];
|
||||
}
|
||||
// not really a fan of this, but meh.
|
||||
$optionalDateFields = [
|
||||
$optionalDateFields = [
|
||||
'interest_date' => $optionalFields['interest_date'] ?? false,
|
||||
'book_date' => $optionalFields['book_date'] ?? false,
|
||||
'process_date' => $optionalFields['process_date'] ?? false,
|
||||
@@ -142,13 +142,13 @@ class CreateController extends Controller
|
||||
];
|
||||
$optionalFields['external_url'] ??= false;
|
||||
$optionalFields['location'] ??= false;
|
||||
$optionalFields['location']
|
||||
= $optionalFields['location'] && true === FireflyConfig::get('enable_external_map', config('firefly.enable_external_map'))->data;
|
||||
$optionalFields['location'] = $optionalFields['location']
|
||||
&& true === FireflyConfig::get('enable_external_map', config('firefly.enable_external_map'))->data;
|
||||
|
||||
// map info:
|
||||
$longitude = config('firefly.default_location.longitude');
|
||||
$latitude = config('firefly.default_location.latitude');
|
||||
$zoomLevel = config('firefly.default_location.zoom_level');
|
||||
$longitude = config('firefly.default_location.longitude');
|
||||
$latitude = config('firefly.default_location.latitude');
|
||||
$zoomLevel = config('firefly.default_location.zoom_level');
|
||||
|
||||
session()->put('preFilled', $preFilled);
|
||||
|
||||
|
||||
@@ -83,29 +83,29 @@ class EditController extends Controller
|
||||
}
|
||||
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
|
||||
$accountToTypes = config('firefly.account_to_transaction');
|
||||
$expectedSourceTypes = config('firefly.expected_source_types');
|
||||
$allowedSourceDests = config('firefly.source_dests');
|
||||
$title = $transactionGroup->transactionJournals()->count() > 1
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
|
||||
$accountToTypes = config('firefly.account_to_transaction');
|
||||
$expectedSourceTypes = config('firefly.expected_source_types');
|
||||
$allowedSourceDests = config('firefly.source_dests');
|
||||
$title = $transactionGroup->transactionJournals()->count() > 1
|
||||
? $transactionGroup->title
|
||||
: $transactionGroup->transactionJournals()->first()->description;
|
||||
$subTitle = (string) trans('firefly.edit_transaction_title', ['description' => $title]);
|
||||
$subTitleIcon = 'fa-plus';
|
||||
$cash = $repository->getCashAccount();
|
||||
$previousUrl = $this->rememberPreviousUrl('transactions.edit.url');
|
||||
$parts = parse_url((string) $previousUrl);
|
||||
$search = sprintf('?%s', $parts['query'] ?? '');
|
||||
$previousUrl = str_replace($search, '', $previousUrl);
|
||||
$subTitle = (string) trans('firefly.edit_transaction_title', ['description' => $title]);
|
||||
$subTitleIcon = 'fa-plus';
|
||||
$cash = $repository->getCashAccount();
|
||||
$previousUrl = $this->rememberPreviousUrl('transactions.edit.url');
|
||||
$parts = parse_url((string) $previousUrl);
|
||||
$search = sprintf('?%s', $parts['query'] ?? '');
|
||||
$previousUrl = str_replace($search, '', $previousUrl);
|
||||
|
||||
// settings necessary for v2
|
||||
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
|
||||
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
|
||||
if (!is_array($optionalFields)) {
|
||||
$optionalFields = [];
|
||||
}
|
||||
// not really a fan of this, but meh.
|
||||
$optionalDateFields = [
|
||||
$optionalDateFields = [
|
||||
'interest_date' => $optionalFields['interest_date'] ?? false,
|
||||
'book_date' => $optionalFields['book_date'] ?? false,
|
||||
'process_date' => $optionalFields['process_date'] ?? false,
|
||||
@@ -115,13 +115,13 @@ class EditController extends Controller
|
||||
];
|
||||
$optionalFields['external_url'] ??= false;
|
||||
$optionalFields['location'] ??= false;
|
||||
$optionalFields['location']
|
||||
= $optionalFields['location'] && true === FireflyConfig::get('enable_external_map', config('firefly.enable_external_map'))->data;
|
||||
$optionalFields['location'] = $optionalFields['location']
|
||||
&& true === FireflyConfig::get('enable_external_map', config('firefly.enable_external_map'))->data;
|
||||
|
||||
// map info voor v2:
|
||||
$longitude = config('firefly.default_location.longitude');
|
||||
$latitude = config('firefly.default_location.latitude');
|
||||
$zoomLevel = config('firefly.default_location.zoom_level');
|
||||
$longitude = config('firefly.default_location.longitude');
|
||||
$latitude = config('firefly.default_location.latitude');
|
||||
$zoomLevel = config('firefly.default_location.zoom_level');
|
||||
|
||||
return view('transactions.edit', [
|
||||
'cash' => $cash,
|
||||
|
||||
@@ -78,7 +78,7 @@ class EditController extends Controller
|
||||
}
|
||||
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
$subTitle = (string) trans('breadcrumbs.edit_currency', ['name' => $currency->name]);
|
||||
$subTitle = (string) trans('breadcrumbs.edit_currency', ['name' => $currency->name]);
|
||||
$currency->symbol = htmlentities($currency->symbol);
|
||||
|
||||
// is currently enabled (for this user?)
|
||||
|
||||
+17
-19
@@ -44,24 +44,22 @@ use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
*/
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
protected $middleware
|
||||
= [
|
||||
// SecureHeaders::class,
|
||||
CheckForMaintenanceMode::class,
|
||||
ValidatePostSize::class,
|
||||
TrimStrings::class,
|
||||
ConvertEmptyStringsToNull::class,
|
||||
TrustProxies::class,
|
||||
InstallationId::class,
|
||||
];
|
||||
protected $middlewareAliases
|
||||
= [
|
||||
'auth' => Authenticate::class,
|
||||
'auth.basic' => AuthenticateWithBasicAuth::class,
|
||||
'bindings' => Binder::class,
|
||||
'can' => Authorize::class,
|
||||
'guest' => RedirectIfAuthenticated::class,
|
||||
'throttle' => ThrottleRequests::class,
|
||||
];
|
||||
protected $middleware = [
|
||||
// SecureHeaders::class,
|
||||
CheckForMaintenanceMode::class,
|
||||
ValidatePostSize::class,
|
||||
TrimStrings::class,
|
||||
ConvertEmptyStringsToNull::class,
|
||||
TrustProxies::class,
|
||||
InstallationId::class,
|
||||
];
|
||||
protected $middlewareAliases = [
|
||||
'auth' => Authenticate::class,
|
||||
'auth.basic' => AuthenticateWithBasicAuth::class,
|
||||
'bindings' => Binder::class,
|
||||
'can' => Authorize::class,
|
||||
'guest' => RedirectIfAuthenticated::class,
|
||||
'throttle' => ThrottleRequests::class,
|
||||
];
|
||||
protected $middlewarePriority = [StartFireflySession::class, ShareErrorsFromSession::class, Authenticate::class, Binder::class, Authorize::class];
|
||||
}
|
||||
|
||||
@@ -384,8 +384,8 @@ class CreateRecurringTransactions implements ShouldQueue
|
||||
Log::info(sprintf('Created new transaction group #%d', $group->id));
|
||||
|
||||
// trigger event:
|
||||
$flags = new TransactionGroupEventFlags();
|
||||
$flags->applyRules = $recurrence->apply_rules;
|
||||
$flags = new TransactionGroupEventFlags();
|
||||
$flags->applyRules = $recurrence->apply_rules;
|
||||
event(new CreatedSingleTransactionGroup($group, $flags));
|
||||
// event(new StoredTransactionGroup($group, $recurrence->apply_rules, true));
|
||||
$this->groups->push($group);
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* ProcessesNewTransactionGroup.php
|
||||
* Copyright (c) 2026 james@firefly-iii.org
|
||||
@@ -47,6 +50,7 @@ class ProcessesNewTransactionGroup implements ShouldQueue
|
||||
Log::debug(sprintf('In ProcessesNewTransactionGroup::handle(#%d)', $event->transactionGroup->id));
|
||||
if (true === $event->flags->batchSubmission) {
|
||||
Log::debug(sprintf('Will do nothing for group #%d because it is part of a batch.', $event->transactionGroup->id));
|
||||
|
||||
return;
|
||||
}
|
||||
Log::debug(sprintf('Will join group #%d with all other open transaction groups and process them.', $event->transactionGroup->id));
|
||||
@@ -55,6 +59,7 @@ class ProcessesNewTransactionGroup implements ShouldQueue
|
||||
$set = $collection->merge($repository->getUncompletedJournals());
|
||||
if (0 === $set->count()) {
|
||||
Log::debug('Set is empty, never mind.');
|
||||
|
||||
return;
|
||||
}
|
||||
if (!$event->flags->applyRules) {
|
||||
@@ -86,7 +91,6 @@ class ProcessesNewTransactionGroup implements ShouldQueue
|
||||
}
|
||||
|
||||
$repository->markAsCompleted($set);
|
||||
|
||||
}
|
||||
|
||||
private function recalculateRunningBalance(Collection $set): void
|
||||
@@ -94,27 +98,27 @@ class ProcessesNewTransactionGroup implements ShouldQueue
|
||||
Log::debug('Now in recalculateRunningBalance');
|
||||
// find the earliest date in the set, based on date and _internal_previous_date
|
||||
$earliest = $set->pluck('date')->sort()->first();
|
||||
$entries = TransactionJournalMeta
|
||||
::whereIn('transaction_journal_id', $set->pluck('id')->toArray())
|
||||
->where('name', '_internal_previous_date')
|
||||
->get(['journal_meta.*']);
|
||||
$entries = TransactionJournalMeta::whereIn('transaction_journal_id', $set->pluck('id')->toArray())->where('name', '_internal_previous_date')->get([
|
||||
'journal_meta.*',
|
||||
]);
|
||||
$array = $entries->toArray();
|
||||
if (count($array) > 0) {
|
||||
usort($array, function (array $a, array $b) {
|
||||
return Carbon::parse($a['data'])->gt(Carbon::parse($b['data']));
|
||||
});
|
||||
|
||||
/** @var Carbon $date */
|
||||
$date = Carbon::parse($array[0]['data']);
|
||||
$earliest = $date->lt($earliest) ? $date : $earliest;
|
||||
}
|
||||
|
||||
// get accounts
|
||||
$accounts = Account
|
||||
::leftJoin('transactions', 'transactions.account_id', 'accounts.id')
|
||||
$accounts = Account::leftJoin('transactions', 'transactions.account_id', 'accounts.id')
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', 'transactions.transaction_journal_id')
|
||||
->leftJoin('account_types', 'account_types.id', 'accounts.account_type_id')
|
||||
->whereIn('transaction_journals.id', $set->pluck('id')->toArray())
|
||||
->get(['accounts.*']);
|
||||
->get(['accounts.*'])
|
||||
;
|
||||
|
||||
AccountBalanceCalculator::optimizedCalculation($accounts, $earliest);
|
||||
}
|
||||
@@ -122,6 +126,7 @@ class ProcessesNewTransactionGroup implements ShouldQueue
|
||||
private function removePeriodStatistics(Collection $set): void
|
||||
{
|
||||
Log::debug('Always remove period statistics');
|
||||
|
||||
/** @var PeriodStatisticRepositoryInterface $repository */
|
||||
$repository = app(PeriodStatisticRepositoryInterface::class);
|
||||
$repository->deleteStatisticsForCollection($set);
|
||||
@@ -133,7 +138,7 @@ class ProcessesNewTransactionGroup implements ShouldQueue
|
||||
$groups = TransactionGroup::whereIn('id', array_unique($set->pluck('transaction_group_id')->toArray()))->get();
|
||||
|
||||
Log::debug(__METHOD__);
|
||||
$user = $set->first()->user;
|
||||
$user = $set->first()->user;
|
||||
|
||||
/** @var MessageGeneratorInterface $engine */
|
||||
$engine = app(MessageGeneratorInterface::class);
|
||||
@@ -164,9 +169,9 @@ class ProcessesNewTransactionGroup implements ShouldQueue
|
||||
private function processRules(Collection $set): void
|
||||
{
|
||||
Log::debug(sprintf('Will now processRules for %d journal(s)', $set->count()));
|
||||
$array = $set->pluck('id')->toArray();
|
||||
$journalIds = implode(',', $array);
|
||||
$user = $set->first()->user;
|
||||
$array = $set->pluck('id')->toArray();
|
||||
$journalIds = implode(',', $array);
|
||||
$user = $set->first()->user;
|
||||
Log::debug(sprintf('Add local operator for journal(s): %s', $journalIds));
|
||||
|
||||
// collect rules:
|
||||
@@ -176,14 +181,13 @@ class ProcessesNewTransactionGroup implements ShouldQueue
|
||||
// add the groups to the rule engine.
|
||||
// it should run the rules in the group and cancel the group if necessary.
|
||||
Log::debug('Fire processRules with ALL store-journal rule groups.');
|
||||
$groups = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
|
||||
$groups = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
|
||||
|
||||
// create and fire rule engine.
|
||||
$newRuleEngine = app(RuleEngineInterface::class);
|
||||
$newRuleEngine = app(RuleEngineInterface::class);
|
||||
$newRuleEngine->setUser($user);
|
||||
$newRuleEngine->addOperator(['type' => 'journal_id', 'value' => $journalIds]);
|
||||
$newRuleEngine->addOperator(['type' => 'journal_id', 'value' => $journalIds]);
|
||||
$newRuleEngine->setRuleGroups($groups);
|
||||
$newRuleEngine->fire();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Listeners\Security\System;
|
||||
|
||||
use Exception;
|
||||
|
||||
use FireflyIII\Events\Security\System\NewInvitationCreated;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Mail\InvitationMail;
|
||||
@@ -46,7 +45,6 @@ class NotifiesAboutNewInvitation implements ShouldQueue
|
||||
$this->sendRegistrationInvite($event->invitee);
|
||||
}
|
||||
|
||||
|
||||
private function sendRegistrationInvite(InvitedUser $invitee): void
|
||||
{
|
||||
$email = $invitee->email;
|
||||
@@ -88,5 +86,4 @@ class NotifiesAboutNewInvitation implements ShouldQueue
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class RespondsToNewLogin implements ShouldQueue
|
||||
public function handle(Login $event): void
|
||||
{
|
||||
$user = $event->user;
|
||||
if (!($user instanceof User)) {
|
||||
if (!$user instanceof User) {
|
||||
throw new InvalidArgumentException(sprintf('User cannot be an instance of %s.', get_class($user)));
|
||||
}
|
||||
|
||||
@@ -85,5 +85,4 @@ class RespondsToNewLogin implements ShouldQueue
|
||||
Preferences::mark();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+13
-13
@@ -50,9 +50,9 @@ class Account extends Model
|
||||
use ReturnsIntegerUserIdTrait;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = ['user_id', 'user_group_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban', 'native_virtual_balance'];
|
||||
protected $fillable = ['user_id', 'user_group_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban', 'native_virtual_balance'];
|
||||
|
||||
protected $hidden = ['encrypted'];
|
||||
protected $hidden = ['encrypted'];
|
||||
private bool $joinedAccountTypes = false;
|
||||
|
||||
/**
|
||||
@@ -60,19 +60,19 @@ class Account extends Model
|
||||
*
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
public static function routeBinder(self | string $value): self
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if ($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$accountId = (int)$value;
|
||||
$accountId = (int) $value;
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var null|Account $account */
|
||||
$account = $user->accounts()->with(['accountType'])->find($accountId);
|
||||
$account = $user->accounts()->with(['accountType'])->find($accountId);
|
||||
if (null !== $account) {
|
||||
return $account;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ class Account extends Model
|
||||
|
||||
public function setVirtualBalanceAttribute(mixed $value): void
|
||||
{
|
||||
$value = (string)$value;
|
||||
$value = (string) $value;
|
||||
if ('' === $value) {
|
||||
$value = null;
|
||||
}
|
||||
@@ -148,7 +148,7 @@ class Account extends Model
|
||||
|
||||
protected function accountId(): Attribute
|
||||
{
|
||||
return Attribute::make(get: static fn($value): int => (int)$value);
|
||||
return Attribute::make(get: static fn ($value): int => (int) $value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,7 +174,7 @@ class Account extends Model
|
||||
*/
|
||||
protected function accountTypeId(): Attribute
|
||||
{
|
||||
return Attribute::make(get: static fn($value): int => (int)$value);
|
||||
return Attribute::make(get: static fn ($value): int => (int) $value);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
@@ -216,12 +216,12 @@ class Account extends Model
|
||||
|
||||
protected function iban(): Attribute
|
||||
{
|
||||
return Attribute::make(get: static fn($value): ?string => null === $value ? null : trim(str_replace(' ', '', (string)$value)));
|
||||
return Attribute::make(get: static fn ($value): ?string => null === $value ? null : trim(str_replace(' ', '', (string) $value)));
|
||||
}
|
||||
|
||||
protected function order(): Attribute
|
||||
{
|
||||
return Attribute::make(get: static fn($value): int => (int)$value);
|
||||
return Attribute::make(get: static fn ($value): int => (int) $value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -229,7 +229,7 @@ class Account extends Model
|
||||
*/
|
||||
protected function virtualBalance(): Attribute
|
||||
{
|
||||
return Attribute::make(get: static fn($value): string => (string)$value);
|
||||
return Attribute::make(get: static fn ($value): string => (string) $value);
|
||||
}
|
||||
|
||||
public function primaryPeriodStatistics(): MorphMany
|
||||
|
||||
@@ -64,8 +64,8 @@ class Attachment extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$attachmentId = (int) $value;
|
||||
|
||||
@@ -61,8 +61,8 @@ class AvailableBudget extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$availableBudgetId = (int) $value;
|
||||
|
||||
+2
-2
@@ -76,8 +76,8 @@ class Bill extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$billId = (int) $value;
|
||||
|
||||
@@ -55,8 +55,8 @@ class Budget extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$budgetId = (int) $value;
|
||||
|
||||
@@ -55,8 +55,8 @@ class BudgetLimit extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$budgetLimitId = (int) $value;
|
||||
|
||||
@@ -54,8 +54,8 @@ class Category extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$categoryId = (int) $value;
|
||||
|
||||
@@ -44,8 +44,8 @@ class InvitedUser extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$attemptId = (int) $value;
|
||||
|
||||
@@ -43,8 +43,8 @@ class LinkType extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$linkTypeId = (int) $value;
|
||||
|
||||
@@ -47,8 +47,8 @@ class ObjectGroup extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$objectGroupId = (int) $value;
|
||||
|
||||
@@ -62,8 +62,8 @@ class PiggyBank extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$piggyBankId = (int) $value;
|
||||
|
||||
@@ -44,8 +44,8 @@ class Preference extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
/** @var User $user */
|
||||
|
||||
@@ -76,8 +76,8 @@ class Recurrence extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$recurrenceId = (int) $value;
|
||||
|
||||
+2
-2
@@ -54,8 +54,8 @@ class Rule extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$ruleId = (int) $value;
|
||||
|
||||
@@ -56,8 +56,8 @@ class RuleGroup extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$ruleGroupId = (int) $value;
|
||||
|
||||
+2
-2
@@ -54,8 +54,8 @@ class Tag extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$tagId = (int) $value;
|
||||
|
||||
@@ -50,8 +50,8 @@ class TransactionCurrency extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$currencyId = (int) $value;
|
||||
|
||||
@@ -57,8 +57,8 @@ class TransactionGroup extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
Log::debug(sprintf('Now in %s("%s")', __METHOD__, $value));
|
||||
if (auth()->check()) {
|
||||
|
||||
@@ -81,8 +81,8 @@ class TransactionJournal extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$journalId = (int) $value;
|
||||
|
||||
@@ -43,8 +43,8 @@ class TransactionJournalLink extends Model
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
|
||||
if (auth()->check()) {
|
||||
|
||||
@@ -77,8 +77,8 @@ class TransactionType extends Model
|
||||
if (!auth()->check()) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
if($value instanceof self) {
|
||||
$value = (string)$value->type;
|
||||
if ($value instanceof self) {
|
||||
$value = (string) $value->type;
|
||||
}
|
||||
$transactionType = self::where('type', ucfirst($value))->first();
|
||||
if (null !== $transactionType) {
|
||||
|
||||
@@ -47,8 +47,8 @@ class UserGroup extends Model
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if (auth()->check()) {
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
|
||||
$userGroupId = (int) $value;
|
||||
|
||||
@@ -133,8 +133,8 @@ class Webhook extends Model
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if (auth()->check()) {
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
$webhookId = (int) $value;
|
||||
|
||||
|
||||
@@ -45,8 +45,8 @@ class WebhookAttempt extends Model
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if (auth()->check()) {
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
$attemptId = (int) $value;
|
||||
|
||||
|
||||
@@ -47,8 +47,8 @@ class WebhookMessage extends Model
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if (auth()->check()) {
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
$messageId = (int) $value;
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class SubscriptionsOverdueReminder extends Notification
|
||||
$info = [];
|
||||
$count = 0;
|
||||
foreach ($this->overdue as $item) {
|
||||
$current = ['bill' => $item['bill']];
|
||||
$current = ['bill' => $item['bill']];
|
||||
$current['pay_dates'] = array_map(static fn (string $date): string => new Carbon($date)->isoFormat((string) trans(
|
||||
'config.month_and_day_moment_js'
|
||||
)), $item['dates']['pay_dates']);
|
||||
|
||||
@@ -40,24 +40,21 @@ use Override;
|
||||
*/
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected $listen
|
||||
= [
|
||||
// is a Transaction Journal related event.
|
||||
// StoredTransactionGroup::class => ['FireflyIII\Handlers\Events\StoredGroupEventHandler@runAllHandlers'],
|
||||
// TriggeredStoredTransactionGroup::class => ['FireflyIII\Handlers\Events\StoredGroupEventHandler@triggerRulesManually'],
|
||||
// is a Transaction Journal related event.
|
||||
// UpdatedTransactionGroup::class => ['FireflyIII\Handlers\Events\UpdatedGroupEventHandler@runAllHandlers'],
|
||||
// DestroyedTransactionGroup::class => ['FireflyIII\Handlers\Events\DestroyedGroupEventHandler@runAllHandlers'],
|
||||
// API related events:
|
||||
// AccessTokenCreated::class => ['FireflyIII\Handlers\Events\APIEventHandler@accessTokenCreated'],
|
||||
|
||||
// account related events:
|
||||
// StoredAccount::class => ['FireflyIII\Handlers\Events\StoredAccountEventHandler@recalculateCredit'],
|
||||
// UpdatedAccount::class => ['FireflyIII\Handlers\Events\UpdatedAccountEventHandler@recalculateCredit'],
|
||||
|
||||
// preferences
|
||||
// UserGroupChangedPrimaryCurrency::class => ['FireflyIII\Handlers\Events\PreferencesEventHandler@resetPrimaryCurrencyAmounts'],
|
||||
];
|
||||
protected $listen = [
|
||||
// is a Transaction Journal related event.
|
||||
// StoredTransactionGroup::class => ['FireflyIII\Handlers\Events\StoredGroupEventHandler@runAllHandlers'],
|
||||
// TriggeredStoredTransactionGroup::class => ['FireflyIII\Handlers\Events\StoredGroupEventHandler@triggerRulesManually'],
|
||||
// is a Transaction Journal related event.
|
||||
// UpdatedTransactionGroup::class => ['FireflyIII\Handlers\Events\UpdatedGroupEventHandler@runAllHandlers'],
|
||||
// DestroyedTransactionGroup::class => ['FireflyIII\Handlers\Events\DestroyedGroupEventHandler@runAllHandlers'],
|
||||
// API related events:
|
||||
// AccessTokenCreated::class => ['FireflyIII\Handlers\Events\APIEventHandler@accessTokenCreated'],
|
||||
// account related events:
|
||||
// StoredAccount::class => ['FireflyIII\Handlers\Events\StoredAccountEventHandler@recalculateCredit'],
|
||||
// UpdatedAccount::class => ['FireflyIII\Handlers\Events\UpdatedAccountEventHandler@recalculateCredit'],
|
||||
// preferences
|
||||
// UserGroupChangedPrimaryCurrency::class => ['FireflyIII\Handlers\Events\PreferencesEventHandler@resetPrimaryCurrencyAmounts'],
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any events for your application.
|
||||
|
||||
@@ -39,6 +39,7 @@ use FireflyIII\Support\CacheProperties;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Support\Collection;
|
||||
use Override;
|
||||
|
||||
/**
|
||||
* Class JournalRepository.
|
||||
@@ -251,13 +252,17 @@ class JournalRepository implements JournalRepositoryInterface, UserGroupInterfac
|
||||
return $journal;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
#[Override]
|
||||
public function getUncompletedJournals(): Collection
|
||||
{
|
||||
return $this->userGroup->transactionJournals()->where('completed', false)->get(['transaction_journals.*']);
|
||||
return $this->userGroup
|
||||
->transactionJournals()
|
||||
->where('completed', false)
|
||||
->get(['transaction_journals.*'])
|
||||
;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
#[Override]
|
||||
public function markAsCompleted(Collection $set): void
|
||||
{
|
||||
TransactionJournal::whereIn('id', $set->pluck('id')->toArray())->update(['completed' => true]);
|
||||
|
||||
@@ -56,7 +56,7 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface, U
|
||||
|
||||
public function saveStatistic(Model $model, int $currencyId, Carbon $start, Carbon $end, string $type, int $count, string $amount): PeriodStatistic
|
||||
{
|
||||
$stat = new PeriodStatistic();
|
||||
$stat = new PeriodStatistic();
|
||||
$stat->primaryStatable()->associate($model);
|
||||
$stat->transaction_currency_id = $currencyId;
|
||||
$stat->user_group_id = $this->getUserGroup()->id;
|
||||
@@ -70,16 +70,16 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface, U
|
||||
$stat->save();
|
||||
|
||||
Log::debug(sprintf(
|
||||
'Saved #%d [currency #%d, Model %s #%d, %s to %s, %d, %s] as new statistic.',
|
||||
$stat->id,
|
||||
$model::class,
|
||||
$model->id,
|
||||
$stat->transaction_currency_id,
|
||||
$stat->start->toW3cString(),
|
||||
$stat->end->toW3cString(),
|
||||
$count,
|
||||
$amount
|
||||
));
|
||||
'Saved #%d [currency #%d, Model %s #%d, %s to %s, %d, %s] as new statistic.',
|
||||
$stat->id,
|
||||
$model::class,
|
||||
$model->id,
|
||||
$stat->transaction_currency_id,
|
||||
$stat->start->toW3cString(),
|
||||
$stat->end->toW3cString(),
|
||||
$count,
|
||||
$amount
|
||||
));
|
||||
|
||||
return $stat;
|
||||
}
|
||||
@@ -102,20 +102,20 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface, U
|
||||
->where('type', 'LIKE', sprintf('%s%%', $prefix))
|
||||
->where('start', '>=', $start)
|
||||
->where('end', '<=', $end)
|
||||
->get();
|
||||
->get()
|
||||
;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function savePrefixedStatistic(
|
||||
string $prefix,
|
||||
int $currencyId,
|
||||
int $currencyId,
|
||||
Carbon $start,
|
||||
Carbon $end,
|
||||
string $type,
|
||||
int $count,
|
||||
int $count,
|
||||
string $amount
|
||||
): PeriodStatistic
|
||||
{
|
||||
): PeriodStatistic {
|
||||
$stat = new PeriodStatistic();
|
||||
$stat->transaction_currency_id = $currencyId;
|
||||
$stat->user_group_id = $this->getUserGroup()->id;
|
||||
@@ -129,15 +129,15 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface, U
|
||||
$stat->save();
|
||||
|
||||
Log::debug(sprintf(
|
||||
'Saved #%d [currency #%d, type "%s", %s to %s, %d, %s] as new statistic.',
|
||||
$stat->id,
|
||||
$stat->transaction_currency_id,
|
||||
$stat->type,
|
||||
$stat->start->toW3cString(),
|
||||
$stat->end->toW3cString(),
|
||||
$count,
|
||||
$amount
|
||||
));
|
||||
'Saved #%d [currency #%d, type "%s", %s to %s, %d, %s] as new statistic.',
|
||||
$stat->id,
|
||||
$stat->transaction_currency_id,
|
||||
$stat->type,
|
||||
$stat->start->toW3cString(),
|
||||
$stat->end->toW3cString(),
|
||||
$count,
|
||||
$amount
|
||||
));
|
||||
|
||||
return $stat;
|
||||
}
|
||||
@@ -145,15 +145,18 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface, U
|
||||
#[Override]
|
||||
public function deleteStatisticsForPrefix(string $prefix, Collection $dates): void
|
||||
{
|
||||
$count = $this->userGroup->periodStatistics()
|
||||
->where(function (Builder $q) use ($dates) {
|
||||
foreach ($dates as $date) {
|
||||
$q->where(function (Builder $q1) use ($date) {
|
||||
$q1->where('start', '<=', $date)->where('end', '>=', $date);
|
||||
});
|
||||
}
|
||||
})
|
||||
->where('type', 'LIKE', sprintf('%s%%', $prefix))->delete();
|
||||
$count = $this->userGroup
|
||||
->periodStatistics()
|
||||
->where(function (Builder $q) use ($dates): void {
|
||||
foreach ($dates as $date) {
|
||||
$q->where(function (Builder $q1) use ($date): void {
|
||||
$q1->where('start', '<=', $date)->where('end', '>=', $date);
|
||||
});
|
||||
}
|
||||
})
|
||||
->where('type', 'LIKE', sprintf('%s%%', $prefix))
|
||||
->delete()
|
||||
;
|
||||
Log::debug(sprintf('Deleted %d entries for prefix "%s"', $count, $prefix));
|
||||
}
|
||||
|
||||
@@ -161,44 +164,66 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface, U
|
||||
{
|
||||
if (0 === count($objects)) {
|
||||
Log::debug(sprintf('Nothing to delete in deleteStatisticsForType("%s")', $class));
|
||||
|
||||
return;
|
||||
}
|
||||
$count = PeriodStatistic
|
||||
::where('primary_statable_type', $class)
|
||||
$count = PeriodStatistic::where('primary_statable_type', $class)
|
||||
->whereIn('primary_statable_id', $objects->pluck('id')->toArray())
|
||||
->where(function (Builder $q) use ($dates) {
|
||||
->where(function (Builder $q) use ($dates): void {
|
||||
foreach ($dates as $date) {
|
||||
$q->where(function (Builder $q1) use ($date) {
|
||||
$q->where(function (Builder $q1) use ($date): void {
|
||||
$q1->where('start', '<=', $date)->where('end', '>=', $date);
|
||||
});
|
||||
}
|
||||
})
|
||||
->delete();
|
||||
->delete()
|
||||
;
|
||||
Log::debug(sprintf('Delete %d statistics for %dx %s', $count, $objects->count(), $class));
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function deleteStatisticsForCollection(Collection $set)
|
||||
#[Override]
|
||||
public function deleteStatisticsForCollection(Collection $set): void
|
||||
{
|
||||
Log::debug(sprintf('Delete statistics for %d transaction journals.', count($set)));
|
||||
// collect all transactions:
|
||||
$transactions = Transaction::whereIn('transaction_journal_id', $set->pluck('id')->toArray())->get(['transactions.*']);
|
||||
|
||||
// collect all accounts and delete stats:
|
||||
$accounts = Account::whereIn('id', $transactions->pluck('account_id')->toArray())->get(['accounts.*']);
|
||||
$dates = $set->pluck('date');
|
||||
$accounts = Account::whereIn('id', $transactions->pluck('account_id')->toArray())->get(['accounts.*']);
|
||||
$dates = $set->pluck('date');
|
||||
$this->deleteStatisticsForType(Account::class, $accounts, $dates);
|
||||
|
||||
// collect all categories, and remove stats.
|
||||
$categories = Category::whereIn('id', DB::table('category_transaction_journal')->whereIn('transaction_journal_id', $set->pluck('id')->toArray())->get(['category_transaction_journal.category_id'])->pluck('category_id')->toArray())->get(['categories.*']);
|
||||
$categories = Category::whereIn(
|
||||
'id',
|
||||
DB::table('category_transaction_journal')
|
||||
->whereIn('transaction_journal_id', $set->pluck('id')->toArray())
|
||||
->get(['category_transaction_journal.category_id'])
|
||||
->pluck('category_id')
|
||||
->toArray()
|
||||
)->get(['categories.*']);
|
||||
$this->deleteStatisticsForType(Category::class, $categories, $dates);
|
||||
|
||||
// budgets, same thing
|
||||
$budgets = Budget::whereIn('id', DB::table('budget_transaction_journal')->whereIn('transaction_journal_id', $set->pluck('id')->toArray())->get(['budget_transaction_journal.budget_id'])->pluck('budget_id')->toArray())->get(['budgets.*']);
|
||||
$budgets = Budget::whereIn(
|
||||
'id',
|
||||
DB::table('budget_transaction_journal')
|
||||
->whereIn('transaction_journal_id', $set->pluck('id')->toArray())
|
||||
->get(['budget_transaction_journal.budget_id'])
|
||||
->pluck('budget_id')
|
||||
->toArray()
|
||||
)->get(['budgets.*']);
|
||||
$this->deleteStatisticsForType(Budget::class, $budgets, $dates);
|
||||
|
||||
// tags
|
||||
$tags = Tag::whereIn('id', DB::table('tag_transaction_journal')->whereIn('transaction_journal_id', $set->pluck('id')->toArray())->get(['tag_transaction_journal.tag_id'])->pluck('tag_id')->toArray())->get(['tags.*']);
|
||||
$tags = Tag::whereIn(
|
||||
'id',
|
||||
DB::table('tag_transaction_journal')
|
||||
->whereIn('transaction_journal_id', $set->pluck('id')->toArray())
|
||||
->get(['tag_transaction_journal.tag_id'])
|
||||
->pluck('tag_id')
|
||||
->toArray()
|
||||
)->get(['tags.*']);
|
||||
$this->deleteStatisticsForType(Tag::class, $tags, $dates);
|
||||
|
||||
// remove for no tag, no cat, etc.
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace FireflyIII\Repositories\PeriodStatistic;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\PeriodStatistic;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
|
||||
@@ -172,7 +172,11 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
}
|
||||
$listedJournals[] = $journalId;
|
||||
|
||||
$array[$currencyId]['tags'][$tagId] ??= ['id' => $tagId, 'name' => $tagName, 'transaction_journals' => []];
|
||||
$array[$currencyId]['tags'][$tagId] ??= [
|
||||
'id' => $tagId,
|
||||
'name' => $tagName,
|
||||
'transaction_journals' => [],
|
||||
];
|
||||
$journalId = (int) $journal['transaction_journal_id'];
|
||||
$array[$currencyId]['tags'][$tagId]['transaction_journals'][$journalId] = [
|
||||
'amount' => Steam::positive($journal['amount']),
|
||||
|
||||
@@ -42,11 +42,11 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class CreditRecalculateService
|
||||
{
|
||||
private ?Account $account = null;
|
||||
private ?TransactionGroup $group = null;
|
||||
private Collection $journals;
|
||||
private ?Account $account = null;
|
||||
private ?TransactionGroup $group = null;
|
||||
private Collection $journals;
|
||||
private AccountRepositoryInterface $repository;
|
||||
private array $work = [];
|
||||
private array $work = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -70,6 +70,7 @@ class CreditRecalculateService
|
||||
}
|
||||
if (0 === count($this->work)) {
|
||||
Log::debug('No work found for recalculate() to do.');
|
||||
|
||||
return;
|
||||
}
|
||||
$this->processWork();
|
||||
@@ -79,13 +80,13 @@ class CreditRecalculateService
|
||||
{
|
||||
Log::debug('Now in collectFromJournals()');
|
||||
$valid = config('firefly.valid_liabilities');
|
||||
$accounts = Account
|
||||
::leftJoin('transactions', 'transactions.account_id', 'accounts.id')
|
||||
$accounts = Account::leftJoin('transactions', 'transactions.account_id', 'accounts.id')
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', 'transactions.transaction_journal_id')
|
||||
->leftJoin('account_types', 'account_types.id', 'accounts.account_type_id')
|
||||
->whereIn('transaction_journals.id', $transactionJournals->pluck('id')->toArray())
|
||||
->whereIn('account_types.type', $valid)
|
||||
->get(['accounts.*']);
|
||||
->get(['accounts.*'])
|
||||
;
|
||||
if ($accounts->count() > 0) {
|
||||
Log::debug(sprintf('Found %d account(s) to process.', $accounts->count()));
|
||||
foreach ($accounts as $account) {
|
||||
@@ -104,7 +105,6 @@ class CreditRecalculateService
|
||||
$this->collectFromJournals($this->journals);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
@@ -114,7 +114,7 @@ class CreditRecalculateService
|
||||
$destination = $this->getDestinationAccount($journal);
|
||||
|
||||
// destination or source must be liability.
|
||||
$valid = config('firefly.valid_liabilities');
|
||||
$valid = config('firefly.valid_liabilities');
|
||||
if (in_array($destination->accountType->type, $valid, true)) {
|
||||
$this->work[] = $destination;
|
||||
}
|
||||
@@ -137,7 +137,7 @@ class CreditRecalculateService
|
||||
private function getAccountByDirection(TransactionJournal $journal, string $direction): Account
|
||||
{
|
||||
/** @var null|Transaction $transaction */
|
||||
$transaction = $journal->transactions()->where('amount', $direction, '0')->first();
|
||||
$transaction = $journal->transactions()->where('amount', $direction, '0')->first();
|
||||
if (null === $transaction) {
|
||||
throw new FireflyException(sprintf('Cannot find "%s"-transaction of journal #%d', $direction, $journal->id));
|
||||
}
|
||||
@@ -180,19 +180,19 @@ class CreditRecalculateService
|
||||
Log::debug(sprintf('Now processing account #%d ("%s").', $account->id, $account->name));
|
||||
// get opening balance (if present)
|
||||
$this->repository->setUser($account->user);
|
||||
$direction = (string)$this->repository->getMetaValue($account, 'liability_direction');
|
||||
$direction = (string) $this->repository->getMetaValue($account, 'liability_direction');
|
||||
$openingBalance = $this->repository->getOpeningBalance($account);
|
||||
// Log::debug(sprintf('Found opening balance transaction journal #%d', $openingBalance->id));
|
||||
// if account direction is "debit" ("I owe this amount") the opening balance must always be AWAY from the account:
|
||||
if ($openingBalance instanceof TransactionJournal && 'debit' === $direction) {
|
||||
$this->validateOpeningBalance($account, $openingBalance);
|
||||
}
|
||||
$startOfDebt = $this->repository->getOpeningBalanceAmount($account, false) ?? '0';
|
||||
$leftOfDebt = Steam::positive($startOfDebt);
|
||||
$startOfDebt = $this->repository->getOpeningBalanceAmount($account, false) ?? '0';
|
||||
$leftOfDebt = Steam::positive($startOfDebt);
|
||||
// Log::debug(sprintf('Start of debt is "%s", so initial left of debt is "%s"', \FireflyIII\Support\Facades\Steam::bcround($startOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2)));
|
||||
|
||||
/** @var AccountMetaFactory $factory */
|
||||
$factory = app(AccountMetaFactory::class);
|
||||
$factory = app(AccountMetaFactory::class);
|
||||
|
||||
// amount is positive or negative, doesn't matter.
|
||||
$factory->crud($account, 'start_of_debt', $startOfDebt);
|
||||
@@ -200,11 +200,12 @@ class CreditRecalculateService
|
||||
// Log::debug(sprintf('Debt direction is "%s"', $direction));
|
||||
|
||||
// now loop all transactions (except opening balance and credit thing)
|
||||
$transactions = $account
|
||||
$transactions = $account
|
||||
->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->orderBy('transaction_journals.date', 'ASC')
|
||||
->get(['transactions.*']);
|
||||
->get(['transactions.*'])
|
||||
;
|
||||
$transactions->count();
|
||||
// Log::debug(sprintf('Found %d transaction(s) to process.', $total));
|
||||
|
||||
@@ -226,7 +227,7 @@ class CreditRecalculateService
|
||||
$source = $openingBalance->transactions()->where('amount', '<', 0)->first();
|
||||
|
||||
/** @var Transaction $dest */
|
||||
$dest = $openingBalance->transactions()->where('amount', '>', 0)->first();
|
||||
$dest = $openingBalance->transactions()->where('amount', '>', 0)->first();
|
||||
if ($source->account_id !== $account->id) {
|
||||
Log::info(sprintf('Liability #%d has a reversed opening balance. Will fix this now.', $account->id));
|
||||
Log::debug(sprintf('Source amount "%s" is now "%s"', $source->amount, Steam::positive($source->amount)));
|
||||
@@ -257,7 +258,7 @@ class CreditRecalculateService
|
||||
*/
|
||||
private function processTransaction(Account $account, string $direction, Transaction $transaction, string $leftOfDebt): string
|
||||
{
|
||||
$journal = $transaction->transactionJournal;
|
||||
$journal = $transaction->transactionJournal;
|
||||
|
||||
// here be null pointers.
|
||||
if (null === $journal) {
|
||||
@@ -284,15 +285,15 @@ class CreditRecalculateService
|
||||
// Log::debug(sprintf('Liability direction is "%s"', $direction));
|
||||
|
||||
// amount to use depends on the currency:
|
||||
$usedAmount = $this->getAmountToUse($transaction, $accountCurrency, $foreignCurrency);
|
||||
$isSameAccount = $account->id === $transaction->account_id;
|
||||
$isDebit = 'debit' === $direction;
|
||||
$isCredit = 'credit' === $direction;
|
||||
$usedAmount = $this->getAmountToUse($transaction, $accountCurrency, $foreignCurrency);
|
||||
$isSameAccount = $account->id === $transaction->account_id;
|
||||
$isDebit = 'debit' === $direction;
|
||||
$isCredit = 'credit' === $direction;
|
||||
|
||||
if ($isSameAccount && $isCredit && $this->isWithdrawalIn($usedAmount, $type)) { // case 1
|
||||
$usedAmount = Steam::positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, (string)$usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
|
||||
// Log::debug(sprintf('Case 1 (withdrawal into credit liability): %s + %s = %s', \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($usedAmount, 2), \FireflyIII\Support\Facades\Steam::bcround($result, 2)));
|
||||
}
|
||||
@@ -300,7 +301,7 @@ class CreditRecalculateService
|
||||
if ($isSameAccount && $isCredit && $this->isWithdrawalOut($usedAmount, $type)) { // case 2
|
||||
$usedAmount = Steam::positive($usedAmount);
|
||||
|
||||
return bcsub($leftOfDebt, (string)$usedAmount);
|
||||
return bcsub($leftOfDebt, (string) $usedAmount);
|
||||
|
||||
// Log::debug(sprintf('Case 2 (withdrawal away from liability): %s - %s = %s', \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($usedAmount, 2), \FireflyIII\Support\Facades\Steam::bcround($result, 2)));
|
||||
}
|
||||
@@ -308,7 +309,7 @@ class CreditRecalculateService
|
||||
if ($isSameAccount && $isCredit && $this->isDepositOut($usedAmount, $type)) { // case 3
|
||||
$usedAmount = Steam::positive($usedAmount);
|
||||
|
||||
return bcsub($leftOfDebt, (string)$usedAmount);
|
||||
return bcsub($leftOfDebt, (string) $usedAmount);
|
||||
|
||||
// Log::debug(sprintf('Case 3 (deposit away from liability): %s - %s = %s', \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($usedAmount, 2), \FireflyIII\Support\Facades\Steam::bcround($result, 2)));
|
||||
}
|
||||
@@ -316,35 +317,35 @@ class CreditRecalculateService
|
||||
if ($isSameAccount && $isCredit && $this->isDepositIn($usedAmount, $type)) { // case 4
|
||||
$usedAmount = Steam::positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, (string)$usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
|
||||
// Log::debug(sprintf('Case 4 (deposit into credit liability): %s + %s = %s', \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($usedAmount, 2), \FireflyIII\Support\Facades\Steam::bcround($result, 2)));
|
||||
}
|
||||
if ($isSameAccount && $isCredit && $this->isTransferIn($usedAmount, $type)) { // case 5
|
||||
$usedAmount = Steam::positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, (string)$usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
|
||||
// Log::debug(sprintf('Case 5 (transfer into credit liability): %s + %s = %s', \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($usedAmount, 2), \FireflyIII\Support\Facades\Steam::bcround($result, 2)));
|
||||
}
|
||||
if ($isSameAccount && $isDebit && $this->isWithdrawalIn($usedAmount, $type)) { // case 6
|
||||
$usedAmount = Steam::positive($usedAmount);
|
||||
|
||||
return bcsub($leftOfDebt, (string)$usedAmount);
|
||||
return bcsub($leftOfDebt, (string) $usedAmount);
|
||||
|
||||
// Log::debug(sprintf('Case 6 (withdrawal into debit liability): %s - %s = %s', \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($usedAmount, 2), \FireflyIII\Support\Facades\Steam::bcround($result, 2)));
|
||||
}
|
||||
if ($isSameAccount && $isDebit && $this->isDepositOut($usedAmount, $type)) { // case 7
|
||||
$usedAmount = Steam::positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, (string)$usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
|
||||
// Log::debug(sprintf('Case 7 (deposit away from liability): %s + %s = %s', \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($usedAmount, 2), \FireflyIII\Support\Facades\Steam::bcround($result, 2)));
|
||||
}
|
||||
if ($isSameAccount && $isDebit && $this->isWithdrawalOut($usedAmount, $type)) { // case 8
|
||||
$usedAmount = Steam::positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, (string)$usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
|
||||
// Log::debug(sprintf('Case 8 (withdrawal away from liability): %s + %s = %s', \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($usedAmount, 2), \FireflyIII\Support\Facades\Steam::bcround($result, 2)));
|
||||
}
|
||||
@@ -352,7 +353,7 @@ class CreditRecalculateService
|
||||
if ($isSameAccount && $isDebit && $this->isTransferIn($usedAmount, $type)) { // case 9
|
||||
$usedAmount = Steam::positive($usedAmount);
|
||||
|
||||
return bcsub($leftOfDebt, (string)$usedAmount);
|
||||
return bcsub($leftOfDebt, (string) $usedAmount);
|
||||
|
||||
// 2024-10-05, #9225 this used to say you would owe more, but a transfer INTO a debit from wherever means you owe LESS.
|
||||
// Log::debug(sprintf('Case 9 (transfer into debit liability, means you owe LESS): %s - %s = %s', \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($usedAmount, 2), \FireflyIII\Support\Facades\Steam::bcround($result, 2)));
|
||||
@@ -360,7 +361,7 @@ class CreditRecalculateService
|
||||
if ($isSameAccount && $isDebit && $this->isTransferOut($usedAmount, $type)) { // case 10
|
||||
$usedAmount = Steam::positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, (string)$usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
|
||||
// 2024-10-05, #9225 this used to say you would owe less, but a transfer OUT OF a debit from wherever means you owe MORE.
|
||||
// Log::debug(sprintf('Case 10 (transfer out of debit liability, means you owe MORE): %s + %s = %s', \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($usedAmount, 2), \FireflyIII\Support\Facades\Steam::bcround($result, 2)));
|
||||
@@ -370,7 +371,7 @@ class CreditRecalculateService
|
||||
if (in_array($type, [TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value], true)) {
|
||||
$usedAmount = Steam::negative($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, (string)$usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
|
||||
// Log::debug(sprintf('Case X (all other cases): %s + %s = %s', \FireflyIII\Support\Facades\Steam::bcround($leftOfDebt, 2), \FireflyIII\Support\Facades\Steam::bcround($usedAmount, 2), \FireflyIII\Support\Facades\Steam::bcround($result, 2)));
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Rules\UniqueIban;
|
||||
use FireflyIII\Support\NullArrayObject;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Safe\Exceptions\JsonException;
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ class AccountBalanceGrouped
|
||||
{
|
||||
$this->primary = $primary;
|
||||
$primaryCurrencyId = $primary->id;
|
||||
$this->currencies = [$primary->id => $primary]; // currency cache
|
||||
$this->currencies = [$primary->id => $primary]; // currency cache
|
||||
$this->data[$primaryCurrencyId] = [
|
||||
'currency_id' => (string) $primaryCurrencyId,
|
||||
'currency_symbol' => $primary->symbol,
|
||||
|
||||
@@ -222,7 +222,14 @@ trait AugumentData
|
||||
$currentEnd->addMonth();
|
||||
}
|
||||
// primary currency amount.
|
||||
$expenses = $opsRepository->sumExpenses($currentStart, $currentEnd, null, $budgetCollection, $entry->transactionCurrency, $this->convertToPrimary);
|
||||
$expenses = $opsRepository->sumExpenses(
|
||||
$currentStart,
|
||||
$currentEnd,
|
||||
null,
|
||||
$budgetCollection,
|
||||
$entry->transactionCurrency,
|
||||
$this->convertToPrimary
|
||||
);
|
||||
$spent = $expenses[$currency->id]['sum'] ?? '0';
|
||||
$entry->pc_spent = $spent;
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ trait GetConfigurationData
|
||||
|
||||
// previous year:
|
||||
$yearBegin = today(config('app.timezone'))->subYear()->startOfYear();
|
||||
$index = (string) trans('firefly.previous_year', ['year' => $yearBegin->year]);
|
||||
$index = (string) trans('firefly.previous_year', ['year' => $yearBegin->year]);
|
||||
$ranges[$index] = [$yearBegin, $yearBegin->clone()->endOfYear()];
|
||||
|
||||
// everything
|
||||
|
||||
@@ -326,7 +326,8 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
'zoom_level' => (int) $location['zoom_level'],
|
||||
];
|
||||
}
|
||||
// Log::debug(sprintf('Enrich with %d locations(s)', count($this->locations)));
|
||||
|
||||
// Log::debug(sprintf('Enrich with %d locations(s)', count($this->locations)));
|
||||
}
|
||||
|
||||
private function collectMetaData(): void
|
||||
@@ -382,7 +383,8 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
foreach ($notes as $note) {
|
||||
$this->notes[(int) $note['noteable_id']] = (string) $note['text'];
|
||||
}
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
}
|
||||
|
||||
private function collectObjectGroups(): void
|
||||
|
||||
@@ -183,7 +183,8 @@ class BudgetEnrichment implements EnrichmentInterface
|
||||
foreach ($notes as $note) {
|
||||
$this->notes[(int) $note['noteable_id']] = (string) $note['text'];
|
||||
}
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
}
|
||||
|
||||
private function collectObjectGroups(): void
|
||||
|
||||
@@ -152,7 +152,10 @@ class BudgetLimitEnrichment implements EnrichmentInterface
|
||||
private function collectCurrencies(): void
|
||||
{
|
||||
$this->currencies[$this->primaryCurrency->id] = $this->primaryCurrency;
|
||||
$currencies = TransactionCurrency::whereIn('id', $this->currencyIds)->whereNot('id', $this->primaryCurrency->id)->get();
|
||||
$currencies = TransactionCurrency::whereIn('id', $this->currencyIds)->whereNot(
|
||||
'id',
|
||||
$this->primaryCurrency->id
|
||||
)->get();
|
||||
foreach ($currencies as $currency) {
|
||||
$this->currencies[(int) $currency->id] = $currency;
|
||||
}
|
||||
@@ -191,7 +194,8 @@ class BudgetLimitEnrichment implements EnrichmentInterface
|
||||
foreach ($notes as $note) {
|
||||
$this->notes[(int) $note['noteable_id']] = (string) $note['text'];
|
||||
}
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
}
|
||||
|
||||
private function filterToBudget(array $expenses, int $budget): array
|
||||
|
||||
@@ -132,7 +132,8 @@ class CategoryEnrichment implements EnrichmentInterface
|
||||
foreach ($notes as $note) {
|
||||
$this->notes[(int) $note['noteable_id']] = (string) $note['text'];
|
||||
}
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
}
|
||||
|
||||
private function collectTransactions(): void
|
||||
|
||||
@@ -262,7 +262,8 @@ class PiggyBankEnrichment implements EnrichmentInterface
|
||||
foreach ($notes as $note) {
|
||||
$this->notes[(int) $note['noteable_id']] = (string) $note['text'];
|
||||
}
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
}
|
||||
|
||||
private function collectObjectGroups(): void
|
||||
|
||||
@@ -327,7 +327,8 @@ class RecurringEnrichment implements EnrichmentInterface
|
||||
$this->notes[$notableId] = (string) $note['text'];
|
||||
Log::debug(sprintf('Collected note #%d for recurrence #%d', $note['id'], $notableId));
|
||||
}
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
}
|
||||
|
||||
private function collectPiggyBankInfo(array $piggyBankIds): void
|
||||
@@ -357,7 +358,10 @@ class RecurringEnrichment implements EnrichmentInterface
|
||||
|
||||
/** @var RecurrenceRepetition $repetition */
|
||||
foreach ($set as $repetition) {
|
||||
$recurrence = $this->collection->filter(static fn (Recurrence $item): bool => (int) $item->id === (int) $repetition->recurrence_id)->first();
|
||||
$recurrence = $this->collection
|
||||
->filter(static fn (Recurrence $item): bool => (int) $item->id === (int) $repetition->recurrence_id)
|
||||
->first()
|
||||
;
|
||||
$fromDate = clone ($recurrence->latest_date ?? $recurrence->first_date);
|
||||
$recurrenceId = (int) $repetition->recurrence_id;
|
||||
$repId = (int) $repetition->id;
|
||||
|
||||
@@ -205,7 +205,8 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
||||
foreach ($notes as $note) {
|
||||
$this->notes[(int) $note['noteable_id']] = (string) $note['text'];
|
||||
}
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
}
|
||||
|
||||
private function collectObjectGroups(): void
|
||||
|
||||
@@ -206,7 +206,8 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
'zoom_level' => (int) $location['zoom_level'],
|
||||
];
|
||||
}
|
||||
// Log::debug(sprintf('Enrich with %d locations(s)', count($this->locations)));
|
||||
|
||||
// Log::debug(sprintf('Enrich with %d locations(s)', count($this->locations)));
|
||||
}
|
||||
|
||||
private function collectMetaData(): void
|
||||
@@ -242,7 +243,8 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
foreach ($notes as $note) {
|
||||
$this->notes[(int) $note['noteable_id']] = (string) $note['text'];
|
||||
}
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
|
||||
// Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
}
|
||||
|
||||
private function collectTags(): void
|
||||
|
||||
@@ -398,7 +398,7 @@ trait ConvertsDataTypes
|
||||
protected function getCarbonDate(string $field): ?Carbon
|
||||
{
|
||||
$data = (string) $this->get($field);
|
||||
//Log::debug(sprintf('Date string is "%s"', $data));
|
||||
// Log::debug(sprintf('Date string is "%s"', $data));
|
||||
|
||||
if ('' === $data) {
|
||||
return null;
|
||||
|
||||
@@ -65,7 +65,7 @@ class QueryParser implements QueryParserInterface
|
||||
// Log::debug('BACKSLASH!');
|
||||
// escaped quote, pretend it's a normal char and continue two places (skipping the actual character).
|
||||
$tokenUnderConstruction .= '\\'.$nextChar;
|
||||
$this->position += 2;
|
||||
$this->position += 2;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@ class Steam
|
||||
}
|
||||
$final = array_merge($return, $sumsByCode);
|
||||
$result[$account->id] = $final;
|
||||
|
||||
// Log::debug(sprintf('Final balance for account #%d is', $account->id), $final);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -88,8 +88,8 @@ class User extends Authenticatable
|
||||
*/
|
||||
public static function routeBinder(self|string $value): self
|
||||
{
|
||||
if($value instanceof self) {
|
||||
$value = (int)$value->id;
|
||||
if ($value instanceof self) {
|
||||
$value = (int) $value->id;
|
||||
}
|
||||
if (auth()->check()) {
|
||||
$userId = (int) $value;
|
||||
|
||||
Generated
+108
-111
@@ -6428,16 +6428,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/cache",
|
||||
"version": "v8.0.3",
|
||||
"version": "v8.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/cache.git",
|
||||
"reference": "ef8c7dbfe613d2773d0b5e68b2ef2db72c8b025f"
|
||||
"reference": "5d3fcada5e1b80157cfdfd1f9dbbd63f95ef6f13"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/cache/zipball/ef8c7dbfe613d2773d0b5e68b2ef2db72c8b025f",
|
||||
"reference": "ef8c7dbfe613d2773d0b5e68b2ef2db72c8b025f",
|
||||
"url": "https://api.github.com/repos/symfony/cache/zipball/5d3fcada5e1b80157cfdfd1f9dbbd63f95ef6f13",
|
||||
"reference": "5d3fcada5e1b80157cfdfd1f9dbbd63f95ef6f13",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6504,7 +6504,7 @@
|
||||
"psr6"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/cache/tree/v8.0.3"
|
||||
"source": "https://github.com/symfony/cache/tree/v8.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6524,7 +6524,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-28T10:45:32+00:00"
|
||||
"time": "2026-01-23T12:59:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/cache-contracts",
|
||||
@@ -6681,16 +6681,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.4.3",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "732a9ca6cd9dfd940c639062d5edbde2f6727fb6"
|
||||
"reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/732a9ca6cd9dfd940c639062d5edbde2f6727fb6",
|
||||
"reference": "732a9ca6cd9dfd940c639062d5edbde2f6727fb6",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/41e38717ac1dd7a46b6bda7d6a82af2d98a78894",
|
||||
"reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6755,7 +6755,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.4.3"
|
||||
"source": "https://github.com/symfony/console/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6775,7 +6775,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-23T14:50:43+00:00"
|
||||
"time": "2026-01-13T11:36:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
@@ -6915,16 +6915,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/error-handler",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/error-handler.git",
|
||||
"reference": "48be2b0653594eea32dcef130cca1c811dcf25c2"
|
||||
"reference": "8da531f364ddfee53e36092a7eebbbd0b775f6b8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/error-handler/zipball/48be2b0653594eea32dcef130cca1c811dcf25c2",
|
||||
"reference": "48be2b0653594eea32dcef130cca1c811dcf25c2",
|
||||
"url": "https://api.github.com/repos/symfony/error-handler/zipball/8da531f364ddfee53e36092a7eebbbd0b775f6b8",
|
||||
"reference": "8da531f364ddfee53e36092a7eebbbd0b775f6b8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6973,7 +6973,7 @@
|
||||
"description": "Provides tools to manage errors and ease debugging PHP code",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/error-handler/tree/v7.4.0"
|
||||
"source": "https://github.com/symfony/error-handler/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6993,20 +6993,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-05T14:29:59+00:00"
|
||||
"time": "2026-01-20T16:42:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v8.0.0",
|
||||
"version": "v8.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "573f95783a2ec6e38752979db139f09fec033f03"
|
||||
"reference": "99301401da182b6cfaa4700dbe9987bb75474b47"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/573f95783a2ec6e38752979db139f09fec033f03",
|
||||
"reference": "573f95783a2ec6e38752979db139f09fec033f03",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/99301401da182b6cfaa4700dbe9987bb75474b47",
|
||||
"reference": "99301401da182b6cfaa4700dbe9987bb75474b47",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7058,7 +7058,7 @@
|
||||
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v8.0.0"
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v8.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7078,7 +7078,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-10-30T14:17:19+00:00"
|
||||
"time": "2026-01-05T11:45:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher-contracts",
|
||||
@@ -7158,16 +7158,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/expression-language",
|
||||
"version": "v8.0.0",
|
||||
"version": "v8.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/expression-language.git",
|
||||
"reference": "43f520aef59d2fd089662d721b39e0101bb69232"
|
||||
"reference": "83989cfbcf2ba08a400be339a88468b05ddc21c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/expression-language/zipball/43f520aef59d2fd089662d721b39e0101bb69232",
|
||||
"reference": "43f520aef59d2fd089662d721b39e0101bb69232",
|
||||
"url": "https://api.github.com/repos/symfony/expression-language/zipball/83989cfbcf2ba08a400be339a88468b05ddc21c9",
|
||||
"reference": "83989cfbcf2ba08a400be339a88468b05ddc21c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7201,7 +7201,7 @@
|
||||
"description": "Provides an engine that can compile and evaluate expressions",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/expression-language/tree/v8.0.0"
|
||||
"source": "https://github.com/symfony/expression-language/tree/v8.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7221,20 +7221,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-12T15:46:48+00:00"
|
||||
"time": "2026-01-05T09:27:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v7.4.3",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "fffe05569336549b20a1be64250b40516d6e8d06"
|
||||
"reference": "01b24a145bbeaa7141e75887ec904c34a6728a5f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/fffe05569336549b20a1be64250b40516d6e8d06",
|
||||
"reference": "fffe05569336549b20a1be64250b40516d6e8d06",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/01b24a145bbeaa7141e75887ec904c34a6728a5f",
|
||||
"reference": "01b24a145bbeaa7141e75887ec904c34a6728a5f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7269,7 +7269,7 @@
|
||||
"description": "Finds files and directories via an intuitive fluent interface",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/finder/tree/v7.4.3"
|
||||
"source": "https://github.com/symfony/finder/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7289,20 +7289,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-23T14:50:43+00:00"
|
||||
"time": "2026-01-12T12:19:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-client",
|
||||
"version": "v8.0.3",
|
||||
"version": "v8.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-client.git",
|
||||
"reference": "ea062691009cc2b7bb87734fef20e02671cbd50b"
|
||||
"reference": "ee9cc4a32fd1cb202b052ba9905a3c873363a465"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/ea062691009cc2b7bb87734fef20e02671cbd50b",
|
||||
"reference": "ea062691009cc2b7bb87734fef20e02671cbd50b",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/ee9cc4a32fd1cb202b052ba9905a3c873363a465",
|
||||
"reference": "ee9cc4a32fd1cb202b052ba9905a3c873363a465",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7365,7 +7365,7 @@
|
||||
"http"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-client/tree/v8.0.3"
|
||||
"source": "https://github.com/symfony/http-client/tree/v8.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7385,7 +7385,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-23T14:52:06+00:00"
|
||||
"time": "2026-01-23T16:34:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-client-contracts",
|
||||
@@ -7467,16 +7467,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v7.4.3",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-foundation.git",
|
||||
"reference": "a70c745d4cea48dbd609f4075e5f5cbce453bd52"
|
||||
"reference": "977a554a34cf8edc95ca351fbecb1bb1ad05cc94"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/a70c745d4cea48dbd609f4075e5f5cbce453bd52",
|
||||
"reference": "a70c745d4cea48dbd609f4075e5f5cbce453bd52",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/977a554a34cf8edc95ca351fbecb1bb1ad05cc94",
|
||||
"reference": "977a554a34cf8edc95ca351fbecb1bb1ad05cc94",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7525,7 +7525,7 @@
|
||||
"description": "Defines an object-oriented layer for the HTTP specification",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v7.4.3"
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7545,20 +7545,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-23T14:23:49+00:00"
|
||||
"time": "2026-01-09T12:14:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
"version": "v7.4.3",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-kernel.git",
|
||||
"reference": "885211d4bed3f857b8c964011923528a55702aa5"
|
||||
"reference": "48b067768859f7b68acf41dfb857a5a4be00acdd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/885211d4bed3f857b8c964011923528a55702aa5",
|
||||
"reference": "885211d4bed3f857b8c964011923528a55702aa5",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/48b067768859f7b68acf41dfb857a5a4be00acdd",
|
||||
"reference": "48b067768859f7b68acf41dfb857a5a4be00acdd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7644,7 +7644,7 @@
|
||||
"description": "Provides a structured process for converting a Request into a Response",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-kernel/tree/v7.4.3"
|
||||
"source": "https://github.com/symfony/http-kernel/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7664,20 +7664,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-31T08:43:57+00:00"
|
||||
"time": "2026-01-24T22:13:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mailer",
|
||||
"version": "v7.4.3",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mailer.git",
|
||||
"reference": "e472d35e230108231ccb7f51eb6b2100cac02ee4"
|
||||
"reference": "7b750074c40c694ceb34cb926d6dffee231c5cd6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mailer/zipball/e472d35e230108231ccb7f51eb6b2100cac02ee4",
|
||||
"reference": "e472d35e230108231ccb7f51eb6b2100cac02ee4",
|
||||
"url": "https://api.github.com/repos/symfony/mailer/zipball/7b750074c40c694ceb34cb926d6dffee231c5cd6",
|
||||
"reference": "7b750074c40c694ceb34cb926d6dffee231c5cd6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7728,7 +7728,7 @@
|
||||
"description": "Helps sending emails",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mailer/tree/v7.4.3"
|
||||
"source": "https://github.com/symfony/mailer/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7748,7 +7748,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-16T08:02:06+00:00"
|
||||
"time": "2026-01-08T08:25:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mailgun-mailer",
|
||||
@@ -7822,16 +7822,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/mime",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mime.git",
|
||||
"reference": "bdb02729471be5d047a3ac4a69068748f1a6be7a"
|
||||
"reference": "40945014c0a9471ccfe19673c54738fa19367a3c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/bdb02729471be5d047a3ac4a69068748f1a6be7a",
|
||||
"reference": "bdb02729471be5d047a3ac4a69068748f1a6be7a",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/40945014c0a9471ccfe19673c54738fa19367a3c",
|
||||
"reference": "40945014c0a9471ccfe19673c54738fa19367a3c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7887,7 +7887,7 @@
|
||||
"mime-type"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mime/tree/v7.4.0"
|
||||
"source": "https://github.com/symfony/mime/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7907,7 +7907,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-16T10:14:42+00:00"
|
||||
"time": "2026-01-08T16:12:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
@@ -8811,16 +8811,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v7.4.3",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "2f8e1a6cdf590ca63715da4d3a7a3327404a523f"
|
||||
"reference": "626f07a53f4b4e2f00e11824cc29f928d797783b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/2f8e1a6cdf590ca63715da4d3a7a3327404a523f",
|
||||
"reference": "2f8e1a6cdf590ca63715da4d3a7a3327404a523f",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/626f07a53f4b4e2f00e11824cc29f928d797783b",
|
||||
"reference": "626f07a53f4b4e2f00e11824cc29f928d797783b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -8852,7 +8852,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v7.4.3"
|
||||
"source": "https://github.com/symfony/process/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -8872,20 +8872,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-19T10:00:43+00:00"
|
||||
"time": "2026-01-20T09:23:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/psr-http-message-bridge",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/psr-http-message-bridge.git",
|
||||
"reference": "0101ff8bd0506703b045b1670960302d302a726c"
|
||||
"reference": "929ffe10bbfbb92e711ac3818d416f9daffee067"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/0101ff8bd0506703b045b1670960302d302a726c",
|
||||
"reference": "0101ff8bd0506703b045b1670960302d302a726c",
|
||||
"url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/929ffe10bbfbb92e711ac3818d416f9daffee067",
|
||||
"reference": "929ffe10bbfbb92e711ac3818d416f9daffee067",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -8940,7 +8940,7 @@
|
||||
"psr-7"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.4.0"
|
||||
"source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -8960,20 +8960,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-13T08:38:49+00:00"
|
||||
"time": "2026-01-03T23:30:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
"version": "v7.4.3",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/routing.git",
|
||||
"reference": "5d3fd7adf8896c2fdb54e2f0f35b1bcbd9e45090"
|
||||
"reference": "0798827fe2c79caeed41d70b680c2c3507d10147"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/routing/zipball/5d3fd7adf8896c2fdb54e2f0f35b1bcbd9e45090",
|
||||
"reference": "5d3fd7adf8896c2fdb54e2f0f35b1bcbd9e45090",
|
||||
"url": "https://api.github.com/repos/symfony/routing/zipball/0798827fe2c79caeed41d70b680c2c3507d10147",
|
||||
"reference": "0798827fe2c79caeed41d70b680c2c3507d10147",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9025,7 +9025,7 @@
|
||||
"url"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/routing/tree/v7.4.3"
|
||||
"source": "https://github.com/symfony/routing/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9045,7 +9045,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-19T10:00:43+00:00"
|
||||
"time": "2026-01-12T12:19:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
@@ -9136,16 +9136,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v8.0.1",
|
||||
"version": "v8.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc"
|
||||
"reference": "758b372d6882506821ed666032e43020c4f57194"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/ba65a969ac918ce0cc3edfac6cdde847eba231dc",
|
||||
"reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/758b372d6882506821ed666032e43020c4f57194",
|
||||
"reference": "758b372d6882506821ed666032e43020c4f57194",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9202,7 +9202,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v8.0.1"
|
||||
"source": "https://github.com/symfony/string/tree/v8.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9222,20 +9222,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-01T09:13:36+00:00"
|
||||
"time": "2026-01-12T12:37:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v8.0.3",
|
||||
"version": "v8.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "60a8f11f0e15c48f2cc47c4da53873bb5b62135d"
|
||||
"reference": "db70c8ce7db74fd2da7b1d268db46b2a8ce32c10"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/60a8f11f0e15c48f2cc47c4da53873bb5b62135d",
|
||||
"reference": "60a8f11f0e15c48f2cc47c4da53873bb5b62135d",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/db70c8ce7db74fd2da7b1d268db46b2a8ce32c10",
|
||||
"reference": "db70c8ce7db74fd2da7b1d268db46b2a8ce32c10",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9295,7 +9295,7 @@
|
||||
"description": "Provides tools to internationalize your application",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/translation/tree/v8.0.3"
|
||||
"source": "https://github.com/symfony/translation/tree/v8.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9315,7 +9315,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-21T10:59:45+00:00"
|
||||
"time": "2026-01-13T13:06:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation-contracts",
|
||||
@@ -9401,16 +9401,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/uid",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/uid.git",
|
||||
"reference": "2498e9f81b7baa206f44de583f2f48350b90142c"
|
||||
"reference": "7719ce8aba76be93dfe249192f1fbfa52c588e36"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/uid/zipball/2498e9f81b7baa206f44de583f2f48350b90142c",
|
||||
"reference": "2498e9f81b7baa206f44de583f2f48350b90142c",
|
||||
"url": "https://api.github.com/repos/symfony/uid/zipball/7719ce8aba76be93dfe249192f1fbfa52c588e36",
|
||||
"reference": "7719ce8aba76be93dfe249192f1fbfa52c588e36",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9455,7 +9455,7 @@
|
||||
"uuid"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/uid/tree/v7.4.0"
|
||||
"source": "https://github.com/symfony/uid/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9475,20 +9475,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-25T11:02:55+00:00"
|
||||
"time": "2026-01-03T23:30:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v7.4.3",
|
||||
"version": "v7.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "7e99bebcb3f90d8721890f2963463280848cba92"
|
||||
"reference": "0e4769b46a0c3c62390d124635ce59f66874b282"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/7e99bebcb3f90d8721890f2963463280848cba92",
|
||||
"reference": "7e99bebcb3f90d8721890f2963463280848cba92",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/0e4769b46a0c3c62390d124635ce59f66874b282",
|
||||
"reference": "0e4769b46a0c3c62390d124635ce59f66874b282",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9542,7 +9542,7 @@
|
||||
"dump"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v7.4.3"
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v7.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9562,7 +9562,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-18T07:04:31+00:00"
|
||||
"time": "2026-01-01T22:13:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-exporter",
|
||||
@@ -13088,8 +13088,5 @@
|
||||
"ext-xmlwriter": "*"
|
||||
},
|
||||
"platform-dev": {},
|
||||
"platform-overrides": {
|
||||
"php": "8.4"
|
||||
},
|
||||
"plugin-api-version": "2.9.0"
|
||||
}
|
||||
|
||||
+2
-2
@@ -78,8 +78,8 @@ return [
|
||||
'running_balance_column' => (bool)envNonEmpty('USE_RUNNING_BALANCE', true), // this is only the default value, is not used.
|
||||
// see cer.php for exchange rates feature flag.
|
||||
],
|
||||
'version' => 'develop/2026-01-24',
|
||||
'build_time' => 1769259315,
|
||||
'version' => 'develop/2026-01-25',
|
||||
'build_time' => 1769334802,
|
||||
'api_version' => '2.1.0', // field is no longer used.
|
||||
'db_version' => 28, // field is no longer used.
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class ConfigSeeder extends Seeder
|
||||
|
||||
return;
|
||||
}
|
||||
$version = (int) config('firefly.db_version');
|
||||
$version = (int) config('firefly.db_version');
|
||||
$entry->data = $version;
|
||||
$entry->save();
|
||||
}
|
||||
|
||||
Generated
+3
-3
@@ -4131,9 +4131,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/baseline-browser-mapping": {
|
||||
"version": "2.9.17",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.17.tgz",
|
||||
"integrity": "sha512-agD0MgJFUP/4nvjqzIB29zRPUuCF7Ge6mEv9s8dHrtYD7QWXRcx75rOADE/d5ah1NI+0vkDl0yorDd5U852IQQ==",
|
||||
"version": "2.9.18",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.18.tgz",
|
||||
"integrity": "sha512-e23vBV1ZLfjb9apvfPk4rHVu2ry6RIr2Wfs+O324okSidrX7pTAnEJPCh/O5BtRlr7QtZI7ktOP3vsqr7Z5XoA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
|
||||
Reference in New Issue
Block a user