A lot less queries for the account transformer.

This commit is contained in:
James Cole
2025-02-15 16:51:13 +01:00
parent f755dd2d48
commit 90fc4b44f2
11 changed files with 321 additions and 154 deletions

View File

@@ -29,7 +29,9 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter; use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
use FireflyIII\Transformers\AccountTransformer; use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
@@ -88,9 +90,17 @@ class ShowController extends Controller
$count = $collection->count(); $count = $collection->count();
// continue sort: // continue sort:
$accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); $accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new AccountEnrichment();
$enrichment->setUser($admin);
$enrichment->setConvertToNative($this->convertToNative);
$enrichment->setNative($this->nativeCurrency);
$accounts = $enrichment->enrich($accounts);
// make paginator: // make paginator:
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page')); $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.accounts.index').$this->buildParams()); $paginator->setPath(route('api.v1.accounts.index').$this->buildParams());
@@ -118,6 +128,16 @@ class ShowController extends Controller
$account->refresh(); $account->refresh();
$manager = $this->getManager(); $manager = $this->getManager();
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new AccountEnrichment();
$enrichment->setUser($admin);
$enrichment->setConvertToNative($this->convertToNative);
$enrichment->setNative($this->nativeCurrency);
$account = $enrichment->enrichSingle($account);
/** @var AccountTransformer $transformer */ /** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class); $transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);

View File

@@ -27,7 +27,9 @@ namespace FireflyIII\Api\V1\Controllers\Models\Account;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\Account\StoreRequest; use FireflyIII\Api\V1\Requests\Models\Account\StoreRequest;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
use FireflyIII\Transformers\AccountTransformer; use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use League\Fractal\Resource\Item; use League\Fractal\Resource\Item;
@@ -69,6 +71,15 @@ class StoreController extends Controller
$account = $this->repository->store($data); $account = $this->repository->store($data);
$manager = $this->getManager(); $manager = $this->getManager();
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new AccountEnrichment();
$enrichment->setUser($admin);
$enrichment->setConvertToNative($this->convertToNative);
$enrichment->setNative($this->nativeCurrency);
$account = $enrichment->enrichSingle($account);
/** @var AccountTransformer $transformer */ /** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class); $transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);

View File

@@ -28,7 +28,9 @@ use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\Account\UpdateRequest; use FireflyIII\Api\V1\Requests\Models\Account\UpdateRequest;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
use FireflyIII\Transformers\AccountTransformer; use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use League\Fractal\Resource\Item; use League\Fractal\Resource\Item;
@@ -73,6 +75,15 @@ class UpdateController extends Controller
$account->refresh(); $account->refresh();
app('preferences')->mark(); app('preferences')->mark();
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new AccountEnrichment();
$enrichment->setUser($admin);
$enrichment->setConvertToNative($this->convertToNative);
$enrichment->setNative($this->nativeCurrency);
$account = $enrichment->enrichSingle($account);
/** @var AccountTransformer $transformer */ /** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class); $transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);

View File

@@ -28,9 +28,11 @@ use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\PiggyBank; use FireflyIII\Models\PiggyBank;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
use FireflyIII\Transformers\AccountTransformer; use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\Transformers\AttachmentTransformer; use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\Transformers\PiggyBankEventTransformer; use FireflyIII\Transformers\PiggyBankEventTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Pagination\IlluminatePaginatorAdapter; use League\Fractal\Pagination\IlluminatePaginatorAdapter;
@@ -75,17 +77,26 @@ class ListController extends Controller
$collection = $piggyBank->accounts; $collection = $piggyBank->accounts;
$count = $collection->count(); $count = $collection->count();
$events = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); $accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new AccountEnrichment();
$enrichment->setUser($admin);
$enrichment->setConvertToNative($this->convertToNative);
$enrichment->setNative($this->nativeCurrency);
$accounts = $enrichment->enrich($accounts);
// make paginator: // make paginator:
$paginator = new LengthAwarePaginator($events, $count, $pageSize, $this->parameters->get('page')); $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.piggy-banks.accounts', [$piggyBank->id]).$this->buildParams()); $paginator->setPath(route('api.v1.piggy-banks.accounts', [$piggyBank->id]).$this->buildParams());
/** @var AccountTransformer $transformer */ /** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class); $transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);
$resource = new FractalCollection($events, $transformer, 'accounts'); $resource = new FractalCollection($accounts, $transformer, 'accounts');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);

View File

@@ -42,6 +42,7 @@ use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
use FireflyIII\Repositories\Rule\RuleRepositoryInterface; use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter; use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
use FireflyIII\Transformers\AccountTransformer; use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\Transformers\AvailableBudgetTransformer; use FireflyIII\Transformers\AvailableBudgetTransformer;
@@ -101,6 +102,15 @@ class ListController extends Controller
$count = $collection->count(); $count = $collection->count();
$accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); $accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new AccountEnrichment();
$enrichment->setUser($admin);
$enrichment->setConvertToNative($this->convertToNative);
$enrichment->setNative($this->nativeCurrency);
$accounts = $enrichment->enrich($accounts);
// make paginator: // make paginator:
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page')); $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.currencies.accounts', [$currency->code]).$this->buildParams()); $paginator->setPath(route('api.v1.currencies.accounts', [$currency->code]).$this->buildParams());

View File

@@ -26,8 +26,10 @@ namespace FireflyIII\Api\V1\Controllers\Search;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Support\Http\Api\AccountFilter; use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
use FireflyIII\Support\Search\AccountSearch; use FireflyIII\Support\Search\AccountSearch;
use FireflyIII\Transformers\AccountTransformer; use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response; use Illuminate\Http\Response;
@@ -81,6 +83,15 @@ class AccountController extends Controller
$accounts = $search->search(); $accounts = $search->search();
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new AccountEnrichment();
$enrichment->setUser($admin);
$enrichment->setConvertToNative($this->convertToNative);
$enrichment->setNative($this->nativeCurrency);
$accounts = $enrichment->enrich($accounts);
/** @var AccountTransformer $transformer */ /** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class); $transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);

View File

@@ -25,14 +25,20 @@ declare(strict_types=1);
namespace FireflyIII\Support\JsonApi\Enrichments; namespace FireflyIII\Support\JsonApi\Enrichments;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta; use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Models\Location;
use FireflyIII\Models\Note;
use FireflyIII\Models\ObjectGroup; use FireflyIII\Models\ObjectGroup;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\UserGroup; use FireflyIII\Models\UserGroup;
use FireflyIII\Support\Facades\Balance; use FireflyIII\Support\Facades\Balance;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Api\ExchangeRateConverter; use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@@ -67,15 +73,21 @@ class AccountEnrichment implements EnrichmentInterface
private array $accountTypes; private array $accountTypes;
private array $currencies; private array $currencies;
private array $meta; private array $meta;
private array $openingBalances;
private array $notes;
private array $locations;
public function __construct() public function __construct()
{ {
$this->convertToNative = false; $this->convertToNative = false;
$this->accountIds = []; $this->accountIds = [];
$this->openingBalances = [];
$this->currencies = []; $this->currencies = [];
$this->accountTypeIds = []; $this->accountTypeIds = [];
$this->accountTypes = []; $this->accountTypes = [];
$this->meta = []; $this->meta = [];
$this->notes = [];
$this->locations = [];
// $this->repository = app(AccountRepositoryInterface::class); // $this->repository = app(AccountRepositoryInterface::class);
// $this->currencyRepository = app(CurrencyRepositoryInterface::class); // $this->currencyRepository = app(CurrencyRepositoryInterface::class);
// $this->start = null; // $this->start = null;
@@ -105,6 +117,8 @@ class AccountEnrichment implements EnrichmentInterface
$this->collectAccountIds(); $this->collectAccountIds();
$this->getAccountTypes(); $this->getAccountTypes();
$this->collectMetaData(); $this->collectMetaData();
$this->collectLocations();
$this->collectOpeningBalances();
// $this->default = app('amount')->getNativeCurrency(); // $this->default = app('amount')->getNativeCurrency();
// $this->currencies = []; // $this->currencies = [];
// $this->balances = []; // $this->balances = [];
@@ -156,23 +170,90 @@ class AccountEnrichment implements EnrichmentInterface
private function appendCollectedData(): void private function appendCollectedData(): void
{ {
$accountTypes = $this->accountTypes; $accountTypes = $this->accountTypes;
$meta = $this->meta; $meta = $this->meta;
$this->collection = $this->collection->map(function (Account $item) use ($accountTypes, $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; $item->full_account_type = $accountTypes[(int) $item->account_type_id] ?? null;
$meta = []; $accountMeta = [
'currency' => null,
'location' => [
'latitude' => null,
'longitude' => null,
'zoom_level' => null,
],
];
if (array_key_exists((int) $item->id, $meta)) { if (array_key_exists((int) $item->id, $meta)) {
foreach ($meta[(int) $item->id] as $name => $value) { foreach ($meta[(int) $item->id] as $name => $value) {
$meta[$name] = $value; $accountMeta[$name] = $value;
} }
} }
$item->meta = $meta; // 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; 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)));
}
/** /**
* TODO this method refers to a single-use method inside Steam that could be moved here. * TODO this method refers to a single-use method inside Steam that could be moved here.
*/ */
@@ -386,5 +467,17 @@ class AccountEnrichment implements EnrichmentInterface
$this->native = $native; $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)));
}
} }

View File

@@ -24,6 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Support\JsonApi\Enrichments; namespace FireflyIII\Support\JsonApi\Enrichments;
use FireflyIII\Models\UserGroup;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -32,4 +34,11 @@ interface EnrichmentInterface
public function enrich(Collection $collection): Collection; public function enrich(Collection $collection): Collection;
public function enrichSingle(Model|array $model): Model|array; public function enrichSingle(Model|array $model): Model|array;
public function setUserGroup(UserGroup $userGroup): void;
public function setUser(User $user): void;
} }

View File

@@ -29,6 +29,7 @@ use FireflyIII\Models\Attachment;
use FireflyIII\Models\Location; use FireflyIII\Models\Location;
use FireflyIII\Models\Note; use FireflyIII\Models\Note;
use FireflyIII\Models\Tag; use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionJournalMeta; use FireflyIII\Models\TransactionJournalMeta;
use FireflyIII\Models\UserGroup; use FireflyIII\Models\UserGroup;
@@ -80,7 +81,7 @@ class TransactionGroupEnrichment implements EnrichmentInterface
return $this->collection; return $this->collection;
} }
#[\Override] public function enrichSingle(Model|array $model): Model|array #[\Override] public function enrichSingle(Model|array $model): TransactionGroup|array
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
if(is_array($model)) { if(is_array($model)) {

View File

@@ -41,14 +41,14 @@ class Steam
{ {
public function getAccountCurrency(Account $account): ?TransactionCurrency public function getAccountCurrency(Account $account): ?TransactionCurrency
{ {
$type = $account->accountType->type; $type = $account->accountType->type;
$list = config('firefly.valid_currency_account_types'); $list = config('firefly.valid_currency_account_types');
// return null if not in this list. // return null if not in this list.
if (!in_array($type, $list, true)) { if (!in_array($type, $list, true)) {
return null; return null;
} }
$result = $account->accountMeta->where('name', 'currency_id')->first(); $result = $account->accountMeta()->where('name', 'currency_id')->first();
if (null === $result) { if (null === $result) {
return null; return null;
} }
@@ -64,7 +64,7 @@ class Steam
Log::debug(sprintf('finalAccountBalanceInRange(#%d, %s, %s)', $account->id, $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s'))); Log::debug(sprintf('finalAccountBalanceInRange(#%d, %s, %s)', $account->id, $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
// set up cache // set up cache
$cache = new CacheProperties(); $cache = new CacheProperties();
$cache->addProperty($account->id); $cache->addProperty($account->id);
$cache->addProperty('final-balance-in-range'); $cache->addProperty('final-balance-in-range');
$cache->addProperty($start); $cache->addProperty($start);
@@ -74,21 +74,21 @@ class Steam
return $cache->get(); return $cache->get();
} }
$balances = []; $balances = [];
$formatted = $start->format('Y-m-d'); $formatted = $start->format('Y-m-d');
/* /*
* To make sure the start balance is correct, we need to get the balance at the exact end of the previous day. * To make sure the start balance is correct, we need to get the balance at the exact end of the previous day.
* Since we just did "startOfDay" we can do subDay()->endOfDay() to get the correct moment. * Since we just did "startOfDay" we can do subDay()->endOfDay() to get the correct moment.
* THAT will be the start balance. * THAT will be the start balance.
*/ */
$request = clone $start; $request = clone $start;
$request->subDay()->endOfDay(); $request->subDay()->endOfDay();
Log::debug(sprintf('finalAccountBalanceInRange: Call finalAccountBalance with date/time "%s"', $request->toIso8601String())); Log::debug(sprintf('finalAccountBalanceInRange: Call finalAccountBalance with date/time "%s"', $request->toIso8601String()));
$startBalance = $this->finalAccountBalance($account, $request); $startBalance = $this->finalAccountBalance($account, $request);
$nativeCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); $nativeCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup);
$accountCurrency = $this->getAccountCurrency($account); $accountCurrency = $this->getAccountCurrency($account);
$hasCurrency = null !== $accountCurrency; $hasCurrency = null !== $accountCurrency;
$currency = $accountCurrency ?? $nativeCurrency; $currency = $accountCurrency ?? $nativeCurrency;
Log::debug(sprintf('Currency is %s', $currency->code)); Log::debug(sprintf('Currency is %s', $currency->code));
@@ -101,7 +101,7 @@ class Steam
Log::debug(sprintf('Also set start balance in %s', $nativeCurrency->code)); Log::debug(sprintf('Also set start balance in %s', $nativeCurrency->code));
$startBalance[$nativeCurrency->code] ??= '0'; $startBalance[$nativeCurrency->code] ??= '0';
} }
$currencies = [ $currencies = [
$currency->id => $currency, $currency->id => $currency,
$nativeCurrency->id => $nativeCurrency, $nativeCurrency->id => $nativeCurrency,
]; ];
@@ -111,46 +111,45 @@ class Steam
// sums up the balance changes per day. // sums up the balance changes per day.
Log::debug(sprintf('Date >= %s and <= %s', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s'))); Log::debug(sprintf('Date >= %s and <= %s', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
$set = $account->transactions() $set = $account->transactions()
->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s'))
->groupBy('transaction_journals.date') ->groupBy('transaction_journals.date')
->groupBy('transactions.transaction_currency_id') ->groupBy('transactions.transaction_currency_id')
->orderBy('transaction_journals.date', 'ASC') ->orderBy('transaction_journals.date', 'ASC')
->whereNull('transaction_journals.deleted_at') ->whereNull('transaction_journals.deleted_at')
->get( ->get(
[ // @phpstan-ignore-line [ // @phpstan-ignore-line
'transaction_journals.date', 'transaction_journals.date',
'transactions.transaction_currency_id', 'transactions.transaction_currency_id',
DB::raw('SUM(transactions.amount) AS sum_of_day'), DB::raw('SUM(transactions.amount) AS sum_of_day'),
] ]
) );
;
$currentBalance = $startBalance; $currentBalance = $startBalance;
$converter = new ExchangeRateConverter(); $converter = new ExchangeRateConverter();
/** @var Transaction $entry */ /** @var Transaction $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
// get date object // get date object
$carbon = new Carbon($entry->date, $entry->date_tz); $carbon = new Carbon($entry->date, $entry->date_tz);
$carbonKey = $carbon->format('Y-m-d'); $carbonKey = $carbon->format('Y-m-d');
// make sure sum is a string: // make sure sum is a string:
$sumOfDay = (string) (null === $entry->sum_of_day ? '0' : $entry->sum_of_day); $sumOfDay = (string) (null === $entry->sum_of_day ? '0' : $entry->sum_of_day);
// find currency of this entry, does not have to exist. // find currency of this entry, does not have to exist.
$currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id); $currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id);
// make sure this $entry has its own $entryCurrency // make sure this $entry has its own $entryCurrency
/** @var TransactionCurrency $entryCurrency */ /** @var TransactionCurrency $entryCurrency */
$entryCurrency = $currencies[$entry->transaction_currency_id]; $entryCurrency = $currencies[$entry->transaction_currency_id];
Log::debug(sprintf('Processing transaction(s) on moment %s', $carbon->format('Y-m-d H:i:s'))); Log::debug(sprintf('Processing transaction(s) on moment %s', $carbon->format('Y-m-d H:i:s')));
// add amount to current balance in currency code. // add amount to current balance in currency code.
$currentBalance[$entryCurrency->code] ??= '0'; $currentBalance[$entryCurrency->code] ??= '0';
$currentBalance[$entryCurrency->code] = bcadd($sumOfDay, $currentBalance[$entryCurrency->code]); $currentBalance[$entryCurrency->code] = bcadd($sumOfDay, $currentBalance[$entryCurrency->code]);
// if not convert to native, add the amount to "balance", do nothing else. // if not convert to native, add the amount to "balance", do nothing else.
@@ -168,7 +167,7 @@ class Steam
} }
// just set it. // just set it.
$balances[$carbonKey] = $currentBalance; $balances[$carbonKey] = $currentBalance;
Log::debug(sprintf('Updated entry [%s]', $carbonKey), $currentBalance); Log::debug(sprintf('Updated entry [%s]', $carbonKey), $currentBalance);
} }
$cache->store($balances); $cache->store($balances);
@@ -207,10 +206,10 @@ class Steam
// Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision)); // Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision));
if (str_contains($number, '.')) { if (str_contains($number, '.')) {
if ('-' !== $number[0]) { if ('-' !== $number[0]) {
return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision); return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision);
} }
return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision); return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision);
} }
return $number; return $number;
@@ -288,35 +287,45 @@ class Steam
* --> "native_balance": balance in the user's native balance, with all amounts converted to native. * --> "native_balance": balance in the user's native balance, with all amounts converted to native.
* "EUR": balance in EUR (or whatever currencies the account has balance in) * "EUR": balance in EUR (or whatever currencies the account has balance in)
*/ */
public function finalAccountBalance(Account $account, Carbon $date): array public function finalAccountBalance(Account $account, Carbon $date, ?TransactionCurrency $native = null, ?bool $convertToNative = null): array
{ {
$cache = new CacheProperties(); $cache = new CacheProperties();
$cache->addProperty($account->id); $cache->addProperty($account->id);
$cache->addProperty($date); $cache->addProperty($date);
if ($cache->has()) { if ($cache->has()) {
// Log::debug(sprintf('CACHED finalAccountBalance(#%d, %s)', $account->id, $date->format('Y-m-d H:i:s'))); Log::debug(sprintf('CACHED finalAccountBalance(#%d, %s)', $account->id, $date->format('Y-m-d H:i:s')));
return $cache->get(); return $cache->get();
} }
Log::debug(sprintf('finalAccountBalance(#%d, %s)', $account->id, $date->format('Y-m-d H:i:s'))); Log::debug(sprintf('finalAccountBalance(#%d, %s)', $account->id, $date->format('Y-m-d H:i:s')));
if (null === $convertToNative) {
$convertToNative = Amount::convertToNative($account->user);
}
if (null === $native) {
$native = Amount::getNativeCurrencyByUserGroup($account->user->userGroup);
}
// account balance thing.
$currencyPresent = isset($account->meta) && array_key_exists('currency', $account->meta) && $account->meta['currency'] !== null;
if($currencyPresent) {
$accountCurrency = $account->meta['currency'];
}
if(!$currencyPresent) {
$native = Amount::getNativeCurrencyByUserGroup($account->user->userGroup); $accountCurrency = $this->getAccountCurrency($account);
$convertToNative = Amount::convertToNative($account->user); }
$accountCurrency = $this->getAccountCurrency($account); $hasCurrency = null !== $accountCurrency;
$hasCurrency = null !== $accountCurrency; $currency = $hasCurrency ? $accountCurrency : $native;
$currency = $hasCurrency ? $accountCurrency : $native; $return = [
$return = [
'native_balance' => '0', 'native_balance' => '0',
'balance' => '0', // this key is overwritten right away, but I must remember it is always created. 'balance' => '0', // this key is overwritten right away, but I must remember it is always created.
]; ];
// balance(s) in all currencies. // balance(s) in all currencies.
$array = $account->transactions() $array = $account->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id')
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
->get(['transaction_currencies.code', 'transactions.amount'])->toArray() ->get(['transaction_currencies.code', 'transactions.amount'])->toArray();
; $others = $this->groupAndSumTransactions($array, 'code', 'amount');
$others = $this->groupAndSumTransactions($array, 'code', 'amount');
// Log::debug('All balances are (joined)', $others); // Log::debug('All balances are (joined)', $others);
// if there is no request to convert, take this as "balance" and "native_balance". // if there is no request to convert, take this as "balance" and "native_balance".
$return['balance'] = $others[$currency->code] ?? '0'; $return['balance'] = $others[$currency->code] ?? '0';
@@ -331,7 +340,7 @@ class Steam
} }
// either way, the balance is always combined with the virtual balance: // either way, the balance is always combined with the virtual balance:
$virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance); $virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance);
if ($convertToNative) { if ($convertToNative) {
// the native balance is combined with a converted virtual_balance: // the native balance is combined with a converted virtual_balance:
@@ -345,7 +354,7 @@ class Steam
$return['balance'] = bcadd($return['balance'], $virtualBalance); $return['balance'] = bcadd($return['balance'], $virtualBalance);
// Log::debug(sprintf('Virtual balance makes the (native) total %s', $return['balance'])); // Log::debug(sprintf('Virtual balance makes the (native) total %s', $return['balance']));
} }
$final = array_merge($return, $others); $final = array_merge($return, $others);
Log::debug('Final balance is', $final); Log::debug('Final balance is', $final);
$cache->store($final); $cache->store($final);
@@ -452,15 +461,15 @@ class Steam
{ {
$list = []; $list = [];
$set = auth()->user()->transactions() $set = auth()->user()->transactions()
->whereIn('transactions.account_id', $accounts) ->whereIn('transactions.account_id', $accounts)
->groupBy(['transactions.account_id', 'transaction_journals.user_id']) ->groupBy(['transactions.account_id', 'transaction_journals.user_id'])
->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line ->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line
; ;
/** @var Transaction $entry */ /** @var Transaction $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
$date = new Carbon($entry->max_date, config('app.timezone')); $date = new Carbon($entry->max_date, config('app.timezone'));
$date->setTimezone(config('app.timezone')); $date->setTimezone(config('app.timezone'));
$list[(int) $entry->account_id] = $date; $list[(int) $entry->account_id] = $date;
} }
@@ -535,9 +544,9 @@ class Steam
public function getSafeUrl(string $unknownUrl, string $safeUrl): string public function getSafeUrl(string $unknownUrl, string $safeUrl): string
{ {
// Log::debug(sprintf('getSafeUrl(%s, %s)', $unknownUrl, $safeUrl)); // Log::debug(sprintf('getSafeUrl(%s, %s)', $unknownUrl, $safeUrl));
$returnUrl = $safeUrl; $returnUrl = $safeUrl;
$unknownHost = parse_url($unknownUrl, PHP_URL_HOST); $unknownHost = parse_url($unknownUrl, PHP_URL_HOST);
$safeHost = parse_url($safeUrl, PHP_URL_HOST); $safeHost = parse_url($safeUrl, PHP_URL_HOST);
if (null !== $unknownHost && $unknownHost === $safeHost) { if (null !== $unknownHost && $unknownHost === $safeHost) {
$returnUrl = $unknownUrl; $returnUrl = $unknownUrl;
@@ -574,7 +583,7 @@ class Steam
*/ */
public function floatalize(string $value): string public function floatalize(string $value): string
{ {
$value = strtoupper($value); $value = strtoupper($value);
if (!str_contains($value, 'E')) { if (!str_contains($value, 'E')) {
return $value; return $value;
} }
@@ -662,9 +671,9 @@ class Steam
if (null === $currency) { if (null === $currency) {
continue; continue;
} }
$current = $converter->convert($currency, $native, $date, $amount); $current = $converter->convert($currency, $native, $date, $amount);
Log::debug(sprintf('Convert %s %s to %s %s', $currency->code, $amount, $native->code, $current)); Log::debug(sprintf('Convert %s %s to %s %s', $currency->code, $amount, $native->code, $current));
$total = bcadd($current, $total); $total = bcadd($current, $total);
} }
return $total; return $total;

View File

@@ -31,6 +31,7 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\ParameterBag;
@@ -61,60 +62,51 @@ class AccountTransformer extends AbstractTransformer
*/ */
public function transform(Account $account): array public function transform(Account $account): array
{ {
$this->repository->setUser($account->user);
// get account type: // get account type:
$accountType = (string) config(sprintf('firefly.shortNamesByFullName.%s', $account->full_account_type));
$liabilityType = (string) config(sprintf('firefly.shortLiabilityNameByFullName.%s', $account->full_account_type));
$liabilityType = '' === $liabilityType ? null : strtolower($liabilityType);
$fullType = $account->accountType->type; $liabilityDirection = $account->meta['liability_direction'] ?? null;
$accountType = (string) config(sprintf('firefly.shortNamesByFullName.%s', $fullType));
$liabilityType = (string) config(sprintf('firefly.shortLiabilityNameByFullName.%s', $fullType));
$liabilityType = '' === $liabilityType ? null : strtolower($liabilityType);
$liabilityDirection = $this->repository->getMetaValue($account, 'liability_direction');
$convertToNative = Amount::convertToNative();
// get account role (will only work if the type is asset). // get account role (will only work if the type is asset).
$native = Amount::getNativeCurrency(); $accountRole = $this->getAccountRole($account, $accountType);
$accountRole = $this->getAccountRole($account, $accountType);
$date = $this->getDate(); // date (for balance etc.)
$date = $this->getDate();
$date->endOfDay(); $date->endOfDay();
[$currencyId, $currencyCode, $currencySymbol, $decimalPlaces] = $this->getCurrency($account); [$creditCardType, $monthlyPaymentDate] = $this->getCCInfo($account, $accountRole, $accountType);
[$creditCardType, $monthlyPaymentDate] = $this->getCCInfo($account, $accountRole, $accountType); [$openingBalance, $nativeOpeningBalance, $openingBalanceDate] = $this->getOpeningBalance($account, $accountType);
[$openingBalance, $nativeOpeningBalance, $openingBalanceDate] = $this->getOpeningBalance($account, $accountType, $convertToNative); [$interest, $interestPeriod] = $this->getInterest($account, $accountType);
[$interest, $interestPeriod] = $this->getInterest($account, $accountType);
$native = $this->native; $native = $this->native;
if (!$this->convertToNative) { if (!$this->convertToNative) {
// reset native currency to NULL, not interesting. // reset native currency to NULL, not interesting.
$native = null; $native = null;
} }
//
$openingBalance = app('steam')->bcround($openingBalance, $decimalPlaces); $decimalPlaces = (int) $account->meta['currency']?->decimal_places;
$includeNetWorth = '0' !== $this->repository->getMetaValue($account, 'include_net_worth'); $decimalPlaces = 0 === $decimalPlaces ? 2 : $decimalPlaces;
$longitude = null; $openingBalance = Steam::bcround($openingBalance, $decimalPlaces);
$latitude = null; $includeNetWorth = '0' !== ($account->meta['include_net_worth'] ?? null);
$zoomLevel = null; $longitude = $account->meta['location']['longitude'] ?? null;
$location = $this->repository->getLocation($account); $latitude = $account->meta['location']['latitude'] ?? null;
if (null !== $location) { $zoomLevel = $account->meta['location']['zoom_level'] ?? null;
$longitude = $location->longitude;
$latitude = $location->latitude;
$zoomLevel = (int) $location->zoom_level;
}
// no order for some accounts: // no order for some accounts:
$order = $account->order; $order = $account->order;
if (!in_array(strtolower($accountType), ['liability', 'liabilities', 'asset'], true)) { if (!in_array(strtolower($accountType), ['liability', 'liabilities', 'asset'], true)) {
$order = null; $order = null;
} }
// balance, native balance, virtual balance, native virtual balance? // balance, native balance, virtual balance, native virtual balance?
Log::debug(sprintf('transform: Call finalAccountBalance with date/time "%s"', $date->toIso8601String())); Log::debug(sprintf('transform: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
$finalBalance = Steam::finalAccountBalance($account, $date); $finalBalance = Steam::finalAccountBalance($account, $date, $this->native, $this->convertToNative);
if ($convertToNative) { if ($this->convertToNative) {
$finalBalance['balance'] = $finalBalance[$currencyCode] ?? '0'; $finalBalance['balance'] = $finalBalance[$account->meta['currency']?->code] ?? '0';
} }
$currentBalance = app('steam')->bcround($finalBalance['balance'] ?? '0', $decimalPlaces); $currentBalance = Steam::bcround($finalBalance['balance'] ?? '0', $decimalPlaces);
$nativeCurrentBalance = $convertToNative ? app('steam')->bcround($finalBalance['native_balance'] ?? '0', $native->decimal_places) : null; $nativeCurrentBalance = $this->convertToNative ? Steam::bcround($finalBalance['native_balance'] ?? '0', $native->decimal_places) : null;
return [ return [
'id' => (string) $account->id, 'id' => (string) $account->id,
@@ -125,10 +117,10 @@ class AccountTransformer extends AbstractTransformer
'name' => $account->name, 'name' => $account->name,
'type' => strtolower($accountType), 'type' => strtolower($accountType),
'account_role' => $accountRole, 'account_role' => $accountRole,
'currency_id' => $currencyId, 'currency_id' => $account->meta['currency_id'] ?? null,
'currency_code' => $currencyCode, 'currency_code' => $account->meta['currency']?->code,
'currency_symbol' => $currencySymbol, 'currency_symbol' => $account->meta['currency']?->symbol,
'currency_decimal_places' => $decimalPlaces, 'currency_decimal_places' => $account->meta['currency']?->decimal_places,
'native_currency_id' => null === $native ? null : (string) $native->id, 'native_currency_id' => null === $native ? null : (string) $native->id,
'native_currency_code' => $native?->code, 'native_currency_code' => $native?->code,
'native_currency_symbol' => $native?->symbol, 'native_currency_symbol' => $native?->symbol,
@@ -136,14 +128,14 @@ class AccountTransformer extends AbstractTransformer
'current_balance' => $currentBalance, 'current_balance' => $currentBalance,
'native_current_balance' => $nativeCurrentBalance, 'native_current_balance' => $nativeCurrentBalance,
'current_balance_date' => $date->toAtomString(), 'current_balance_date' => $date->toAtomString(),
'notes' => $this->repository->getNoteText($account), 'notes' => $account->meta['notes'] ?? null,
'monthly_payment_date' => $monthlyPaymentDate, 'monthly_payment_date' => $monthlyPaymentDate,
'credit_card_type' => $creditCardType, 'credit_card_type' => $creditCardType,
'account_number' => $this->repository->getMetaValue($account, 'account_number'), 'account_number' => $account->meta['account_number'] ?? null,
'iban' => '' === $account->iban ? null : $account->iban, 'iban' => '' === $account->iban ? null : $account->iban,
'bic' => $this->repository->getMetaValue($account, 'BIC'), 'bic' => $account->meta['BIC'] ?? null,
'virtual_balance' => app('steam')->bcround($account->virtual_balance, $decimalPlaces), 'virtual_balance' => Steam::bcround($account->virtual_balance, $decimalPlaces),
'native_virtual_balance' => $this->convertToNative ? app('steam')->bcround($account->native_virtual_balance, $native->decimal_places) : null, 'native_virtual_balance' => $this->convertToNative ? Steam::bcround($account->native_virtual_balance, $native->decimal_places) : null,
'opening_balance' => $openingBalance, 'opening_balance' => $openingBalance,
'native_opening_balance' => $nativeOpeningBalance, 'native_opening_balance' => $nativeOpeningBalance,
'opening_balance_date' => $openingBalanceDate, 'opening_balance_date' => $openingBalanceDate,
@@ -151,7 +143,7 @@ class AccountTransformer extends AbstractTransformer
'liability_direction' => $liabilityDirection, 'liability_direction' => $liabilityDirection,
'interest' => $interest, 'interest' => $interest,
'interest_period' => $interestPeriod, 'interest_period' => $interestPeriod,
'current_debt' => $this->repository->getMetaValue($account, 'current_debt'), 'current_debt' => $account->meta['current_debt'] ?? null,
'include_net_worth' => $includeNetWorth, 'include_net_worth' => $includeNetWorth,
'longitude' => $longitude, 'longitude' => $longitude,
'latitude' => $latitude, 'latitude' => $latitude,
@@ -159,7 +151,7 @@ class AccountTransformer extends AbstractTransformer
'links' => [ 'links' => [
[ [
'rel' => 'self', 'rel' => 'self',
'uri' => '/accounts/'.$account->id, 'uri' => sprintf('/accounts/%d', $account->id),
], ],
], ],
]; ];
@@ -167,7 +159,7 @@ class AccountTransformer extends AbstractTransformer
private function getAccountRole(Account $account, string $accountType): ?string private function getAccountRole(Account $account, string $accountType): ?string
{ {
$accountRole = $this->repository->getMetaValue($account, 'account_role'); $accountRole = $account->meta['account_role'] ?? null;
if ('asset' !== $accountType || '' === (string) $accountRole) { if ('asset' !== $accountType || '' === (string) $accountRole) {
$accountRole = null; $accountRole = null;
} }
@@ -188,34 +180,18 @@ class AccountTransformer extends AbstractTransformer
return $date; return $date;
} }
private function getCurrency(Account $account): array
{
$currency = $this->repository->getAccountCurrency($account);
// only grab native when result is null:
if (null === $currency) {
$currency = $this->native;
}
$currencyId = (string) $currency->id;
$currencyCode = $currency->code;
$decimalPlaces = $currency->decimal_places;
$currencySymbol = $currency->symbol;
return [$currencyId, $currencyCode, $currencySymbol, $decimalPlaces];
}
private function getCCInfo(Account $account, ?string $accountRole, string $accountType): array private function getCCInfo(Account $account, ?string $accountRole, string $accountType): array
{ {
$monthlyPaymentDate = null; $monthlyPaymentDate = null;
$creditCardType = null; $creditCardType = null;
if ('ccAsset' === $accountRole && 'asset' === $accountType) { if ('ccAsset' === $accountRole && 'asset' === $accountType) {
$creditCardType = $this->repository->getMetaValue($account, 'cc_type'); $creditCardType = $account->meta['cc_type'] ?? null;
$monthlyPaymentDate = $this->repository->getMetaValue($account, 'cc_monthly_payment_date'); $monthlyPaymentDate = $account->meta['cc_monthly_payment_date'] ?? null;
} }
if (null !== $monthlyPaymentDate) { if (null !== $monthlyPaymentDate) {
// try classic date: // try classic date:
if (10 === strlen($monthlyPaymentDate)) { if (10 === strlen($monthlyPaymentDate)) {
$object = Carbon::createFromFormat('!Y-m-d', $monthlyPaymentDate, config('app.timezone')); $object = Carbon::createFromFormat('!Y-m-d', $monthlyPaymentDate, config('app.timezone'));
if (null === $object) { if (null === $object) {
$object = today(config('app.timezone')); $object = today(config('app.timezone'));
} }
@@ -229,25 +205,30 @@ class AccountTransformer extends AbstractTransformer
return [$creditCardType, $monthlyPaymentDate]; return [$creditCardType, $monthlyPaymentDate];
} }
/** private function getOpeningBalance(Account $account, string $accountType): array
* TODO refactor call to get~OpeningBalanceAmount / Date because it is a lot of queries
*/
private function getOpeningBalance(Account $account, string $accountType, bool $convertToNative): array
{ {
$openingBalance = null; $openingBalance = null;
$openingBalanceDate = null; $openingBalanceDate = null;
$nativeOpeningBalance = null; $nativeOpeningBalance = null;
if (in_array($accountType, ['asset', 'liabilities'], true)) { if (in_array($accountType, ['asset', 'liabilities'], true)) {
$openingBalance = $this->repository->getOpeningBalanceAmount($account, false); // grab from meta.
$nativeOpeningBalance = $this->repository->getOpeningBalanceAmount($account, true); $openingBalance = $account->meta['opening_balance_amount'] ?? null;
$openingBalanceDate = $this->repository->getOpeningBalanceDate($account); $nativeOpeningBalance = null;
$openingBalanceDate = $account->meta['opening_balance_date'] ?? null;
} }
if (null !== $openingBalanceDate) { if (null !== $openingBalanceDate) {
$object = Carbon::createFromFormat('Y-m-d H:i:s', $openingBalanceDate, config('app.timezone')); $object = Carbon::createFromFormat('Y-m-d H:i:s', $openingBalanceDate, config('app.timezone'));
if (null === $object) { if (null === $object) {
$object = today(config('app.timezone')); $object = today(config('app.timezone'));
} }
$openingBalanceDate = $object->toAtomString(); $openingBalanceDate = $object->toAtomString();
// NOW do conversion.
if ($this->convertToNative && null !== $account->meta['currency']) {
$converter = new ExchangeRateConverter();
$nativeOpeningBalance = $converter->convert($account->meta['currency'], $this->native, $object, $openingBalance);
}
} }
return [$openingBalance, $nativeOpeningBalance, $openingBalanceDate]; return [$openingBalance, $nativeOpeningBalance, $openingBalanceDate];
@@ -258,8 +239,8 @@ class AccountTransformer extends AbstractTransformer
$interest = null; $interest = null;
$interestPeriod = null; $interestPeriod = null;
if ('liabilities' === $accountType) { if ('liabilities' === $accountType) {
$interest = $this->repository->getMetaValue($account, 'interest'); $interest = $account->meta['interest'] ?? null;
$interestPeriod = $this->repository->getMetaValue($account, 'interest_period'); $interestPeriod = $account->meta['interest_period'] ?? null;
} }
return [$interest, $interestPeriod]; return [$interest, $interestPeriod];