Fix columns, improve views.

This commit is contained in:
James Cole
2025-09-01 20:39:40 +02:00
parent ad77d55c16
commit 26a8bd921d
6 changed files with 235 additions and 146 deletions

View File

@@ -94,6 +94,8 @@ class ShowController extends Controller
$admin = auth()->user();
$enrichment = new AccountEnrichment();
$enrichment->setDate($this->parameters->get('date'));
$enrichment->setStart($this->parameters->get('start'));
$enrichment->setEnd($this->parameters->get('end'));
$enrichment->setUser($admin);
$accounts = $enrichment->enrich($accounts);
@@ -117,7 +119,7 @@ class ShowController extends Controller
*
* Show single instance.
*/
public function show(Account $account): JsonResponse
public function show(ShowRequest $request, Account $account): JsonResponse
{
// get list of accounts. Count it and split it.
$this->repository->resetAccountOrder();
@@ -129,6 +131,8 @@ class ShowController extends Controller
$admin = auth()->user();
$enrichment = new AccountEnrichment();
$enrichment->setDate($this->parameters->get('date'));
$enrichment->setStart($this->parameters->get('start'));
$enrichment->setEnd($this->parameters->get('end'));
$enrichment->setUser($admin);
$account = $enrichment->enrichSingle($account);

View File

@@ -63,12 +63,11 @@ class ShowRequest extends FormRequest
public function rules(): array
{
$keys = implode(',', array_keys($this->types));
return [
'date' => 'date',
'start' => 'date|present_with:end|before_or_equal:end|before:2038-01-17|after:1970-01-02',
'end' => 'date|present_with:start|after_or_equal:start|before:2038-01-17|after:1970-01-02',
'sort' => 'in:active,iban,name,order,-active,-iban,-name,-order', // TODO improve me.
'sort' => 'nullable|in:active,iban,name,order,-active,-iban,-name,-order', // TODO improve me.
'type' => sprintf('in:%s', $keys),
'limit' => 'numeric|min:1|max:131337',
'page' => 'numeric|min:1|max:131337',
@@ -83,6 +82,8 @@ class ShowRequest extends FormRequest
return;
}
$data = $validator->getData();
if (array_key_exists('date', $data) && array_key_exists('start', $data) && array_key_exists('end', $data)) {
// assume valid dates, before we got here.
$start = Carbon::parse($data['start'], config('app.timezone'))->startOfDay();

View File

@@ -67,8 +67,12 @@ class AccountEnrichment implements EnrichmentInterface
private UserGroup $userGroup;
private array $lastActivities = [];
private ?Carbon $date = null;
private ?Carbon $start = null;
private ?Carbon $end = null;
private bool $convertToPrimary;
private array $balances = [];
private array $startBalances = [];
private array $endBalances = [];
private array $objectGroups = [];
private array $mappedObjects = [];
@@ -140,8 +144,7 @@ class AccountEnrichment implements EnrichmentInterface
{
$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->ids)
->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 */
foreach ($set as $entry) {
@@ -169,8 +172,7 @@ class AccountEnrichment implements EnrichmentInterface
$notes = Note::query()->whereIn('noteable_id', $this->ids)
->whereNotNull('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) {
$this->notes[(int)$note['noteable_id']] = (string)$note['text'];
}
@@ -180,8 +182,7 @@ class AccountEnrichment implements EnrichmentInterface
private function collectLocations(): void
{
$locations = Location::query()->whereIn('locatable_id', $this->ids)
->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) {
$this->locations[(int)$location['locatable_id']]
= [
@@ -203,8 +204,7 @@ class AccountEnrichment implements EnrichmentInterface
->setUserGroup($this->userGroup)
->setAccounts($this->collection)
->withAccountInformation()
->setTypes([TransactionTypeEnum::OPENING_BALANCE->value])
;
->setTypes([TransactionTypeEnum::OPENING_BALANCE->value]);
$journals = $collector->getExtractedJournals();
foreach ($journals as $journal) {
$this->openingBalances[(int)$journal['source_account_id']]
@@ -292,6 +292,7 @@ class AccountEnrichment implements EnrichmentInterface
$date = $this->getDate();
// $finalBalance = Steam::finalAccountBalance($item, $date, $this->primaryCurrency, $this->convertToPrimary);
$finalBalance = $this->balances[$id];
$balanceDifference = $this->getBalanceDifference($id, $currency);
Log::debug(sprintf('Call finalAccountBalance(%s) with date/time "%s"', var_export($this->convertToPrimary, true), $date->toIso8601String()), $finalBalance);
// collect current balances:
@@ -305,6 +306,7 @@ class AccountEnrichment implements EnrichmentInterface
$pcOpeningBalance = null;
$pcVirtualBalance = null;
$pcDebtAmount = null;
$pcBalanceDifference = null;
// convert to primary currency if needed:
if ($this->convertToPrimary && $currency->id !== $this->primaryCurrency->id) {
@@ -313,12 +315,14 @@ class AccountEnrichment implements EnrichmentInterface
$pcCurrentBalance = $converter->convert($currency, $this->primaryCurrency, $date, $currentBalance);
$pcOpeningBalance = $converter->convert($currency, $this->primaryCurrency, $date, $openingBalance);
$pcVirtualBalance = $converter->convert($currency, $this->primaryCurrency, $date, $virtualBalance);
$pcBalanceDifference = null === $balanceDifference ? null : $converter->convert($currency, $this->primaryCurrency, $date, $balanceDifference);
$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;
$pcBalanceDifference = $balanceDifference;
$pcDebtAmount = $debtAmount;
}
@@ -337,6 +341,8 @@ class AccountEnrichment implements EnrichmentInterface
'pc_virtual_balance' => $pcVirtualBalance,
'debt_amount' => $debtAmount,
'pc_debt_amount' => $pcDebtAmount,
'balance_difference' => $balanceDifference,
'pc_balance_difference' => $pcBalanceDifference,
];
// end add balances
$item->meta = $meta;
@@ -353,6 +359,10 @@ class AccountEnrichment implements EnrichmentInterface
private function collectBalances(): void
{
$this->balances = Steam::accountsBalancesOptimized($this->collection, $this->getDate(), $this->primaryCurrency, $this->convertToPrimary);
if (null !== $this->start && null !== $this->end) {
$this->startBalances = Steam::accountsBalancesOptimized($this->collection, $this->start, $this->primaryCurrency, $this->convertToPrimary);
$this->endBalances = Steam::accountsBalancesOptimized($this->collection, $this->end, $this->primaryCurrency, $this->convertToPrimary);
}
}
private function collectObjectGroups(): void
@@ -360,8 +370,7 @@ class AccountEnrichment implements EnrichmentInterface
$set = DB::table('object_groupables')
->whereIn('object_groupable_id', $this->ids)
->where('object_groupable_type', Account::class)
->get(['object_groupable_id', 'object_group_id'])
;
->get(['object_groupable_id', 'object_group_id']);
$ids = array_unique($set->pluck('object_group_id')->toArray());
@@ -394,4 +403,32 @@ class AccountEnrichment implements EnrichmentInterface
return $this->date;
}
public function setStart(?Carbon $start): void
{
$this->start = $start;
}
public function setEnd(?Carbon $end): void
{
$this->end = $end;
}
private function getBalanceDifference(int $id, TransactionCurrency $currency): ?string
{
if (null === $this->start || null === $this->end) {
return null;
}
$startBalance = $this->startBalances[$id] ?? [];
$endBalance = $this->endBalances[$id] ?? [];
if (count($startBalance) === 0 || count($endBalance) === 0) {
return null;
}
$start = $startBalance[$currency->code] ?? '0';
$end = $endBalance[$currency->code] ?? '0';
return bcsub($end, $start);
}
}

View File

@@ -137,6 +137,9 @@ class AccountTransformer extends AbstractTransformer
'debt_amount' => $account->meta['balances']['debt_amount'],
'pc_debt_amount' => $account->meta['balances']['pc_debt_amount'],
'balance_difference' => $account->meta['balances']['balance_difference'],
'pc_balance_difference' => $account->meta['balances']['pc_balance_difference'],
'current_balance_date' => $account->meta['current_balance_date']->toAtomString(),
'notes' => $account->meta['notes'] ?? null,
'monthly_payment_date' => $monthlyPaymentDate,

View File

@@ -378,8 +378,8 @@ let index = function () {
date: format(today,'yyyy-MM-dd'),
type: type,
page: this.page,
// startPeriod: start,
// endPeriod: end
start: start,
end: end
};
if (!this.tableColumns.balance_difference.enabled) {
@@ -403,17 +403,26 @@ let index = function () {
role: current.attributes.account_role,
iban: null === current.attributes.iban ? '' : current.attributes.iban.match(/.{1,4}/g).join(' '),
account_number: null === current.attributes.account_number ? '' : current.attributes.account_number,
current_balance: current.attributes.current_balance,
currency_code: current.attributes.currency_code,
last_activity: null === current.attributes.last_activity ? '' : format(new Date(current.attributes.last_activity), i18next.t('config.month_and_day_fns')),
liability_type: current.attributes.liability_type,
liability_direction: current.attributes.liability_direction,
interest: current.attributes.interest,
interest_period: current.attributes.interest_period,
// balance: current.attributes.balance,
// pc_balance: current.attributes.pc_balance,
// balances: current.attributes.balances,
// currency info
currency_code: current.attributes.currency_code,
primary_currency_code: current.attributes.primary_currency_code,
// balances.
current_balance: current.attributes.current_balance,
pc_current_balance: current.attributes.pc_current_balance,
balance_difference: current.attributes.balance_difference,
pc_balance_difference: current.attributes.pc_balance_difference,
debt_amount: current.attributes.debt_amount,
pc_debt_amount: current.attributes.debt_amount,
};
console.log(account);
// get group info:
let groupId = current.attributes.object_group_id;
if(!this.pageOptions.groupedAccounts) {

View File

@@ -263,39 +263,74 @@
</td>
<td x-show="tableColumns.current_balance.visible && tableColumns.current_balance.enabled">
<span x-show="parseFloat(account.current_balance) < 0.0" class="text-danger"
x-text="formatMoney(account.current_balance, account.currency_code)"></span>
x-text="formatMoney(account.current_balance, account.primary_currency_code)"></span>
<span x-show="parseFloat(account.current_balance) === 0.0" class="text-muted"
x-text="formatMoney(account.current_balance, account.currency_code)"></span>
x-text="formatMoney(account.current_balance, account.primary_currency_code)"></span>
<span x-show="parseFloat(account.current_balance) > 0.0" class="text-success"
x-text="formatMoney(account.current_balance, account.currency_code)"></span>
x-text="formatMoney(account.current_balance, account.primary_currency_code)"></span>
<template x-if="null !== account.pc_current_balance">
<span>PC current balance TODO.</span>
<span>(
<span x-show="parseFloat(account.pc_current_balance) < 0.0" class="text-danger"
x-text="formatMoney(account.pc_current_balance, account.primary_currency_code)"></span>
<span x-show="parseFloat(account.pc_current_balance) === 0.0" class="text-muted"
x-text="formatMoney(account.pc_current_balance, account.primary_currency_code)"></span>
<span x-show="parseFloat(account.pc_current_balance) > 0.0" class="text-success"
x-text="formatMoney(account.pc_current_balance, account.primary_currency_code)"></span>
)
</span>
</template>
</td>
<td x-show="tableColumns.amount_due.visible && tableColumns.amount_due.enabled">
<!--
<template x-if="null !== account.current_debt">
<span class="text-info"
x-text="formatMoney(account.current_debt, account.currency_code)"></span>
<template x-if="null !== account.debt_amount">
<span>
<span x-show="null != account.debt_amount && account.debt_amount < 0" class="text-danger"
x-text="formatMoney(account.debt_amount, account.currency_code)"></span>
<span x-show="null != account.debt_amount && account.debt_amount == 0" class="text-muted"
x-text="formatMoney(account.debt_amount, account.currency_code)"></span>
<span x-show="null != account.debt_amount && account.debt_amount > 0" class="text-success"
x-text="formatMoney(account.debt_amount, account.currency_code)"></span>
</span>
<template x-if="null !== account.pc_debt_amount">
<span>(
<span x-show="parseFloat(account.pc_debt_amount) < 0.0" class="text-danger"
x-text="formatMoney(account.pc_debt_amount, account.primary_currency_code)"></span>
<span x-show="parseFloat(account.pc_debt_amount) === 0.0" class="text-muted"
x-text="formatMoney(account.pc_debt_amount, account.primary_currency_code)"></span>
<span x-show="parseFloat(account.pc_debt_amount) > 0.0" class="text-success"
x-text="formatMoney(account.pc_debt_amount, account.primary_currency_code)"></span>
)
</span>
</template>
-->
FIXME
</template>
</td>
<td x-show="tableColumns.last_activity.visible && tableColumns.last_activity.enabled">
<span x-text="account.last_activity"></span>
</td>
<td x-show="tableColumns.balance_difference.visible && tableColumns.balance_difference.enabled">
<template x-if="null !== account.balance">
<template x-for="balance in account.balance">
<template x-if="null !== account.balance_difference">
<span>
<span x-show="null != balance.balance_difference && balance.balance_difference < 0" class="text-danger"
x-text="formatMoney(balance.balance_difference, balance.currency_code)"></span>
<span x-show="null != balance.balance_difference && balance.balance_difference == 0" class="text-muted"
x-text="formatMoney(balance.balance_difference, balance.currency_code)"></span>
<span x-show="null != balance.balance_difference && balance.balance_difference > 0" class="text-success"
x-text="formatMoney(balance.balance_difference, balance.currency_code)"></span>
<span x-show="null != account.balance_difference && account.balance_difference < 0" class="text-danger"
x-text="formatMoney(account.balance_difference, account.currency_code)"></span>
<span x-show="null != account.balance_difference && account.balance_difference == 0" class="text-muted"
x-text="formatMoney(account.balance_difference, account.currency_code)"></span>
<span x-show="null != account.balance_difference && account.balance_difference > 0" class="text-success"
x-text="formatMoney(account.balance_difference, account.currency_code)"></span>
</span>
<template x-if="null !== account.pc_balance_difference">
<span>(
<span x-show="parseFloat(account.pc_balance_difference) < 0.0" class="text-danger"
x-text="formatMoney(account.pc_balance_difference, account.primary_currency_code)"></span>
<span x-show="parseFloat(account.pc_balance_difference) === 0.0" class="text-muted"
x-text="formatMoney(account.pc_balance_difference, account.primary_currency_code)"></span>
<span x-show="parseFloat(account.pc_balance_difference) > 0.0" class="text-success"
x-text="formatMoney(account.pc_balance_difference, account.primary_currency_code)"></span>
)
</span>
</template>
</template>
</td>
<td x-show="tableColumns.menu.visible && tableColumns.menu.enabled">