Expand balances.

This commit is contained in:
James Cole
2025-07-23 07:01:10 +02:00
parent 1add505644
commit 64a643ceec
5 changed files with 99 additions and 46 deletions

View File

@@ -67,53 +67,100 @@ 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;
// get account role (will only work if the type is asset). // get account role (will only work if the type is asset).
$accountRole = $this->getAccountRole($account, $accountType); $accountRole = $this->getAccountRole($account, $accountType);
// 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); [$creditCardType, $monthlyPaymentDate] = $this->getCCInfo($account, $accountRole, $accountType);
[$openingBalance, $nativeOpeningBalance, $openingBalanceDate] = $this->getOpeningBalance($account, $accountType); [$openingBalance, $nativeOpeningBalance, $openingBalanceDate] = $this->getOpeningBalance($account, $accountType);
[$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;
} }
$decimalPlaces = (int) $account->meta['currency']?->decimal_places; $decimalPlaces = (int)$account->meta['currency']?->decimal_places;
$decimalPlaces = 0 === $decimalPlaces ? 2 : $decimalPlaces; $decimalPlaces = 0 === $decimalPlaces ? 2 : $decimalPlaces;
$openingBalance = Steam::bcround($openingBalance, $decimalPlaces); $openingBalanceRounded = Steam::bcround($openingBalance, $decimalPlaces);
$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;
// 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, $this->native, $this->convertToNative); $finalBalance = Steam::finalAccountBalance($account, $date, $this->native, $this->convertToNative);
if ($this->convertToNative) { if ($this->convertToNative) {
$finalBalance['balance'] = $finalBalance[$account->meta['currency']?->code] ?? '0'; $finalBalance['balance'] = $finalBalance[$account->meta['currency']?->code] ?? '0';
} }
$currentBalance = Steam::bcround($finalBalance['balance'] ?? '0', $decimalPlaces); $currentBalance = Steam::bcround($finalBalance['balance'] ?? '0', $decimalPlaces);
$nativeCurrentBalance = $this->convertToNative ? Steam::bcround($finalBalance['native_balance'] ?? '0', $native->decimal_places) : null; $nativeCurrentBalance = $this->convertToNative ? Steam::bcround($finalBalance['native_balance'] ?? '0', $native->decimal_places) : null;
// set up balances array:
$balances = [];
$balances[] =
[
'type' => 'current',
'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 !== $nativeCurrentBalance) {
$balances[] = [
'type' => 'native_current',
'amount' => $nativeCurrentBalance,
'currency_id' => $native instanceof TransactionCurrency ? (string)$native->id : null,
'currency_code' => $native?->code,
'currency_symbol' => $native?->symbol,
'ccurrency_decimal_places' => $native?->decimal_places,
'date' => $date->toAtomString()
];
}
if (null !== $openingBalance) {
$balances[] = [
'type' => 'opening',
'amount' => $openingBalanceRounded,
'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' => $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 [
'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,
@@ -125,7 +172,7 @@ class AccountTransformer extends AbstractTransformer
'currency_code' => $account->meta['currency']?->code, 'currency_code' => $account->meta['currency']?->code,
'currency_symbol' => $account->meta['currency']?->symbol, 'currency_symbol' => $account->meta['currency']?->symbol,
'currency_decimal_places' => $account->meta['currency']?->decimal_places, 'currency_decimal_places' => $account->meta['currency']?->decimal_places,
'native_currency_id' => $native instanceof TransactionCurrency ? (string) $native->id : null, 'native_currency_id' => $native instanceof TransactionCurrency ? (string)$native->id : null,
'native_currency_code' => $native?->code, 'native_currency_code' => $native?->code,
'native_currency_symbol' => $native?->symbol, 'native_currency_symbol' => $native?->symbol,
'native_currency_decimal_places' => $native?->decimal_places, 'native_currency_decimal_places' => $native?->decimal_places,
@@ -140,7 +187,7 @@ class AccountTransformer extends AbstractTransformer
'bic' => $account->meta['BIC'] ?? null, 'bic' => $account->meta['BIC'] ?? null,
'virtual_balance' => Steam::bcround($account->virtual_balance, $decimalPlaces), 'virtual_balance' => Steam::bcround($account->virtual_balance, $decimalPlaces),
'native_virtual_balance' => $this->convertToNative ? 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' => $openingBalanceRounded,
'native_opening_balance' => $nativeOpeningBalance, 'native_opening_balance' => $nativeOpeningBalance,
'opening_balance_date' => $openingBalanceDate, 'opening_balance_date' => $openingBalanceDate,
'liability_type' => $liabilityType, 'liability_type' => $liabilityType,
@@ -153,6 +200,7 @@ class AccountTransformer extends AbstractTransformer
'latitude' => $latitude, 'latitude' => $latitude,
'zoom_level' => $zoomLevel, 'zoom_level' => $zoomLevel,
'last_activity' => array_key_exists('last_activity', $account->meta) ? $account->meta['last_activity']->toAtomString() : null, 'last_activity' => array_key_exists('last_activity', $account->meta) ? $account->meta['last_activity']->toAtomString() : null,
'balances' => $balances,
'links' => [ 'links' => [
[ [
'rel' => 'self', 'rel' => 'self',
@@ -165,7 +213,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;
} }
@@ -195,13 +243,13 @@ 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'));
} }
$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();
} }
} }
@@ -221,7 +269,7 @@ 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'));
} }

View File

@@ -352,12 +352,15 @@ let index = function () {
// filter instructions // filter instructions
let filters = {}; let filters = {};
let type = this.filters.type;
let active = this.filters.active;
for (let k in this.filters) { for (let k in this.filters) {
if (this.filters.hasOwnProperty(k) && null !== this.filters[k]) { if (this.filters.hasOwnProperty(k) && null !== this.filters[k]) {
filters[k] = this.filters[k]; filters[k] = this.filters[k];
//filters.push({column: k, filter: this.filters[k]}); //filters.push({column: k, filter: this.filters[k]});
} }
} }
delete filters.type;
// get start and end from the store: // get start and end from the store:
const start = new Date(window.store.get('start')); const start = new Date(window.store.get('start'));
@@ -367,24 +370,23 @@ let index = function () {
let params = { let params = {
sort: sorting, sort: sorting,
filter: filters, filter: filters,
active: active,
currentMoment: today, currentMoment: today,
// type: type, type: type,
page: {number: this.page}, page: this.page,
startPeriod: start, startPeriod: start,
endPeriod: end endPeriod: end
}; };
if (!this.tableColumns.balance_difference.enabled) { if (!this.tableColumns.balance_difference.enabled) {
delete params.startPeriod; delete params.startPeriod;
delete params.enPeriod; delete params.endPeriod;
} }
this.accounts = []; this.accounts = [];
let groupedAccounts = {}; let groupedAccounts = {};
// one page only.o // one page only.o
(new Get()).index(params).then(response => { (new Get()).index(params).then(response => {
console.log(response);
this.totalPages = response.meta.pagination.total_pages; this.totalPages = response.meta.pagination.total_pages;
console.log('a');
for (let i = 0; i < response.data.length; i++) { for (let i = 0; i < response.data.length; i++) {
if (response.data.hasOwnProperty(i)) { if (response.data.hasOwnProperty(i)) {
let current = response.data[i]; let current = response.data[i];
@@ -399,18 +401,14 @@ let index = function () {
account_number: null === current.attributes.account_number ? '' : current.attributes.account_number, account_number: null === current.attributes.account_number ? '' : current.attributes.account_number,
current_balance: current.attributes.current_balance, current_balance: current.attributes.current_balance,
currency_code: current.attributes.currency_code, currency_code: current.attributes.currency_code,
//native_current_balance: current.attributes.native_current_balance,
//native_currency_code: current.attributes.native_currency_code,
last_activity: null === current.attributes.last_activity ? '' : format(new Date(current.attributes.last_activity), i18next.t('config.month_and_day_fns')), last_activity: null === current.attributes.last_activity ? '' : format(new Date(current.attributes.last_activity), i18next.t('config.month_and_day_fns')),
//balance_difference: current.attributes.balance_difference,
//native_balance_difference: current.attributes.native_balance_difference,
liability_type: current.attributes.liability_type, liability_type: current.attributes.liability_type,
liability_direction: current.attributes.liability_direction, liability_direction: current.attributes.liability_direction,
interest: current.attributes.interest, interest: current.attributes.interest,
interest_period: current.attributes.interest_period, interest_period: current.attributes.interest_period,
//current_debt: current.attributes.current_debt,
balance: current.attributes.balance, balance: current.attributes.balance,
native_balance: current.attributes.native_balance, native_balance: current.attributes.native_balance,
balances: current.attributes.balances,
}; };
// get group info: // get group info:
let groupId = current.attributes.object_group_id; let groupId = current.attributes.object_group_id;

View File

@@ -196,6 +196,14 @@ export default () => ({
(new Get).show(accountId, new Date(window.store.get('end'))).then((response) => { (new Get).show(accountId, new Date(window.store.get('end'))).then((response) => {
let parent = response.data.data; let parent = response.data.data;
// apply function to each element of parent:
parent.attributes.balances = parent.attributes.balances.map((balance) => {
balance.amount_formatted = formatMoney(balance.amount, balance.currency_code);
return balance;
});
console.log(parent);
// get groups for account: // get groups for account:
const params = { const params = {
page: 1, page: 1,
@@ -243,8 +251,7 @@ export default () => ({
name: parent.attributes.name, name: parent.attributes.name,
order: parent.attributes.order, order: parent.attributes.order,
id: parent.id, id: parent.id,
balance: parent.attributes.balance, balances: parent.attributes.balances,
//native_balance: parent.attributes.native_balance,
groups: groups, groups: groups,
}); });
// console.log(parent.attributes); // console.log(parent.attributes);

View File

@@ -76,7 +76,7 @@ function parsePaidTransactions(paid_dates, bill) {
for (let i in paid_dates) { for (let i in paid_dates) {
if (paid_dates.hasOwnProperty(i)) { if (paid_dates.hasOwnProperty(i)) {
const currentPayment = paid_dates[i]; const currentPayment = paid_dates[i];
console.log(currentPayment); // console.log(currentPayment);
// math: -100+(paid/expected)*100 // math: -100+(paid/expected)*100
let percentage = Math.round(-100 + ((parseFloat(currentPayment.amount) ) / parseFloat(bill.amount)) * 100); let percentage = Math.round(-100 + ((parseFloat(currentPayment.amount) ) / parseFloat(bill.amount)) * 100);
let currentTransaction = { let currentTransaction = {

View File

@@ -13,13 +13,13 @@
x-text="account.name"></a> x-text="account.name"></a>
<span class="small"> <span class="small">
<template x-for="balance in account.balance"> <template x-for="balance in account.balances">
<span>x</span> <template x-if="balance.type === 'current'">
<span class="text-muted">(<span x-text="balance.amount_formatted"></span>)
</span>
</template>
</template> </template>
<template x-for="balance in account.native_balance"> </span>
<span>Y</span>
</template>
</span>
</h3> </h3>
</div> </div>
<div class="card-body p-0"> <div class="card-body p-0">