convertToNative = false; $this->accountIds = []; $this->openingBalances = []; $this->currencies = []; $this->accountTypeIds = []; $this->accountTypes = []; $this->meta = []; $this->notes = []; $this->locations = []; // $this->repository = app(AccountRepositoryInterface::class); // $this->currencyRepository = app(CurrencyRepositoryInterface::class); // $this->start = null; // $this->end = null; } #[\Override] public function enrichSingle(array|Model $model): Account|array { Log::debug(__METHOD__); $collection = new Collection([$model]); $collection = $this->enrich($collection); return $collection->first(); } #[\Override] /** * Do the actual enrichment. */ public function enrich(Collection $collection): Collection { Log::debug(sprintf('Now doing account enrichment for %d account(s)', $collection->count())); // prep local fields $this->collection = $collection; $this->collectAccountIds(); $this->getAccountTypes(); $this->collectMetaData(); $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->collection->transform(function (Account $account) { // $account->user_array = ['id' => 1, 'bla bla' => 'bla']; // $account->balances = collect([ // ['balance_id' => 1, 'balance' => 5], // ['balance_id' => 2, 'balance' => 5], // ['balance_id' => 3, 'balance' => 5], // ]); // // return $account; // }); $this->appendCollectedData(); return $this->collection; } 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; } } private function collectAccountIds(): void { /** @var Account $account */ foreach ($this->collection as $account) { $this->accountIds[] = (int) $account->id; $this->accountTypeIds[] = (int) $account->account_type_id; } $this->accountIds = array_unique($this->accountIds); $this->accountTypeIds = array_unique($this->accountTypeIds); } private function appendCollectedData(): void { $accountTypes = $this->accountTypes; $meta = $this->meta; $currencies = $this->currencies; $notes = $this->notes; $openingBalances = $this->openingBalances; $locations = $this->locations; $this->collection = $this->collection->map(function (Account $item) use ($accountTypes, $meta, $currencies, $notes, $openingBalances, $locations) { $item->full_account_type = $accountTypes[(int) $item->account_type_id] ?? null; $accountMeta = [ 'currency' => null, 'location' => [ 'latitude' => null, 'longitude' => null, 'zoom_level' => null, ], ]; if (array_key_exists((int) $item->id, $meta)) { foreach ($meta[(int) $item->id] as $name => $value) { $accountMeta[$name] = $value; } } // also add currency, if present. if (array_key_exists('currency_id', $accountMeta)) { $currencyId = (int) $accountMeta['currency_id']; $accountMeta['currency'] = $currencies[$currencyId]; } // if notes, add notes. if (array_key_exists($item->id, $notes)) { $accountMeta['notes'] = $notes[$item->id]; } // if opening balance, add opening balance if (array_key_exists($item->id, $openingBalances)) { $accountMeta['opening_balance_date'] = $openingBalances[$item->id]['date']; $accountMeta['opening_balance_amount'] = $openingBalances[$item->id]['amount']; } // if location, add location: if (array_key_exists($item->id, $locations)) { $accountMeta['location'] = $locations[$item->id]; } $item->meta = $accountMeta; return $item; }); } private function collectOpeningBalances(): void { // use new group collector: /** @var GroupCollectorInterface $collector */ $collector = app(GroupCollectorInterface::class); $collector->setUser($this->user)->setAccounts($this->collection) ->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'], ]; $this->openingBalances[(int) $journal['destination_account_id']] = [ 'amount' => Steam::positive($journal['amount']), 'date' => $journal['date'], ]; } } 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() ; foreach ($locations as $location) { $this->locations[(int) $location['locatable_id']] = [ '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']) ->whereIn('account_id', $this->accountIds) ->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']; if ('currency_id' === $entry['name']) { $this->currencies[(int) $entry['data']] = true; } } $currencies = TransactionCurrency::whereIn('id', array_keys($this->currencies))->get(); foreach ($currencies as $currency) { $this->currencies[(int) $currency->id] = $currency; } foreach ($this->currencies as $id => $currency) { if (true === $currency) { throw new FireflyException(sprintf('Currency #%d not found.', $id)); } } } public function setUserGroup(UserGroup $userGroup): void { $this->userGroup = $userGroup; } public function setUser(User $user): void { $this->user = $user; $this->userGroup = $user->userGroup; } public function setConvertToNative(bool $convertToNative): void { $this->convertToNative = $convertToNative; } public function setNative(TransactionCurrency $native): void { $this->native = $native; } 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() ; foreach ($notes as $note) { $this->notes[(int) $note['noteable_id']] = (string) $note['text']; } Log::debug(sprintf('Enrich with %d note(s)', count($this->notes))); } }