mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-04 11:43:02 +00:00
Move account balance logic to enrichment.
This commit is contained in:
@@ -96,6 +96,7 @@ class ShowController extends Controller
|
|||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setDate($this->parameters->get('date'));
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$accounts = $enrichment->enrich($accounts);
|
$accounts = $enrichment->enrich($accounts);
|
||||||
|
|
||||||
@@ -130,6 +131,7 @@ class ShowController extends Controller
|
|||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setDate($this->parameters->get('date'));
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$account = $enrichment->enrichSingle($account);
|
$account = $enrichment->enrichSingle($account);
|
||||||
|
|
||||||
|
@@ -75,6 +75,7 @@ class StoreController extends Controller
|
|||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setDate(null);
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$account = $enrichment->enrichSingle($account);
|
$account = $enrichment->enrichSingle($account);
|
||||||
|
|
||||||
|
@@ -80,6 +80,7 @@ class UpdateController extends Controller
|
|||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setDate(null);
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$account = $enrichment->enrichSingle($account);
|
$account = $enrichment->enrichSingle($account);
|
||||||
|
|
||||||
|
@@ -83,6 +83,7 @@ class ListController extends Controller
|
|||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setDate($this->parameters->get('date'));
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$accounts = $enrichment->enrich($accounts);
|
$accounts = $enrichment->enrich($accounts);
|
||||||
|
|
||||||
|
@@ -107,6 +107,7 @@ class ListController extends Controller
|
|||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setDate($this->parameters->get('date'));
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$accounts = $enrichment->enrich($accounts);
|
$accounts = $enrichment->enrich($accounts);
|
||||||
|
|
||||||
|
@@ -88,6 +88,7 @@ class AccountController extends Controller
|
|||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setDate($this->parameters->get('date'));
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$accounts = $enrichment->enrich($accounts);
|
$accounts = $enrichment->enrich($accounts);
|
||||||
|
|
||||||
|
@@ -176,6 +176,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
|||||||
/** @var TransactionGroup $model */
|
/** @var TransactionGroup $model */
|
||||||
$accounts = $this->collectAccounts($model);
|
$accounts = $this->collectAccounts($model);
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setDate(null);
|
||||||
$enrichment->setUser($model->user);
|
$enrichment->setUser($model->user);
|
||||||
$accounts = $enrichment->enrich($accounts);
|
$accounts = $enrichment->enrich($accounts);
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
|
@@ -148,6 +148,7 @@ class IndexController extends Controller
|
|||||||
// enrich each account.
|
// enrich each account.
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
$enrichment->setUser(auth()->user());
|
$enrichment->setUser(auth()->user());
|
||||||
|
$enrichment->setDate($end);
|
||||||
$return = [];
|
$return = [];
|
||||||
|
|
||||||
/** @var PiggyBank $piggy */
|
/** @var PiggyBank $piggy */
|
||||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Support\JsonApi\Enrichments;
|
namespace FireflyIII\Support\JsonApi\Enrichments;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
@@ -36,6 +37,7 @@ use FireflyIII\Models\TransactionCurrency;
|
|||||||
use FireflyIII\Models\UserGroup;
|
use FireflyIII\Models\UserGroup;
|
||||||
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 FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
@@ -62,26 +64,29 @@ class AccountEnrichment implements EnrichmentInterface
|
|||||||
private User $user;
|
private User $user;
|
||||||
private UserGroup $userGroup;
|
private UserGroup $userGroup;
|
||||||
private array $lastActivities;
|
private array $lastActivities;
|
||||||
|
private ?Carbon $date = null;
|
||||||
|
private bool $convertToPrimary = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO The account enricher must do conversion from and to the primary currency.
|
* TODO The account enricher must do conversion from and to the primary currency.
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->accountIds = [];
|
$this->accountIds = [];
|
||||||
$this->openingBalances = [];
|
$this->openingBalances = [];
|
||||||
$this->currencies = [];
|
$this->currencies = [];
|
||||||
$this->accountTypeIds = [];
|
$this->accountTypeIds = [];
|
||||||
$this->accountTypes = [];
|
$this->accountTypes = [];
|
||||||
$this->meta = [];
|
$this->meta = [];
|
||||||
$this->notes = [];
|
$this->notes = [];
|
||||||
$this->lastActivities = [];
|
$this->lastActivities = [];
|
||||||
$this->locations = [];
|
$this->locations = [];
|
||||||
$this->primaryCurrency = Amount::getPrimaryCurrency();
|
$this->primaryCurrency = Amount::getPrimaryCurrency();
|
||||||
|
$this->convertToPrimary = Amount::convertToPrimary();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Override]
|
#[Override]
|
||||||
public function enrichSingle(array|Model $model): Account|array
|
public function enrichSingle(array | Model $model): Account | array
|
||||||
{
|
{
|
||||||
Log::debug(__METHOD__);
|
Log::debug(__METHOD__);
|
||||||
$collection = new Collection([$model]);
|
$collection = new Collection([$model]);
|
||||||
@@ -107,6 +112,7 @@ class AccountEnrichment implements EnrichmentInterface
|
|||||||
$this->collectLastActivities();
|
$this->collectLastActivities();
|
||||||
$this->collectLocations();
|
$this->collectLocations();
|
||||||
$this->collectOpeningBalances();
|
$this->collectOpeningBalances();
|
||||||
|
$this->collectBalances();
|
||||||
$this->appendCollectedData();
|
$this->appendCollectedData();
|
||||||
|
|
||||||
return $this->collection;
|
return $this->collection;
|
||||||
@@ -135,10 +141,9 @@ class AccountEnrichment implements EnrichmentInterface
|
|||||||
|
|
||||||
private function collectMetaData(): void
|
private function collectMetaData(): void
|
||||||
{
|
{
|
||||||
$set = AccountMeta::whereIn('name', ['is_multi_currency', 'include_net_worth', 'currency_id', 'account_role', 'account_number', 'BIC', 'liability_direction', 'interest', 'interest_period', 'current_debt'])
|
$set = AccountMeta::whereIn('name', ['is_multi_currency', 'include_net_worth', 'currency_id', 'account_role', 'account_number', 'BIC', 'liability_direction', 'interest', 'interest_period', 'current_debt'])
|
||||||
->whereIn('account_id', $this->accountIds)
|
->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 */
|
/** @var array $entry */
|
||||||
foreach ($set as $entry) {
|
foreach ($set as $entry) {
|
||||||
@@ -147,7 +152,7 @@ class AccountEnrichment implements EnrichmentInterface
|
|||||||
$this->currencies[(int) $entry['data']] = true;
|
$this->currencies[(int) $entry['data']] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$currencies = TransactionCurrency::whereIn('id', array_keys($this->currencies))->get();
|
$currencies = TransactionCurrency::whereIn('id', array_keys($this->currencies))->get();
|
||||||
foreach ($currencies as $currency) {
|
foreach ($currencies as $currency) {
|
||||||
$this->currencies[(int) $currency->id] = $currency;
|
$this->currencies[(int) $currency->id] = $currency;
|
||||||
}
|
}
|
||||||
@@ -162,10 +167,9 @@ class AccountEnrichment implements EnrichmentInterface
|
|||||||
private function collectNotes(): void
|
private function collectNotes(): void
|
||||||
{
|
{
|
||||||
$notes = Note::query()->whereIn('noteable_id', $this->accountIds)
|
$notes = Note::query()->whereIn('noteable_id', $this->accountIds)
|
||||||
->whereNotNull('notes.text')
|
->whereNotNull('notes.text')
|
||||||
->where('notes.text', '!=', '')
|
->where('notes.text', '!=', '')
|
||||||
->where('noteable_type', Account::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
|
->where('noteable_type', Account::class)->get(['notes.noteable_id', 'notes.text'])->toArray();
|
||||||
;
|
|
||||||
foreach ($notes as $note) {
|
foreach ($notes as $note) {
|
||||||
$this->notes[(int) $note['noteable_id']] = (string) $note['text'];
|
$this->notes[(int) $note['noteable_id']] = (string) $note['text'];
|
||||||
}
|
}
|
||||||
@@ -175,15 +179,14 @@ class AccountEnrichment implements EnrichmentInterface
|
|||||||
private function collectLocations(): void
|
private function collectLocations(): void
|
||||||
{
|
{
|
||||||
$locations = Location::query()->whereIn('locatable_id', $this->accountIds)
|
$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) {
|
foreach ($locations as $location) {
|
||||||
$this->locations[(int) $location['locatable_id']]
|
$this->locations[(int) $location['locatable_id']]
|
||||||
= [
|
= [
|
||||||
'latitude' => (float) $location['latitude'],
|
'latitude' => (float) $location['latitude'],
|
||||||
'longitude' => (float) $location['longitude'],
|
'longitude' => (float) $location['longitude'],
|
||||||
'zoom_level' => (int) $location['zoom_level'],
|
'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)));
|
||||||
}
|
}
|
||||||
@@ -198,20 +201,19 @@ class AccountEnrichment implements EnrichmentInterface
|
|||||||
->setUserGroup($this->userGroup)
|
->setUserGroup($this->userGroup)
|
||||||
->setAccounts($this->collection)
|
->setAccounts($this->collection)
|
||||||
->withAccountInformation()
|
->withAccountInformation()
|
||||||
->setTypes([TransactionTypeEnum::OPENING_BALANCE->value])
|
->setTypes([TransactionTypeEnum::OPENING_BALANCE->value]);
|
||||||
;
|
$journals = $collector->getExtractedJournals();
|
||||||
$journals = $collector->getExtractedJournals();
|
|
||||||
foreach ($journals as $journal) {
|
foreach ($journals as $journal) {
|
||||||
$this->openingBalances[(int) $journal['source_account_id']]
|
$this->openingBalances[(int) $journal['source_account_id']]
|
||||||
= [
|
= [
|
||||||
'amount' => Steam::negative($journal['amount']),
|
'amount' => Steam::negative($journal['amount']),
|
||||||
'date' => $journal['date'],
|
'date' => $journal['date'],
|
||||||
];
|
];
|
||||||
$this->openingBalances[(int) $journal['destination_account_id']]
|
$this->openingBalances[(int) $journal['destination_account_id']]
|
||||||
= [
|
= [
|
||||||
'amount' => Steam::positive($journal['amount']),
|
'amount' => Steam::positive($journal['amount']),
|
||||||
'date' => $journal['date'],
|
'date' => $journal['date'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,32 +230,30 @@ class AccountEnrichment implements EnrichmentInterface
|
|||||||
|
|
||||||
private function appendCollectedData(): void
|
private function appendCollectedData(): void
|
||||||
{
|
{
|
||||||
$accountTypes = $this->accountTypes;
|
|
||||||
$meta = $this->meta;
|
|
||||||
$currencies = $this->currencies;
|
|
||||||
$notes = $this->notes;
|
$notes = $this->notes;
|
||||||
$openingBalances = $this->openingBalances;
|
$openingBalances = $this->openingBalances;
|
||||||
$locations = $this->locations;
|
$locations = $this->locations;
|
||||||
$lastActivities = $this->lastActivities;
|
$lastActivities = $this->lastActivities;
|
||||||
$this->collection = $this->collection->map(function (Account $item) use ($accountTypes, $meta, $currencies, $notes, $openingBalances, $locations, $lastActivities) {
|
$this->collection = $this->collection->map(function (Account $item) use ($notes, $openingBalances, $locations, $lastActivities) {
|
||||||
$item->full_account_type = $accountTypes[(int) $item->account_type_id] ?? null;
|
$item->full_account_type = $this->accountTypes[(int) $item->account_type_id] ?? null;
|
||||||
$accountMeta = [
|
$accountMeta = [
|
||||||
'currency' => null,
|
'currency' => null,
|
||||||
'location' => [
|
'location' => [
|
||||||
'latitude' => null,
|
'latitude' => null,
|
||||||
'longitude' => null,
|
'longitude' => null,
|
||||||
'zoom_level' => null,
|
'zoom_level' => null,
|
||||||
],
|
],
|
||||||
|
'opening_balance_date' => null,
|
||||||
];
|
];
|
||||||
if (array_key_exists((int) $item->id, $meta)) {
|
if (array_key_exists((int) $item->id, $this->meta)) {
|
||||||
foreach ($meta[(int) $item->id] as $name => $value) {
|
foreach ($this->meta[(int) $item->id] as $name => $value) {
|
||||||
$accountMeta[$name] = $value;
|
$accountMeta[$name] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// also add currency, if present.
|
// also add currency, if present.
|
||||||
if (array_key_exists('currency_id', $accountMeta)) {
|
if (array_key_exists('currency_id', $accountMeta)) {
|
||||||
$currencyId = (int) $accountMeta['currency_id'];
|
$currencyId = (int) $accountMeta['currency_id'];
|
||||||
$accountMeta['currency'] = $currencies[$currencyId];
|
$accountMeta['currency'] = $this->currencies[$currencyId];
|
||||||
}
|
}
|
||||||
|
|
||||||
// if notes, add notes.
|
// if notes, add notes.
|
||||||
@@ -266,6 +266,64 @@ class AccountEnrichment implements EnrichmentInterface
|
|||||||
$accountMeta['opening_balance_amount'] = $openingBalances[$item->id]['amount'];
|
$accountMeta['opening_balance_amount'] = $openingBalances[$item->id]['amount'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add balances
|
||||||
|
// get currencies:
|
||||||
|
$currency = $this->primaryCurrency; // assume primary currency
|
||||||
|
if (null !== $accountMeta['currency']) {
|
||||||
|
$currency = $accountMeta['currency'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the current balance:
|
||||||
|
$date = $this->getDate();
|
||||||
|
$finalBalance = Steam::finalAccountBalance($item, $date, $this->primaryCurrency, $this->convertToPrimary);
|
||||||
|
Log::debug(sprintf('Call finalAccountBalance(%s) with date/time "%s"', var_export($this->convertToPrimary, true), $date->toIso8601String()), $finalBalance);
|
||||||
|
|
||||||
|
// collect current balances:
|
||||||
|
$currentBalance = Steam::bcround($finalBalance[$currency->code] ?? '0', $currency->decimal_places);
|
||||||
|
$openingBalance = Steam::bcround($accountMeta['opening_balance_amount'] ?? '0', $currency->decimal_places);
|
||||||
|
$virtualBalance = Steam::bcround($account->virtual_balance ?? '0', $currency->decimal_places);
|
||||||
|
$debtAmount = $accountMeta['current_debt'] ?? null;
|
||||||
|
|
||||||
|
// set some pc_ default values to NULL:
|
||||||
|
$pcCurrentBalance = null;
|
||||||
|
$pcOpeningBalance = null;
|
||||||
|
$pcVirtualBalance = null;
|
||||||
|
$pcDebtAmount = null;
|
||||||
|
|
||||||
|
// convert to primary currency if needed:
|
||||||
|
if ($this->convertToPrimary && $currency->id !== $this->primaryCurrency->id) {
|
||||||
|
Log::debug(sprintf('Convert to primary, from %s to %s', $currency->code, $this->primaryCurrency->code));
|
||||||
|
$converter = new ExchangeRateConverter();
|
||||||
|
$pcCurrentBalance = $converter->convert($currency, $this->primaryCurrency, $date, $currentBalance);
|
||||||
|
$pcOpeningBalance = $converter->convert($currency, $this->primaryCurrency, $date, $openingBalance);
|
||||||
|
$pcVirtualBalance = $converter->convert($currency, $this->primaryCurrency, $date, $virtualBalance);
|
||||||
|
$pcDebtAmount = null === $debtAmount ? null : $converter->convert($currency, $this->primaryCurrency, $date, $debtAmount);
|
||||||
|
}
|
||||||
|
if ($this->convertToPrimary && $currency->id === $this->primaryCurrency->id) {
|
||||||
|
$pcCurrentBalance = $currentBalance;
|
||||||
|
$pcOpeningBalance = $openingBalance;
|
||||||
|
$pcVirtualBalance = $virtualBalance;
|
||||||
|
$pcDebtAmount = $debtAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set opening balance(s) to NULL if the date is null
|
||||||
|
if (null === $accountMeta['opening_balance_date']) {
|
||||||
|
$openingBalance = null;
|
||||||
|
$pcOpeningBalance = null;
|
||||||
|
}
|
||||||
|
$accountMeta['balances'] = [
|
||||||
|
'current_balance' => $currentBalance,
|
||||||
|
'pc_current_balance' => $pcCurrentBalance,
|
||||||
|
'opening_balance' => $openingBalance,
|
||||||
|
'pc_opening_balance' => $pcOpeningBalance,
|
||||||
|
'virtual_balance' => $virtualBalance,
|
||||||
|
'pc_virtual_balance' => $pcVirtualBalance,
|
||||||
|
'debt_amount' => $debtAmount,
|
||||||
|
'pc_debt_amount' => $pcDebtAmount,
|
||||||
|
];
|
||||||
|
// end add balances
|
||||||
|
|
||||||
|
|
||||||
// if location, add location:
|
// if location, add location:
|
||||||
if (array_key_exists($item->id, $locations)) {
|
if (array_key_exists($item->id, $locations)) {
|
||||||
$accountMeta['location'] = $locations[$item->id];
|
$accountMeta['location'] = $locations[$item->id];
|
||||||
@@ -273,7 +331,7 @@ class AccountEnrichment implements EnrichmentInterface
|
|||||||
if (array_key_exists($item->id, $lastActivities)) {
|
if (array_key_exists($item->id, $lastActivities)) {
|
||||||
$accountMeta['last_activity'] = $lastActivities[$item->id];
|
$accountMeta['last_activity'] = $lastActivities[$item->id];
|
||||||
}
|
}
|
||||||
$item->meta = $accountMeta;
|
$item->meta = $accountMeta;
|
||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
});
|
});
|
||||||
@@ -283,4 +341,21 @@ class AccountEnrichment implements EnrichmentInterface
|
|||||||
{
|
{
|
||||||
$this->lastActivities = Steam::getLastActivities($this->accountIds);
|
$this->lastActivities = Steam::getLastActivities($this->accountIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function collectBalances(): void {}
|
||||||
|
|
||||||
|
public function setDate(?Carbon $date): void
|
||||||
|
{
|
||||||
|
$this->date = $date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDate(): Carbon
|
||||||
|
{
|
||||||
|
if (null === $this->date) {
|
||||||
|
return today();
|
||||||
|
}
|
||||||
|
return $this->date;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -61,11 +61,11 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
$paidDates = $this->paidDates;
|
$paidDates = $this->paidDates;
|
||||||
$payDates = $this->payDates;
|
$payDates = $this->payDates;
|
||||||
$this->collection = $this->collection->map(function (Bill $item) use ($notes, $objectGroups, $paidDates, $payDates) {
|
$this->collection = $this->collection->map(function (Bill $item) use ($notes, $objectGroups, $paidDates, $payDates) {
|
||||||
$id = (int)$item->id;
|
$id = (int) $item->id;
|
||||||
$currency = $item->transactionCurrency;
|
$currency = $item->transactionCurrency;
|
||||||
$nem = $this->getNextExpectedMatch($payDates[$id] ?? []);
|
$nem = $this->getNextExpectedMatch($payDates[$id] ?? []);
|
||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'notes' => null,
|
'notes' => null,
|
||||||
'object_group_id' => null,
|
'object_group_id' => null,
|
||||||
'object_group_title' => null,
|
'object_group_title' => null,
|
||||||
@@ -76,20 +76,20 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
'nem' => $nem,
|
'nem' => $nem,
|
||||||
'nem_diff' => $this->getNextExpectedMatchDiff($nem, $payDates[$id] ?? []),
|
'nem_diff' => $this->getNextExpectedMatchDiff($nem, $payDates[$id] ?? []),
|
||||||
];
|
];
|
||||||
$amounts = [
|
$amounts = [
|
||||||
'amount_min' => Steam::bcround($item->amount_min, $currency->decimal_places),
|
'amount_min' => Steam::bcround($item->amount_min, $currency->decimal_places),
|
||||||
'amount_max' => Steam::bcround($item->amount_max, $currency->decimal_places),
|
'amount_max' => Steam::bcround($item->amount_max, $currency->decimal_places),
|
||||||
'average' => Steam::bcround(bcdiv(bcadd($item->amount_min, $item->amount_max), '2'), $currency->decimal_places),
|
'average' => Steam::bcround(bcdiv(bcadd($item->amount_min, $item->amount_max), '2'), $currency->decimal_places),
|
||||||
'pc_amount_min' => null,
|
'pc_amount_min' => null,
|
||||||
'pc_amount_max' => null,
|
'pc_amount_max' => null,
|
||||||
'pc_average' => null,
|
'pc_average' => null,
|
||||||
];
|
];
|
||||||
if($this->convertToPrimary && $currency->id === $this->primaryCurrency->id) {
|
if ($this->convertToPrimary && $currency->id === $this->primaryCurrency->id) {
|
||||||
$amounts['pc_amount_min'] = $amounts['amount_min'];
|
$amounts['pc_amount_min'] = $amounts['amount_min'];
|
||||||
$amounts['pc_amount_max'] = $amounts['amount_max'];
|
$amounts['pc_amount_max'] = $amounts['amount_max'];
|
||||||
$amounts['pc_average'] = $amounts['average'];
|
$amounts['pc_average'] = $amounts['average'];
|
||||||
}
|
}
|
||||||
if($this->convertToPrimary && $currency->id !== $this->primaryCurrency->id) {
|
if ($this->convertToPrimary && $currency->id !== $this->primaryCurrency->id) {
|
||||||
$amounts['pc_amount_min'] = Steam::bcround($item->native_amount_min, $this->primaryCurrency->decimal_places);
|
$amounts['pc_amount_min'] = Steam::bcround($item->native_amount_min, $this->primaryCurrency->decimal_places);
|
||||||
$amounts['pc_amount_max'] = Steam::bcround($item->native_amount_max, $this->primaryCurrency->decimal_places);
|
$amounts['pc_amount_max'] = Steam::bcround($item->native_amount_max, $this->primaryCurrency->decimal_places);
|
||||||
$amounts['pc_average'] = Steam::bcround(bcdiv(bcadd($item->native_amount_min, $item->native_amount_max), '2'), $this->primaryCurrency->decimal_places);
|
$amounts['pc_average'] = Steam::bcround(bcdiv(bcadd($item->native_amount_min, $item->native_amount_max), '2'), $this->primaryCurrency->decimal_places);
|
||||||
@@ -117,7 +117,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
return $collection;
|
return $collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function enrichSingle(array|Model $model): array|Model
|
public function enrichSingle(array | Model $model): array | Model
|
||||||
{
|
{
|
||||||
Log::debug(__METHOD__);
|
Log::debug(__METHOD__);
|
||||||
$collection = new Collection([$model]);
|
$collection = new Collection([$model]);
|
||||||
@@ -129,12 +129,11 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
private function collectNotes(): void
|
private function collectNotes(): void
|
||||||
{
|
{
|
||||||
$notes = Note::query()->whereIn('noteable_id', $this->subscriptionIds)
|
$notes = Note::query()->whereIn('noteable_id', $this->subscriptionIds)
|
||||||
->whereNotNull('notes.text')
|
->whereNotNull('notes.text')
|
||||||
->where('notes.text', '!=', '')
|
->where('notes.text', '!=', '')
|
||||||
->where('noteable_type', Bill::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
|
->where('noteable_type', Bill::class)->get(['notes.noteable_id', 'notes.text'])->toArray();
|
||||||
;
|
|
||||||
foreach ($notes as $note) {
|
foreach ($notes as $note) {
|
||||||
$this->notes[(int)$note['noteable_id']] = (string)$note['text'];
|
$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)));
|
||||||
}
|
}
|
||||||
@@ -154,30 +153,29 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
{
|
{
|
||||||
/** @var Bill $bill */
|
/** @var Bill $bill */
|
||||||
foreach ($this->collection as $bill) {
|
foreach ($this->collection as $bill) {
|
||||||
$this->subscriptionIds[] = (int)$bill->id;
|
$this->subscriptionIds[] = (int) $bill->id;
|
||||||
}
|
}
|
||||||
$this->subscriptionIds = array_unique($this->subscriptionIds);
|
$this->subscriptionIds = array_unique($this->subscriptionIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function collectObjectGroups(): void
|
private function collectObjectGroups(): void
|
||||||
{
|
{
|
||||||
$set = DB::table('object_groupables')
|
$set = DB::table('object_groupables')
|
||||||
->whereIn('object_groupable_id', $this->subscriptionIds)
|
->whereIn('object_groupable_id', $this->subscriptionIds)
|
||||||
->where('object_groupable_type', Bill::class)
|
->where('object_groupable_type', Bill::class)
|
||||||
->get(['object_groupable_id', 'object_group_id'])
|
->get(['object_groupable_id', 'object_group_id']);
|
||||||
;
|
|
||||||
|
|
||||||
$ids = array_unique($set->pluck('object_group_id')->toArray());
|
$ids = array_unique($set->pluck('object_group_id')->toArray());
|
||||||
|
|
||||||
foreach ($set as $entry) {
|
foreach ($set as $entry) {
|
||||||
$this->mappedObjects[(int)$entry->object_groupable_id] = (int)$entry->object_group_id;
|
$this->mappedObjects[(int) $entry->object_groupable_id] = (int) $entry->object_group_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$groups = ObjectGroup::whereIn('id', $ids)->get(['id', 'title', 'order'])->toArray();
|
$groups = ObjectGroup::whereIn('id', $ids)->get(['id', 'title', 'order'])->toArray();
|
||||||
foreach ($groups as $group) {
|
foreach ($groups as $group) {
|
||||||
$group['id'] = (int)$group['id'];
|
$group['id'] = (int) $group['id'];
|
||||||
$group['order'] = (int)$group['order'];
|
$group['order'] = (int) $group['order'];
|
||||||
$this->objectGroups[(int)$group['id']] = $group;
|
$this->objectGroups[(int) $group['id']] = $group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,13 +193,13 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
// 2023-07-18 this particular date is used to search for the last paid date.
|
// 2023-07-18 this particular date is used to search for the last paid date.
|
||||||
// 2023-07-18 the cloned $searchDate is used to grab the correct transactions.
|
// 2023-07-18 the cloned $searchDate is used to grab the correct transactions.
|
||||||
/** @var Carbon $start */
|
/** @var Carbon $start */
|
||||||
$start = clone $this->start;
|
$start = clone $this->start;
|
||||||
$searchStart = clone $start;
|
$searchStart = clone $start;
|
||||||
$start->subDay();
|
$start->subDay();
|
||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = clone $this->end;
|
$end = clone $this->end;
|
||||||
$searchEnd = clone $end;
|
$searchEnd = clone $end;
|
||||||
|
|
||||||
// move the search dates to the start of the day.
|
// move the search dates to the start of the day.
|
||||||
$searchStart->startOfDay();
|
$searchStart->startOfDay();
|
||||||
@@ -210,13 +208,13 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
Log::debug(sprintf('Search parameters are: start: %s, end: %s', $searchStart->format('Y-m-d H:i:s'), $searchEnd->format('Y-m-d H:i:s')));
|
Log::debug(sprintf('Search parameters are: start: %s, end: %s', $searchStart->format('Y-m-d H:i:s'), $searchEnd->format('Y-m-d H:i:s')));
|
||||||
|
|
||||||
// Get from database when bills were paid.
|
// Get from database when bills were paid.
|
||||||
$set = $this->user->transactionJournals()
|
$set = $this->user->transactionJournals()
|
||||||
->whereIn('bill_id', $this->subscriptionIds)
|
->whereIn('bill_id', $this->subscriptionIds)
|
||||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||||
->leftJoin('transaction_currencies AS currency', 'currency.id', '=', 'transactions.transaction_currency_id')
|
->leftJoin('transaction_currencies AS currency', 'currency.id', '=', 'transactions.transaction_currency_id')
|
||||||
->leftJoin('transaction_currencies AS foreign_currency', 'foreign_currency.id', '=', 'transactions.foreign_currency_id')
|
->leftJoin('transaction_currencies AS foreign_currency', 'foreign_currency.id', '=', 'transactions.foreign_currency_id')
|
||||||
->where('transactions.amount', '>', 0)
|
->where('transactions.amount', '>', 0)
|
||||||
->before($searchEnd)->after($searchStart)->get(
|
->before($searchEnd)->after($searchStart)->get(
|
||||||
[
|
[
|
||||||
'transaction_journals.id',
|
'transaction_journals.id',
|
||||||
'transaction_journals.date',
|
'transaction_journals.date',
|
||||||
@@ -224,58 +222,79 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
'transaction_journals.transaction_group_id',
|
'transaction_journals.transaction_group_id',
|
||||||
'transactions.transaction_currency_id',
|
'transactions.transaction_currency_id',
|
||||||
'currency.code AS transaction_currency_code',
|
'currency.code AS transaction_currency_code',
|
||||||
|
'currency.symbol AS transaction_currency_symbol',
|
||||||
'currency.decimal_places AS transaction_currency_decimal_places',
|
'currency.decimal_places AS transaction_currency_decimal_places',
|
||||||
'transactions.foreign_currency_id',
|
'transactions.foreign_currency_id',
|
||||||
'foreign_currency.code AS foreign_currency_code',
|
'foreign_currency.code AS foreign_currency_code',
|
||||||
|
'foreign_currency.symbol AS foreign_currency_symbol',
|
||||||
'foreign_currency.decimal_places AS foreign_currency_decimal_places',
|
'foreign_currency.decimal_places AS foreign_currency_decimal_places',
|
||||||
'transactions.amount',
|
'transactions.amount',
|
||||||
'transactions.foreign_amount',
|
'transactions.foreign_amount',
|
||||||
]
|
]
|
||||||
)
|
);
|
||||||
;
|
|
||||||
Log::debug(sprintf('Count %d entries in set', $set->count()));
|
Log::debug(sprintf('Count %d entries in set', $set->count()));
|
||||||
|
|
||||||
// for each bill, do a loop.
|
// for each bill, do a loop.
|
||||||
$converter = new ExchangeRateConverter();
|
$converter = new ExchangeRateConverter();
|
||||||
|
|
||||||
/** @var Bill $subscription */
|
/** @var Bill $subscription */
|
||||||
foreach ($this->collection as $subscription) {
|
foreach ($this->collection as $subscription) {
|
||||||
// Grab from array the most recent payment. If none exist, fall back to the start date and pretend *that* was the last paid date.
|
// Grab from array the most recent payment. If none exist, fall back to the start date and pretend *that* was the last paid date.
|
||||||
Log::debug(sprintf('Grab last paid date from function, return %s if it comes up with nothing.', $start->format('Y-m-d')));
|
Log::debug(sprintf('Grab last paid date from function, return %s if it comes up with nothing.', $start->format('Y-m-d')));
|
||||||
$lastPaidDate = $this->lastPaidDate($subscription, $set, $start);
|
$lastPaidDate = $this->lastPaidDate($subscription, $set, $start);
|
||||||
Log::debug(sprintf('Result of lastPaidDate is %s', $lastPaidDate->format('Y-m-d')));
|
Log::debug(sprintf('Result of lastPaidDate is %s', $lastPaidDate->format('Y-m-d')));
|
||||||
|
|
||||||
// At this point the "next match" is exactly after the last time the bill was paid.
|
// At this point the "next match" is exactly after the last time the bill was paid.
|
||||||
$result = [];
|
$result = [];
|
||||||
$filtered = $set->filter(function (TransactionJournal $journal) use ($subscription) {
|
$filtered = $set->filter(function (TransactionJournal $journal) use ($subscription) {
|
||||||
return (int) $journal->bill_id === (int) $subscription->id;
|
return (int) $journal->bill_id === (int) $subscription->id;
|
||||||
});
|
});
|
||||||
foreach ($filtered as $entry) {
|
foreach ($filtered as $entry) {
|
||||||
$array = [
|
$array = [
|
||||||
'transaction_group_id' => (string)$entry->transaction_group_id,
|
'transaction_group_id' => (string) $entry->transaction_group_id,
|
||||||
'transaction_journal_id' => (string)$entry->id,
|
'transaction_journal_id' => (string) $entry->id,
|
||||||
'date' => $entry->date->toAtomString(),
|
'date' => $entry->date->toAtomString(),
|
||||||
'date_object' => $entry->date,
|
'date_object' => $entry->date,
|
||||||
'bill_id' => $entry->bill_id,
|
'subscription_id' => (string) $entry->bill_id,
|
||||||
'currency_id' => $entry->transaction_currency_id,
|
'currency_id' => (string) $entry->transaction_currency_id,
|
||||||
'currency_code' => $entry->transaction_currency_code,
|
'currency_code' => $entry->transaction_currency_code,
|
||||||
'currency_decimal_places' => $entry->transaction_currency_decimal_places,
|
'currency_symbol' => $entry->transaction_currency_symbol,
|
||||||
'amount' => Steam::bcround($entry->amount, $entry->transaction_currency_decimal_places),
|
'currency_decimal_places' => $entry->transaction_currency_decimal_places,
|
||||||
|
'primary_currency_id' => (string) $this->primaryCurrency->id,
|
||||||
|
'primary_currency_code' => $this->primaryCurrency->code,
|
||||||
|
'primary_currency_symbol' => $this->primaryCurrency->symbol,
|
||||||
|
'primary_currency_decimal_places' => $this->primaryCurrency->decimal_places,
|
||||||
|
'amount' => Steam::bcround($entry->amount, $entry->transaction_currency_decimal_places),
|
||||||
|
'pc_amount' => null,
|
||||||
|
'foreign_amount' => null,
|
||||||
|
'pc_foreign_amount' => null,
|
||||||
|
|
||||||
];
|
];
|
||||||
if (null !== $entry->foreign_amount && null !== $entry->foreign_currency_code) {
|
if (null !== $entry->foreign_amount && null !== $entry->foreign_currency_code) {
|
||||||
$array['foreign_currency_id'] = $entry->foreign_currency_id;
|
$array['foreign_currency_id'] = (string) $entry->foreign_currency_id;
|
||||||
$array['foreign_currency_code'] = $entry->foreign_currency_code;
|
$array['foreign_currency_code'] = $entry->foreign_currency_code;
|
||||||
|
$array['foreign_currency_symbol'] = $entry->foreign_currency_symbol;
|
||||||
$array['foreign_currency_decimal_places'] = $entry->foreign_currency_decimal_places;
|
$array['foreign_currency_decimal_places'] = $entry->foreign_currency_decimal_places;
|
||||||
$array['foreign_amount'] = Steam::bcround($entry->foreign_amount, $entry->foreign_currency_decimal_places);
|
$array['foreign_amount'] = Steam::bcround($entry->foreign_amount, $entry->foreign_currency_decimal_places);
|
||||||
}
|
}
|
||||||
if ($this->convertToPrimary) {
|
// convert to primary, but is already primary.
|
||||||
$array['amount'] = $converter->convert($entry->transactionCurrency, $this->primaryCurrency, $entry->date, $entry->amount);
|
if ($this->convertToPrimary && (int) $entry->transaction_currency_id === $this->primaryCurrency->id) {
|
||||||
$array['currency_id'] = $this->primaryCurrency->id;
|
$array['pc_amount'] = $array['amount'];
|
||||||
$array['currency_code'] = $this->primaryCurrency->code;
|
}
|
||||||
$array['currency_decimal_places'] = $this->primaryCurrency->decimal_places;
|
// convert to primary, but is NOT already primary.
|
||||||
|
if ($this->convertToPrimary && (int) $entry->transaction_currency_id !== $this->primaryCurrency->id) {
|
||||||
|
$array['pc_amount'] = $converter->convert($entry->transactionCurrency, $this->primaryCurrency, $entry->date, $entry->amount);
|
||||||
|
}
|
||||||
|
// convert to primary, but foreign is already primary.
|
||||||
|
if ($this->convertToPrimary && (int) $entry->foreign_currency_id === $this->primaryCurrency->id) {
|
||||||
|
$array['pc_foreign_amount'] = $array['foreign_amount'];
|
||||||
|
}
|
||||||
|
// convert to primary, but foreign is NOT already primary.
|
||||||
|
if ($this->convertToPrimary && null !== $entry->foreign_currency_id && (int) $entry->foreign_currency_id !== $this->primaryCurrency->id) {
|
||||||
|
// TODO this is very database intensive.
|
||||||
|
$foreignCurrency = TransactionCurrency::find($entry->foreign_currency_id);
|
||||||
|
$array['pc_foreign_amount'] = $converter->convert($foreignCurrency, $this->primaryCurrency, $entry->date, $entry->amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
$result[] = $array;
|
$result[] = $array;
|
||||||
}
|
}
|
||||||
$this->paidDates[(int) $subscription->id] = $result;
|
$this->paidDates[(int) $subscription->id] = $result;
|
||||||
@@ -306,7 +325,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
$latest = $filtered->first()->date;
|
$latest = $filtered->first()->date;
|
||||||
|
|
||||||
/** @var TransactionJournal $journal */
|
/** @var TransactionJournal $journal */
|
||||||
foreach ($filtered as $journal) {
|
foreach ($filtered as $journal) {
|
||||||
@@ -352,12 +371,12 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
|
|
||||||
/** @var Bill $subscription */
|
/** @var Bill $subscription */
|
||||||
foreach ($this->collection as $subscription) {
|
foreach ($this->collection as $subscription) {
|
||||||
$id = (int)$subscription->id;
|
$id = (int) $subscription->id;
|
||||||
$lastPaidDate = $this->getLastPaidDate($paidDates[$id] ?? []);
|
$lastPaidDate = $this->getLastPaidDate($paidDates[$id] ?? []);
|
||||||
$payDates = $this->calculator->getPayDates($this->start, $this->end, $subscription->date, $subscription->repeat_freq, $subscription->skip, $lastPaidDate);
|
$payDates = $this->calculator->getPayDates($this->start, $this->end, $subscription->date, $subscription->repeat_freq, $subscription->skip, $lastPaidDate);
|
||||||
$payDatesFormatted = [];
|
$payDatesFormatted = [];
|
||||||
foreach ($payDates as $string) {
|
foreach ($payDates as $string) {
|
||||||
$date = Carbon::createFromFormat('!Y-m-d', $string, config('app.timezone'));
|
$date = Carbon::createFromFormat('!Y-m-d', $string, config('app.timezone'));
|
||||||
if (!$date instanceof Carbon) {
|
if (!$date instanceof Carbon) {
|
||||||
$date = today(config('app.timezone'));
|
$date = today(config('app.timezone'));
|
||||||
}
|
}
|
||||||
@@ -387,7 +406,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
if (!$nemDate instanceof Carbon) {
|
if (!$nemDate instanceof Carbon) {
|
||||||
$nemDate = today(config('app.timezone'));
|
$nemDate = today(config('app.timezone'));
|
||||||
}
|
}
|
||||||
$nem = $nemDate;
|
$nem = $nemDate;
|
||||||
|
|
||||||
// nullify again when it's outside the current view range.
|
// nullify again when it's outside the current view range.
|
||||||
if (
|
if (
|
||||||
@@ -416,7 +435,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
|
|
||||||
$current = $payDates[0] ?? null;
|
$current = $payDates[0] ?? null;
|
||||||
if (null !== $current && !$nem->isToday()) {
|
if (null !== $current && !$nem->isToday()) {
|
||||||
$temp2 = Carbon::parse($current, config('app.timezone'));
|
$temp2 = Carbon::parse($current, config('app.timezone'));
|
||||||
if (!$temp2 instanceof Carbon) {
|
if (!$temp2 instanceof Carbon) {
|
||||||
$temp2 = today(config('app.timezone'));
|
$temp2 = today(config('app.timezone'));
|
||||||
}
|
}
|
||||||
|
@@ -30,9 +30,6 @@ use FireflyIII\Models\Account;
|
|||||||
use FireflyIII\Models\TransactionCurrency;
|
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\Http\Api\ExchangeRateConverter;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,17 +60,19 @@ class AccountTransformer extends AbstractTransformer
|
|||||||
public function transform(Account $account): array
|
public function transform(Account $account): array
|
||||||
{
|
{
|
||||||
if (null === $account->meta) {
|
if (null === $account->meta) {
|
||||||
$account->meta = [];
|
$account->meta = [
|
||||||
|
'currency' => null,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// get account type:
|
// get account type:
|
||||||
$accountType = (string)config(sprintf('firefly.shortNamesByFullName.%s', $account->full_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 = (string) config(sprintf('firefly.shortLiabilityNameByFullName.%s', $account->full_account_type));
|
||||||
$liabilityType = '' === $liabilityType ? null : strtolower($liabilityType);
|
$liabilityType = '' === $liabilityType ? null : strtolower($liabilityType);
|
||||||
$liabilityDirection = $account->meta['liability_direction'] ?? null;
|
$liabilityDirection = $account->meta['liability_direction'] ?? null;
|
||||||
$accountRole = $this->getAccountRole($account, $accountType);
|
$accountRole = $this->getAccountRole($account, $accountType);
|
||||||
$hasCurrencySettings = array_key_exists('currency_id', $account->meta) && (int)$account->meta['currency_id'] > 0;
|
$hasCurrencySettings = null !== $account->meta['currency'];
|
||||||
$includeNetWorth = 1 === (int)($account->meta['include_net_worth'] ?? 0);
|
$includeNetWorth = 1 === (int) ($account->meta['include_net_worth'] ?? 0);
|
||||||
$longitude = $account->meta['location']['longitude'] ?? null;
|
$longitude = $account->meta['location']['longitude'] ?? null;
|
||||||
$latitude = $account->meta['location']['latitude'] ?? null;
|
$latitude = $account->meta['location']['latitude'] ?? null;
|
||||||
$zoomLevel = $account->meta['location']['zoom_level'] ?? null;
|
$zoomLevel = $account->meta['location']['zoom_level'] ?? null;
|
||||||
@@ -83,6 +82,12 @@ class AccountTransformer extends AbstractTransformer
|
|||||||
$date = $this->getDate();
|
$date = $this->getDate();
|
||||||
$date->endOfDay();
|
$date->endOfDay();
|
||||||
|
|
||||||
|
// get primary currency as fallback:
|
||||||
|
$currency = $this->primary; // assume primary currency
|
||||||
|
if ($hasCurrencySettings) {
|
||||||
|
$currency = $account->meta['currency'];
|
||||||
|
}
|
||||||
|
|
||||||
// no order for some accounts:
|
// no order for some accounts:
|
||||||
if (!in_array(strtolower($accountType), ['liability', 'liabilities', 'asset'], true)) {
|
if (!in_array(strtolower($accountType), ['liability', 'liabilities', 'asset'], true)) {
|
||||||
$order = null;
|
$order = null;
|
||||||
@@ -90,56 +95,11 @@ class AccountTransformer extends AbstractTransformer
|
|||||||
|
|
||||||
// get some listed information from the account meta-data:
|
// get some listed information from the account meta-data:
|
||||||
[$creditCardType, $monthlyPaymentDate] = $this->getCCInfo($account, $accountRole, $accountType);
|
[$creditCardType, $monthlyPaymentDate] = $this->getCCInfo($account, $accountRole, $accountType);
|
||||||
[$openingBalance, $openingBalanceDate] = $this->getOpeningBalance($account, $accountType);
|
$openingBalanceDate = $this->getOpeningBalance($account, $accountType);
|
||||||
[$interest, $interestPeriod] = $this->getInterest($account, $accountType);
|
[$interest, $interestPeriod] = $this->getInterest($account, $accountType);
|
||||||
|
|
||||||
// get currencies:
|
|
||||||
$currency = $this->primary; // assume primary currency
|
|
||||||
if ($hasCurrencySettings) {
|
|
||||||
$currency = $account->meta['currency'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the current balance:
|
|
||||||
$finalBalance = Steam::finalAccountBalance($account, $date, $this->primary, $this->convertToPrimary);
|
|
||||||
Log::debug(sprintf('Call finalAccountBalance(%s) with date/time "%s"', var_export($this->convertToPrimary, true), $date->toIso8601String()), $finalBalance);
|
|
||||||
|
|
||||||
// collect current balances:
|
|
||||||
$currentBalance = Steam::bcround($finalBalance[$currency->code] ?? '0', $currency->decimal_places);
|
|
||||||
$openingBalance = Steam::bcround($openingBalance ?? '0', $currency->decimal_places);
|
|
||||||
$virtualBalance = Steam::bcround($account->virtual_balance ?? '0', $currency->decimal_places);
|
|
||||||
$debtAmount = $account->meta['current_debt'] ?? null;
|
|
||||||
|
|
||||||
// TODO this currency conversion must not be happening here.
|
|
||||||
// set some pc_ default values to NULL:
|
|
||||||
$pcCurrentBalance = null;
|
|
||||||
$pcOpeningBalance = null;
|
|
||||||
$pcVirtualBalance = null;
|
|
||||||
$pcDebtAmount = null;
|
|
||||||
|
|
||||||
// convert to primary currency if needed:
|
|
||||||
if ($this->convertToPrimary && $currency->id !== $this->primary->id) {
|
|
||||||
Log::debug(sprintf('Convert to primary, from %s to %s', $currency->code, $this->primary->code));
|
|
||||||
$converter = new ExchangeRateConverter();
|
|
||||||
$pcCurrentBalance = $converter->convert($currency, $this->primary, $date, $currentBalance);
|
|
||||||
$pcOpeningBalance = $converter->convert($currency, $this->primary, $date, $openingBalance);
|
|
||||||
$pcVirtualBalance = $converter->convert($currency, $this->primary, $date, $virtualBalance);
|
|
||||||
$pcDebtAmount = null === $debtAmount ? null : $converter->convert($currency, $this->primary, $date, $debtAmount);
|
|
||||||
}
|
|
||||||
if ($this->convertToPrimary && $currency->id === $this->primary->id) {
|
|
||||||
$pcCurrentBalance = $currentBalance;
|
|
||||||
$pcOpeningBalance = $openingBalance;
|
|
||||||
$pcVirtualBalance = $virtualBalance;
|
|
||||||
$pcDebtAmount = $debtAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set opening balance(s) to NULL if the date is null
|
|
||||||
if (null === $openingBalanceDate) {
|
|
||||||
$openingBalance = null;
|
|
||||||
$pcOpeningBalance = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => (string)$account->id,
|
'id' => (string) $account->id,
|
||||||
'created_at' => $account->created_at->toAtomString(),
|
'created_at' => $account->created_at->toAtomString(),
|
||||||
'updated_at' => $account->updated_at->toAtomString(),
|
'updated_at' => $account->updated_at->toAtomString(),
|
||||||
'active' => $account->active,
|
'active' => $account->active,
|
||||||
@@ -152,27 +112,27 @@ class AccountTransformer extends AbstractTransformer
|
|||||||
'object_has_currency_setting' => $hasCurrencySettings,
|
'object_has_currency_setting' => $hasCurrencySettings,
|
||||||
|
|
||||||
// currency is object specific or primary, already determined above.
|
// currency is object specific or primary, already determined above.
|
||||||
'currency_id' => (string)$currency['id'],
|
'currency_id' => (string) $currency['id'],
|
||||||
'currency_code' => $currency['code'],
|
'currency_code' => $currency['code'],
|
||||||
'currency_symbol' => $currency['symbol'],
|
'currency_symbol' => $currency['symbol'],
|
||||||
'currency_decimal_places' => $currency['decimal_places'],
|
'currency_decimal_places' => $currency['decimal_places'],
|
||||||
'primary_currency_id' => (string)$this->primary->id,
|
'primary_currency_id' => (string) $this->primary->id,
|
||||||
'primary_currency_code' => $this->primary->code,
|
'primary_currency_code' => $this->primary->code,
|
||||||
'primary_currency_symbol' => $this->primary->symbol,
|
'primary_currency_symbol' => $this->primary->symbol,
|
||||||
'primary_currency_decimal_places' => $this->primary->decimal_places,
|
'primary_currency_decimal_places' => $this->primary->decimal_places,
|
||||||
|
|
||||||
// balances, structured for 6.3.0.
|
// balances, structured for 6.3.0.
|
||||||
'current_balance' => $currentBalance,
|
'current_balance' => $account->meta['balances']['current_balance'],
|
||||||
'pc_current_balance' => $pcCurrentBalance,
|
'pc_current_balance' => $account->meta['balances']['pc_current_balance'],
|
||||||
|
|
||||||
'opening_balance' => $openingBalance,
|
'opening_balance' => $account->meta['balances']['opening_balance'],
|
||||||
'pc_opening_balance' => $pcOpeningBalance,
|
'pc_opening_balance' => $account->meta['balances']['pc_opening_balance'],
|
||||||
|
|
||||||
'virtual_balance' => $virtualBalance,
|
'virtual_balance' => $account->meta['balances']['virtual_balance'],
|
||||||
'pc_virtual_balance' => $pcVirtualBalance,
|
'pc_virtual_balance' => $account->meta['balances']['pc_virtual_balance'],
|
||||||
|
|
||||||
'debt_amount' => $debtAmount,
|
'debt_amount' => $account->meta['balances']['debt_amount'],
|
||||||
'pc_debt_amount' => $pcDebtAmount,
|
'pc_debt_amount' => $account->meta['balances']['pc_debt_amount'],
|
||||||
|
|
||||||
'current_balance_date' => $date->toAtomString(),
|
'current_balance_date' => $date->toAtomString(),
|
||||||
'notes' => $account->meta['notes'] ?? null,
|
'notes' => $account->meta['notes'] ?? null,
|
||||||
@@ -203,7 +163,7 @@ class AccountTransformer extends AbstractTransformer
|
|||||||
private function getAccountRole(Account $account, string $accountType): ?string
|
private function getAccountRole(Account $account, string $accountType): ?string
|
||||||
{
|
{
|
||||||
$accountRole = $account->meta['account_role'] ?? null;
|
$accountRole = $account->meta['account_role'] ?? null;
|
||||||
if ('asset' !== $accountType || '' === (string)$accountRole) {
|
if ('asset' !== $accountType || '' === (string) $accountRole) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +199,7 @@ class AccountTransformer extends AbstractTransformer
|
|||||||
}
|
}
|
||||||
$monthlyPaymentDate = $object->toAtomString();
|
$monthlyPaymentDate = $object->toAtomString();
|
||||||
}
|
}
|
||||||
if (10 !== strlen((string)$monthlyPaymentDate)) {
|
if (10 !== strlen((string) $monthlyPaymentDate)) {
|
||||||
$monthlyPaymentDate = Carbon::parse($monthlyPaymentDate, config('app.timezone'))->toAtomString();
|
$monthlyPaymentDate = Carbon::parse($monthlyPaymentDate, config('app.timezone'))->toAtomString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,15 +207,10 @@ class AccountTransformer extends AbstractTransformer
|
|||||||
return [$creditCardType, $monthlyPaymentDate];
|
return [$creditCardType, $monthlyPaymentDate];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getOpeningBalance(Account $account, string $accountType): array
|
private function getOpeningBalance(Account $account, string $accountType): ?string
|
||||||
{
|
{
|
||||||
$openingBalance = null;
|
|
||||||
$openingBalanceDate = null;
|
$openingBalanceDate = null;
|
||||||
// $pcOpeningBalance = null;
|
|
||||||
if (in_array($accountType, ['asset', 'liabilities'], true)) {
|
if (in_array($accountType, ['asset', 'liabilities'], true)) {
|
||||||
// grab from meta.
|
|
||||||
$openingBalance = $account->meta['opening_balance_amount'] ?? null;
|
|
||||||
$pcOpeningBalance = null;
|
|
||||||
$openingBalanceDate = $account->meta['opening_balance_date'] ?? null;
|
$openingBalanceDate = $account->meta['opening_balance_date'] ?? null;
|
||||||
}
|
}
|
||||||
if (null !== $openingBalanceDate) {
|
if (null !== $openingBalanceDate) {
|
||||||
@@ -265,15 +220,9 @@ class AccountTransformer extends AbstractTransformer
|
|||||||
}
|
}
|
||||||
$openingBalanceDate = $object->toAtomString();
|
$openingBalanceDate = $object->toAtomString();
|
||||||
|
|
||||||
// NOW do conversion.
|
|
||||||
// if ($this->convertToPrimary && null !== $account->meta['currency']) {
|
|
||||||
// $converter = new ExchangeRateConverter();
|
|
||||||
// $pcOpeningBalance = $converter->convert($account->meta['currency'], $this->primary, $object, $openingBalance);
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [$openingBalance, $openingBalanceDate];
|
return $openingBalanceDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getInterest(Account $account, string $accountType): array
|
private function getInterest(Account $account, string $accountType): array
|
||||||
|
Reference in New Issue
Block a user