More code for multi account piggy banks.

This commit is contained in:
James Cole 2024-12-04 06:38:47 +01:00
parent d740814f88
commit 4819b5ac5d
No known key found for this signature in database
GPG Key ID: B49A324B7EAD6D80
6 changed files with 131 additions and 63 deletions

View File

@ -169,9 +169,20 @@ class PiggyBankFactory
}
private function resetOrder(): void
public function resetOrder(): void
{
$set = $this->user->piggyBanks()->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']);
// TODO duplicate code
$set = PiggyBank
::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
->where('accounts.user_id', $this->user->id)
->with(
[
'account',
'objectGroups',
]
)
->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']);
$current = 1;
foreach ($set as $piggyBank) {
if ($piggyBank->order !== $current) {

View File

@ -36,6 +36,7 @@ use FireflyIII\Transformers\PiggyBankTransformer;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\ParameterBag;
@ -57,7 +58,7 @@ class IndexController extends Controller
$this->middleware(
function ($request, $next) {
app('view')->share('title', (string)trans('firefly.piggyBanks'));
app('view')->share('title', (string) trans('firefly.piggyBanks'));
app('view')->share('mainTitleIcon', 'fa-bullseye');
$this->piggyRepos = app(PiggyBankRepositoryInterface::class);
@ -79,63 +80,26 @@ class IndexController extends Controller
public function index()
{
$this->cleanupObjectGroups();
//$this->piggyRepos->resetOrder();
$collection = $this->piggyRepos->getPiggyBanks();
$accounts = [];
$this->piggyRepos->resetOrder();
$collection = $this->piggyRepos->getPiggyBanks();
/** @var Carbon $end */
$end = session('end', today(config('app.timezone'))->endOfMonth());
$end = session('end', today(config('app.timezone'))->endOfMonth());
// transform piggies using the transformer:
$parameters = new ParameterBag();
$parameters = new ParameterBag();
$parameters->set('end', $end);
// make piggy bank groups:
$piggyBanks = [];
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters(new ParameterBag());
/** @var AccountTransformer $accountTransformer */
$accountTransformer = app(AccountTransformer::class);
$accountTransformer->setParameters($parameters);
/** @var PiggyBank $piggy */
foreach ($collection as $piggy) {
$array = $transformer->transform($piggy);
$groupOrder = (int)$array['object_group_order'];
// make group array if necessary:
$piggyBanks[$groupOrder] ??= [
'object_group_id' => $array['object_group_id'] ?? 0,
'object_group_title' => $array['object_group_title'] ?? trans('firefly.default_group_title_name'),
'piggy_banks' => [],
];
$account = $accountTransformer->transform($piggy->account);
$accountId = (int)$account['id'];
$array['attachments'] = $this->piggyRepos->getAttachments($piggy);
if (!array_key_exists($accountId, $accounts)) {
// create new:
$accounts[$accountId] = $account;
// add some interesting details:
$accounts[$accountId]['left'] = $accounts[$accountId]['current_balance'];
$accounts[$accountId]['saved'] = 0;
$accounts[$accountId]['target'] = 0;
$accounts[$accountId]['to_save'] = 0;
}
// calculate new interesting fields:
$accounts[$accountId]['left'] -= $array['current_amount'];
$accounts[$accountId]['saved'] += $array['current_amount'];
$accounts[$accountId]['target'] += $array['target_amount'];
$accounts[$accountId]['to_save'] += ($array['target_amount'] - $array['current_amount']);
$array['account_name'] = $account['name'];
$piggyBanks[$groupOrder]['piggy_banks'][] = $array;
}
// do a bunch of summaries.
$piggyBanks = $this->makeSums($piggyBanks);
// data
$piggyBanks = $this->groupPiggyBanks($collection);
$accounts = $this->collectAccounts($collection);
$accounts = $this->mergeAccountsAndPiggies($piggyBanks, $accounts);
$piggyBanks = $this->makeSums($piggyBanks);
ksort($piggyBanks);
@ -148,7 +112,7 @@ class IndexController extends Controller
foreach ($piggyBanks as $groupOrder => $group) {
$groupId = $group['object_group_id'];
foreach ($group['piggy_banks'] as $piggy) {
$currencyId = $piggy['currency_id'];
$currencyId = $piggy['currency_id'];
$sums[$groupId][$currencyId] ??= [
'target' => '0',
'saved' => '0',
@ -163,10 +127,10 @@ class IndexController extends Controller
// current_amount
// left_to_save
// save_per_month
$sums[$groupId][$currencyId]['target'] = bcadd($sums[$groupId][$currencyId]['target'], (string)$piggy['target_amount']);
$sums[$groupId][$currencyId]['saved'] = bcadd($sums[$groupId][$currencyId]['saved'], (string)$piggy['current_amount']);
$sums[$groupId][$currencyId]['left_to_save'] = bcadd($sums[$groupId][$currencyId]['left_to_save'], (string)$piggy['left_to_save']);
$sums[$groupId][$currencyId]['save_per_month'] = bcadd($sums[$groupId][$currencyId]['save_per_month'], (string)$piggy['save_per_month']);
$sums[$groupId][$currencyId]['target'] = bcadd($sums[$groupId][$currencyId]['target'], (string) $piggy['target_amount']);
$sums[$groupId][$currencyId]['saved'] = bcadd($sums[$groupId][$currencyId]['saved'], (string) $piggy['current_amount']);
$sums[$groupId][$currencyId]['left_to_save'] = bcadd($sums[$groupId][$currencyId]['left_to_save'], (string) $piggy['left_to_save']);
$sums[$groupId][$currencyId]['save_per_month'] = bcadd($sums[$groupId][$currencyId]['save_per_month'], (string) $piggy['save_per_month']);
}
}
foreach ($piggyBanks as $groupOrder => $group) {
@ -182,8 +146,8 @@ class IndexController extends Controller
*/
public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse
{
$objectGroupTitle = (string)$request->get('objectGroupTitle');
$newOrder = (int)$request->get('order');
$objectGroupTitle = (string) $request->get('objectGroupTitle');
$newOrder = (int) $request->get('order');
$this->piggyRepos->setOrder($piggyBank, $newOrder);
if ('' !== $objectGroupTitle) {
$this->piggyRepos->setObjectGroup($piggyBank, $objectGroupTitle);
@ -194,4 +158,91 @@ class IndexController extends Controller
return response()->json(['data' => 'OK']);
}
private function groupPiggyBanks(Collection $collection): array
{
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters(new ParameterBag());
$piggyBanks = [];
/** @var PiggyBank $piggy */
foreach ($collection as $piggy) {
$array = $transformer->transform($piggy);
$groupOrder = (int) $array['object_group_order'];
$piggyBanks[$groupOrder] ??= [
'object_group_id' => $array['object_group_id'] ?? 0,
'object_group_title' => $array['object_group_title'] ?? trans('firefly.default_group_title_name'),
'piggy_banks' => [],
];
$array['attachments'] = $this->piggyRepos->getAttachments($piggy);
// sum the total amount for the index.
$piggyBanks[$groupOrder]['piggy_banks'][] = $array;
}
return $piggyBanks;
}
private function collectAccounts(Collection $collection): array
{
/** @var Carbon $end */
$end = session('end', today(config('app.timezone'))->endOfMonth());
// transform piggies using the transformer:
$parameters = new ParameterBag();
$parameters->set('end', $end);
/** @var AccountTransformer $accountTransformer */
$accountTransformer = app(AccountTransformer::class);
$accountTransformer->setParameters($parameters);
$return = [];
/** @var PiggyBank $piggy */
foreach ($collection as $piggy) {
$accounts = $piggy->accounts;
/** @var Account $account */
foreach ($accounts as $account) {
$array = $accountTransformer->transform($account);
$accountId = (int) $array['id'];
if (!array_key_exists($accountId, $return)) {
$return[$accountId] = $array;
// add some interesting details:
$return[$accountId]['left'] = $return[$accountId]['current_balance'];
$return[$accountId]['saved'] = '0';
$return[$accountId]['target'] = '0';
$return[$accountId]['to_save'] = '0';
}
// calculate new interesting fields:
// $return[$accountId]['left'] -= $array['current_amount'];
// $return[$accountId]['saved'] += $array['current_amount'];
// $return[$accountId]['target'] += $array['target_amount'];
// $return[$accountId]['to_save'] += ($array['target_amount'] - $array['current_amount']);
// $return['account_name'] = $account['name'];
}
}
return $return;
}
private function mergeAccountsAndPiggies(array $piggyBanks, array $accounts): array
{
/** @var array $piggyBank */
foreach ($piggyBanks as $group) {
foreach ($group['piggy_banks'] as $piggyBank) {
// loop all accounts in this piggy bank subtract the current amount from "left to save" in the $accounts array.
/** @var array $piggyAccount */
foreach ($piggyBank['accounts'] as $piggyAccount) {
$accountId = $piggyAccount['id'];
if (array_key_exists($accountId, $accounts)) {
$accounts[$accountId]['left'] = bcsub($accounts[$accountId]['left'], $piggyAccount['current_amount']);
$accounts[$accountId]['saved'] = bcadd($accounts[$accountId]['saved'], $piggyAccount['current_amount']);
$accounts[$accountId]['target'] = bcadd($accounts[$accountId]['target'], $piggyBank['target_amount']);
$accounts[$accountId]['to_save'] = bcadd($accounts[$accountId]['to_save'], bcsub($piggyBank['target_amount'], $piggyAccount['current_amount']));
}
}
}
}
return $accounts;
}
}

View File

@ -116,7 +116,7 @@ class PiggyBank extends Model
public function accounts(): BelongsToMany
{
return $this->belongsToMany(Account::class);
return $this->belongsToMany(Account::class)->withPivot('current_amount');
}
public function piggyBankRepetitions(): HasMany

View File

@ -25,6 +25,7 @@ namespace FireflyIII\Repositories\PiggyBank;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\PiggyBankFactory;
use FireflyIII\Models\Attachment;
use FireflyIII\Models\Note;
use FireflyIII\Models\PiggyBank;
@ -285,7 +286,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
'objectGroups',
]
)
->orderBy('piggy_banks.order', 'ASC')->get();
->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']);
}
/**
@ -352,4 +353,11 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
{
throw new FireflyException('TODO Not implemented');
}
#[\Override] public function resetOrder(): void
{
$factory = new PiggyBankFactory();
$factory->setUser($this->user);
$factory->resetOrder();
}
}

View File

@ -113,10 +113,7 @@ interface PiggyBankRepositoryInterface
public function removeObjectGroup(PiggyBank $piggyBank): PiggyBank;
// /**
// * Correct order of piggies in case of issues.
// */
// public function resetOrder(): void;
public function resetOrder(): void;
/**
* Search for piggy banks.

View File

@ -132,10 +132,11 @@ class PiggyBankTransformer extends AbstractTransformer
private function renderAccounts(PiggyBank $piggyBank): array
{
$return = [];
foreach ($piggyBank->accounts as $account) {
foreach ($piggyBank->accounts()->get() as $account) {
$return[] = [
'id' => $account->id,
'name' => $account->name,
'current_amount' => $account->pivot->current_amount,
// TODO add balance, add left to save.
];
}