Clean up account transformer.

This commit is contained in:
James Cole
2025-08-02 07:16:30 +02:00
parent 04cbff4b9a
commit 3745d79f1f
6 changed files with 104 additions and 118 deletions

View File

@@ -142,7 +142,7 @@ class Amount
$cache->addProperty('getPrimaryCurrencyByGroup'); $cache->addProperty('getPrimaryCurrencyByGroup');
$cache->addProperty($userGroup->id); $cache->addProperty($userGroup->id);
if ($cache->has()) { if ($cache->has()) {
return $cache->get(); return $cache->get();
} }
/** @var null|TransactionCurrency $primary */ /** @var null|TransactionCurrency $primary */

View File

@@ -381,7 +381,7 @@ class Steam
} }
// if there is a request to convert, convert to "pc_balance" and use "balance" for whichever amount is in the primary currency. // if there is a request to convert, convert to "pc_balance" and use "balance" for whichever amount is in the primary currency.
if ($convertToPrimary) { if ($convertToPrimary) {
$return['primary_balance'] = $this->convertAllBalances($others, $primary, $date); // todo sum all and convert. $return['pc_balance'] = $this->convertAllBalances($others, $primary, $date); // todo sum all and convert.
// Log::debug(sprintf('Set pc_balance to %s', $return['pc_balance'])); // Log::debug(sprintf('Set pc_balance to %s', $return['pc_balance']));
} }

View File

@@ -67,95 +67,68 @@ class AccountTransformer extends AbstractTransformer
} }
// 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);
// get account role (will only work if the type is asset). $hasCurrencySettings = array_key_exists('currency_id', $account->meta) && (int)$account->meta['currency_id'] > 0;
$accountRole = $this->getAccountRole($account, $accountType); $includeNetWorth = 1 === (int)($account->meta['include_net_worth'] ?? 0);
$longitude = $account->meta['location']['longitude'] ?? null;
$latitude = $account->meta['location']['latitude'] ?? null;
$zoomLevel = $account->meta['location']['zoom_level'] ?? null;
$order = $account->order;
// date (for balance etc.) // date (for balance etc.)
$date = $this->getDate(); $date = $this->getDate();
$date->endOfDay(); $date->endOfDay();
[$creditCardType, $monthlyPaymentDate] = $this->getCCInfo($account, $accountRole, $accountType);
[$openingBalance, $pcOpeningBalance, $openingBalanceDate] = $this->getOpeningBalance($account, $accountType);
[$interest, $interestPeriod] = $this->getInterest($account, $accountType);
$primary = $this->primary;
if (!$this->convertToPrimary) {
// reset primary currency to NULL, not interesting.
$primary = null;
}
$decimalPlaces = (int)$account->meta['currency']?->decimal_places;
$decimalPlaces = 0 === $decimalPlaces ? 2 : $decimalPlaces;
$openingBalanceRounded = Steam::bcround($openingBalance, $decimalPlaces);
$includeNetWorth = 1 === (int)($account->meta['include_net_worth'] ?? 0);
$longitude = $account->meta['location']['longitude'] ?? null;
$latitude = $account->meta['location']['latitude'] ?? null;
$zoomLevel = $account->meta['location']['zoom_level'] ?? null;
// no order for some accounts: // no order for some accounts:
$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;
} }
Log::debug(sprintf('transform: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
$finalBalance = Steam::finalAccountBalance($account, $date, $this->primary, $this->convertToPrimary); // get some listed information from the account meta-data:
if ($this->convertToPrimary) { [$creditCardType, $monthlyPaymentDate] = $this->getCCInfo($account, $accountRole, $accountType);
$finalBalance['balance'] = $finalBalance[$account->meta['currency']?->code] ?? '0'; [$openingBalance, $openingBalanceDate] = $this->getOpeningBalance($account, $accountType);
[$interest, $interestPeriod] = $this->getInterest($account, $accountType);
// get currencies:
$currency = $this->primary; // assume primary currency
if ($hasCurrencySettings) {
$currency = $account->meta['currency'];
} }
$currentBalance = Steam::bcround($finalBalance['balance'] ?? '0', $decimalPlaces); // get the current balance:
$pcCurrentBalance = $this->convertToPrimary ? Steam::bcround($finalBalance['pc_balance'] ?? '0', $primary->decimal_places) : null; $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);
// set up balances array: // set some pc_ default values to NULL:
$balances = []; $pcCurrentBalance = null;
$balances[] $pcOpeningBalance = null;
= [ $pcVirtualBalance = null;
'type' => 'current', $pcDebtAmount = null;
'amount' => $currentBalance,
'currency_id' => $account->meta['currency_id'] ?? null,
'currency_code' => $account->meta['currency']?->code,
'currency_symbol' => $account->meta['currency']?->symbol,
'currency_decimal_places' => $account->meta['currency']?->decimal_places,
'date' => $date->toAtomString(),
];
if (null !== $pcCurrentBalance) {
$balances[] = [
'type' => 'pc_current',
'amount' => $pcCurrentBalance,
'currency_id' => $primary instanceof TransactionCurrency ? (string)$primary->id : null,
'currency_code' => $primary?->code,
'currency_symbol' => $primary?->symbol,
'ccurrency_decimal_places' => $primary?->decimal_places,
'date' => $date->toAtomString(),
]; // 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;
// 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 (null !== $openingBalance) {
$balances[] = [ // set opening balance(s) to NULL if the date is null
'type' => 'opening', if (null === $openingBalanceDate) {
'amount' => $openingBalanceRounded, $openingBalance = null;
'currency_id' => $account->meta['currency_id'] ?? null, $pcOpeningBalance = null;
'currency_code' => $account->meta['currency']?->code,
'currency_symbol' => $account->meta['currency']?->symbol,
'currency_decimal_places' => $account->meta['currency']?->decimal_places,
'date' => $openingBalanceDate,
];
}
if (null !== $account->virtual_balance) {
$balances[] = [
'type' => 'virtual',
'amount' => Steam::bcround($account->virtual_balance, $decimalPlaces),
'currency_id' => $account->meta['currency_id'] ?? null,
'currency_code' => $account->meta['currency']?->code,
'currency_symbol' => $account->meta['currency']?->symbol,
'currency_decimal_places' => $account->meta['currency']?->decimal_places,
'date' => $date->toAtomString(),
];
} }
return [ return [
@@ -167,40 +140,51 @@ class AccountTransformer extends AbstractTransformer
'name' => $account->name, 'name' => $account->name,
'type' => strtolower($accountType), 'type' => strtolower($accountType),
'account_role' => $accountRole, 'account_role' => $accountRole,
'currency_id' => $account->meta['currency_id'] ?? null,
'currency_code' => $account->meta['currency']?->code, // currency information, structured for 6.3.0.
'currency_symbol' => $account->meta['currency']?->symbol, 'object_has_currency_setting' => $hasCurrencySettings,
'currency_decimal_places' => $account->meta['currency']?->decimal_places,
'primary_currency_id' => $primary instanceof TransactionCurrency ? (string)$primary->id : null, // currency is object specific or primary, already determined above.
'primary_currency_code' => $primary?->code, 'currency_id' => (string)$currency['id'],
'primary_currency_symbol' => $primary?->symbol, 'currency_code' => $currency['code'],
'primary_currency_decimal_places' => $primary?->decimal_places, 'currency_symbol' => $currency['symbol'],
'currency_decimal_places' => $currency['decimal_places'],
'primary_currency_id' => (string)$this->primary->id,
'primary_currency_code' => $this->primary->code,
'primary_currency_symbol' => $this->primary->symbol,
'primary_currency_decimal_places' => $this->primary->decimal_places,
// balances, structured for 6.3.0.
'current_balance' => $currentBalance, 'current_balance' => $currentBalance,
'pc_current_balance' => $pcCurrentBalance, 'pc_current_balance' => $pcCurrentBalance,
'current_balance_date' => $date->toAtomString(),
'notes' => $account->meta['notes'] ?? null, 'opening_balance' => $openingBalance,
'monthly_payment_date' => $monthlyPaymentDate, 'pc_opening_balance' => $pcOpeningBalance,
'credit_card_type' => $creditCardType,
'account_number' => $account->meta['account_number'] ?? null, 'virtual_balance' => $virtualBalance,
'iban' => '' === $account->iban ? null : $account->iban, 'pc_virtual_balance' => $pcVirtualBalance,
'bic' => $account->meta['BIC'] ?? null,
'virtual_balance' => Steam::bcround($account->virtual_balance, $decimalPlaces), 'debt_amount' => $debtAmount,
'pc_virtual_balance' => $this->convertToPrimary ? Steam::bcround($account->native_virtual_balance, $primary->decimal_places) : null, 'pc_debt_amount' => $pcDebtAmount,
'opening_balance' => $openingBalanceRounded,
'pc_opening_balance' => $pcOpeningBalance, 'current_balance_date' => $date->toAtomString(),
'opening_balance_date' => $openingBalanceDate, 'notes' => $account->meta['notes'] ?? null,
'liability_type' => $liabilityType, 'monthly_payment_date' => $monthlyPaymentDate,
'liability_direction' => $liabilityDirection, 'credit_card_type' => $creditCardType,
'interest' => $interest, 'account_number' => $account->meta['account_number'] ?? null,
'interest_period' => $interestPeriod, 'iban' => '' === $account->iban ? null : $account->iban,
'current_debt' => $account->meta['current_debt'] ?? null, 'bic' => $account->meta['BIC'] ?? null,
'include_net_worth' => $includeNetWorth, 'opening_balance_date' => $openingBalanceDate,
'longitude' => $longitude, 'liability_type' => $liabilityType,
'latitude' => $latitude, 'liability_direction' => $liabilityDirection,
'zoom_level' => $zoomLevel, 'interest' => $interest,
'last_activity' => array_key_exists('last_activity', $account->meta) ? $account->meta['last_activity']->toAtomString() : null, 'interest_period' => $interestPeriod,
'balances' => $balances, 'include_net_worth' => $includeNetWorth,
'links' => [ 'longitude' => $longitude,
'latitude' => $latitude,
'zoom_level' => $zoomLevel,
'last_activity' => array_key_exists('last_activity', $account->meta) ? $account->meta['last_activity']->toAtomString() : null,
'links' => [
[ [
'rel' => 'self', 'rel' => 'self',
'uri' => sprintf('/accounts/%d', $account->id), 'uri' => sprintf('/accounts/%d', $account->id),
@@ -242,7 +226,7 @@ class AccountTransformer extends AbstractTransformer
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 (!$object instanceof Carbon) { if (!$object instanceof Carbon) {
$object = today(config('app.timezone')); $object = today(config('app.timezone'));
} }
@@ -260,7 +244,7 @@ class AccountTransformer extends AbstractTransformer
{ {
$openingBalance = null; $openingBalance = null;
$openingBalanceDate = null; $openingBalanceDate = null;
$pcOpeningBalance = null; // $pcOpeningBalance = null;
if (in_array($accountType, ['asset', 'liabilities'], true)) { if (in_array($accountType, ['asset', 'liabilities'], true)) {
// grab from meta. // grab from meta.
$openingBalance = $account->meta['opening_balance_amount'] ?? null; $openingBalance = $account->meta['opening_balance_amount'] ?? null;
@@ -268,21 +252,21 @@ class AccountTransformer extends AbstractTransformer
$openingBalanceDate = $account->meta['opening_balance_date'] ?? 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 (!$object instanceof Carbon) { if (!$object instanceof Carbon) {
$object = today(config('app.timezone')); $object = today(config('app.timezone'));
} }
$openingBalanceDate = $object->toAtomString(); $openingBalanceDate = $object->toAtomString();
// NOW do conversion. // NOW do conversion.
if ($this->convertToPrimary && null !== $account->meta['currency']) { // if ($this->convertToPrimary && null !== $account->meta['currency']) {
$converter = new ExchangeRateConverter(); // $converter = new ExchangeRateConverter();
$pcOpeningBalance = $converter->convert($account->meta['currency'], $this->primary, $object, $openingBalance); // $pcOpeningBalance = $converter->convert($account->meta['currency'], $this->primary, $object, $openingBalance);
} // }
} }
return [$openingBalance, $pcOpeningBalance, $openingBalanceDate]; return [$openingBalance, $openingBalanceDate];
} }
private function getInterest(Account $account, string $accountType): array private function getInterest(Account $account, string $accountType): array

View File

@@ -42,6 +42,7 @@ class CurrencyTransformer extends AbstractTransformer
'updated_at' => $currency->updated_at->toAtomString(), 'updated_at' => $currency->updated_at->toAtomString(),
'native' => $currency->userGroupNative, 'native' => $currency->userGroupNative,
'default' => $currency->userGroupNative, 'default' => $currency->userGroupNative,
'primary' => $currency->userGroupNative,
'enabled' => $currency->userGroupEnabled, 'enabled' => $currency->userGroupEnabled,
'name' => $currency->name, 'name' => $currency->name,
'code' => $currency->code, 'code' => $currency->code,

0
public/v1/js/.gitkeep Normal file → Executable file
View File

View File

@@ -110,6 +110,7 @@
"/public/v1/js/lib/jquery.autocomplete.min.js": "/public/v1/js/lib/jquery.autocomplete.min.js", "/public/v1/js/lib/jquery.autocomplete.min.js": "/public/v1/js/lib/jquery.autocomplete.min.js",
"/public/v1/js/lib/jquery.color-2.1.2.min.js": "/public/v1/js/lib/jquery.color-2.1.2.min.js", "/public/v1/js/lib/jquery.color-2.1.2.min.js": "/public/v1/js/lib/jquery.color-2.1.2.min.js",
"/public/v1/js/lib/modernizr-custom.js": "/public/v1/js/lib/modernizr-custom.js", "/public/v1/js/lib/modernizr-custom.js": "/public/v1/js/lib/modernizr-custom.js",
"/public/v1/js/lib/moment/af_ZA.js": "/public/v1/js/lib/moment/af_ZA.js",
"/public/v1/js/lib/moment/bg_BG.js": "/public/v1/js/lib/moment/bg_BG.js", "/public/v1/js/lib/moment/bg_BG.js": "/public/v1/js/lib/moment/bg_BG.js",
"/public/v1/js/lib/moment/ca_ES.js": "/public/v1/js/lib/moment/ca_ES.js", "/public/v1/js/lib/moment/ca_ES.js": "/public/v1/js/lib/moment/ca_ES.js",
"/public/v1/js/lib/moment/cs_CZ.js": "/public/v1/js/lib/moment/cs_CZ.js", "/public/v1/js/lib/moment/cs_CZ.js": "/public/v1/js/lib/moment/cs_CZ.js",