mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-12-12 01:42:32 +00:00
Auto commit for release 'develop' on 2025-02-17
This commit is contained in:
@@ -33,13 +33,10 @@ use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Location;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Support\Facades\Balance;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -52,15 +49,15 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class AccountEnrichment implements EnrichmentInterface
|
||||
{
|
||||
// private array $balances;
|
||||
// private array $currencies;
|
||||
// private CurrencyRepositoryInterface $currencyRepository;
|
||||
// private TransactionCurrency $default;
|
||||
// private ?Carbon $end;
|
||||
// private array $grouped;
|
||||
// private array $objectGroups;
|
||||
// private AccountRepositoryInterface $repository;
|
||||
// private ?Carbon $start;
|
||||
// private array $balances;
|
||||
// private array $currencies;
|
||||
// private CurrencyRepositoryInterface $currencyRepository;
|
||||
// private TransactionCurrency $default;
|
||||
// private ?Carbon $end;
|
||||
// private array $grouped;
|
||||
// private array $objectGroups;
|
||||
// private AccountRepositoryInterface $repository;
|
||||
// private ?Carbon $start;
|
||||
|
||||
private Collection $collection;
|
||||
|
||||
@@ -88,14 +85,14 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
$this->meta = [];
|
||||
$this->notes = [];
|
||||
$this->locations = [];
|
||||
// $this->repository = app(AccountRepositoryInterface::class);
|
||||
// $this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
// $this->start = null;
|
||||
// $this->end = null;
|
||||
// $this->repository = app(AccountRepositoryInterface::class);
|
||||
// $this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
// $this->start = null;
|
||||
// $this->end = null;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function enrichSingle(Model | array $model): Account | array
|
||||
public function enrichSingle(array|Model $model): Account|array
|
||||
{
|
||||
Log::debug(__METHOD__);
|
||||
$collection = new Collection([$model]);
|
||||
@@ -120,18 +117,18 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
$this->collectNotes();
|
||||
$this->collectLocations();
|
||||
$this->collectOpeningBalances();
|
||||
// $this->default = app('amount')->getNativeCurrency();
|
||||
// $this->currencies = [];
|
||||
// $this->balances = [];
|
||||
// $this->objectGroups = [];
|
||||
// $this->grouped = [];
|
||||
//
|
||||
// // do everything here:
|
||||
// $this->getLastActivity();
|
||||
// $this->collectAccountTypes();
|
||||
// $this->collectMetaData();
|
||||
// $this->getMetaBalances();
|
||||
// $this->getObjectGroups();
|
||||
// $this->default = app('amount')->getNativeCurrency();
|
||||
// $this->currencies = [];
|
||||
// $this->balances = [];
|
||||
// $this->objectGroups = [];
|
||||
// $this->grouped = [];
|
||||
//
|
||||
// // do everything here:
|
||||
// $this->getLastActivity();
|
||||
// $this->collectAccountTypes();
|
||||
// $this->collectMetaData();
|
||||
// $this->getMetaBalances();
|
||||
// $this->getObjectGroups();
|
||||
|
||||
// $this->collection->transform(function (Account $account) {
|
||||
// $account->user_array = ['id' => 1, 'bla bla' => 'bla'];
|
||||
@@ -152,6 +149,7 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
private function getAccountTypes(): void
|
||||
{
|
||||
$types = AccountType::whereIn('id', $this->accountTypeIds)->get();
|
||||
|
||||
/** @var AccountType $type */
|
||||
foreach ($types as $type) {
|
||||
$this->accountTypes[(int) $type->id] = $type->type;
|
||||
@@ -212,7 +210,7 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
if (array_key_exists($item->id, $locations)) {
|
||||
$accountMeta['location'] = $locations[$item->id];
|
||||
}
|
||||
$item->meta = $accountMeta;
|
||||
$item->meta = $accountMeta;
|
||||
|
||||
return $item;
|
||||
});
|
||||
@@ -224,43 +222,47 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user)->setAccounts($this->collection)
|
||||
->withAccountInformation()
|
||||
->setTypes([TransactionTypeEnum::OPENING_BALANCE->value]);
|
||||
$journals = $collector->getExtractedJournals();
|
||||
->withAccountInformation()
|
||||
->setTypes([TransactionTypeEnum::OPENING_BALANCE->value])
|
||||
;
|
||||
$journals = $collector->getExtractedJournals();
|
||||
foreach ($journals as $journal) {
|
||||
$this->openingBalances[(int) $journal['source_account_id']]
|
||||
= [
|
||||
'amount' => Steam::negative($journal['amount']),
|
||||
'date' => $journal['date'],
|
||||
];
|
||||
'amount' => Steam::negative($journal['amount']),
|
||||
'date' => $journal['date'],
|
||||
];
|
||||
$this->openingBalances[(int) $journal['destination_account_id']]
|
||||
= [
|
||||
'amount' => Steam::positive($journal['amount']),
|
||||
'date' => $journal['date'],
|
||||
];
|
||||
'amount' => Steam::positive($journal['amount']),
|
||||
'date' => $journal['date'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
private function collectLocations(): void {
|
||||
private function collectLocations(): void
|
||||
{
|
||||
$locations = Location::query()->whereIn('locatable_id', $this->accountIds)
|
||||
->where('locatable_type', Account::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray();
|
||||
->where('locatable_type', Account::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray()
|
||||
;
|
||||
foreach ($locations as $location) {
|
||||
$this->locations[(int) $location['locatable_id']]
|
||||
= [
|
||||
'latitude' => (float) $location['latitude'],
|
||||
'longitude' => (float) $location['longitude'],
|
||||
'zoom_level' => (int) $location['zoom_level'],
|
||||
];
|
||||
'latitude' => (float) $location['latitude'],
|
||||
'longitude' => (float) $location['longitude'],
|
||||
'zoom_level' => (int) $location['zoom_level'],
|
||||
];
|
||||
}
|
||||
Log::debug(sprintf('Enrich with %d locations(s)', count($this->locations)));
|
||||
}
|
||||
|
||||
private function collectMetaData(): void
|
||||
{
|
||||
$set = AccountMeta
|
||||
::whereIn('name', ['is_multi_currency', 'currency_id', 'account_role', 'account_number', 'liability_direction', 'interest', 'interest_period', 'current_debt'])
|
||||
$set = AccountMeta::whereIn('name', ['is_multi_currency', 'currency_id', 'account_role', 'account_number', 'liability_direction', 'interest', 'interest_period', 'current_debt'])
|
||||
->whereIn('account_id', $this->accountIds)
|
||||
->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data'])->toArray();
|
||||
->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data'])->toArray()
|
||||
;
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($set as $entry) {
|
||||
$this->meta[(int) $entry['account_id']][$entry['name']] = (string) $entry['data'];
|
||||
@@ -303,14 +305,13 @@ class AccountEnrichment implements EnrichmentInterface
|
||||
private function collectNotes(): void
|
||||
{
|
||||
$notes = Note::query()->whereIn('noteable_id', $this->accountIds)
|
||||
->whereNotNull('notes.text')
|
||||
->where('notes.text', '!=', '')
|
||||
->where('noteable_type', Account::class)->get(['notes.noteable_id', 'notes.text'])->toArray();
|
||||
->whereNotNull('notes.text')
|
||||
->where('notes.text', '!=', '')
|
||||
->where('noteable_type', Account::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
|
||||
;
|
||||
foreach ($notes as $note) {
|
||||
$this->notes[(int) $note['noteable_id']] = (string) $note['text'];
|
||||
}
|
||||
Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -33,12 +33,9 @@ interface EnrichmentInterface
|
||||
{
|
||||
public function enrich(Collection $collection): Collection;
|
||||
|
||||
public function enrichSingle(Model|array $model): Model|array;
|
||||
public function enrichSingle(array|Model $model): array|Model;
|
||||
|
||||
public function setUserGroup(UserGroup $userGroup): void;
|
||||
|
||||
public function setUser(User $user): void;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* TransactionGroupEnrichment.php
|
||||
* Copyright (c) 2025 james@firefly-iii.org.
|
||||
@@ -60,10 +61,11 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
$this->metaData = [];
|
||||
$this->locations = [];
|
||||
$this->attachmentCount = [];
|
||||
$this->dateFields = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date',];
|
||||
$this->dateFields = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'];
|
||||
}
|
||||
|
||||
#[\Override] public function enrich(Collection $collection): Collection
|
||||
#[\Override]
|
||||
public function enrich(Collection $collection): Collection
|
||||
{
|
||||
Log::debug(sprintf('Now doing account enrichment for %d transaction group(s)', $collection->count()));
|
||||
// prep local fields
|
||||
@@ -81,14 +83,17 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
return $this->collection;
|
||||
}
|
||||
|
||||
#[\Override] public function enrichSingle(Model|array $model): TransactionGroup|array
|
||||
#[\Override]
|
||||
public function enrichSingle(array|Model $model): array|TransactionGroup
|
||||
{
|
||||
Log::debug(__METHOD__);
|
||||
if(is_array($model)) {
|
||||
if (is_array($model)) {
|
||||
$collection = new Collection([$model]);
|
||||
$collection = $this->enrich($collection);
|
||||
|
||||
return $collection->first();
|
||||
}
|
||||
|
||||
throw new FireflyException('Cannot enrich single model.');
|
||||
}
|
||||
|
||||
@@ -117,9 +122,10 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
private function collectNotes(): void
|
||||
{
|
||||
$notes = Note::query()->whereIn('noteable_id', $this->journalIds)
|
||||
->whereNotNull('notes.text')
|
||||
->where('notes.text', '!=', '')
|
||||
->where('noteable_type', TransactionJournal::class)->get(['notes.noteable_id', 'notes.text'])->toArray();
|
||||
->whereNotNull('notes.text')
|
||||
->where('notes.text', '!=', '')
|
||||
->where('noteable_type', TransactionJournal::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
|
||||
;
|
||||
foreach ($notes as $note) {
|
||||
$this->notes[(int) $note['noteable_id']] = (string) $note['text'];
|
||||
}
|
||||
@@ -128,13 +134,13 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
|
||||
private function collectTags(): void
|
||||
{
|
||||
$set = Tag::
|
||||
leftJoin('tag_transaction_journal', 'tags.id', '=', 'tag_transaction_journal.tag_id')
|
||||
->whereIn('tag_transaction_journal.transaction_journal_id', $this->journalIds)
|
||||
->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag'])->toArray();
|
||||
$set = Tag::leftJoin('tag_transaction_journal', 'tags.id', '=', 'tag_transaction_journal.tag_id')
|
||||
->whereIn('tag_transaction_journal.transaction_journal_id', $this->journalIds)
|
||||
->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag'])->toArray()
|
||||
;
|
||||
foreach ($set as $item) {
|
||||
$journalId = $item['transaction_journal_id'];
|
||||
$this->tags[$journalId] ??= [];
|
||||
$this->tags[$journalId] ??= [];
|
||||
$this->tags[$journalId][] = $item['tag'];
|
||||
}
|
||||
}
|
||||
@@ -143,13 +149,14 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
{
|
||||
$set = TransactionJournalMeta::whereIn('transaction_journal_id', $this->journalIds)->get(['transaction_journal_id', 'name', 'data'])->toArray();
|
||||
foreach ($set as $entry) {
|
||||
$name = $entry['name'];
|
||||
$data = (string) $entry['data'];
|
||||
$name = $entry['name'];
|
||||
$data = (string) $entry['data'];
|
||||
if ('' === $data) {
|
||||
continue;
|
||||
}
|
||||
if (in_array($name, $this->dateFields, true)) {
|
||||
$this->metaData[$entry['transaction_journal_id']][$name] = Carbon::parse($data);
|
||||
|
||||
continue;
|
||||
}
|
||||
$this->metaData[(int) $entry['transaction_journal_id']][$name] = $data;
|
||||
@@ -159,14 +166,15 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
private function collectLocations(): void
|
||||
{
|
||||
$locations = Location::query()->whereIn('locatable_id', $this->journalIds)
|
||||
->where('locatable_type', TransactionJournal::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray();
|
||||
->where('locatable_type', TransactionJournal::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray()
|
||||
;
|
||||
foreach ($locations as $location) {
|
||||
$this->locations[(int) $location['locatable_id']]
|
||||
= [
|
||||
'latitude' => (float) $location['latitude'],
|
||||
'longitude' => (float) $location['longitude'],
|
||||
'zoom_level' => (int) $location['zoom_level'],
|
||||
];
|
||||
'latitude' => (float) $location['latitude'],
|
||||
'longitude' => (float) $location['longitude'],
|
||||
'zoom_level' => (int) $location['zoom_level'],
|
||||
];
|
||||
}
|
||||
Log::debug(sprintf('Enrich with %d locations(s)', count($this->locations)));
|
||||
}
|
||||
@@ -174,19 +182,21 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
private function collectAttachmentCount(): void
|
||||
{
|
||||
// select count(id) as nr_of_attachments, attachable_id from attachments
|
||||
//group by attachable_id
|
||||
// group by attachable_id
|
||||
$attachments = Attachment::query()
|
||||
->whereIn('attachable_id', $this->journalIds)
|
||||
->where('attachable_type', TransactionJournal::class)
|
||||
->groupBy('attachable_id')
|
||||
->get(['attachable_id', DB::raw('COUNT(id) as nr_of_attachments')]) // @phpstan-ignore-line
|
||||
->toArray();
|
||||
->whereIn('attachable_id', $this->journalIds)
|
||||
->where('attachable_type', TransactionJournal::class)
|
||||
->groupBy('attachable_id')
|
||||
->get(['attachable_id', DB::raw('COUNT(id) as nr_of_attachments')]) // @phpstan-ignore-line
|
||||
->toArray()
|
||||
;
|
||||
foreach ($attachments as $row) {
|
||||
$this->attachmentCount[(int) $row['attachable_id']] = (int) $row['nr_of_attachments'];
|
||||
}
|
||||
}
|
||||
|
||||
private function appendCollectedData(): void {
|
||||
private function appendCollectedData(): void
|
||||
{
|
||||
$notes = $this->notes;
|
||||
$tags = $this->tags;
|
||||
$metaData = $this->metaData;
|
||||
@@ -195,32 +205,33 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
|
||||
$this->collection = $this->collection->map(function (array $item) use ($notes, $tags, $metaData, $locations, $attachmentCount) {
|
||||
foreach ($item['transactions'] as $index => $transaction) {
|
||||
$journalId = (int) $transaction['transaction_journal_id'];
|
||||
$journalId = (int) $transaction['transaction_journal_id'];
|
||||
|
||||
// attach notes if they exist:
|
||||
$item['transactions'][$index]['notes'] = array_key_exists($journalId, $notes) ? $notes[$journalId] : null;
|
||||
$item['transactions'][$index]['notes'] = array_key_exists($journalId, $notes) ? $notes[$journalId] : null;
|
||||
|
||||
// attach tags if they exist:
|
||||
$item['transactions'][$index]['tags'] = array_key_exists($journalId, $tags) ? $tags[$journalId] : [];
|
||||
$item['transactions'][$index]['tags'] = array_key_exists($journalId, $tags) ? $tags[$journalId] : [];
|
||||
|
||||
// attachment count
|
||||
$item['transactions'][$index]['attachment_count'] = array_key_exists($journalId, $attachmentCount) ? $attachmentCount[$journalId] : 0;
|
||||
|
||||
// default location data
|
||||
$item['transactions'][$index]['location'] = [
|
||||
$item['transactions'][$index]['location'] = [
|
||||
'latitude' => null,
|
||||
'longitude' => null,
|
||||
'zoom_level' => null,
|
||||
];
|
||||
|
||||
// append meta data
|
||||
$item['transactions'][$index]['meta'] = [];
|
||||
$item['transactions'][$index]['meta_date'] = [];
|
||||
$item['transactions'][$index]['meta'] = [];
|
||||
$item['transactions'][$index]['meta_date'] = [];
|
||||
if (array_key_exists($journalId, $metaData)) {
|
||||
// loop al meta data:
|
||||
foreach ($metaData[$journalId] as $name => $value) {
|
||||
if (in_array($name, $this->dateFields, true)) {
|
||||
$item['transactions'][$index]['meta_date'][$name] = Carbon::parse($value);
|
||||
|
||||
continue;
|
||||
}
|
||||
$item['transactions'][$index]['meta'][$name] = $value;
|
||||
@@ -232,9 +243,8 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
$item['transactions'][$index]['location'] = $locations[$journalId];
|
||||
}
|
||||
}
|
||||
|
||||
return $item;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user