Build administration-compatible budget chart.

This commit is contained in:
James Cole
2023-08-01 19:38:53 +02:00
parent 5f9f621fa6
commit 0c087f33c2
23 changed files with 785 additions and 59 deletions

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Helpers\Collector\Extensions;
use FireflyIII\Models\UserGroup;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Relations\HasMany;
@@ -33,28 +34,29 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
trait CollectorProperties
{
public const TEST = 'Test';
private bool $expandGroupSearch;
private array $fields;
private bool $hasAccountInfo;
private bool $hasBillInformation;
private bool $hasBudgetInformation;
private bool $hasCatInformation;
private bool $hasJoinedAttTables;
private bool $hasJoinedMetaTables;
private bool $hasJoinedTagTables;
private bool $hasNotesInformation;
private array $integerFields;
private ?int $limit;
private ?int $page;
private array $postFilters;
private bool $expandGroupSearch;
private array $fields;
private bool $hasAccountInfo;
private bool $hasBillInformation;
private bool $hasBudgetInformation;
private bool $hasCatInformation;
private bool $hasJoinedAttTables;
private bool $hasJoinedMetaTables;
private bool $hasJoinedTagTables;
private bool $hasNotesInformation;
private array $integerFields;
private ?int $limit;
private ?int $page;
private array $postFilters;
private HasMany $query;
private array $stringFields;
private array $stringFields;
/*
* This array is used to collect ALL tags the user may search for (using 'setTags').
* This way the user can call 'setTags' multiple times and get a joined result.
*
*/
private array $tags;
private int $total;
private int $total;
private ?User $user;
private ?UserGroup $userGroup;
}

View File

@@ -38,6 +38,7 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Models\UserGroup;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\JoinClause;
@@ -67,6 +68,7 @@ class GroupCollector implements GroupCollectorInterface
$this->postFilters = [];
$this->tags = [];
$this->user = null;
$this->userGroup = null;
$this->limit = null;
$this->page = null;
@@ -82,6 +84,7 @@ class GroupCollector implements GroupCollectorInterface
$this->integerFields = [
'transaction_group_id',
'user_id',
'user_group_id',
'transaction_journal_id',
'transaction_type_id',
'order',
@@ -102,6 +105,7 @@ class GroupCollector implements GroupCollectorInterface
# group
'transaction_groups.id as transaction_group_id',
'transaction_groups.user_id as user_id',
'transaction_groups.user_group_id as user_group_id',
'transaction_groups.created_at as created_at',
'transaction_groups.updated_at as updated_at',
'transaction_groups.title as transaction_group_title',
@@ -300,7 +304,20 @@ class GroupCollector implements GroupCollectorInterface
*/
public function dumpQuery(): void
{
echo $this->query->select($this->fields)->toSql();
$query = $this->query->select($this->fields)->toSql();
$params = $this->query->getBindings();
foreach ($params as $param) {
$replace = sprintf('"%s"', $param);
if (is_int($param)) {
$replace = (string)$param;
}
$pos = strpos($query, '?');
if ($pos !== false) {
$query = substr_replace($query, $replace, $pos, 1);
}
}
echo $query;
echo '<pre>';
print_r($this->query->getBindings());
echo '</pre>';
@@ -548,6 +565,7 @@ class GroupCollector implements GroupCollectorInterface
$groupArray = [
'id' => (int)$augumentedJournal->transaction_group_id,
'user_id' => (int)$augumentedJournal->user_id,
'user_group_id' => (int)$augumentedJournal->user_group_id,
// Field transaction_group_title was added by the query.
'title' => $augumentedJournal->transaction_group_title, // @phpstan-ignore-line
'transaction_type' => $parsedGroup['transaction_type_type'],
@@ -1087,6 +1105,64 @@ class GroupCollector implements GroupCollectorInterface
->orderBy('source.amount', 'DESC');
}
/**
* Set the user object and start the query.
*
* @param User $user
*
* @return GroupCollectorInterface
*/
public function setUserGroup(UserGroup $userGroup): GroupCollectorInterface
{
if (null === $this->userGroup) {
$this->userGroup = $userGroup;
$this->startQueryForGroup();
}
return $this;
}
/**
* Build the query.
*/
private function startQueryForGroup(): void
{
//app('log')->debug('GroupCollector::startQuery');
$this->query = $this->userGroup
->transactionJournals()
->leftJoin('transaction_groups', 'transaction_journals.transaction_group_id', 'transaction_groups.id')
// join source transaction.
->leftJoin(
'transactions as source',
function (JoinClause $join) {
$join->on('source.transaction_journal_id', '=', 'transaction_journals.id')
->where('source.amount', '<', 0);
}
)
// join destination transaction
->leftJoin(
'transactions as destination',
function (JoinClause $join) {
$join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')
->where('destination.amount', '>', 0);
}
)
// left join transaction type.
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->leftJoin('transaction_currencies as currency', 'currency.id', '=', 'source.transaction_currency_id')
->leftJoin('transaction_currencies as foreign_currency', 'foreign_currency.id', '=', 'source.foreign_currency_id')
->whereNull('transaction_groups.deleted_at')
->whereNull('transaction_journals.deleted_at')
->whereNull('source.deleted_at')
->whereNull('destination.deleted_at')
->orderBy('transaction_journals.date', 'DESC')
->orderBy('transaction_journals.order', 'ASC')
->orderBy('transaction_journals.id', 'DESC')
->orderBy('transaction_journals.description', 'DESC')
->orderBy('source.amount', 'DESC');
}
/**
* Automatically include all stuff required to make API calls work.
*

View File

@@ -30,6 +30,7 @@ use FireflyIII\Models\Category;
use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\UserGroup;
use FireflyIII\User;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
@@ -1315,6 +1316,15 @@ interface GroupCollectorInterface
*/
public function setUser(User $user): GroupCollectorInterface;
/**
* Set the user group object and start the query.
*
* @param UserGroup $userGroup
*
* @return GroupCollectorInterface
*/
public function setUserGroup(UserGroup $userGroup): GroupCollectorInterface;
/**
* Only when does not have these tags
*