Auto commit for release 'develop' on 2024-04-07

This commit is contained in:
github-actions
2024-04-07 06:51:34 +02:00
parent ea89f6177f
commit 911f46c590
109 changed files with 1681 additions and 328 deletions

View File

@@ -81,15 +81,15 @@ class AccountController extends Controller
public function dashboard(DashboardChartRequest $request): JsonResponse
{
/** @var Carbon $start */
$start = $this->parameters->get('start');
$start = $this->parameters->get('start');
/** @var Carbon $end */
$end = $this->parameters->get('end');
$end = $this->parameters->get('end');
$end->endOfDay();
/** @var TransactionCurrency $default */
$default = app('amount')->getDefaultCurrency();
$params = $request->getAll();
$default = app('amount')->getDefaultCurrency();
$params = $request->getAll();
/** @var Collection $accounts */
$accounts = $params['accounts'];
@@ -105,7 +105,7 @@ class AccountController extends Controller
$frontpage->save();
}
$accounts = $this->repository->getAccountsById($frontpage->data);
$accounts = $this->repository->getAccountsById($frontpage->data);
}
// both options are overruled by "preselected"
@@ -121,11 +121,11 @@ class AccountController extends Controller
/** @var Account $account */
foreach ($accounts as $account) {
$currency = $this->repository->getAccountCurrency($account);
$currency = $this->repository->getAccountCurrency($account);
if (null === $currency) {
$currency = $default;
}
$currentSet = [
$currentSet = [
'label' => $account->name,
// the currency that belongs to the account.
'currency_id' => (string)$currency->id,
@@ -144,25 +144,25 @@ class AccountController extends Controller
'entries' => [],
'native_entries' => [],
];
$currentStart = clone $start;
$range = app('steam')->balanceInRange($account, $start, clone $end, $currency);
$rangeConverted = app('steam')->balanceInRangeConverted($account, $start, clone $end, $default);
$currentStart = clone $start;
$range = app('steam')->balanceInRange($account, $start, clone $end, $currency);
$rangeConverted = app('steam')->balanceInRangeConverted($account, $start, clone $end, $default);
$previous = array_values($range)[0];
$previousConverted = array_values($rangeConverted)[0];
while ($currentStart <= $end) {
$format = $currentStart->format('Y-m-d');
$label = $currentStart->toAtomString();
$balance = array_key_exists($format, $range) ? $range[$format] : $previous;
$balanceConverted = array_key_exists($format, $rangeConverted) ? $rangeConverted[$format] : $previousConverted;
$previous = $balance;
$previousConverted = $balanceConverted;
$format = $currentStart->format('Y-m-d');
$label = $currentStart->toAtomString();
$balance = array_key_exists($format, $range) ? $range[$format] : $previous;
$balanceConverted = array_key_exists($format, $rangeConverted) ? $rangeConverted[$format] : $previousConverted;
$previous = $balance;
$previousConverted = $balanceConverted;
$currentStart->addDay();
$currentSet['entries'][$label] = $balance;
$currentSet['native_entries'][$label] = $balanceConverted;
}
$chartData[] = $currentSet;
$chartData[] = $currentSet;
}
return response()->json($this->clean($chartData));

View File

@@ -56,7 +56,7 @@ class Controller extends BaseController
protected const string CONTENT_TYPE = 'application/vnd.api+json';
protected ParameterBag $parameters;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
public function __construct()
{

View File

@@ -34,7 +34,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
class IndexController extends Controller
{
public const string RESOURCE_KEY = 'accounts';
public const string RESOURCE_KEY = 'accounts';
private AccountRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS];
@@ -49,7 +49,7 @@ class IndexController extends Controller
function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
// new way of user group validation
$userGroup = $this->validateUserGroup($request);
$userGroup = $this->validateUserGroup($request);
$this->repository->setUserGroup($userGroup);
return $next($request);
@@ -77,7 +77,8 @@ class IndexController extends Controller
return response()
->json($this->jsonApiList('accounts', $paginator, $transformer))
->header('Content-Type', self::CONTENT_TYPE);
->header('Content-Type', self::CONTENT_TYPE)
;
}
public function infiniteList(InfiniteListRequest $request): JsonResponse
@@ -85,7 +86,7 @@ class IndexController extends Controller
$this->repository->resetAccountOrder();
// get accounts of the specified type, and return.
$types = $request->getAccountTypes();
$types = $request->getAccountTypes();
// get from repository
$accounts = $this->repository->getAccountsInOrder($types, $request->getSortInstructions('accounts'), $request->getStartRow(), $request->getEndRow());
@@ -97,6 +98,7 @@ class IndexController extends Controller
return response()
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
->header('Content-Type', self::CONTENT_TYPE);
->header('Content-Type', self::CONTENT_TYPE)
;
}
}

View File

@@ -38,10 +38,11 @@ use Illuminate\Http\JsonResponse;
*/
class ShowController extends Controller
{
public const string RESOURCE_KEY = 'accounts';
public const string RESOURCE_KEY = 'accounts';
private AccountRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS];
/**
* AccountController constructor.
*/
@@ -52,7 +53,7 @@ class ShowController extends Controller
function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
// new way of user group validation
$userGroup = $this->validateUserGroup($request);
$userGroup = $this->validateUserGroup($request);
$this->repository->setUserGroup($userGroup);
return $next($request);

View File

@@ -76,7 +76,7 @@ class BasicController extends Controller
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
$this->opsRepository = app(OperationsRepositoryInterface::class);
$userGroup = $this->validateUserGroup($request);
$userGroup = $this->validateUserGroup($request);
$this->abRepository->setUserGroup($userGroup);
$this->accountRepository->setUserGroup($userGroup);
$this->billRepository->setUserGroup($userGroup);
@@ -99,8 +99,8 @@ class BasicController extends Controller
public function basic(DateRequest $request): JsonResponse
{
// parameters for boxes:
$start = $this->parameters->get('start');
$end = $this->parameters->get('end');
$start = $this->parameters->get('start');
$end = $this->parameters->get('end');
// balance information:
$balanceData = $this->getBalanceInformation($start, $end);
@@ -117,13 +117,13 @@ class BasicController extends Controller
*/
private function getBalanceInformation(Carbon $start, Carbon $end): array
{
$object = new SummaryBalanceGrouped();
$default = app('amount')->getDefaultCurrency();
$object = new SummaryBalanceGrouped();
$default = app('amount')->getDefaultCurrency();
$object->setDefault($default);
/** @var User $user */
$user = auth()->user();
$user = auth()->user();
// collect income of user using the new group collector.
/** @var GroupCollectorInterface $collector */
@@ -135,9 +135,10 @@ class BasicController extends Controller
->setPage($this->parameters->get('page'))
// set types of transactions to return.
->setTypes([TransactionType::DEPOSIT])
->setRange($start, $end);
->setRange($start, $end)
;
$set = $collector->getExtractedJournals();
$set = $collector->getExtractedJournals();
$object->groupTransactions('income', $set);
// collect expenses of user using the new group collector.
@@ -150,8 +151,9 @@ class BasicController extends Controller
->setPage($this->parameters->get('page'))
// set types of transactions to return.
->setTypes([TransactionType::WITHDRAWAL])
->setRange($start, $end);
$set = $collector->getExtractedJournals();
->setRange($start, $end)
;
$set = $collector->getExtractedJournals();
$object->groupTransactions('expense', $set);
return $object->groupData();
@@ -166,7 +168,7 @@ class BasicController extends Controller
$paidAmount = $this->billRepository->sumPaidInRange($start, $end);
$unpaidAmount = $this->billRepository->sumUnpaidInRange($start, $end);
$return = [];
$return = [];
/**
* @var array $info
@@ -226,14 +228,14 @@ class BasicController extends Controller
{
Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
app('log')->debug('Now in getLeftToSpendInfo');
$return = [];
$today = today(config('app.timezone'));
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
$budgets = $this->budgetRepository->getActiveBudgets();
$spent = $this->opsRepository->listExpenses($start, $end, null, $budgets);
$default = app('amount')->getDefaultCurrency();
$currencies = [];
$converter = new ExchangeRateConverter();
$return = [];
$today = today(config('app.timezone'));
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
$budgets = $this->budgetRepository->getActiveBudgets();
$spent = $this->opsRepository->listExpenses($start, $end, null, $budgets);
$default = app('amount')->getDefaultCurrency();
$currencies = [];
$converter = new ExchangeRateConverter();
// native info:
$nativeLeft = [
@@ -259,8 +261,8 @@ class BasicController extends Controller
*/
foreach ($spent as $currencyId => $row) {
app('log')->debug(sprintf('Processing spent array in currency #%d', $currencyId));
$spent = '0';
$spentNative = '0';
$spent = '0';
$spentNative = '0';
// get the sum from the array of transactions (double loop but who cares)
/** @var array $budget */
@@ -277,8 +279,8 @@ class BasicController extends Controller
if ((int)$journal['foreign_currency_id'] === $default->id) {
$amountNative = $journal['foreign_amount'];
}
$spent = bcadd($spent, $amount);
$spentNative = bcadd($spentNative, $amountNative);
$spent = bcadd($spent, $amount);
$spentNative = bcadd($spentNative, $amountNative);
}
app('log')->debug(sprintf('Total spent in budget "%s" is %s', $budget['name'], $spent));
}
@@ -294,9 +296,9 @@ class BasicController extends Controller
app('log')->debug(sprintf('Amount left is %s', $left));
// how much left per day?
$days = (int)$today->diffInDays($end, true) + 1;
$perDay = '0';
$perDayNative = '0';
$days = (int)$today->diffInDays($end, true) + 1;
$perDay = '0';
$perDayNative = '0';
if (0 !== $days && bccomp($left, '0') > -1) {
$perDay = bcdiv($left, (string)$days);
}
@@ -305,7 +307,7 @@ class BasicController extends Controller
}
// left
$return[] = [
$return[] = [
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
'value' => $left,
'currency_id' => (string)$row['currency_id'],
@@ -314,10 +316,10 @@ class BasicController extends Controller
'currency_decimal_places' => (int)$row['currency_decimal_places'],
];
// left (native)
$nativeLeft['value'] = $leftNative;
$nativeLeft['value'] = $leftNative;
// left per day:
$return[] = [
$return[] = [
'key' => sprintf('left-per-day-to-spend-in-%s', $row['currency_code']),
'value' => $perDay,
'currency_id' => (string)$row['currency_id'],
@@ -327,10 +329,10 @@ class BasicController extends Controller
];
// left per day (native)
$nativePerDay['value'] = $perDayNative;
$nativePerDay['value'] = $perDayNative;
}
$return[] = $nativeLeft;
$return[] = $nativePerDay;
$return[] = $nativeLeft;
$return[] = $nativePerDay;
$converter->summarize();
return $return;
@@ -339,8 +341,8 @@ class BasicController extends Controller
private function getNetWorthInfo(Carbon $start, Carbon $end): array
{
/** @var UserGroup $userGroup */
$userGroup = auth()->user()->userGroup;
$date = today(config('app.timezone'))->startOfDay();
$userGroup = auth()->user()->userGroup;
$date = today(config('app.timezone'))->startOfDay();
// start and end in the future? use $end
if ($this->notInDateRange($date, $start, $end)) {
/** @var Carbon $date */
@@ -350,12 +352,12 @@ class BasicController extends Controller
/** @var NetWorthInterface $netWorthHelper */
$netWorthHelper = app(NetWorthInterface::class);
$netWorthHelper->setUserGroup($userGroup);
$allAccounts = $this->accountRepository->getActiveAccountsByType(
$allAccounts = $this->accountRepository->getActiveAccountsByType(
[AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT]
);
// filter list on preference of being included.
$filtered = $allAccounts->filter(
$filtered = $allAccounts->filter(
function (Account $account) {
$includeNetWorth = $this->accountRepository->getMetaValue($account, 'include_net_worth');
@@ -363,10 +365,10 @@ class BasicController extends Controller
}
);
$netWorthSet = $netWorthHelper->byAccounts($filtered, $date);
$return = [];
$netWorthSet = $netWorthHelper->byAccounts($filtered, $date);
$return = [];
// in native amount
$return[] = [
$return[] = [
'key' => 'net-worth-in-native',
'value' => $netWorthSet['native']['balance'],
'currency_id' => (string)$netWorthSet['native']['currency_id'],

View File

@@ -32,7 +32,6 @@ use FireflyIII\Http\Middleware\Installer;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface as UserGroupAccountRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -62,8 +61,8 @@ class HomeController extends Controller
*/
public function dateRange(Request $request): JsonResponse
{
$stringStart = '';
$stringEnd = '';
$stringStart = '';
$stringEnd = '';
try {
$stringStart = e((string)$request->get('start'));
@@ -98,7 +97,7 @@ class HomeController extends Controller
app('log')->debug('Range is now marked as "custom".');
}
$diff = $start->diffInDays($end, true) + 1;
$diff = $start->diffInDays($end, true) + 1;
if ($diff > 366) {
$request->session()->flash('warning', (string)trans('firefly.warning_much_data', ['days' => (int)$diff]));
@@ -121,8 +120,8 @@ class HomeController extends Controller
*/
public function index(AccountRepositoryInterface $repository): mixed
{
$types = config('firefly.accountTypesByIdentifier.asset');
$count = $repository->count($types);
$types = config('firefly.accountTypesByIdentifier.asset');
$count = $repository->count($types);
Log::channel('audit')->info('User visits homepage.');
if (0 === $count) {
@@ -135,13 +134,14 @@ class HomeController extends Controller
if ('v2' === (string)config('view.layout')) {
return $this->indexV2();
}
throw new FireflyException('Invalid layout configuration');
}
private function indexV1(AccountRepositoryInterface $repository): mixed
{
$types = config('firefly.accountTypesByIdentifier.asset');
$count = $repository->count($types);
$types = config('firefly.accountTypesByIdentifier.asset');
$count = $repository->count($types);
$subTitle = (string)trans('firefly.welcome_back');
$transactions = [];
$frontpage = app('preferences')->getFresh('frontpageAccounts', $repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray());
@@ -152,11 +152,11 @@ class HomeController extends Controller
/** @var Carbon $start */
/** @var Carbon $end */
$start = session('start', today(config('app.timezone'))->startOfMonth());
$end = session('end', today(config('app.timezone'))->endOfMonth());
$accounts = $repository->getAccountsById($frontpageArray);
$today = today(config('app.timezone'));
$accounts = $accounts->sortBy('order'); // sort frontpage accounts by order
$start = session('start', today(config('app.timezone'))->startOfMonth());
$end = session('end', today(config('app.timezone'))->endOfMonth());
$accounts = $repository->getAccountsById($frontpageArray);
$today = today(config('app.timezone'));
$accounts = $accounts->sortBy('order'); // sort frontpage accounts by order
app('log')->debug('Frontpage accounts are ', $frontpageArray);
@@ -166,14 +166,14 @@ class HomeController extends Controller
// collect groups for each transaction.
foreach ($accounts as $account) {
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->withAccountInformation()->setRange($start, $end)->setLimit(10)->setPage(1);
$set = $collector->getExtractedJournals();
$transactions[] = ['transactions' => $set, 'account' => $account];
}
/** @var User $user */
$user = auth()->user();
$user = auth()->user();
event(new RequestedVersionCheckStatus($user));
return view('index', compact('count', 'subTitle', 'transactions', 'billCount', 'start', 'end', 'today'));
@@ -181,15 +181,15 @@ class HomeController extends Controller
private function indexV2(): mixed
{
$subTitle = (string)trans('firefly.welcome_back');
$subTitle = (string)trans('firefly.welcome_back');
$start = session('start', today(config('app.timezone'))->startOfMonth());
$end = session('end', today(config('app.timezone'))->endOfMonth());
/** @var User $user */
$user = auth()->user();
$user = auth()->user();
event(new RequestedVersionCheckStatus($user));
return view('index', compact( 'subTitle','start','end'));
return view('index', compact('subTitle', 'start', 'end'));
}
}

View File

@@ -30,7 +30,6 @@ use FireflyIII\User;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
/**
* Trait ValidatesUserGroupTrait
@@ -43,7 +42,7 @@ trait ValidatesUserGroupTrait
*/
protected function validateUserGroup(Request $request): UserGroup
{
app('log')->debug(sprintf('validateUserGroup: %s', get_class($this)));
app('log')->debug(sprintf('validateUserGroup: %s', static::class));
if (!auth()->check()) {
app('log')->debug('validateUserGroup: user is not logged in, return NULL.');
@@ -51,43 +50,48 @@ trait ValidatesUserGroupTrait
}
/** @var User $user */
$user = auth()->user();
$groupId = 0;
$user = auth()->user();
$groupId = 0;
if (!$request->has('user_group_id')) {
$groupId = $user->user_group_id;
$groupId = $user->user_group_id;
app('log')->debug(sprintf('validateUserGroup: no user group submitted, use default group #%d.', $groupId));
}
if ($request->has('user_group_id')) {
$groupId = (int)$request->get('user_group_id');
app('log')->debug(sprintf('validateUserGroup: user group submitted, search for memberships in group #%d.', $groupId));
}
/** @var GroupMembership|null $membership */
/** @var null|GroupMembership $membership */
$membership = $user->groupMemberships()->where('user_group_id', $groupId)->first();
if (null === $membership) {
app('log')->debug(sprintf('validateUserGroup: user has no access to group #%d.', $groupId));
throw new AuthorizationException((string)trans('validation.no_access_group'));
}
// need to get the group from the membership:
/** @var UserGroup|null $group */
$group = $membership->userGroup;
/** @var null|UserGroup $group */
$group = $membership->userGroup;
if (null === $group) {
app('log')->debug(sprintf('validateUserGroup: group #%d does not exist.', $groupId));
throw new AuthorizationException((string)trans('validation.belongs_user_or_user_group'));
}
app('log')->debug(sprintf('validateUserGroup: validate access of user to group #%d ("%s").', $groupId, $group->title));
$roles = property_exists($this, 'acceptedRoles') ? $this->acceptedRoles : [];
if(0 === count($roles)) {
$roles = property_exists($this, 'acceptedRoles') ? $this->acceptedRoles : [];
if (0 === count($roles)) {
app('log')->debug('validateUserGroup: no roles defined, so no access.');
throw new AuthorizationException((string)trans('validation.no_accepted_roles_defined'));
}
app('log')->debug(sprintf('validateUserGroup: have %d roles to check.', count($roles)), $roles);
/** @var UserRoleEnum $role */
foreach($roles as $role) {
if($user->hasRoleInGroupOrOwner($group, $role)) {
foreach ($roles as $role) {
if ($user->hasRoleInGroupOrOwner($group, $role)) {
app('log')->debug(sprintf('validateUserGroup: User has role "%s" in group #%d, return the group.', $role->value, $groupId));
return $group;
}
app('log')->debug(sprintf('validateUserGroup: User does NOT have role "%s" in group #%d, continue searching.', $role->value, $groupId));