mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-12-04 12:01:57 +00:00
chore: reformat code.
This commit is contained in:
@@ -40,87 +40,13 @@ use Psr\Container\NotFoundExceptionInterface;
|
||||
*/
|
||||
class Amount
|
||||
{
|
||||
/**
|
||||
* bool $sepBySpace is $localeconv['n_sep_by_space']
|
||||
* int $signPosn = $localeconv['n_sign_posn']
|
||||
* string $sign = $localeconv['negative_sign']
|
||||
* bool $csPrecedes = $localeconv['n_cs_precedes'].
|
||||
*
|
||||
* @param bool $sepBySpace
|
||||
* @param int $signPosn
|
||||
* @param string $sign
|
||||
* @param bool $csPrecedes
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public static function getAmountJsConfig(bool $sepBySpace, int $signPosn, string $sign, bool $csPrecedes): string
|
||||
{
|
||||
// negative first:
|
||||
$space = ' ';
|
||||
|
||||
// require space between symbol and amount?
|
||||
if (false === $sepBySpace) {
|
||||
$space = ''; // no
|
||||
}
|
||||
|
||||
// there are five possible positions for the "+" or "-" sign (if it is even used)
|
||||
// pos_a and pos_e could be the ( and ) symbol.
|
||||
$posA = ''; // before everything
|
||||
$posB = ''; // before currency symbol
|
||||
$posC = ''; // after currency symbol
|
||||
$posD = ''; // before amount
|
||||
$posE = ''; // after everything
|
||||
|
||||
// format would be (currency before amount)
|
||||
// AB%sC_D%vE
|
||||
// or:
|
||||
// AD%v_B%sCE (amount before currency)
|
||||
// the _ is the optional space
|
||||
|
||||
// switch on how to display amount:
|
||||
switch ($signPosn) {
|
||||
default:
|
||||
case 0:
|
||||
// ( and ) around the whole thing
|
||||
$posA = '(';
|
||||
$posE = ')';
|
||||
break;
|
||||
case 1:
|
||||
// The sign string precedes the quantity and currency_symbol
|
||||
$posA = $sign;
|
||||
break;
|
||||
case 2:
|
||||
// The sign string succeeds the quantity and currency_symbol
|
||||
$posE = $sign;
|
||||
break;
|
||||
case 3:
|
||||
// The sign string immediately precedes the currency_symbol
|
||||
$posB = $sign;
|
||||
break;
|
||||
case 4:
|
||||
// The sign string immediately succeeds the currency_symbol
|
||||
$posC = $sign;
|
||||
}
|
||||
|
||||
// default is amount before currency
|
||||
$format = $posA.$posD.'%v'.$space.$posB.'%s'.$posC.$posE;
|
||||
|
||||
if ($csPrecedes) {
|
||||
// alternative is currency before amount
|
||||
$format = $posA.$posB.'%s'.$posC.$space.$posD.'%v'.$posE;
|
||||
}
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will properly format the given number, in color or "black and white",
|
||||
* as a currency, given two things: the currency required and the current locale.
|
||||
*
|
||||
* @param TransactionCurrency $format
|
||||
* @param string $amount
|
||||
* @param bool $coloured
|
||||
* @param TransactionCurrency $format
|
||||
* @param string $amount
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -134,10 +60,10 @@ class Amount
|
||||
* This method will properly format the given number, in color or "black and white",
|
||||
* as a currency, given two things: the currency required and the current locale.
|
||||
*
|
||||
* @param string $symbol
|
||||
* @param int $decimalPlaces
|
||||
* @param string $amount
|
||||
* @param bool $coloured
|
||||
* @param string $symbol
|
||||
* @param int $decimalPlaces
|
||||
* @param string $amount
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
@@ -224,7 +150,7 @@ class Amount
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param User $user
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
* @throws FireflyException
|
||||
@@ -255,6 +181,22 @@ class Amount
|
||||
return $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function tryDecrypt(string $value): string
|
||||
{
|
||||
try {
|
||||
$value = Crypt::decrypt($value); // verified
|
||||
} catch (DecryptException $e) {
|
||||
// @ignoreException
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the correct format rules required by accounting.js,
|
||||
* the library used to format amounts in charts.
|
||||
@@ -281,26 +223,6 @@ class Amount
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function getSystemCurrency(): TransactionCurrency
|
||||
{
|
||||
return TransactionCurrency::where('code', 'EUR')->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $info
|
||||
* @param string $field
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function getLocaleField(array $info, string $field): bool
|
||||
{
|
||||
return (is_bool($info[$field]) && true === $info[$field])
|
||||
|| (is_int($info[$field]) && 1 === $info[$field]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -330,18 +252,96 @@ class Amount
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param array $info
|
||||
* @param string $field
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function getLocaleField(array $info, string $field): bool
|
||||
{
|
||||
return (is_bool($info[$field]) && true === $info[$field])
|
||||
|| (is_int($info[$field]) && 1 === $info[$field]);
|
||||
}
|
||||
|
||||
/**
|
||||
* bool $sepBySpace is $localeconv['n_sep_by_space']
|
||||
* int $signPosn = $localeconv['n_sign_posn']
|
||||
* string $sign = $localeconv['negative_sign']
|
||||
* bool $csPrecedes = $localeconv['n_cs_precedes'].
|
||||
*
|
||||
* @param bool $sepBySpace
|
||||
* @param int $signPosn
|
||||
* @param string $sign
|
||||
* @param bool $csPrecedes
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
private function tryDecrypt(string $value): string
|
||||
public static function getAmountJsConfig(bool $sepBySpace, int $signPosn, string $sign, bool $csPrecedes): string
|
||||
{
|
||||
try {
|
||||
$value = Crypt::decrypt($value); // verified
|
||||
} catch (DecryptException $e) {
|
||||
// @ignoreException
|
||||
// negative first:
|
||||
$space = ' ';
|
||||
|
||||
// require space between symbol and amount?
|
||||
if (false === $sepBySpace) {
|
||||
$space = ''; // no
|
||||
}
|
||||
|
||||
return $value;
|
||||
// there are five possible positions for the "+" or "-" sign (if it is even used)
|
||||
// pos_a and pos_e could be the ( and ) symbol.
|
||||
$posA = ''; // before everything
|
||||
$posB = ''; // before currency symbol
|
||||
$posC = ''; // after currency symbol
|
||||
$posD = ''; // before amount
|
||||
$posE = ''; // after everything
|
||||
|
||||
// format would be (currency before amount)
|
||||
// AB%sC_D%vE
|
||||
// or:
|
||||
// AD%v_B%sCE (amount before currency)
|
||||
// the _ is the optional space
|
||||
|
||||
// switch on how to display amount:
|
||||
switch ($signPosn) {
|
||||
default:
|
||||
case 0:
|
||||
// ( and ) around the whole thing
|
||||
$posA = '(';
|
||||
$posE = ')';
|
||||
break;
|
||||
case 1:
|
||||
// The sign string precedes the quantity and currency_symbol
|
||||
$posA = $sign;
|
||||
break;
|
||||
case 2:
|
||||
// The sign string succeeds the quantity and currency_symbol
|
||||
$posE = $sign;
|
||||
break;
|
||||
case 3:
|
||||
// The sign string immediately precedes the currency_symbol
|
||||
$posB = $sign;
|
||||
break;
|
||||
case 4:
|
||||
// The sign string immediately succeeds the currency_symbol
|
||||
$posC = $sign;
|
||||
}
|
||||
|
||||
// default is amount before currency
|
||||
$format = $posA . $posD . '%v' . $space . $posB . '%s' . $posC . $posE;
|
||||
|
||||
if ($csPrecedes) {
|
||||
// alternative is currency before amount
|
||||
$format = $posA . $posB . '%s' . $posC . $space . $posD . '%v' . $posE;
|
||||
}
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function getSystemCurrency(): TransactionCurrency
|
||||
{
|
||||
return TransactionCurrency::where('code', 'EUR')->first();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ class RemoteUserGuard implements Guard
|
||||
/**
|
||||
* Create a new authentication guard.
|
||||
*
|
||||
* @param UserProvider $provider
|
||||
* @param Application $app
|
||||
* @param UserProvider $provider
|
||||
* @param Application $app
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
@@ -112,6 +112,15 @@ class RemoteUserGuard implements Guard
|
||||
$this->user = $retrievedUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function guest(): bool
|
||||
{
|
||||
Log::debug(sprintf('Now at %s', __METHOD__));
|
||||
return !$this->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -124,10 +133,16 @@ class RemoteUserGuard implements Guard
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function guest(): bool
|
||||
public function user(): ?User
|
||||
{
|
||||
Log::debug(sprintf('Now at %s', __METHOD__));
|
||||
return !$this->check();
|
||||
$user = $this->user;
|
||||
if (null === $user) {
|
||||
Log::debug('User is NULL');
|
||||
return null;
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,21 +172,6 @@ class RemoteUserGuard implements Guard
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function user(): ?User
|
||||
{
|
||||
Log::debug(sprintf('Now at %s', __METHOD__));
|
||||
$user = $this->user;
|
||||
if (null === $user) {
|
||||
Log::debug('User is NULL');
|
||||
return null;
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
||||
@@ -35,8 +35,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
class AccountList implements BinderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotFoundHttpException
|
||||
|
||||
@@ -31,8 +31,8 @@ use Illuminate\Routing\Route;
|
||||
interface BinderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
@@ -34,8 +34,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
class BudgetList implements BinderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotFoundHttpException
|
||||
|
||||
@@ -35,8 +35,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
class CLIToken implements BinderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return mixed
|
||||
* @throws FireflyException
|
||||
|
||||
@@ -34,8 +34,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
class CategoryList implements BinderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotFoundHttpException
|
||||
|
||||
@@ -33,8 +33,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
class CurrencyCode implements BinderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
* @throws NotFoundHttpException
|
||||
|
||||
@@ -36,8 +36,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
class Date implements BinderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws NotFoundHttpException
|
||||
|
||||
@@ -40,8 +40,8 @@ class DynamicConfigKey
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return string
|
||||
* @throws NotFoundHttpException
|
||||
|
||||
@@ -57,8 +57,8 @@ class EitherConfigKey
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return string
|
||||
* @throws NotFoundHttpException
|
||||
|
||||
@@ -34,8 +34,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
class JournalList implements BinderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
@@ -63,7 +63,7 @@ class JournalList implements BinderInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param string $value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -36,8 +36,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
class TagList implements BinderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotFoundHttpException
|
||||
|
||||
@@ -35,8 +35,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
class TagOrId implements BinderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return Tag
|
||||
*/
|
||||
|
||||
@@ -50,7 +50,7 @@ class CacheProperties
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $property
|
||||
* @param mixed $property
|
||||
*/
|
||||
public function addProperty($property): void
|
||||
{
|
||||
@@ -86,14 +86,6 @@ class CacheProperties
|
||||
return Cache::has($this->hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function store($data): void
|
||||
{
|
||||
Cache::forever($this->hash, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
private function hash(): void
|
||||
@@ -109,4 +101,12 @@ class CacheProperties
|
||||
}
|
||||
$this->hash = substr(hash('sha256', $content), 0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function store($data): void
|
||||
{
|
||||
Cache::forever($this->hash, $data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,61 +79,34 @@ class FrontpageChartGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $end
|
||||
*/
|
||||
public function setEnd(Carbon $end): void
|
||||
{
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
*/
|
||||
public function setStart(Carbon $start): void
|
||||
{
|
||||
$this->start = $start;
|
||||
}
|
||||
|
||||
/**
|
||||
* A basic setter for the user. Also updates the repositories with the right user.
|
||||
* For each budget, gets all budget limits for the current time range.
|
||||
* When no limits are present, the time range is used to collect information on money spent.
|
||||
* If limits are present, each limit is processed individually.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->budgetRepository->setUser($user);
|
||||
$this->blRepository->setUser($user);
|
||||
$this->opsRepository->setUser($user);
|
||||
|
||||
$locale = app('steam')->getLocale();
|
||||
$this->monthAndDayFormat = (string)trans('config.month_and_day_js', [], $locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a budget has budget limit, each limit is processed individually.
|
||||
*
|
||||
* @param array $data
|
||||
* @param Budget $budget
|
||||
* @param Collection $limits
|
||||
* @param array $data
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function budgetLimits(array $data, Budget $budget, Collection $limits): array
|
||||
private function processBudget(array $data, Budget $budget): array
|
||||
{
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($limits as $limit) {
|
||||
$data = $this->processLimit($data, $budget, $limit);
|
||||
// get all limits:
|
||||
$limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end);
|
||||
|
||||
// if no limits
|
||||
if (0 === $limits->count()) {
|
||||
return $this->noBudgetLimits($data, $budget);
|
||||
}
|
||||
|
||||
return $data;
|
||||
return $this->budgetLimits($data, $budget, $limits);
|
||||
}
|
||||
|
||||
/**
|
||||
* When no limits are present, the expenses of the whole period are collected and grouped.
|
||||
* This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
|
||||
*
|
||||
* @param array $data
|
||||
* @param Budget $budget
|
||||
* @param array $data
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -152,34 +125,31 @@ class FrontpageChartGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* For each budget, gets all budget limits for the current time range.
|
||||
* When no limits are present, the time range is used to collect information on money spent.
|
||||
* If limits are present, each limit is processed individually.
|
||||
* If a budget has budget limit, each limit is processed individually.
|
||||
*
|
||||
* @param array $data
|
||||
* @param Budget $budget
|
||||
* @param array $data
|
||||
* @param Budget $budget
|
||||
* @param Collection $limits
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function processBudget(array $data, Budget $budget): array
|
||||
private function budgetLimits(array $data, Budget $budget, Collection $limits): array
|
||||
{
|
||||
// get all limits:
|
||||
$limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end);
|
||||
|
||||
// if no limits
|
||||
if (0 === $limits->count()) {
|
||||
return $this->noBudgetLimits($data, $budget);
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($limits as $limit) {
|
||||
$data = $this->processLimit($data, $budget, $limit);
|
||||
}
|
||||
|
||||
return $this->budgetLimits($data, $budget, $limits);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* For each limit, the expenses from the time range of the limit are collected. Each row from the result is processed individually.
|
||||
* For each limit, the expenses from the time range of the limit are collected. Each row from the result is
|
||||
* processed individually.
|
||||
*
|
||||
* @param array $data
|
||||
* @param Budget $budget
|
||||
* @param BudgetLimit $limit
|
||||
* @param array $data
|
||||
* @param Budget $budget
|
||||
* @param BudgetLimit $limit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -200,13 +170,13 @@ class FrontpageChartGenerator
|
||||
/**
|
||||
* Each row of expenses from a budget limit is in another currency (note $entry['currency_name']).
|
||||
*
|
||||
* Each one is added to the $data array. If the limit's date range is different from the global $start and $end dates,
|
||||
* for example when a limit only partially falls into this month, the title is expanded to clarify.
|
||||
* Each one is added to the $data array. If the limit's date range is different from the global $start and $end
|
||||
* dates, for example when a limit only partially falls into this month, the title is expanded to clarify.
|
||||
*
|
||||
* @param array $data
|
||||
* @param Budget $budget
|
||||
* @param BudgetLimit $limit
|
||||
* @param array $entry
|
||||
* @param array $data
|
||||
* @param Budget $budget
|
||||
* @param BudgetLimit $limit
|
||||
* @param array $entry
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -230,4 +200,35 @@ class FrontpageChartGenerator
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $end
|
||||
*/
|
||||
public function setEnd(Carbon $end): void
|
||||
{
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
*/
|
||||
public function setStart(Carbon $start): void
|
||||
{
|
||||
$this->start = $start;
|
||||
}
|
||||
|
||||
/**
|
||||
* A basic setter for the user. Also updates the repositories with the right user.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->budgetRepository->setUser($user);
|
||||
$this->blRepository->setUser($user);
|
||||
$this->opsRepository->setUser($user);
|
||||
|
||||
$locale = app('steam')->getLocale();
|
||||
$this->monthAndDayFormat = (string)trans('config.month_and_day_js', [], $locale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ class FrontpageChartGenerator
|
||||
/**
|
||||
* FrontpageChartGenerator constructor.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*/
|
||||
public function __construct(Carbon $start, Carbon $end)
|
||||
{
|
||||
@@ -99,24 +99,8 @@ class FrontpageChartGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $currency
|
||||
*/
|
||||
private function addCurrency(array $currency): void
|
||||
{
|
||||
$currencyId = (int)$currency['currency_id'];
|
||||
|
||||
$this->currencies[$currencyId] = $this->currencies[$currencyId] ?? [
|
||||
'currency_id' => $currencyId,
|
||||
'currency_name' => $currency['currency_name'],
|
||||
'currency_symbol' => $currency['currency_symbol'],
|
||||
'currency_code' => $currency['currency_code'],
|
||||
'currency_decimal_places' => $currency['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -138,7 +122,23 @@ class FrontpageChartGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param array $currency
|
||||
*/
|
||||
private function addCurrency(array $currency): void
|
||||
{
|
||||
$currencyId = (int)$currency['currency_id'];
|
||||
|
||||
$this->currencies[$currencyId] = $this->currencies[$currencyId] ?? [
|
||||
'currency_id' => $currencyId,
|
||||
'currency_name' => $currency['currency_name'],
|
||||
'currency_symbol' => $currency['currency_symbol'],
|
||||
'currency_code' => $currency['currency_code'],
|
||||
'currency_decimal_places' => $currency['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -160,7 +160,7 @@ class FrontpageChartGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -185,8 +185,8 @@ class FrontpageChartGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $currencyData
|
||||
* @param array $monetaryData
|
||||
* @param array $currencyData
|
||||
* @param array $monetaryData
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -36,9 +36,9 @@ use Illuminate\Support\Collection;
|
||||
class WholePeriodChartGenerator
|
||||
{
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Category $category
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -117,8 +117,8 @@ class WholePeriodChartGenerator
|
||||
/**
|
||||
* TODO this method is duplicated
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -143,7 +143,7 @@ class WholePeriodChartGenerator
|
||||
* Loop array of spent/earned info, and extract which currencies are present.
|
||||
* Key is the currency ID.
|
||||
*
|
||||
* @param array $array
|
||||
* @param array $array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -55,7 +55,7 @@ class ChartColour
|
||||
];
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
* @param int $index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
||||
@@ -59,7 +59,7 @@ abstract class AbstractCronjob
|
||||
abstract public function fire(): void;
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
* @param Carbon $date
|
||||
*/
|
||||
final public function setDate(Carbon $date): void
|
||||
{
|
||||
@@ -68,7 +68,7 @@ abstract class AbstractCronjob
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $force
|
||||
* @param bool $force
|
||||
*/
|
||||
final public function setForce(bool $force): void
|
||||
{
|
||||
|
||||
@@ -23,7 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support;
|
||||
|
||||
use Amount as Amt;
|
||||
use Eloquent;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Support\Form\FormSupport;
|
||||
@@ -42,9 +41,9 @@ class ExpandedForm
|
||||
use FormSupport;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -75,10 +74,10 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param int|null $value
|
||||
* @param mixed $checked
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param int|null $value
|
||||
* @param mixed $checked
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -112,9 +111,9 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -138,8 +137,8 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -162,9 +161,9 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -189,9 +188,9 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -215,7 +214,7 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $set
|
||||
* @param Collection $set
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
@@ -244,8 +243,8 @@ class ExpandedForm
|
||||
|
||||
|
||||
/**
|
||||
* @param null $value
|
||||
* @param array|null $options
|
||||
* @param null $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -275,8 +274,8 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -295,8 +294,8 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -320,9 +319,9 @@ class ExpandedForm
|
||||
/**
|
||||
* Function to render a percentage.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -347,9 +346,9 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -371,9 +370,9 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -396,9 +395,9 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
|
||||
@@ -140,126 +140,6 @@ class ExportDataGenerator
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get(string $key, mixed $default = null): mixed
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function has(mixed $key): mixed
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
*/
|
||||
public function setAccounts(Collection $accounts): void
|
||||
{
|
||||
$this->accounts = $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $end
|
||||
*/
|
||||
public function setEnd(Carbon $end): void
|
||||
{
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportAccounts
|
||||
*/
|
||||
public function setExportAccounts(bool $exportAccounts): void
|
||||
{
|
||||
$this->exportAccounts = $exportAccounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportBills
|
||||
*/
|
||||
public function setExportBills(bool $exportBills): void
|
||||
{
|
||||
$this->exportBills = $exportBills;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportBudgets
|
||||
*/
|
||||
public function setExportBudgets(bool $exportBudgets): void
|
||||
{
|
||||
$this->exportBudgets = $exportBudgets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportCategories
|
||||
*/
|
||||
public function setExportCategories(bool $exportCategories): void
|
||||
{
|
||||
$this->exportCategories = $exportCategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportPiggies
|
||||
*/
|
||||
public function setExportPiggies(bool $exportPiggies): void
|
||||
{
|
||||
$this->exportPiggies = $exportPiggies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportRecurring
|
||||
*/
|
||||
public function setExportRecurring(bool $exportRecurring): void
|
||||
{
|
||||
$this->exportRecurring = $exportRecurring;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportRules
|
||||
*/
|
||||
public function setExportRules(bool $exportRules): void
|
||||
{
|
||||
$this->exportRules = $exportRules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportTags
|
||||
*/
|
||||
public function setExportTags(bool $exportTags): void
|
||||
{
|
||||
$this->exportTags = $exportTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportTransactions
|
||||
*/
|
||||
public function setExportTransactions(bool $exportTransactions): void
|
||||
{
|
||||
$this->exportTransactions = $exportTransactions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
*/
|
||||
public function setStart(Carbon $start): void
|
||||
{
|
||||
$this->start = $start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -337,6 +217,14 @@ class ExportDataGenerator
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -940,6 +828,14 @@ class ExportDataGenerator
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get(string $key, mixed $default = null): mixed
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -1084,7 +980,15 @@ class ExportDataGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $tags
|
||||
* @param Collection $accounts
|
||||
*/
|
||||
public function setAccounts(Collection $accounts): void
|
||||
{
|
||||
$this->accounts = $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $tags
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -1100,4 +1004,100 @@ class ExportDataGenerator
|
||||
|
||||
return implode(',', $smol);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function has(mixed $key): mixed
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $end
|
||||
*/
|
||||
public function setEnd(Carbon $end): void
|
||||
{
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportAccounts
|
||||
*/
|
||||
public function setExportAccounts(bool $exportAccounts): void
|
||||
{
|
||||
$this->exportAccounts = $exportAccounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportBills
|
||||
*/
|
||||
public function setExportBills(bool $exportBills): void
|
||||
{
|
||||
$this->exportBills = $exportBills;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportBudgets
|
||||
*/
|
||||
public function setExportBudgets(bool $exportBudgets): void
|
||||
{
|
||||
$this->exportBudgets = $exportBudgets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportCategories
|
||||
*/
|
||||
public function setExportCategories(bool $exportCategories): void
|
||||
{
|
||||
$this->exportCategories = $exportCategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportPiggies
|
||||
*/
|
||||
public function setExportPiggies(bool $exportPiggies): void
|
||||
{
|
||||
$this->exportPiggies = $exportPiggies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportRecurring
|
||||
*/
|
||||
public function setExportRecurring(bool $exportRecurring): void
|
||||
{
|
||||
$this->exportRecurring = $exportRecurring;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportRules
|
||||
*/
|
||||
public function setExportRules(bool $exportRules): void
|
||||
{
|
||||
$this->exportRules = $exportRules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportTags
|
||||
*/
|
||||
public function setExportTags(bool $exportTags): void
|
||||
{
|
||||
$this->exportTags = $exportTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $exportTransactions
|
||||
*/
|
||||
public function setExportTransactions(bool $exportTransactions): void
|
||||
{
|
||||
$this->exportTransactions = $exportTransactions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
*/
|
||||
public function setStart(Carbon $start): void
|
||||
{
|
||||
$this->start = $start;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,11 +38,11 @@ use Illuminate\Support\Facades\Log;
|
||||
class FireflyConfig
|
||||
{
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
*/
|
||||
public function delete(string $name): void
|
||||
{
|
||||
$fullName = 'ff-config-'.$name;
|
||||
$fullName = 'ff-config-' . $name;
|
||||
if (Cache::has($fullName)) {
|
||||
Cache::forget($fullName);
|
||||
}
|
||||
@@ -50,15 +50,25 @@ class FireflyConfig
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool|string|int|null $default
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $name): bool
|
||||
{
|
||||
return Configuration::where('name', $name)->count() === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool|string|int|null $default
|
||||
*
|
||||
* @return Configuration|null
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function get(string $name, $default = null): ?Configuration
|
||||
{
|
||||
$fullName = 'ff-config-'.$name;
|
||||
$fullName = 'ff-config-' . $name;
|
||||
if (Cache::has($fullName)) {
|
||||
return Cache::get($fullName);
|
||||
}
|
||||
@@ -66,7 +76,7 @@ class FireflyConfig
|
||||
try {
|
||||
/** @var Configuration|null $config */
|
||||
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
|
||||
} catch (QueryException|Exception $e) {
|
||||
} catch (QueryException | Exception $e) {
|
||||
throw new FireflyException(sprintf('Could not poll the database: %s', $e->getMessage()), 0, $e);
|
||||
}
|
||||
|
||||
@@ -84,49 +94,8 @@ class FireflyConfig
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return Configuration|null
|
||||
*/
|
||||
public function getFresh(string $name, $default = null): ?Configuration
|
||||
{
|
||||
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
|
||||
if ($config) {
|
||||
return $config;
|
||||
}
|
||||
// no preference found and default is null:
|
||||
if (null === $default) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->set($name, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $name): bool
|
||||
{
|
||||
return Configuration::where('name', $name)->count() === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Configuration
|
||||
*/
|
||||
public function put(string $name, $value): Configuration
|
||||
{
|
||||
return $this->set($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Configuration
|
||||
*/
|
||||
@@ -148,14 +117,45 @@ class FireflyConfig
|
||||
$item->name = $name;
|
||||
$item->data = $value;
|
||||
$item->save();
|
||||
Cache::forget('ff-config-'.$name);
|
||||
Cache::forget('ff-config-' . $name);
|
||||
|
||||
return $item;
|
||||
}
|
||||
$config->data = $value;
|
||||
$config->save();
|
||||
Cache::forget('ff-config-'.$name);
|
||||
Cache::forget('ff-config-' . $name);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return Configuration|null
|
||||
*/
|
||||
public function getFresh(string $name, $default = null): ?Configuration
|
||||
{
|
||||
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
|
||||
if ($config) {
|
||||
return $config;
|
||||
}
|
||||
// no preference found and default is null:
|
||||
if (null === $default) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->set($name, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Configuration
|
||||
*/
|
||||
public function put(string $name, $value): Configuration
|
||||
{
|
||||
return $this->set($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,9 +45,9 @@ class AccountForm
|
||||
/**
|
||||
* Grouped dropdown list of all accounts that are valid as the destination of a withdrawal.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -64,97 +64,8 @@ class AccountForm
|
||||
}
|
||||
|
||||
/**
|
||||
* Grouped dropdown list of all accounts that are valid as the destination of a withdrawal.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function activeWithdrawalDestinations(string $name, mixed $value = null, array $options = null): string
|
||||
{
|
||||
$types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::EXPENSE,];
|
||||
$repository = $this->getAccountRepository();
|
||||
$grouped = $this->getAccountsGrouped($types, $repository);
|
||||
|
||||
$cash = $repository->getCashAccount();
|
||||
$key = (string)trans('firefly.cash_account_type');
|
||||
$grouped[$key][$cash->id] = sprintf('(%s)', (string)trans('firefly.cash'));
|
||||
|
||||
return $this->select($name, $grouped, $value, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check list of asset accounts.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function assetAccountCheckList(string $name, array $options = null): string
|
||||
{
|
||||
$options = $options ?? [];
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$selected = request()->old($name) ?? [];
|
||||
|
||||
// get all asset accounts:
|
||||
$types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT];
|
||||
$grouped = $this->getAccountsGrouped($types);
|
||||
|
||||
unset($options['class']);
|
||||
try {
|
||||
$html = view('form.assetAccountCheckList', compact('classes', 'selected', 'name', 'label', 'options', 'grouped'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Could not render assetAccountCheckList(): %s', $e->getMessage()));
|
||||
$html = 'Could not render assetAccountCheckList.';
|
||||
throw new FireflyException($html, 0, $e);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic list of asset accounts.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function assetAccountList(string $name, $value = null, array $options = null): string
|
||||
{
|
||||
$types = [AccountType::ASSET, AccountType::DEFAULT];
|
||||
$grouped = $this->getAccountsGrouped($types);
|
||||
|
||||
return $this->select($name, $grouped, $value, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same list but all liabilities as well.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function longAccountList(string $name, $value = null, array $options = null): string
|
||||
{
|
||||
$types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN,];
|
||||
$grouped = $this->getAccountsGrouped($types);
|
||||
|
||||
return $this->select($name, $grouped, $value, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
* @param AccountRepositoryInterface|null $repository
|
||||
* @param array $types
|
||||
* @param AccountRepositoryInterface|null $repository
|
||||
* @return array
|
||||
*/
|
||||
private function getAccountsGrouped(array $types, AccountRepositoryInterface $repository = null): array
|
||||
@@ -187,4 +98,93 @@ class AccountForm
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grouped dropdown list of all accounts that are valid as the destination of a withdrawal.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function activeWithdrawalDestinations(string $name, mixed $value = null, array $options = null): string
|
||||
{
|
||||
$types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::EXPENSE,];
|
||||
$repository = $this->getAccountRepository();
|
||||
$grouped = $this->getAccountsGrouped($types, $repository);
|
||||
|
||||
$cash = $repository->getCashAccount();
|
||||
$key = (string)trans('firefly.cash_account_type');
|
||||
$grouped[$key][$cash->id] = sprintf('(%s)', (string)trans('firefly.cash'));
|
||||
|
||||
return $this->select($name, $grouped, $value, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check list of asset accounts.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function assetAccountCheckList(string $name, array $options = null): string
|
||||
{
|
||||
$options = $options ?? [];
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$selected = request()->old($name) ?? [];
|
||||
|
||||
// get all asset accounts:
|
||||
$types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT];
|
||||
$grouped = $this->getAccountsGrouped($types);
|
||||
|
||||
unset($options['class']);
|
||||
try {
|
||||
$html = view('form.assetAccountCheckList', compact('classes', 'selected', 'name', 'label', 'options', 'grouped'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Could not render assetAccountCheckList(): %s', $e->getMessage()));
|
||||
$html = 'Could not render assetAccountCheckList.';
|
||||
throw new FireflyException($html, 0, $e);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic list of asset accounts.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function assetAccountList(string $name, $value = null, array $options = null): string
|
||||
{
|
||||
$types = [AccountType::ASSET, AccountType::DEFAULT];
|
||||
$grouped = $this->getAccountsGrouped($types);
|
||||
|
||||
return $this->select($name, $grouped, $value, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same list but all liabilities as well.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function longAccountList(string $name, $value = null, array $options = null): string
|
||||
{
|
||||
$types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN,];
|
||||
$grouped = $this->getAccountsGrouped($types);
|
||||
|
||||
return $this->select($name, $grouped, $value, $options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@ class CurrencyForm
|
||||
use FormSupport;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -54,134 +54,10 @@ class CurrencyForm
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO describe and cleanup.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function balanceAll(string $name, $value = null, array $options = null): string
|
||||
{
|
||||
return $this->allCurrencyField($name, 'balance', $value, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO cleanup and describe
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function currencyList(string $name, $value = null, array $options = null): string
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $currencyRepos */
|
||||
$currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
|
||||
// get all currencies:
|
||||
$list = $currencyRepos->get();
|
||||
$array = [];
|
||||
/** @var TransactionCurrency $currency */
|
||||
foreach ($list as $currency) {
|
||||
$array[$currency->id] = $currency->name.' ('.$currency->symbol.')';
|
||||
}
|
||||
|
||||
return $this->select($name, $array, $value, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO cleanup and describe
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function currencyListEmpty(string $name, $value = null, array $options = null): string
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $currencyRepos */
|
||||
$currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
|
||||
// get all currencies:
|
||||
$list = $currencyRepos->get();
|
||||
$array = [
|
||||
0 => (string)trans('firefly.no_currency'),
|
||||
];
|
||||
/** @var TransactionCurrency $currency */
|
||||
foreach ($list as $currency) {
|
||||
$array[$currency->id] = $currency->name.' ('.$currency->symbol.')';
|
||||
}
|
||||
|
||||
return $this->select($name, $array, $value, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO describe and cleanup
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $view
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function allCurrencyField(string $name, string $view, $value = null, array $options = null): string
|
||||
{
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
$options['step'] = 'any';
|
||||
$defaultCurrency = $options['currency'] ?? Amt::getDefaultCurrency();
|
||||
/** @var Collection $currencies */
|
||||
$currencies = app('amount')->getAllCurrencies();
|
||||
unset($options['currency'], $options['placeholder']);
|
||||
|
||||
// perhaps the currency has been sent to us in the field $amount_currency_id_$name (amount_currency_id_amount)
|
||||
$preFilled = session('preFilled');
|
||||
if (!is_array($preFilled)) {
|
||||
$preFilled = [];
|
||||
}
|
||||
$key = 'amount_currency_id_'.$name;
|
||||
$sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $defaultCurrency->id;
|
||||
|
||||
Log::debug(sprintf('Sent currency ID is %d', $sentCurrencyId));
|
||||
|
||||
// find this currency in set of currencies:
|
||||
foreach ($currencies as $currency) {
|
||||
if ($currency->id === $sentCurrencyId) {
|
||||
$defaultCurrency = $currency;
|
||||
Log::debug(sprintf('default currency is now %s', $defaultCurrency->code));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure value is formatted nicely:
|
||||
if (null !== $value && '' !== $value) {
|
||||
$value = app('steam')->bcround($value, $defaultCurrency->decimal_places);
|
||||
}
|
||||
try {
|
||||
$html = view('form.'.$view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Could not render currencyField(): %s', $e->getMessage()));
|
||||
$html = 'Could not render currencyField.';
|
||||
throw new FireflyException($html, 0, $e);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $view
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param string $view
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -203,7 +79,7 @@ class CurrencyForm
|
||||
if (!is_array($preFilled)) {
|
||||
$preFilled = [];
|
||||
}
|
||||
$key = 'amount_currency_id_'.$name;
|
||||
$key = 'amount_currency_id_' . $name;
|
||||
$sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $defaultCurrency->id;
|
||||
|
||||
Log::debug(sprintf('Sent currency ID is %d', $sentCurrencyId));
|
||||
@@ -222,7 +98,7 @@ class CurrencyForm
|
||||
$value = app('steam')->bcround($value, $defaultCurrency->decimal_places);
|
||||
}
|
||||
try {
|
||||
$html = view('form.'.$view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
||||
$html = view('form.' . $view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Could not render currencyField(): %s', $e->getMessage()));
|
||||
$html = 'Could not render currencyField.';
|
||||
@@ -231,4 +107,128 @@ class CurrencyForm
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO describe and cleanup.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function balanceAll(string $name, $value = null, array $options = null): string
|
||||
{
|
||||
return $this->allCurrencyField($name, 'balance', $value, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO describe and cleanup
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $view
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function allCurrencyField(string $name, string $view, $value = null, array $options = null): string
|
||||
{
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
$options['step'] = 'any';
|
||||
$defaultCurrency = $options['currency'] ?? Amt::getDefaultCurrency();
|
||||
/** @var Collection $currencies */
|
||||
$currencies = app('amount')->getAllCurrencies();
|
||||
unset($options['currency'], $options['placeholder']);
|
||||
|
||||
// perhaps the currency has been sent to us in the field $amount_currency_id_$name (amount_currency_id_amount)
|
||||
$preFilled = session('preFilled');
|
||||
if (!is_array($preFilled)) {
|
||||
$preFilled = [];
|
||||
}
|
||||
$key = 'amount_currency_id_' . $name;
|
||||
$sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $defaultCurrency->id;
|
||||
|
||||
Log::debug(sprintf('Sent currency ID is %d', $sentCurrencyId));
|
||||
|
||||
// find this currency in set of currencies:
|
||||
foreach ($currencies as $currency) {
|
||||
if ($currency->id === $sentCurrencyId) {
|
||||
$defaultCurrency = $currency;
|
||||
Log::debug(sprintf('default currency is now %s', $defaultCurrency->code));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure value is formatted nicely:
|
||||
if (null !== $value && '' !== $value) {
|
||||
$value = app('steam')->bcround($value, $defaultCurrency->decimal_places);
|
||||
}
|
||||
try {
|
||||
$html = view('form.' . $view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Could not render currencyField(): %s', $e->getMessage()));
|
||||
$html = 'Could not render currencyField.';
|
||||
throw new FireflyException($html, 0, $e);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO cleanup and describe
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function currencyList(string $name, $value = null, array $options = null): string
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $currencyRepos */
|
||||
$currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
|
||||
// get all currencies:
|
||||
$list = $currencyRepos->get();
|
||||
$array = [];
|
||||
/** @var TransactionCurrency $currency */
|
||||
foreach ($list as $currency) {
|
||||
$array[$currency->id] = $currency->name . ' (' . $currency->symbol . ')';
|
||||
}
|
||||
|
||||
return $this->select($name, $array, $value, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO cleanup and describe
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function currencyListEmpty(string $name, $value = null, array $options = null): string
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $currencyRepos */
|
||||
$currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
|
||||
// get all currencies:
|
||||
$list = $currencyRepos->get();
|
||||
$array = [
|
||||
0 => (string)trans('firefly.no_currency'),
|
||||
];
|
||||
/** @var TransactionCurrency $currency */
|
||||
foreach ($list as $currency) {
|
||||
$array[$currency->id] = $currency->name . ' (' . $currency->symbol . ')';
|
||||
}
|
||||
|
||||
return $this->select($name, $array, $value, $options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,10 +36,10 @@ use Throwable;
|
||||
trait FormSupport
|
||||
{
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array|null $list
|
||||
* @param mixed $selected
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param array|null $list
|
||||
* @param mixed $selected
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -62,9 +62,26 @@ trait FormSupport
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $label
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function label(string $name, array $options = null): string
|
||||
{
|
||||
$options = $options ?? [];
|
||||
if (array_key_exists('label', $options)) {
|
||||
return $options['label'];
|
||||
}
|
||||
$name = str_replace('[]', '', $name);
|
||||
|
||||
return (string)trans('form.' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $label
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -73,7 +90,7 @@ trait FormSupport
|
||||
$options = $options ?? [];
|
||||
$name = str_replace('[]', '', $name);
|
||||
$options['class'] = 'form-control';
|
||||
$options['id'] = 'ffInput_'.$name;
|
||||
$options['id'] = 'ffInput_' . $name;
|
||||
$options['autocomplete'] = 'off';
|
||||
$options['placeholder'] = ucfirst($label);
|
||||
|
||||
@@ -81,8 +98,27 @@ trait FormSupport
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed|null $value
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getHolderClasses(string $name): string
|
||||
{
|
||||
// Get errors from session:
|
||||
/** @var MessageBag $errors */
|
||||
$errors = session('errors');
|
||||
$classes = 'form-group';
|
||||
|
||||
if (null !== $errors && $errors->has($name)) {
|
||||
$classes = 'form-group has-error has-feedback';
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed|null $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -127,40 +163,4 @@ trait FormSupport
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getHolderClasses(string $name): string
|
||||
{
|
||||
// Get errors from session:
|
||||
/** @var MessageBag $errors */
|
||||
$errors = session('errors');
|
||||
$classes = 'form-group';
|
||||
|
||||
if (null !== $errors && $errors->has($name)) {
|
||||
$classes = 'form-group has-error has-feedback';
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function label(string $name, array $options = null): string
|
||||
{
|
||||
$options = $options ?? [];
|
||||
if (array_key_exists('label', $options)) {
|
||||
return $options['label'];
|
||||
}
|
||||
$name = str_replace('[]', '', $name);
|
||||
|
||||
return (string)trans('form.'.$name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,9 @@ class PiggyBankForm
|
||||
/**
|
||||
* TODO cleanup and describe
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
||||
@@ -37,8 +37,8 @@ class RuleForm
|
||||
use FormSupport;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return string
|
||||
@@ -60,8 +60,8 @@ class RuleForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param null $value
|
||||
* @param string $name
|
||||
* @param null $value
|
||||
* @param array|null $options
|
||||
*
|
||||
* @return HtmlString
|
||||
|
||||
@@ -35,7 +35,7 @@ trait AccountFilter
|
||||
/**
|
||||
* All the available types.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -36,7 +36,7 @@ trait ApiSupport
|
||||
/**
|
||||
* Small helper function for the revenue and expense account charts.
|
||||
*
|
||||
* @param array $names
|
||||
* @param array $names
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -53,7 +53,7 @@ trait ApiSupport
|
||||
/**
|
||||
* Small helper function for the revenue and expense account charts.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -38,7 +38,7 @@ trait ConvertsExchangeRates
|
||||
private ?bool $enabled = null;
|
||||
|
||||
/**
|
||||
* @param array $set
|
||||
* @param array $set
|
||||
* @return array
|
||||
*/
|
||||
public function cerChartSet(array $set): array
|
||||
@@ -74,10 +74,135 @@ trait ConvertsExchangeRates
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function getPreference(): void
|
||||
{
|
||||
$this->enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $currencyId
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
private function getCurrency(int $currencyId): TransactionCurrency
|
||||
{
|
||||
$result = TransactionCurrency::find($currencyId);
|
||||
if (null === $result) {
|
||||
return app('amount')->getDefaultCurrency();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $from
|
||||
* @param TransactionCurrency $to
|
||||
* @param Carbon $date
|
||||
* @return string
|
||||
*/
|
||||
private function getRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string
|
||||
{
|
||||
Log::debug(sprintf('getRate(%s, %s, "%s")', $from->code, $to->code, $date->format('Y-m-d')));
|
||||
/** @var CurrencyExchangeRate $result */
|
||||
$result = auth()->user()
|
||||
->currencyExchangeRates()
|
||||
->where('from_currency_id', $from->id)
|
||||
->where('to_currency_id', $to->id)
|
||||
->where('date', '<=', $date->format('Y-m-d'))
|
||||
->orderBy('date', 'DESC')
|
||||
->first();
|
||||
if (null !== $result) {
|
||||
$rate = (string)$result->rate;
|
||||
Log::debug(sprintf('Rate is %s', $rate));
|
||||
return $rate;
|
||||
}
|
||||
// no result. perhaps the other way around?
|
||||
/** @var CurrencyExchangeRate $result */
|
||||
$result = auth()->user()
|
||||
->currencyExchangeRates()
|
||||
->where('from_currency_id', $to->id)
|
||||
->where('to_currency_id', $from->id)
|
||||
->where('date', '<=', $date->format('Y-m-d'))
|
||||
->orderBy('date', 'DESC')
|
||||
->first();
|
||||
if (null !== $result) {
|
||||
$rate = bcdiv('1', (string)$result->rate);
|
||||
Log::debug(sprintf('Reversed rate is %s', $rate));
|
||||
return $rate;
|
||||
}
|
||||
// try euro rates
|
||||
$result1 = $this->getEuroRate($from, $date);
|
||||
if ('0' === $result1) {
|
||||
Log::debug(sprintf('No exchange rate between EUR and %s', $from->code));
|
||||
return '0';
|
||||
}
|
||||
$result2 = $this->getEuroRate($to, $date);
|
||||
if ('0' === $result2) {
|
||||
Log::debug(sprintf('No exchange rate between EUR and %s', $to->code));
|
||||
return '0';
|
||||
}
|
||||
// still need to inverse rate 2:
|
||||
$result2 = bcdiv('1', $result2);
|
||||
$rate = bcmul($result1, $result2);
|
||||
Log::debug(sprintf('Rate %s to EUR is %s', $from->code, $result1));
|
||||
Log::debug(sprintf('Rate EUR to %s is %s', $to->code, $result2));
|
||||
Log::debug(sprintf('Rate for %s to %s is %s', $from->code, $to->code, $rate));
|
||||
return $rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
* @param Carbon $date
|
||||
* @return string
|
||||
*/
|
||||
private function getEuroRate(TransactionCurrency $currency, Carbon $date): string
|
||||
{
|
||||
Log::debug(sprintf('Find rate for %s to Euro', $currency->code));
|
||||
$euro = TransactionCurrency::whereCode('EUR')->first();
|
||||
if (null === $euro) {
|
||||
app('log')->warning('Cannot do indirect conversion without EUR.');
|
||||
return '0';
|
||||
}
|
||||
|
||||
// try one way:
|
||||
/** @var CurrencyExchangeRate $result */
|
||||
$result = auth()->user()
|
||||
->currencyExchangeRates()
|
||||
->where('from_currency_id', $currency->id)
|
||||
->where('to_currency_id', $euro->id)
|
||||
->where('date', '<=', $date->format('Y-m-d'))
|
||||
->orderBy('date', 'DESC')
|
||||
->first();
|
||||
if (null !== $result) {
|
||||
$rate = (string)$result->rate;
|
||||
Log::debug(sprintf('Rate for %s to EUR is %s.', $currency->code, $rate));
|
||||
return $rate;
|
||||
}
|
||||
// try the other way around and inverse it.
|
||||
/** @var CurrencyExchangeRate $result */
|
||||
$result = auth()->user()
|
||||
->currencyExchangeRates()
|
||||
->where('from_currency_id', $euro->id)
|
||||
->where('to_currency_id', $currency->id)
|
||||
->where('date', '<=', $date->format('Y-m-d'))
|
||||
->orderBy('date', 'DESC')
|
||||
->first();
|
||||
if (null !== $result) {
|
||||
$rate = bcdiv('1', (string)$result->rate);
|
||||
Log::debug(sprintf('Inverted rate for %s to EUR is %s.', $currency->code, $rate));
|
||||
return $rate;
|
||||
}
|
||||
|
||||
Log::debug(sprintf('No rate for %s to EUR.', $currency->code));
|
||||
return '0';
|
||||
}
|
||||
|
||||
/**
|
||||
* For a sum of entries, get the exchange rate to the native currency of
|
||||
* the user.
|
||||
* @param array $entries
|
||||
*
|
||||
* @param array $entries
|
||||
* @return array
|
||||
*/
|
||||
public function cerSum(array $entries): array
|
||||
@@ -136,128 +261,4 @@ trait ConvertsExchangeRates
|
||||
|
||||
return bcmul($amount, $rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $currencyId
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
private function getCurrency(int $currencyId): TransactionCurrency
|
||||
{
|
||||
$result = TransactionCurrency::find($currencyId);
|
||||
if (null === $result) {
|
||||
return app('amount')->getDefaultCurrency();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
* @param Carbon $date
|
||||
* @return string
|
||||
*/
|
||||
private function getEuroRate(TransactionCurrency $currency, Carbon $date): string
|
||||
{
|
||||
Log::debug(sprintf('Find rate for %s to Euro', $currency->code));
|
||||
$euro = TransactionCurrency::whereCode('EUR')->first();
|
||||
if (null === $euro) {
|
||||
app('log')->warning('Cannot do indirect conversion without EUR.');
|
||||
return '0';
|
||||
}
|
||||
|
||||
// try one way:
|
||||
/** @var CurrencyExchangeRate $result */
|
||||
$result = auth()->user()
|
||||
->currencyExchangeRates()
|
||||
->where('from_currency_id', $currency->id)
|
||||
->where('to_currency_id', $euro->id)
|
||||
->where('date', '<=', $date->format('Y-m-d'))
|
||||
->orderBy('date', 'DESC')
|
||||
->first();
|
||||
if (null !== $result) {
|
||||
$rate = (string)$result->rate;
|
||||
Log::debug(sprintf('Rate for %s to EUR is %s.', $currency->code, $rate));
|
||||
return $rate;
|
||||
}
|
||||
// try the other way around and inverse it.
|
||||
/** @var CurrencyExchangeRate $result */
|
||||
$result = auth()->user()
|
||||
->currencyExchangeRates()
|
||||
->where('from_currency_id', $euro->id)
|
||||
->where('to_currency_id', $currency->id)
|
||||
->where('date', '<=', $date->format('Y-m-d'))
|
||||
->orderBy('date', 'DESC')
|
||||
->first();
|
||||
if (null !== $result) {
|
||||
$rate = bcdiv('1', (string)$result->rate);
|
||||
Log::debug(sprintf('Inverted rate for %s to EUR is %s.', $currency->code, $rate));
|
||||
return $rate;
|
||||
}
|
||||
|
||||
Log::debug(sprintf('No rate for %s to EUR.', $currency->code));
|
||||
return '0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function getPreference(): void
|
||||
{
|
||||
$this->enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $from
|
||||
* @param TransactionCurrency $to
|
||||
* @param Carbon $date
|
||||
* @return string
|
||||
*/
|
||||
private function getRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string
|
||||
{
|
||||
Log::debug(sprintf('getRate(%s, %s, "%s")', $from->code, $to->code, $date->format('Y-m-d')));
|
||||
/** @var CurrencyExchangeRate $result */
|
||||
$result = auth()->user()
|
||||
->currencyExchangeRates()
|
||||
->where('from_currency_id', $from->id)
|
||||
->where('to_currency_id', $to->id)
|
||||
->where('date', '<=', $date->format('Y-m-d'))
|
||||
->orderBy('date', 'DESC')
|
||||
->first();
|
||||
if (null !== $result) {
|
||||
$rate = (string)$result->rate;
|
||||
Log::debug(sprintf('Rate is %s', $rate));
|
||||
return $rate;
|
||||
}
|
||||
// no result. perhaps the other way around?
|
||||
/** @var CurrencyExchangeRate $result */
|
||||
$result = auth()->user()
|
||||
->currencyExchangeRates()
|
||||
->where('from_currency_id', $to->id)
|
||||
->where('to_currency_id', $from->id)
|
||||
->where('date', '<=', $date->format('Y-m-d'))
|
||||
->orderBy('date', 'DESC')
|
||||
->first();
|
||||
if (null !== $result) {
|
||||
$rate = bcdiv('1', (string)$result->rate);
|
||||
Log::debug(sprintf('Reversed rate is %s', $rate));
|
||||
return $rate;
|
||||
}
|
||||
// try euro rates
|
||||
$result1 = $this->getEuroRate($from, $date);
|
||||
if ('0' === $result1) {
|
||||
Log::debug(sprintf('No exchange rate between EUR and %s', $from->code));
|
||||
return '0';
|
||||
}
|
||||
$result2 = $this->getEuroRate($to, $date);
|
||||
if ('0' === $result2) {
|
||||
Log::debug(sprintf('No exchange rate between EUR and %s', $to->code));
|
||||
return '0';
|
||||
}
|
||||
// still need to inverse rate 2:
|
||||
$result2 = bcdiv('1', $result2);
|
||||
$rate = bcmul($result1, $result2);
|
||||
Log::debug(sprintf('Rate %s to EUR is %s', $from->code, $result1));
|
||||
Log::debug(sprintf('Rate EUR to %s is %s', $to->code, $result2));
|
||||
Log::debug(sprintf('Rate for %s to %s is %s', $from->code, $to->code, $rate));
|
||||
return $rate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ trait TransactionFilter
|
||||
/**
|
||||
* All the types you can request.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -47,7 +47,7 @@ trait AugumentData
|
||||
/**
|
||||
* Searches for the opposing account.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -74,7 +74,7 @@ trait AugumentData
|
||||
/**
|
||||
* Small helper function for the revenue and expense account charts.
|
||||
*
|
||||
* @param array $names
|
||||
* @param array $names
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -91,7 +91,7 @@ trait AugumentData
|
||||
/**
|
||||
* Small helper function for the revenue and expense account charts.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -109,7 +109,7 @@ trait AugumentData
|
||||
/**
|
||||
* Get the account names belonging to a bunch of account ID's.
|
||||
*
|
||||
* @param array $accountIds
|
||||
* @param array $accountIds
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -135,7 +135,7 @@ trait AugumentData
|
||||
/**
|
||||
* Get the budget names from a set of budget ID's.
|
||||
*
|
||||
* @param array $budgetIds
|
||||
* @param array $budgetIds
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -159,7 +159,7 @@ trait AugumentData
|
||||
/**
|
||||
* Get the category names from a set of category ID's. Small helper function for some of the charts.
|
||||
*
|
||||
* @param array $categoryIds
|
||||
* @param array $categoryIds
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -185,9 +185,9 @@ trait AugumentData
|
||||
/**
|
||||
* Gets all budget limits for a budget.
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Budget $budget
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
@@ -233,7 +233,7 @@ trait AugumentData
|
||||
/**
|
||||
* Group set of transactions by name of opposing account.
|
||||
*
|
||||
* @param array $array
|
||||
* @param array $array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -261,10 +261,10 @@ trait AugumentData
|
||||
/**
|
||||
* Spent in a period.
|
||||
*
|
||||
* @param Collection $assets
|
||||
* @param Collection $opposing
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $assets
|
||||
* @param Collection $opposing
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -34,8 +34,8 @@ trait BasicDataSupport
|
||||
/**
|
||||
* Find the ID in a given array. Return '0' if not there (amount).
|
||||
*
|
||||
* @param array $array
|
||||
* @param int $entryId
|
||||
* @param array $array
|
||||
* @param int $entryId
|
||||
*
|
||||
* @return null|mixed
|
||||
*/
|
||||
@@ -47,8 +47,8 @@ trait BasicDataSupport
|
||||
/**
|
||||
* Find the ID in a given array. Return null if not there (amount).
|
||||
*
|
||||
* @param array $array
|
||||
* @param int $entryId
|
||||
* @param array $array
|
||||
* @param int $entryId
|
||||
*
|
||||
* @return null|Carbon
|
||||
*/
|
||||
|
||||
@@ -42,9 +42,9 @@ trait ChartGeneration
|
||||
/**
|
||||
* Shows an overview of the account balances for a set of accounts.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
|
||||
@@ -41,8 +41,8 @@ trait CreateStuff
|
||||
/**
|
||||
* Creates an asset account.
|
||||
*
|
||||
* @param NewUserFormRequest $request
|
||||
* @param TransactionCurrency $currency
|
||||
* @param NewUserFormRequest $request
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -71,8 +71,8 @@ trait CreateStuff
|
||||
/**
|
||||
* Creates a cash wallet.
|
||||
*
|
||||
* @param TransactionCurrency $currency
|
||||
* @param string $language
|
||||
* @param TransactionCurrency $currency
|
||||
* @param string $language
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -123,9 +123,9 @@ trait CreateStuff
|
||||
/**
|
||||
* Create a savings account.
|
||||
*
|
||||
* @param NewUserFormRequest $request
|
||||
* @param TransactionCurrency $currency
|
||||
* @param string $language
|
||||
* @param NewUserFormRequest $request
|
||||
* @param TransactionCurrency $currency
|
||||
* @param string $language
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -153,7 +153,7 @@ trait CreateStuff
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
|
||||
@@ -38,8 +38,8 @@ use Psr\Container\NotFoundExceptionInterface;
|
||||
trait CronRunner
|
||||
{
|
||||
/**
|
||||
* @param bool $force
|
||||
* @param Carbon $date
|
||||
* @param bool $force
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
@@ -71,8 +71,8 @@ trait CronRunner
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $force
|
||||
* @param Carbon $date
|
||||
* @param bool $force
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -102,8 +102,8 @@ trait CronRunner
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $force
|
||||
* @param Carbon $date
|
||||
* @param bool $force
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -133,8 +133,8 @@ trait CronRunner
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $force
|
||||
* @param Carbon $date
|
||||
* @param bool $force
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
|
||||
@@ -35,10 +35,11 @@ trait DateCalculation
|
||||
* Calculate the number of days passed left until end date, as seen from start date.
|
||||
* If today is between start and end, today will be used instead of end.
|
||||
*
|
||||
* If both are in the past OR both are in the future, simply return the number of days in the period with a minimum of 1
|
||||
* If both are in the past OR both are in the future, simply return the number of days in the period with a minimum
|
||||
* of 1
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@@ -59,8 +60,8 @@ trait DateCalculation
|
||||
*
|
||||
* If both are in the past OR both are in the future, simply return the period between them with a minimum of 1
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@@ -77,8 +78,8 @@ trait DateCalculation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -103,8 +104,8 @@ trait DateCalculation
|
||||
* Get a list of the periods that will occur after this date. For example,
|
||||
* March 2018, April 2018, etc.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param string $range
|
||||
* @param Carbon $date
|
||||
* @param string $range
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -139,8 +140,8 @@ trait DateCalculation
|
||||
* Get a list of the periods that occurred before the start date. For example,
|
||||
* March 2018, February 2018, etc.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param string $range
|
||||
* @param Carbon $date
|
||||
* @param string $range
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -38,7 +38,7 @@ trait GetConfigurationData
|
||||
/**
|
||||
* Some common combinations.
|
||||
*
|
||||
* @param int $value
|
||||
* @param int $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -60,7 +60,7 @@ trait GetConfigurationData
|
||||
/**
|
||||
* Get the basic steps from config.
|
||||
*
|
||||
* @param string $route
|
||||
* @param string $route
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -74,7 +74,7 @@ trait GetConfigurationData
|
||||
$currentStep = $options;
|
||||
|
||||
// get the text:
|
||||
$currentStep['intro'] = (string)trans('intro.'.$route.'_'.$key);
|
||||
$currentStep['intro'] = (string)trans('intro.' . $route . '_' . $key);
|
||||
|
||||
// save in array:
|
||||
$steps[] = $currentStep;
|
||||
@@ -183,8 +183,8 @@ trait GetConfigurationData
|
||||
/**
|
||||
* Get specific info for special routes.
|
||||
*
|
||||
* @param string $route
|
||||
* @param string $specificPage
|
||||
* @param string $route
|
||||
* @param string $specificPage
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
@@ -197,13 +197,13 @@ trait GetConfigurationData
|
||||
// user is on page with specific instructions:
|
||||
if ('' !== $specificPage) {
|
||||
$routeKey = str_replace('.', '_', $route);
|
||||
$elements = config(sprintf('intro.%s', $routeKey.'_'.$specificPage));
|
||||
$elements = config(sprintf('intro.%s', $routeKey . '_' . $specificPage));
|
||||
if (is_array($elements) && count($elements) > 0) {
|
||||
foreach ($elements as $key => $options) {
|
||||
$currentStep = $options;
|
||||
|
||||
// get the text:
|
||||
$currentStep['intro'] = (string)trans('intro.'.$route.'_'.$specificPage.'_'.$key);
|
||||
$currentStep['intro'] = (string)trans('intro.' . $route . '_' . $specificPage . '_' . $key);
|
||||
|
||||
// save in array:
|
||||
$steps[] = $currentStep;
|
||||
|
||||
@@ -42,7 +42,7 @@ trait ModelInformation
|
||||
/**
|
||||
* Get actions based on a bill.
|
||||
*
|
||||
* @param Bill $bill
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -109,7 +109,7 @@ trait ModelInformation
|
||||
/**
|
||||
* Create fake triggers to match the bill's properties
|
||||
*
|
||||
* @param Bill $bill
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -161,7 +161,7 @@ trait ModelInformation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
|
||||
@@ -74,9 +74,9 @@ trait PeriodOverview
|
||||
* and for each period, the amount of money spent and earned. This is a complex operation which is cached for
|
||||
* performance reasons.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -150,12 +150,122 @@ trait PeriodOverview
|
||||
return $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter a list of journals by a set of dates, and then group them by currency.
|
||||
*
|
||||
* @param array $array
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filterJournalsByDate(array $array, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$result = [];
|
||||
/** @var array $journal */
|
||||
foreach ($array as $journal) {
|
||||
if ($journal['date'] <= $end && $journal['date'] >= $start) {
|
||||
$result[] = $journal;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only transactions where $account is the source.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param array $journals
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filterTransferredAway(Account $account, array $journals): array
|
||||
{
|
||||
$return = [];
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
if ($account->id === (int)$journal['source_account_id']) {
|
||||
$return[] = $journal;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only transactions where $account is the source.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param array $journals
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filterTransferredIn(Account $account, array $journals): array
|
||||
{
|
||||
$return = [];
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
if ($account->id === (int)$journal['destination_account_id']) {
|
||||
$return[] = $journal;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $journals
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function groupByCurrency(array $journals): array
|
||||
{
|
||||
$return = [];
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$foreignCurrencyId = $journal['foreign_currency_id'];
|
||||
if (!array_key_exists($currencyId, $return)) {
|
||||
$return[$currencyId] = [
|
||||
'amount' => '0',
|
||||
'count' => 0,
|
||||
'currency_id' => $currencyId,
|
||||
'currency_name' => $journal['currency_name'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$currencyId]['amount'] = bcadd($return[$currencyId]['amount'], $journal['amount'] ?? '0');
|
||||
$return[$currencyId]['count']++;
|
||||
|
||||
if (null !== $foreignCurrencyId && null !== $journal['foreign_amount']) {
|
||||
if (!array_key_exists($foreignCurrencyId, $return)) {
|
||||
$return[$foreignCurrencyId] = [
|
||||
'amount' => '0',
|
||||
'count' => 0,
|
||||
'currency_id' => (int)$foreignCurrencyId,
|
||||
'currency_name' => $journal['foreign_currency_name'],
|
||||
'currency_code' => $journal['foreign_currency_code'],
|
||||
'currency_symbol' => $journal['foreign_currency_symbol'],
|
||||
'currency_decimal_places' => $journal['foreign_currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$foreignCurrencyId]['count']++;
|
||||
$return[$foreignCurrencyId]['amount'] = bcadd($return[$foreignCurrencyId]['amount'], $journal['foreign_amount']);
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overview for single category. Has been refactored recently.
|
||||
*
|
||||
* @param Category $category
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Category $category
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -234,8 +344,8 @@ trait PeriodOverview
|
||||
*
|
||||
* This method has been refactored recently.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -290,7 +400,7 @@ trait PeriodOverview
|
||||
*
|
||||
* Show period overview for no category view.
|
||||
*
|
||||
* @param Carbon $theDate
|
||||
* @param Carbon $theDate
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -360,9 +470,9 @@ trait PeriodOverview
|
||||
/**
|
||||
* This shows a period overview for a tag. It goes back in time and lists all relevant transactions and sums.
|
||||
*
|
||||
* @param Tag $tag
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Tag $tag
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -435,9 +545,9 @@ trait PeriodOverview
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $transactionType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param string $transactionType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -498,114 +608,4 @@ trait PeriodOverview
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter a list of journals by a set of dates, and then group them by currency.
|
||||
*
|
||||
* @param array $array
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filterJournalsByDate(array $array, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$result = [];
|
||||
/** @var array $journal */
|
||||
foreach ($array as $journal) {
|
||||
if ($journal['date'] <= $end && $journal['date'] >= $start) {
|
||||
$result[] = $journal;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only transactions where $account is the source.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param array $journals
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filterTransferredAway(Account $account, array $journals): array
|
||||
{
|
||||
$return = [];
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
if ($account->id === (int)$journal['source_account_id']) {
|
||||
$return[] = $journal;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only transactions where $account is the source.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param array $journals
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filterTransferredIn(Account $account, array $journals): array
|
||||
{
|
||||
$return = [];
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
if ($account->id === (int)$journal['destination_account_id']) {
|
||||
$return[] = $journal;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $journals
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function groupByCurrency(array $journals): array
|
||||
{
|
||||
$return = [];
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$foreignCurrencyId = $journal['foreign_currency_id'];
|
||||
if (!array_key_exists($currencyId, $return)) {
|
||||
$return[$currencyId] = [
|
||||
'amount' => '0',
|
||||
'count' => 0,
|
||||
'currency_id' => $currencyId,
|
||||
'currency_name' => $journal['currency_name'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$currencyId]['amount'] = bcadd($return[$currencyId]['amount'], $journal['amount'] ?? '0');
|
||||
$return[$currencyId]['count']++;
|
||||
|
||||
if (null !== $foreignCurrencyId && null !== $journal['foreign_amount']) {
|
||||
if (!array_key_exists($foreignCurrencyId, $return)) {
|
||||
$return[$foreignCurrencyId] = [
|
||||
'amount' => '0',
|
||||
'count' => 0,
|
||||
'currency_id' => (int)$foreignCurrencyId,
|
||||
'currency_name' => $journal['foreign_currency_name'],
|
||||
'currency_code' => $journal['foreign_currency_code'],
|
||||
'currency_symbol' => $journal['foreign_currency_symbol'],
|
||||
'currency_decimal_places' => $journal['foreign_currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$foreignCurrencyId]['count']++;
|
||||
$return[$foreignCurrencyId]['amount'] = bcadd($return[$foreignCurrencyId]['amount'], $journal['foreign_amount']);
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ trait RenderPartialViews
|
||||
/**
|
||||
* View for transactions in a budget for an account.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -104,7 +104,7 @@ trait RenderPartialViews
|
||||
/**
|
||||
* View for spent in a single budget.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -137,7 +137,7 @@ trait RenderPartialViews
|
||||
/**
|
||||
* View for transactions in a category.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -232,7 +232,7 @@ trait RenderPartialViews
|
||||
/**
|
||||
* Returns all the expenses that went to the given expense account.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -267,7 +267,7 @@ trait RenderPartialViews
|
||||
/**
|
||||
* Get current (from system) rule actions.
|
||||
*
|
||||
* @param Rule $rule
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -306,7 +306,7 @@ trait RenderPartialViews
|
||||
/**
|
||||
* Get current (from DB) rule triggers.
|
||||
*
|
||||
* @param Rule $rule
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -362,7 +362,7 @@ trait RenderPartialViews
|
||||
/**
|
||||
* Returns all the incomes that went to the given asset account.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
|
||||
@@ -59,28 +59,10 @@ trait RequestInformation
|
||||
return $parts['host'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
final protected function getPageName(): string // get request info
|
||||
{
|
||||
return str_replace('.', '_', RouteFacade::currentRouteName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specific name of a page for intro.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final protected function getSpecificPageName(): string // get request info
|
||||
{
|
||||
return null === RouteFacade::current()->parameter('objectType') ? '' : '_'.RouteFacade::current()->parameter('objectType');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of triggers.
|
||||
*
|
||||
* @param TestRuleFormRequest $request
|
||||
* @param TestRuleFormRequest $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -133,10 +115,28 @@ trait RequestInformation
|
||||
return $shownDemo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
final protected function getPageName(): string // get request info
|
||||
{
|
||||
return str_replace('.', '_', RouteFacade::currentRouteName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specific name of a page for intro.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final protected function getSpecificPageName(): string // get request info
|
||||
{
|
||||
return null === RouteFacade::current()->parameter('objectType') ? '' : '_' . RouteFacade::current()->parameter('objectType');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if date is outside session range.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
@@ -162,7 +162,7 @@ trait RequestInformation
|
||||
/**
|
||||
* Parses attributes from URL
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -192,9 +192,9 @@ trait RequestInformation
|
||||
/**
|
||||
* Validate users new password.
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $current
|
||||
* @param string $new
|
||||
* @param User $user
|
||||
* @param string $current
|
||||
* @param string $new
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
@@ -216,7 +216,7 @@ trait RequestInformation
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
*
|
||||
* @return ValidatorContract
|
||||
*/
|
||||
|
||||
@@ -37,7 +37,7 @@ use Throwable;
|
||||
trait RuleManagement
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Request $request
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -72,7 +72,7 @@ trait RuleManagement
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Request $request
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -119,7 +119,7 @@ trait RuleManagement
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $submittedOperators
|
||||
* @param array $submittedOperators
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
|
||||
@@ -37,10 +37,10 @@ trait TransactionCalculation
|
||||
/**
|
||||
* Get all expenses for a set of accounts.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Collection $opposing
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Collection $opposing
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -61,10 +61,10 @@ trait TransactionCalculation
|
||||
/**
|
||||
* Get all expenses by tags.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Collection $tags
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Collection $tags
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
@@ -83,10 +83,10 @@ trait TransactionCalculation
|
||||
/**
|
||||
* Helper function that collects expenses for the given budgets.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Collection $budgets
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Collection $budgets
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -103,10 +103,10 @@ trait TransactionCalculation
|
||||
/**
|
||||
* Get all expenses in a period for categories.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Collection $categories
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Collection $categories
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -127,10 +127,10 @@ trait TransactionCalculation
|
||||
/**
|
||||
* Get all income for a period and a bunch of categories.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Collection $categories
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Collection $categories
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -147,10 +147,10 @@ trait TransactionCalculation
|
||||
/**
|
||||
* Get the income for a set of accounts.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Collection $opposing
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Collection $opposing
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -167,10 +167,10 @@ trait TransactionCalculation
|
||||
/**
|
||||
* Get all income by tag.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Collection $tags
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Collection $tags
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -42,11 +42,12 @@ trait UserNavigation
|
||||
/**
|
||||
* Functionality:.
|
||||
*
|
||||
* - If the $identifier contains the word "delete" then a remembered url with the text "/show/" in it will not be returned but instead the index (/)
|
||||
* will be returned.
|
||||
* - If the remembered url contains "jscript/" the remembered url will not be returned but instead the index (/) will be returned.
|
||||
* - If the $identifier contains the word "delete" then a remembered url with the text "/show/" in it will not be
|
||||
* returned but instead the index (/) will be returned.
|
||||
* - If the remembered url contains "jscript/" the remembered url will not be returned but instead the index (/)
|
||||
* will be returned.
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -62,7 +63,7 @@ trait UserNavigation
|
||||
/**
|
||||
* Will return false if you cant edit this account type.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Account $account
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -75,7 +76,7 @@ trait UserNavigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionGroup $group
|
||||
* @param TransactionGroup $group
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -93,7 +94,7 @@ trait UserNavigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Account $account
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
@@ -128,7 +129,7 @@ trait UserNavigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionGroup $group
|
||||
* @param TransactionGroup $group
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
@@ -156,7 +157,7 @@ trait UserNavigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $identifier
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
|
||||
@@ -38,7 +38,7 @@ class AuditLogger
|
||||
/**
|
||||
* Customize the given logger instance.
|
||||
*
|
||||
* @param Logger $logger
|
||||
* @param Logger $logger
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
@@ -34,7 +34,7 @@ use Monolog\LogRecord;
|
||||
class AuditProcessor
|
||||
{
|
||||
/**
|
||||
* @param LogRecord $record
|
||||
* @param LogRecord $record
|
||||
*
|
||||
* @return LogRecord
|
||||
*/
|
||||
|
||||
@@ -36,9 +36,9 @@ use Psr\Container\NotFoundExceptionInterface;
|
||||
class Navigation
|
||||
{
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param string $repeatFreq
|
||||
* @param int $skip
|
||||
* @param Carbon $theDate
|
||||
* @param string $repeatFreq
|
||||
* @param int $skip
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
@@ -113,9 +113,9 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param string $range
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param string $range
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
@@ -174,8 +174,73 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $end
|
||||
* @param string $repeatFreq
|
||||
* @param Carbon $theDate
|
||||
* @param string $repeatFreq
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
public function startOfPeriod(Carbon $theDate, string $repeatFreq): Carbon
|
||||
{
|
||||
$date = clone $theDate;
|
||||
|
||||
$functionMap = [
|
||||
'1D' => 'startOfDay',
|
||||
'daily' => 'startOfDay',
|
||||
'1W' => 'startOfWeek',
|
||||
'week' => 'startOfWeek',
|
||||
'weekly' => 'startOfWeek',
|
||||
'month' => 'startOfMonth',
|
||||
'1M' => 'startOfMonth',
|
||||
'monthly' => 'startOfMonth',
|
||||
'3M' => 'firstOfQuarter',
|
||||
'quarter' => 'firstOfQuarter',
|
||||
'quarterly' => 'firstOfQuarter',
|
||||
'year' => 'startOfYear',
|
||||
'yearly' => 'startOfYear',
|
||||
'1Y' => 'startOfYear',
|
||||
];
|
||||
if (array_key_exists($repeatFreq, $functionMap)) {
|
||||
$function = $functionMap[$repeatFreq];
|
||||
$date->$function();
|
||||
|
||||
return $date;
|
||||
}
|
||||
if ('half-year' === $repeatFreq || '6M' === $repeatFreq) {
|
||||
$month = $date->month;
|
||||
$date->startOfYear();
|
||||
if ($month >= 7) {
|
||||
$date->addMonths(6);
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
$result = match ($repeatFreq) {
|
||||
'last7' => $date->subDays(7)->startOfDay(),
|
||||
'last30' => $date->subDays(30)->startOfDay(),
|
||||
'last90' => $date->subDays(90)->startOfDay(),
|
||||
'last365' => $date->subDays(365)->startOfDay(),
|
||||
'MTD' => $date->startOfMonth()->startOfDay(),
|
||||
'QTD' => $date->firstOfQuarter()->startOfDay(),
|
||||
'YTD' => $date->startOfYear()->startOfDay(),
|
||||
default => null,
|
||||
};
|
||||
if (null !== $result) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
if ('custom' === $repeatFreq) {
|
||||
return $date; // the date is already at the start.
|
||||
}
|
||||
Log::error(sprintf('Cannot do startOfPeriod for $repeat_freq "%s"', $repeatFreq));
|
||||
|
||||
return $theDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $end
|
||||
* @param string $repeatFreq
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
@@ -269,9 +334,9 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theCurrentEnd
|
||||
* @param string $repeatFreq
|
||||
* @param Carbon|null $maxDate
|
||||
* @param Carbon $theCurrentEnd
|
||||
* @param string $repeatFreq
|
||||
* @param Carbon|null $maxDate
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
@@ -311,7 +376,8 @@ class Navigation
|
||||
/**
|
||||
* Returns the user's view range and if necessary, corrects the dynamic view
|
||||
* range to a normal range.
|
||||
* @param bool $correct
|
||||
*
|
||||
* @param bool $correct
|
||||
* @return string
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
@@ -340,8 +406,8 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -377,8 +443,31 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param string $repeatFrequency
|
||||
* If the date difference between start and end is less than a month, method returns "Y-m-d". If the difference is
|
||||
* less than a year, method returns "Y-m". If the date difference is larger, method returns "Y".
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function preferredCarbonFormat(Carbon $start, Carbon $end): string
|
||||
{
|
||||
$format = 'Y-m-d';
|
||||
if ($start->diffInMonths($end) > 1) {
|
||||
$format = 'Y-m';
|
||||
}
|
||||
|
||||
if ($start->diffInMonths($end) > 12) {
|
||||
$format = 'Y';
|
||||
}
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param string $repeatFrequency
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -417,34 +506,12 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* If the date difference between start and end is less than a month, method returns "Y-m-d". If the difference is less than a year,
|
||||
* method returns "Y-m". If the date difference is larger, method returns "Y".
|
||||
* If the date difference between start and end is less than a month, method returns trans(config.month_and_day).
|
||||
* If the difference is less than a year, method returns "config.month". If the date difference is larger, method
|
||||
* returns "config.year".
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function preferredCarbonFormat(Carbon $start, Carbon $end): string
|
||||
{
|
||||
$format = 'Y-m-d';
|
||||
if ($start->diffInMonths($end) > 1) {
|
||||
$format = 'Y-m';
|
||||
}
|
||||
|
||||
if ($start->diffInMonths($end) > 12) {
|
||||
$format = 'Y';
|
||||
}
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the date difference between start and end is less than a month, method returns trans(config.month_and_day). If the difference is less than a year,
|
||||
* method returns "config.month". If the date difference is larger, method returns "config.year".
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -464,11 +531,11 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* If the date difference between start and end is less than a month, method returns "endOfDay". If the difference is less than a year,
|
||||
* method returns "endOfMonth". If the date difference is larger, method returns "endOfYear".
|
||||
* If the date difference between start and end is less than a month, method returns "endOfDay". If the difference
|
||||
* is less than a year, method returns "endOfMonth". If the date difference is larger, method returns "endOfYear".
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -487,11 +554,11 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* If the date difference between start and end is less than a month, method returns "1D". If the difference is less than a year,
|
||||
* method returns "1M". If the date difference is larger, method returns "1Y".
|
||||
* If the date difference between start and end is less than a month, method returns "1D". If the difference is
|
||||
* less than a year, method returns "1M". If the date difference is larger, method returns "1Y".
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -510,11 +577,11 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* If the date difference between start and end is less than a month, method returns "%Y-%m-%d". If the difference is less than a year,
|
||||
* method returns "%Y-%m". If the date difference is larger, method returns "%Y".
|
||||
* If the date difference between start and end is less than a month, method returns "%Y-%m-%d". If the difference
|
||||
* is less than a year, method returns "%Y-%m". If the date difference is larger, method returns "%Y".
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -533,74 +600,9 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param string $repeatFreq
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
public function startOfPeriod(Carbon $theDate, string $repeatFreq): Carbon
|
||||
{
|
||||
$date = clone $theDate;
|
||||
|
||||
$functionMap = [
|
||||
'1D' => 'startOfDay',
|
||||
'daily' => 'startOfDay',
|
||||
'1W' => 'startOfWeek',
|
||||
'week' => 'startOfWeek',
|
||||
'weekly' => 'startOfWeek',
|
||||
'month' => 'startOfMonth',
|
||||
'1M' => 'startOfMonth',
|
||||
'monthly' => 'startOfMonth',
|
||||
'3M' => 'firstOfQuarter',
|
||||
'quarter' => 'firstOfQuarter',
|
||||
'quarterly' => 'firstOfQuarter',
|
||||
'year' => 'startOfYear',
|
||||
'yearly' => 'startOfYear',
|
||||
'1Y' => 'startOfYear',
|
||||
];
|
||||
if (array_key_exists($repeatFreq, $functionMap)) {
|
||||
$function = $functionMap[$repeatFreq];
|
||||
$date->$function();
|
||||
|
||||
return $date;
|
||||
}
|
||||
if ('half-year' === $repeatFreq || '6M' === $repeatFreq) {
|
||||
$month = $date->month;
|
||||
$date->startOfYear();
|
||||
if ($month >= 7) {
|
||||
$date->addMonths(6);
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
$result = match ($repeatFreq) {
|
||||
'last7' => $date->subDays(7)->startOfDay(),
|
||||
'last30' => $date->subDays(30)->startOfDay(),
|
||||
'last90' => $date->subDays(90)->startOfDay(),
|
||||
'last365' => $date->subDays(365)->startOfDay(),
|
||||
'MTD' => $date->startOfMonth()->startOfDay(),
|
||||
'QTD' => $date->firstOfQuarter()->startOfDay(),
|
||||
'YTD' => $date->startOfYear()->startOfDay(),
|
||||
default => null,
|
||||
};
|
||||
if (null !== $result) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
if ('custom' === $repeatFreq) {
|
||||
return $date; // the date is already at the start.
|
||||
}
|
||||
Log::error(sprintf('Cannot do startOfPeriod for $repeat_freq "%s"', $repeatFreq));
|
||||
|
||||
return $theDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param string $repeatFreq
|
||||
* @param int|null $subtract
|
||||
* @param Carbon $theDate
|
||||
* @param string $repeatFreq
|
||||
* @param int|null $subtract
|
||||
*
|
||||
* @return Carbon
|
||||
*
|
||||
@@ -687,8 +689,8 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $range
|
||||
* @param Carbon $start
|
||||
* @param string $range
|
||||
* @param Carbon $start
|
||||
*
|
||||
* @return Carbon
|
||||
*
|
||||
@@ -750,8 +752,8 @@ class Navigation
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $range
|
||||
* @param Carbon $start
|
||||
* @param string $range
|
||||
* @param Carbon $start
|
||||
*
|
||||
* @return Carbon
|
||||
*
|
||||
|
||||
@@ -37,8 +37,8 @@ class NullArrayObject extends ArrayObject
|
||||
/**
|
||||
* NullArrayObject constructor.
|
||||
*
|
||||
* @param array $array
|
||||
* @param null $default
|
||||
* @param array $array
|
||||
* @param null $default
|
||||
*/
|
||||
/* @phpstan-ignore-next-line */
|
||||
public function __construct(array $array, $default = null)
|
||||
@@ -48,7 +48,7 @@ class NullArrayObject extends ArrayObject
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @param mixed $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
@@ -49,7 +49,7 @@ class ParseDateString
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -73,7 +73,7 @@ class ParseDateString
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
* @param string $date
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws FireflyException
|
||||
@@ -122,184 +122,7 @@ class ParseDateString
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function parseRange(string $date): array
|
||||
{
|
||||
// several types of range can be submitted
|
||||
$result = [
|
||||
'exact' => new Carbon('1984-09-17'),
|
||||
];
|
||||
switch (true) {
|
||||
default:
|
||||
break;
|
||||
case $this->isDayRange($date):
|
||||
$result = $this->parseDayRange($date);
|
||||
break;
|
||||
case $this->isMonthRange($date):
|
||||
$result = $this->parseMonthRange($date);
|
||||
break;
|
||||
case $this->isYearRange($date):
|
||||
$result = $this->parseYearRange($date);
|
||||
break;
|
||||
case $this->isMonthDayRange($date):
|
||||
$result = $this->parseMonthDayRange($date);
|
||||
break;
|
||||
case $this->isDayYearRange($date):
|
||||
$result = $this->parseDayYearRange($date);
|
||||
break;
|
||||
case $this->isMonthYearRange($date):
|
||||
$result = $this->parseMonthYearRange($date);
|
||||
break;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isDayRange(string $date): bool
|
||||
{
|
||||
// if regex for xxxx-xx-DD:
|
||||
$pattern = '/^xxxx-xx-(0[1-9]|[12]\d|3[01])$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a day range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a day range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isDayYearRange(string $date): bool
|
||||
{
|
||||
// if regex for YYYY-xx-DD:
|
||||
$pattern = '/^(19|20)\d\d-xx-(0[1-9]|[12]\d|3[01])$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a day/year range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a day/year range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isMonthDayRange(string $date): bool
|
||||
{
|
||||
// if regex for xxxx-MM-DD:
|
||||
$pattern = '/^xxxx-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a month/day range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a month/day range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isMonthRange(string $date): bool
|
||||
{
|
||||
// if regex for xxxx-MM-xx:
|
||||
$pattern = '/^xxxx-(0[1-9]|1[012])-xx$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a month range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a month range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isMonthYearRange(string $date): bool
|
||||
{
|
||||
// if regex for YYYY-MM-xx:
|
||||
$pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-xx$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a month/year range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a month/year range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isYearRange(string $date): bool
|
||||
{
|
||||
// if regex for YYYY-xx-xx:
|
||||
$pattern = '/^(19|20)\d\d-xx-xx$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a year range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a year range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* format of string is xxxx-xx-DD
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parseDayRange(string $date): array
|
||||
{
|
||||
$parts = explode('-', $date);
|
||||
|
||||
return [
|
||||
'day' => $parts[2],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
protected function parseDefaultDate(string $date): Carbon
|
||||
{
|
||||
return Carbon::createFromFormat('Y-m-d', $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $keyword
|
||||
* @param string $keyword
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
@@ -323,42 +146,17 @@ class ParseDateString
|
||||
}
|
||||
|
||||
/**
|
||||
* format of string is xxxx-MM-xx
|
||||
* @param string $date
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return array
|
||||
* @return Carbon
|
||||
*/
|
||||
protected function parseMonthRange(string $date): array
|
||||
protected function parseDefaultDate(string $date): Carbon
|
||||
{
|
||||
Log::debug(sprintf('parseMonthRange: Parsed "%s".', $date));
|
||||
$parts = explode('-', $date);
|
||||
|
||||
return [
|
||||
'month' => $parts[1],
|
||||
];
|
||||
return Carbon::createFromFormat('Y-m-d', $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* format of string is YYYY-MM-xx
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parseMonthYearRange(string $date): array
|
||||
{
|
||||
Log::debug(sprintf('parseMonthYearRange: Parsed "%s".', $date));
|
||||
$parts = explode('-', $date);
|
||||
|
||||
return [
|
||||
'year' => $parts[0],
|
||||
'month' => $parts[1],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
* @param string $date
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
@@ -411,10 +209,137 @@ class ParseDateString
|
||||
return $today;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function parseRange(string $date): array
|
||||
{
|
||||
// several types of range can be submitted
|
||||
$result = [
|
||||
'exact' => new Carbon('1984-09-17'),
|
||||
];
|
||||
switch (true) {
|
||||
default:
|
||||
break;
|
||||
case $this->isDayRange($date):
|
||||
$result = $this->parseDayRange($date);
|
||||
break;
|
||||
case $this->isMonthRange($date):
|
||||
$result = $this->parseMonthRange($date);
|
||||
break;
|
||||
case $this->isYearRange($date):
|
||||
$result = $this->parseYearRange($date);
|
||||
break;
|
||||
case $this->isMonthDayRange($date):
|
||||
$result = $this->parseMonthDayRange($date);
|
||||
break;
|
||||
case $this->isDayYearRange($date):
|
||||
$result = $this->parseDayYearRange($date);
|
||||
break;
|
||||
case $this->isMonthYearRange($date):
|
||||
$result = $this->parseMonthYearRange($date);
|
||||
break;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isDayRange(string $date): bool
|
||||
{
|
||||
// if regex for xxxx-xx-DD:
|
||||
$pattern = '/^xxxx-xx-(0[1-9]|[12]\d|3[01])$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a day range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a day range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* format of string is xxxx-xx-DD
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parseDayRange(string $date): array
|
||||
{
|
||||
$parts = explode('-', $date);
|
||||
|
||||
return [
|
||||
'day' => $parts[2],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isMonthRange(string $date): bool
|
||||
{
|
||||
// if regex for xxxx-MM-xx:
|
||||
$pattern = '/^xxxx-(0[1-9]|1[012])-xx$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a month range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a month range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* format of string is xxxx-MM-xx
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parseMonthRange(string $date): array
|
||||
{
|
||||
Log::debug(sprintf('parseMonthRange: Parsed "%s".', $date));
|
||||
$parts = explode('-', $date);
|
||||
|
||||
return [
|
||||
'month' => $parts[1],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isYearRange(string $date): bool
|
||||
{
|
||||
// if regex for YYYY-xx-xx:
|
||||
$pattern = '/^(19|20)\d\d-xx-xx$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a year range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a year range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* format of string is YYYY-xx-xx
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -428,10 +353,66 @@ class ParseDateString
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isMonthDayRange(string $date): bool
|
||||
{
|
||||
// if regex for xxxx-MM-DD:
|
||||
$pattern = '/^xxxx-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a month/day range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a month/day range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* format of string is xxxx-MM-DD
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseMonthDayRange(string $date): array
|
||||
{
|
||||
Log::debug(sprintf('parseMonthDayRange: Parsed "%s".', $date));
|
||||
$parts = explode('-', $date);
|
||||
|
||||
return [
|
||||
'month' => $parts[1],
|
||||
'day' => $parts[2],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isDayYearRange(string $date): bool
|
||||
{
|
||||
// if regex for YYYY-xx-DD:
|
||||
$pattern = '/^(19|20)\d\d-xx-(0[1-9]|[12]\d|3[01])$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a day/year range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a day/year range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* format of string is YYYY-xx-DD
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -447,20 +428,39 @@ class ParseDateString
|
||||
}
|
||||
|
||||
/**
|
||||
* format of string is xxxx-MM-DD
|
||||
* @param string $date
|
||||
*
|
||||
* @param string $date
|
||||
* @return bool
|
||||
*/
|
||||
protected function isMonthYearRange(string $date): bool
|
||||
{
|
||||
// if regex for YYYY-MM-xx:
|
||||
$pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-xx$/';
|
||||
if (preg_match($pattern, $date)) {
|
||||
Log::debug(sprintf('"%s" is a month/year range.', $date));
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('"%s" is not a month/year range.', $date));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* format of string is YYYY-MM-xx
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseMonthDayRange(string $date): array
|
||||
protected function parseMonthYearRange(string $date): array
|
||||
{
|
||||
Log::debug(sprintf('parseMonthDayRange: Parsed "%s".', $date));
|
||||
Log::debug(sprintf('parseMonthYearRange: Parsed "%s".', $date));
|
||||
$parts = explode('-', $date);
|
||||
|
||||
return [
|
||||
'year' => $parts[0],
|
||||
'month' => $parts[1],
|
||||
'day' => $parts[2],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,57 +52,8 @@ class Preferences
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param string $search
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function beginsWith(User $user, string $search): Collection
|
||||
{
|
||||
return Preference::where('user_id', $user->id)->where('name', 'LIKE', $search.'%')->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function delete(string $name): bool
|
||||
{
|
||||
$fullName = sprintf('preference%s%s', auth()->user()->id, $name);
|
||||
if (Cache::has($fullName)) {
|
||||
Cache::forget($fullName);
|
||||
}
|
||||
Preference::where('user_id', auth()->user()->id)->where('name', $name)->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function findByName(string $name): Collection
|
||||
{
|
||||
return Preference::where('name', $name)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param string $name
|
||||
*/
|
||||
public function forget(User $user, string $name): void
|
||||
{
|
||||
$key = sprintf('preference%s%s', $user->id, $name);
|
||||
Cache::forget($key);
|
||||
Cache::put($key, '', 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return Preference|null
|
||||
* @throws FireflyException
|
||||
@@ -122,32 +73,9 @@ class Preferences
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param array $list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getArrayForUser(User $user, array $list): array
|
||||
{
|
||||
$result = [];
|
||||
$preferences = Preference::where('user_id', $user->id)->whereIn('name', $list)->get(['id', 'name', 'data']);
|
||||
/** @var Preference $preference */
|
||||
foreach ($preferences as $preference) {
|
||||
$result[$preference->name] = $preference->data;
|
||||
}
|
||||
foreach ($list as $name) {
|
||||
if (!array_key_exists($name, $result)) {
|
||||
$result[$name] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param string $name
|
||||
* @param null|string|int $default
|
||||
* @param User $user
|
||||
* @param string $name
|
||||
* @param null|string|int $default
|
||||
*
|
||||
* @return Preference|null
|
||||
* @throws FireflyException
|
||||
@@ -173,8 +101,119 @@ class Preferences
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function delete(string $name): bool
|
||||
{
|
||||
$fullName = sprintf('preference%s%s', auth()->user()->id, $name);
|
||||
if (Cache::has($fullName)) {
|
||||
Cache::forget($fullName);
|
||||
}
|
||||
Preference::where('user_id', auth()->user()->id)->where('name', $name)->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param string $name
|
||||
*/
|
||||
public function forget(User $user, string $name): void
|
||||
{
|
||||
$key = sprintf('preference%s%s', $user->id, $name);
|
||||
Cache::forget($key);
|
||||
Cache::put($key, '', 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Preference
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function setForUser(User $user, string $name, $value): Preference
|
||||
{
|
||||
$fullName = sprintf('preference%s%s', $user->id, $name);
|
||||
Cache::forget($fullName);
|
||||
/** @var Preference|null $pref */
|
||||
$pref = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']);
|
||||
|
||||
if (null !== $pref && null === $value) {
|
||||
$pref->delete();
|
||||
|
||||
return new Preference();
|
||||
}
|
||||
if (null === $value) {
|
||||
return new Preference();
|
||||
}
|
||||
if (null === $pref) {
|
||||
$pref = new Preference();
|
||||
$pref->user_id = $user->id;
|
||||
$pref->name = $name;
|
||||
}
|
||||
$pref->data = $value;
|
||||
try {
|
||||
$pref->save();
|
||||
} catch (PDOException $e) {
|
||||
throw new FireflyException(sprintf('Could not save preference: %s', $e->getMessage()), 0, $e);
|
||||
}
|
||||
Cache::forever($fullName, $pref);
|
||||
|
||||
return $pref;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param string $search
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function beginsWith(User $user, string $search): Collection
|
||||
{
|
||||
return Preference::where('user_id', $user->id)->where('name', 'LIKE', $search . '%')->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function findByName(string $name): Collection
|
||||
{
|
||||
return Preference::where('name', $name)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param array $list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getArrayForUser(User $user, array $list): array
|
||||
{
|
||||
$result = [];
|
||||
$preferences = Preference::where('user_id', $user->id)->whereIn('name', $list)->get(['id', 'name', 'data']);
|
||||
/** @var Preference $preference */
|
||||
foreach ($preferences as $preference) {
|
||||
$result[$preference->name] = $preference->data;
|
||||
}
|
||||
foreach ($list as $name) {
|
||||
if (!array_key_exists($name, $result)) {
|
||||
$result[$name] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return Preference|null
|
||||
* @throws FireflyException
|
||||
@@ -194,9 +233,9 @@ class Preferences
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param string $name
|
||||
* @param null $default
|
||||
* @param User $user
|
||||
* @param string $name
|
||||
* @param null $default
|
||||
*
|
||||
* @return Preference|null
|
||||
* TODO remove me.
|
||||
@@ -236,8 +275,8 @@ class Preferences
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Preference
|
||||
* @throws FireflyException
|
||||
@@ -256,43 +295,4 @@ class Preferences
|
||||
|
||||
return $this->setForUser(auth()->user(), $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Preference
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function setForUser(User $user, string $name, $value): Preference
|
||||
{
|
||||
$fullName = sprintf('preference%s%s', $user->id, $name);
|
||||
Cache::forget($fullName);
|
||||
/** @var Preference|null $pref */
|
||||
$pref = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']);
|
||||
|
||||
if (null !== $pref && null === $value) {
|
||||
$pref->delete();
|
||||
|
||||
return new Preference();
|
||||
}
|
||||
if (null === $value) {
|
||||
return new Preference();
|
||||
}
|
||||
if (null === $pref) {
|
||||
$pref = new Preference();
|
||||
$pref->user_id = $user->id;
|
||||
$pref->name = $name;
|
||||
}
|
||||
$pref->data = $value;
|
||||
try {
|
||||
$pref->save();
|
||||
} catch (PDOException $e) {
|
||||
throw new FireflyException(sprintf('Could not save preference: %s', $e->getMessage()), 0, $e);
|
||||
}
|
||||
Cache::forever($fullName, $pref);
|
||||
|
||||
return $pref;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,48 @@ class BudgetReportGenerator
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process each row of expenses collected for the "Account per budget" partial
|
||||
*
|
||||
* @param array $expenses
|
||||
*/
|
||||
private function processExpenses(array $expenses): void
|
||||
{
|
||||
foreach ($expenses['budgets'] as $budget) {
|
||||
$this->processBudgetExpenses($expenses, $budget);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process each set of transactions for each row of expenses.
|
||||
*
|
||||
* @param array $expenses
|
||||
* @param array $budget
|
||||
*/
|
||||
private function processBudgetExpenses(array $expenses, array $budget): void
|
||||
{
|
||||
$budgetId = (int)$budget['id'];
|
||||
$currencyId = (int)$expenses['currency_id'];
|
||||
foreach ($budget['transaction_journals'] as $journal) {
|
||||
$sourceAccountId = $journal['source_account_id'];
|
||||
|
||||
$this->report[$sourceAccountId]['currencies'][$currencyId]
|
||||
= $this->report[$sourceAccountId]['currencies'][$currencyId] ?? [
|
||||
'currency_id' => $expenses['currency_id'],
|
||||
'currency_symbol' => $expenses['currency_symbol'],
|
||||
'currency_name' => $expenses['currency_name'],
|
||||
'currency_decimal_places' => $expenses['currency_decimal_places'],
|
||||
'budgets' => [],
|
||||
];
|
||||
|
||||
$this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId]
|
||||
= $this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId] ?? '0';
|
||||
|
||||
$this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId]
|
||||
= bcadd($this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId], $journal['amount']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the data necessary to create the card that displays
|
||||
* the budget overview in the general report.
|
||||
@@ -107,60 +149,6 @@ class BudgetReportGenerator
|
||||
$this->percentageReport();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getReport(): array
|
||||
{
|
||||
return $this->report;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
*/
|
||||
public function setAccounts(Collection $accounts): void
|
||||
{
|
||||
$this->accounts = $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
*/
|
||||
public function setBudgets(Collection $budgets): void
|
||||
{
|
||||
$this->budgets = $budgets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $end
|
||||
*/
|
||||
public function setEnd(Carbon $end): void
|
||||
{
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
*/
|
||||
public function setStart(Carbon $start): void
|
||||
{
|
||||
$this->start = $start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @throws FireflyException
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->repository->setUser($user);
|
||||
$this->blRepository->setUser($user);
|
||||
$this->opsRepository->setUser($user);
|
||||
$this->nbRepository->setUser($user);
|
||||
$this->currency = app('amount')->getDefaultCurrencyByUser($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the budgets block on the default report by processing every budget.
|
||||
*/
|
||||
@@ -173,6 +161,82 @@ class BudgetReportGenerator
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process expenses etc. for a single budget for the budgets block on the default report.
|
||||
*
|
||||
* @param Budget $budget
|
||||
*/
|
||||
private function processBudget(Budget $budget): void
|
||||
{
|
||||
$budgetId = (int)$budget->id;
|
||||
$this->report['budgets'][$budgetId] = $this->report['budgets'][$budgetId] ?? [
|
||||
'budget_id' => $budgetId,
|
||||
'budget_name' => $budget->name,
|
||||
'no_budget' => false,
|
||||
'budget_limits' => [],
|
||||
];
|
||||
|
||||
// get all budget limits for budget in period:
|
||||
$limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end);
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($limits as $limit) {
|
||||
$this->processLimit($budget, $limit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a single budget limit for the budgets block on the default report.
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param BudgetLimit $limit
|
||||
*/
|
||||
private function processLimit(Budget $budget, BudgetLimit $limit): void
|
||||
{
|
||||
$budgetId = (int)$budget->id;
|
||||
$limitId = (int)$limit->id;
|
||||
$limitCurrency = $limit->transactionCurrency ?? $this->currency;
|
||||
$currencyId = (int)$limitCurrency->id;
|
||||
$expenses = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, $this->accounts, new Collection([$budget]));
|
||||
$spent = $expenses[$currencyId]['sum'] ?? '0';
|
||||
$left = -1 === bccomp(bcadd($limit->amount, $spent), '0') ? '0' : bcadd($limit->amount, $spent);
|
||||
$overspent = 1 === bccomp(bcmul($spent, '-1'), $limit->amount) ? bcadd($spent, $limit->amount) : '0';
|
||||
|
||||
$this->report['budgets'][$budgetId]['budget_limits'][$limitId] = $this->report['budgets'][$budgetId]['budget_limits'][$limitId] ?? [
|
||||
'budget_limit_id' => $limitId,
|
||||
'start_date' => $limit->start_date,
|
||||
'end_date' => $limit->end_date,
|
||||
'budgeted' => $limit->amount,
|
||||
'budgeted_pct' => '0',
|
||||
'spent' => $spent,
|
||||
'spent_pct' => '0',
|
||||
'left' => $left,
|
||||
'overspent' => $overspent,
|
||||
'currency_id' => $currencyId,
|
||||
'currency_code' => $limitCurrency->code,
|
||||
'currency_name' => $limitCurrency->name,
|
||||
'currency_symbol' => $limitCurrency->symbol,
|
||||
'currency_decimal_places' => $limitCurrency->decimal_places,
|
||||
];
|
||||
|
||||
// make sum information:
|
||||
$this->report['sums'][$currencyId]
|
||||
= $this->report['sums'][$currencyId] ?? [
|
||||
'budgeted' => '0',
|
||||
'spent' => '0',
|
||||
'left' => '0',
|
||||
'overspent' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_code' => $limitCurrency->code,
|
||||
'currency_name' => $limitCurrency->name,
|
||||
'currency_symbol' => $limitCurrency->symbol,
|
||||
'currency_decimal_places' => $limitCurrency->decimal_places,
|
||||
];
|
||||
$this->report['sums'][$currencyId]['budgeted'] = bcadd($this->report['sums'][$currencyId]['budgeted'], $limit->amount);
|
||||
$this->report['sums'][$currencyId]['spent'] = bcadd($this->report['sums'][$currencyId]['spent'], $spent);
|
||||
$this->report['sums'][$currencyId]['left'] = bcadd($this->report['sums'][$currencyId]['left'], bcadd($limit->amount, $spent));
|
||||
$this->report['sums'][$currencyId]['overspent'] = bcadd($this->report['sums'][$currencyId]['overspent'], $overspent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the expenses for transactions without a budget. Part of the "budgets" block of the default report.
|
||||
*/
|
||||
@@ -258,120 +322,56 @@ class BudgetReportGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* Process expenses etc. for a single budget for the budgets block on the default report.
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @return array
|
||||
*/
|
||||
private function processBudget(Budget $budget): void
|
||||
public function getReport(): array
|
||||
{
|
||||
$budgetId = (int)$budget->id;
|
||||
$this->report['budgets'][$budgetId] = $this->report['budgets'][$budgetId] ?? [
|
||||
'budget_id' => $budgetId,
|
||||
'budget_name' => $budget->name,
|
||||
'no_budget' => false,
|
||||
'budget_limits' => [],
|
||||
];
|
||||
|
||||
// get all budget limits for budget in period:
|
||||
$limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end);
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($limits as $limit) {
|
||||
$this->processLimit($budget, $limit);
|
||||
}
|
||||
return $this->report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process each set of transactions for each row of expenses.
|
||||
*
|
||||
* @param array $expenses
|
||||
* @param array $budget
|
||||
* @param Collection $accounts
|
||||
*/
|
||||
private function processBudgetExpenses(array $expenses, array $budget): void
|
||||
public function setAccounts(Collection $accounts): void
|
||||
{
|
||||
$budgetId = (int)$budget['id'];
|
||||
$currencyId = (int)$expenses['currency_id'];
|
||||
foreach ($budget['transaction_journals'] as $journal) {
|
||||
$sourceAccountId = $journal['source_account_id'];
|
||||
|
||||
$this->report[$sourceAccountId]['currencies'][$currencyId]
|
||||
= $this->report[$sourceAccountId]['currencies'][$currencyId] ?? [
|
||||
'currency_id' => $expenses['currency_id'],
|
||||
'currency_symbol' => $expenses['currency_symbol'],
|
||||
'currency_name' => $expenses['currency_name'],
|
||||
'currency_decimal_places' => $expenses['currency_decimal_places'],
|
||||
'budgets' => [],
|
||||
];
|
||||
|
||||
$this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId]
|
||||
= $this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId] ?? '0';
|
||||
|
||||
$this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId]
|
||||
= bcadd($this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId], $journal['amount']);
|
||||
}
|
||||
$this->accounts = $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process each row of expenses collected for the "Account per budget" partial
|
||||
*
|
||||
* @param array $expenses
|
||||
* @param Collection $budgets
|
||||
*/
|
||||
private function processExpenses(array $expenses): void
|
||||
public function setBudgets(Collection $budgets): void
|
||||
{
|
||||
foreach ($expenses['budgets'] as $budget) {
|
||||
$this->processBudgetExpenses($expenses, $budget);
|
||||
}
|
||||
$this->budgets = $budgets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a single budget limit for the budgets block on the default report.
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param BudgetLimit $limit
|
||||
* @param Carbon $end
|
||||
*/
|
||||
private function processLimit(Budget $budget, BudgetLimit $limit): void
|
||||
public function setEnd(Carbon $end): void
|
||||
{
|
||||
$budgetId = (int)$budget->id;
|
||||
$limitId = (int)$limit->id;
|
||||
$limitCurrency = $limit->transactionCurrency ?? $this->currency;
|
||||
$currencyId = (int)$limitCurrency->id;
|
||||
$expenses = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, $this->accounts, new Collection([$budget]));
|
||||
$spent = $expenses[$currencyId]['sum'] ?? '0';
|
||||
$left = -1 === bccomp(bcadd($limit->amount, $spent), '0') ? '0' : bcadd($limit->amount, $spent);
|
||||
$overspent = 1 === bccomp(bcmul($spent, '-1'), $limit->amount) ? bcadd($spent, $limit->amount) : '0';
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
$this->report['budgets'][$budgetId]['budget_limits'][$limitId] = $this->report['budgets'][$budgetId]['budget_limits'][$limitId] ?? [
|
||||
'budget_limit_id' => $limitId,
|
||||
'start_date' => $limit->start_date,
|
||||
'end_date' => $limit->end_date,
|
||||
'budgeted' => $limit->amount,
|
||||
'budgeted_pct' => '0',
|
||||
'spent' => $spent,
|
||||
'spent_pct' => '0',
|
||||
'left' => $left,
|
||||
'overspent' => $overspent,
|
||||
'currency_id' => $currencyId,
|
||||
'currency_code' => $limitCurrency->code,
|
||||
'currency_name' => $limitCurrency->name,
|
||||
'currency_symbol' => $limitCurrency->symbol,
|
||||
'currency_decimal_places' => $limitCurrency->decimal_places,
|
||||
];
|
||||
/**
|
||||
* @param Carbon $start
|
||||
*/
|
||||
public function setStart(Carbon $start): void
|
||||
{
|
||||
$this->start = $start;
|
||||
}
|
||||
|
||||
// make sum information:
|
||||
$this->report['sums'][$currencyId]
|
||||
= $this->report['sums'][$currencyId] ?? [
|
||||
'budgeted' => '0',
|
||||
'spent' => '0',
|
||||
'left' => '0',
|
||||
'overspent' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_code' => $limitCurrency->code,
|
||||
'currency_name' => $limitCurrency->name,
|
||||
'currency_symbol' => $limitCurrency->symbol,
|
||||
'currency_decimal_places' => $limitCurrency->decimal_places,
|
||||
];
|
||||
$this->report['sums'][$currencyId]['budgeted'] = bcadd($this->report['sums'][$currencyId]['budgeted'], $limit->amount);
|
||||
$this->report['sums'][$currencyId]['spent'] = bcadd($this->report['sums'][$currencyId]['spent'], $spent);
|
||||
$this->report['sums'][$currencyId]['left'] = bcadd($this->report['sums'][$currencyId]['left'], bcadd($limit->amount, $spent));
|
||||
$this->report['sums'][$currencyId]['overspent'] = bcadd($this->report['sums'][$currencyId]['overspent'], $overspent);
|
||||
/**
|
||||
* @param User $user
|
||||
* @throws FireflyException
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->repository->setUser($user);
|
||||
$this->blRepository->setUser($user);
|
||||
$this->opsRepository->setUser($user);
|
||||
$this->nbRepository->setUser($user);
|
||||
$this->currency = app('amount')->getDefaultCurrencyByUser($user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,43 +86,52 @@ class CategoryReportGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* Process one of the spent arrays from the operations method.
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function setAccounts(Collection $accounts): void
|
||||
private function processOpsArray(array $data): void
|
||||
{
|
||||
$this->accounts = $accounts;
|
||||
/**
|
||||
* @var int $currencyId
|
||||
* @var array $currencyRow
|
||||
*/
|
||||
foreach ($data as $currencyId => $currencyRow) {
|
||||
$this->processCurrencyArray($currencyId, $currencyRow);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $end
|
||||
* @param int $currencyId
|
||||
* @param array $currencyRow
|
||||
*/
|
||||
public function setEnd(Carbon $end): void
|
||||
private function processCurrencyArray(int $currencyId, array $currencyRow): void
|
||||
{
|
||||
$this->end = $end;
|
||||
$this->report['sums'][$currencyId] = $this->report['sums'][$currencyId] ?? [
|
||||
'spent' => '0',
|
||||
'earned' => '0',
|
||||
'sum' => '0',
|
||||
'currency_id' => $currencyRow['currency_id'],
|
||||
'currency_symbol' => $currencyRow['currency_symbol'],
|
||||
'currency_name' => $currencyRow['currency_name'],
|
||||
'currency_code' => $currencyRow['currency_code'],
|
||||
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var int $categoryId
|
||||
* @var array $categoryRow
|
||||
*/
|
||||
foreach ($currencyRow['categories'] as $categoryId => $categoryRow) {
|
||||
$this->processCategoryRow($currencyId, $currencyRow, $categoryId, $categoryRow);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
*/
|
||||
public function setStart(Carbon $start): void
|
||||
{
|
||||
$this->start = $start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->noCatRepository->setUser($user);
|
||||
$this->opsRepository->setUser($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $currencyId
|
||||
* @param array $currencyRow
|
||||
* @param int $categoryId
|
||||
* @param array $categoryRow
|
||||
* @param int $currencyId
|
||||
* @param array $currencyRow
|
||||
* @param int $categoryId
|
||||
* @param array $categoryRow
|
||||
*/
|
||||
private function processCategoryRow(int $currencyId, array $currencyRow, int $categoryId, array $categoryRow): void
|
||||
{
|
||||
@@ -170,44 +179,35 @@ class CategoryReportGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $currencyId
|
||||
* @param array $currencyRow
|
||||
* @param Collection $accounts
|
||||
*/
|
||||
private function processCurrencyArray(int $currencyId, array $currencyRow): void
|
||||
public function setAccounts(Collection $accounts): void
|
||||
{
|
||||
$this->report['sums'][$currencyId] = $this->report['sums'][$currencyId] ?? [
|
||||
'spent' => '0',
|
||||
'earned' => '0',
|
||||
'sum' => '0',
|
||||
'currency_id' => $currencyRow['currency_id'],
|
||||
'currency_symbol' => $currencyRow['currency_symbol'],
|
||||
'currency_name' => $currencyRow['currency_name'],
|
||||
'currency_code' => $currencyRow['currency_code'],
|
||||
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var int $categoryId
|
||||
* @var array $categoryRow
|
||||
*/
|
||||
foreach ($currencyRow['categories'] as $categoryId => $categoryRow) {
|
||||
$this->processCategoryRow($currencyId, $currencyRow, $categoryId, $categoryRow);
|
||||
}
|
||||
$this->accounts = $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process one of the spent arrays from the operations method.
|
||||
*
|
||||
* @param array $data
|
||||
* @param Carbon $end
|
||||
*/
|
||||
private function processOpsArray(array $data): void
|
||||
public function setEnd(Carbon $end): void
|
||||
{
|
||||
/**
|
||||
* @var int $currencyId
|
||||
* @var array $currencyRow
|
||||
*/
|
||||
foreach ($data as $currencyId => $currencyRow) {
|
||||
$this->processCurrencyArray($currencyId, $currencyRow);
|
||||
}
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
*/
|
||||
public function setStart(Carbon $start): void
|
||||
{
|
||||
$this->start = $start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->noCatRepository->setUser($user);
|
||||
$this->opsRepository->setUser($user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ trait AdministrationTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $administrationId
|
||||
* @param int $administrationId
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function setAdministrationId(int $administrationId): void
|
||||
@@ -56,13 +56,6 @@ trait AdministrationTrait
|
||||
$this->refreshAdministration();
|
||||
}
|
||||
|
||||
public function setUser(Authenticatable|User|null $user): void
|
||||
{
|
||||
if (null !== $user) {
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
@@ -80,4 +73,11 @@ trait AdministrationTrait
|
||||
}
|
||||
throw new FireflyException(sprintf('Cannot validate administration for user #%d', $this->user->id));
|
||||
}
|
||||
|
||||
public function setUser(Authenticatable | User | null $user): void
|
||||
{
|
||||
if (null !== $user) {
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +33,12 @@ use Illuminate\Support\Facades\Log;
|
||||
trait CalculateRangeOccurrences
|
||||
{
|
||||
/**
|
||||
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every $skipMod-1 occurrences.
|
||||
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every
|
||||
* $skipMod-1 occurrences.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $skipMod
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $skipMod
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -57,12 +58,13 @@ trait CalculateRangeOccurrences
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every $skipMod-1 occurrences.
|
||||
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every
|
||||
* $skipMod-1 occurrences.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
@@ -90,12 +92,13 @@ trait CalculateRangeOccurrences
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every $skipMod-1 occurrences.
|
||||
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every
|
||||
* $skipMod-1 occurrences.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -122,12 +125,13 @@ trait CalculateRangeOccurrences
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every $skipMod-1 occurrences.
|
||||
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every
|
||||
* $skipMod-1 occurrences.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
@@ -166,12 +170,13 @@ trait CalculateRangeOccurrences
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every $skipMod-1 occurrences.
|
||||
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every
|
||||
* $skipMod-1 occurrences.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
|
||||
@@ -32,12 +32,12 @@ use Carbon\Carbon;
|
||||
trait CalculateXOccurrences
|
||||
{
|
||||
/**
|
||||
* Calculates the number of daily occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip
|
||||
* over $skipMod -1 recurrences.
|
||||
* Calculates the number of daily occurrences for a recurring transaction, starting at the date, until $count is
|
||||
* reached. It will skip over $skipMod -1 recurrences.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param Carbon $date
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -60,13 +60,13 @@ trait CalculateXOccurrences
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of monthly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip
|
||||
* over $skipMod -1 recurrences.
|
||||
* Calculates the number of monthly occurrences for a recurring transaction, starting at the date, until $count is
|
||||
* reached. It will skip over $skipMod -1 recurrences.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $date
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -97,13 +97,13 @@ trait CalculateXOccurrences
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of NDOM occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip
|
||||
* over $skipMod -1 recurrences.
|
||||
* Calculates the number of NDOM occurrences for a recurring transaction, starting at the date, until $count is
|
||||
* reached. It will skip over $skipMod -1 recurrences.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $date
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -135,13 +135,13 @@ trait CalculateXOccurrences
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of weekly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip
|
||||
* over $skipMod -1 recurrences.
|
||||
* Calculates the number of weekly occurrences for a recurring transaction, starting at the date, until $count is
|
||||
* reached. It will skip over $skipMod -1 recurrences.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $date
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -177,13 +177,13 @@ trait CalculateXOccurrences
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of yearly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip
|
||||
* over $skipMod -1 recurrences.
|
||||
* Calculates the number of yearly occurrences for a recurring transaction, starting at the date, until $count is
|
||||
* reached. It will skip over $skipMod -1 recurrences.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $date
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -33,13 +33,13 @@ use Illuminate\Support\Facades\Log;
|
||||
trait CalculateXOccurrencesSince
|
||||
{
|
||||
/**
|
||||
* Calculates the number of daily occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip
|
||||
* over $skipMod -1 recurrences.
|
||||
* Calculates the number of daily occurrences for a recurring transaction, starting at the date, until $count is
|
||||
* reached. It will skip over $skipMod -1 recurrences.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param Carbon $afterDate
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param Carbon $date
|
||||
* @param Carbon $afterDate
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -63,14 +63,14 @@ trait CalculateXOccurrencesSince
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of monthly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip
|
||||
* over $skipMod -1 recurrences.
|
||||
* Calculates the number of monthly occurrences for a recurring transaction, starting at the date, until $count is
|
||||
* reached. It will skip over $skipMod -1 recurrences.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param Carbon $afterDate
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $date
|
||||
* @param Carbon $afterDate
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -106,14 +106,14 @@ trait CalculateXOccurrencesSince
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of NDOM occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip
|
||||
* over $skipMod -1 recurrences.
|
||||
* Calculates the number of NDOM occurrences for a recurring transaction, starting at the date, until $count is
|
||||
* reached. It will skip over $skipMod -1 recurrences.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param Carbon $afterDate
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $date
|
||||
* @param Carbon $afterDate
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -146,14 +146,14 @@ trait CalculateXOccurrencesSince
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of weekly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip
|
||||
* over $skipMod -1 recurrences.
|
||||
* Calculates the number of weekly occurrences for a recurring transaction, starting at the date, until $count is
|
||||
* reached. It will skip over $skipMod -1 recurrences.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param Carbon $afterDate
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $date
|
||||
* @param Carbon $afterDate
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -191,14 +191,14 @@ trait CalculateXOccurrencesSince
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of yearly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip
|
||||
* over $skipMod -1 recurrences.
|
||||
* Calculates the number of yearly occurrences for a recurring transaction, starting at the date, until $count is
|
||||
* reached. It will skip over $skipMod -1 recurrences.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param Carbon $afterDate
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
* @param Carbon $date
|
||||
* @param Carbon $afterDate
|
||||
* @param int $count
|
||||
* @param int $skipMod
|
||||
* @param string $moment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -37,8 +37,8 @@ trait FiltersWeekends
|
||||
/**
|
||||
* Filters out all weekend entries, if necessary.
|
||||
*
|
||||
* @param RecurrenceRepetition $repetition
|
||||
* @param array $dates
|
||||
* @param RecurrenceRepetition $repetition
|
||||
* @param array $dates
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
|
||||
@@ -30,16 +30,6 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
trait AppendsLocationData
|
||||
{
|
||||
/**
|
||||
* Abstract method stolen from "InteractsWithInput".
|
||||
*
|
||||
* @param null $key
|
||||
* @param bool $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function boolean($key = null, $default = false);
|
||||
|
||||
/**
|
||||
* Abstract method.
|
||||
*
|
||||
@@ -49,28 +39,12 @@ trait AppendsLocationData
|
||||
*/
|
||||
abstract public function has($key);
|
||||
|
||||
/**
|
||||
* Abstract method.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function method();
|
||||
|
||||
/**
|
||||
* Abstract method.
|
||||
*
|
||||
* @param mixed ...$patterns
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function routeIs(...$patterns);
|
||||
|
||||
/**
|
||||
* Read the submitted Request data and add new or updated Location data to the array.
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
*
|
||||
* @param string|null $prefix
|
||||
* @param string|null $prefix
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -126,8 +100,8 @@ trait AppendsLocationData
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $prefix
|
||||
* @param string $key
|
||||
* @param string|null $prefix
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -141,28 +115,7 @@ trait AppendsLocationData
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isValidEmptyPUT(?string $prefix): bool
|
||||
{
|
||||
$longitudeKey = $this->getLocationKey($prefix, 'longitude');
|
||||
$latitudeKey = $this->getLocationKey($prefix, 'latitude');
|
||||
$zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level');
|
||||
|
||||
return (
|
||||
null === $this->get($longitudeKey)
|
||||
&& null === $this->get($latitudeKey)
|
||||
&& null === $this->get($zoomLevelKey))
|
||||
&& (
|
||||
'PUT' === $this->method()
|
||||
|| ('POST' === $this->method() && $this->routeIs('*.update'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $prefix
|
||||
* @param string|null $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -205,7 +158,33 @@ trait AppendsLocationData
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $prefix
|
||||
* Abstract method.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function method();
|
||||
|
||||
/**
|
||||
* Abstract method.
|
||||
*
|
||||
* @param mixed ...$patterns
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function routeIs(...$patterns);
|
||||
|
||||
/**
|
||||
* Abstract method stolen from "InteractsWithInput".
|
||||
*
|
||||
* @param null $key
|
||||
* @param bool $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function boolean($key = null, $default = false);
|
||||
|
||||
/**
|
||||
* @param string|null $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -248,4 +227,25 @@ trait AppendsLocationData
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isValidEmptyPUT(?string $prefix): bool
|
||||
{
|
||||
$longitudeKey = $this->getLocationKey($prefix, 'longitude');
|
||||
$latitudeKey = $this->getLocationKey($prefix, 'latitude');
|
||||
$zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level');
|
||||
|
||||
return (
|
||||
null === $this->get($longitudeKey)
|
||||
&& null === $this->get($latitudeKey)
|
||||
&& null === $this->get($zoomLevelKey))
|
||||
&& (
|
||||
'PUT' === $this->method()
|
||||
|| ('POST' === $this->method() && $this->routeIs('*.update'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,46 @@ use Illuminate\Support\Facades\Log;
|
||||
trait ConvertsDataTypes
|
||||
{
|
||||
/**
|
||||
* @param string|null $string
|
||||
* @param bool $keepNewlines
|
||||
* Return integer value.
|
||||
*
|
||||
* @param string $field
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function convertInteger(string $field): int
|
||||
{
|
||||
return (int)$this->get($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method that always exists in the Request classes that use this
|
||||
* trait, OR a stub needs to be added by any other class that uses this train.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function get(string $key, mixed $default = null): mixed;
|
||||
|
||||
/**
|
||||
* Return string value.
|
||||
*
|
||||
* @param string $field
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convertString(string $field): string
|
||||
{
|
||||
$entry = $this->get($field);
|
||||
if (!is_scalar($entry)) {
|
||||
return '';
|
||||
}
|
||||
return $this->clearString((string)$entry, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $string
|
||||
* @param bool $keepNewlines
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
@@ -114,57 +152,10 @@ trait ConvertsDataTypes
|
||||
return trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return integer value.
|
||||
*
|
||||
* @param string $field
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function convertInteger(string $field): int
|
||||
{
|
||||
return (int)$this->get($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return string value.
|
||||
*
|
||||
* @param string $field
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convertString(string $field): string
|
||||
{
|
||||
$entry = $this->get($field);
|
||||
if (!is_scalar($entry)) {
|
||||
return '';
|
||||
}
|
||||
return $this->clearString((string)$entry, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method that always exists in the Request classes that use this
|
||||
* trait, OR a stub needs to be added by any other class that uses this train.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function get(string $key, mixed $default = null): mixed;
|
||||
|
||||
/**
|
||||
* Abstract method that always exists in the Request classes that use this
|
||||
* trait, OR a stub needs to be added by any other class that uses this train.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function has($key);
|
||||
|
||||
/**
|
||||
* Return string value with newlines.
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $field
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -174,7 +165,7 @@ trait ConvertsDataTypes
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $array
|
||||
* @param mixed $array
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
@@ -194,7 +185,7 @@ trait ConvertsDataTypes
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $value
|
||||
* @param string|null $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -260,7 +251,7 @@ trait ConvertsDataTypes
|
||||
/**
|
||||
* Return floating value.
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $field
|
||||
*
|
||||
* @return float|null
|
||||
*/
|
||||
@@ -275,7 +266,7 @@ trait ConvertsDataTypes
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $string
|
||||
* @param string|null $string
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
@@ -307,7 +298,7 @@ trait ConvertsDataTypes
|
||||
* Returns all data in the request, or omits the field if not set,
|
||||
* according to the config from the request. This is the way.
|
||||
*
|
||||
* @param array $fields
|
||||
* @param array $fields
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -324,10 +315,19 @@ trait ConvertsDataTypes
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method that always exists in the Request classes that use this
|
||||
* trait, OR a stub needs to be added by any other class that uses this train.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function has($key);
|
||||
|
||||
/**
|
||||
* Return date or NULL.
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $field
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
@@ -349,7 +349,7 @@ trait ConvertsDataTypes
|
||||
/**
|
||||
* Parse to integer
|
||||
*
|
||||
* @param string|null $string
|
||||
* @param string|null $string
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
@@ -368,7 +368,7 @@ trait ConvertsDataTypes
|
||||
/**
|
||||
* Return integer value, or NULL when it's not set.
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $field
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace FireflyIII\Support\Request;
|
||||
trait GetRecurrenceData
|
||||
{
|
||||
/**
|
||||
* @param array $transaction
|
||||
* @param array $transaction
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -109,7 +109,7 @@ class AccountSearch implements GenericSearchInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
* @param string $field
|
||||
*/
|
||||
public function setField(string $field): void
|
||||
{
|
||||
@@ -117,7 +117,7 @@ class AccountSearch implements GenericSearchInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
* @param string $query
|
||||
*/
|
||||
public function setQuery(string $query): void
|
||||
{
|
||||
@@ -125,7 +125,7 @@ class AccountSearch implements GenericSearchInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
* @param array $types
|
||||
*/
|
||||
public function setTypes(array $types): void
|
||||
{
|
||||
@@ -133,10 +133,10 @@ class AccountSearch implements GenericSearchInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User|Authenticatable|null $user
|
||||
* @param User|Authenticatable|null $user
|
||||
* @return void
|
||||
*/
|
||||
public function setUser(User|Authenticatable|null $user): void
|
||||
public function setUser(User | Authenticatable | null $user): void
|
||||
{
|
||||
if (null !== $user) {
|
||||
$this->user = $user;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -59,7 +59,7 @@ interface SearchInterface
|
||||
public function hasModifiers(): bool;
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
* @param string $query
|
||||
*/
|
||||
public function parseQuery(string $query);
|
||||
|
||||
@@ -74,22 +74,22 @@ interface SearchInterface
|
||||
public function searchTransactions(): LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
* @param Carbon $date
|
||||
*/
|
||||
public function setDate(Carbon $date): void;
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @param int $limit
|
||||
*/
|
||||
public function setLimit(int $limit): void;
|
||||
|
||||
/**
|
||||
* @param int $page
|
||||
* @param int $page
|
||||
*/
|
||||
public function setPage(int $page): void;
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user);
|
||||
}
|
||||
|
||||
@@ -48,58 +48,8 @@ use ValueError;
|
||||
class Steam
|
||||
{
|
||||
/**
|
||||
* Gets balance at the end of current month by default
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $date
|
||||
* @param TransactionCurrency|null $currency
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function balance(Account $account, Carbon $date, ?TransactionCurrency $currency = null): string
|
||||
{
|
||||
// abuse chart properties:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($account->id);
|
||||
$cache->addProperty('balance');
|
||||
$cache->addProperty($date);
|
||||
$cache->addProperty($currency ? $currency->id : 0);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
if (null === $currency) {
|
||||
$currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user);
|
||||
}
|
||||
// first part: get all balances in own currency:
|
||||
$transactions = $account->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
|
||||
->where('transactions.transaction_currency_id', $currency->id)
|
||||
->get(['transactions.amount'])->toArray();
|
||||
$nativeBalance = $this->sumTransactions($transactions, 'amount');
|
||||
// get all balances in foreign currency:
|
||||
$transactions = $account->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
|
||||
->where('transactions.foreign_currency_id', $currency->id)
|
||||
->where('transactions.transaction_currency_id', '!=', $currency->id)
|
||||
->get(['transactions.foreign_amount'])->toArray();
|
||||
$foreignBalance = $this->sumTransactions($transactions, 'foreign_amount');
|
||||
$balance = bcadd($nativeBalance, $foreignBalance);
|
||||
$virtual = null === $account->virtual_balance ? '0' : (string)$account->virtual_balance;
|
||||
$balance = bcadd($balance, $virtual);
|
||||
|
||||
$cache->store($balance);
|
||||
|
||||
return $balance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $date
|
||||
* @param Account $account
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -129,15 +79,34 @@ class Steam
|
||||
return bcadd($nativeBalance, $foreignBalance);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $transactions
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sumTransactions(array $transactions, string $key): string
|
||||
{
|
||||
$sum = '0';
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$value = (string)($transaction[$key] ?? '0');
|
||||
$value = '' === $value ? '0' : $value;
|
||||
$sum = bcadd($sum, $value);
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the balance for the given account during the whole range, using this format:.
|
||||
*
|
||||
* [yyyy-mm-dd] => 123,2
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param TransactionCurrency|null $currency
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param TransactionCurrency|null $currency
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -220,41 +189,60 @@ class Steam
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $date
|
||||
* Gets balance at the end of current month by default
|
||||
*
|
||||
* @return array
|
||||
* @param Account $account
|
||||
* @param Carbon $date
|
||||
* @param TransactionCurrency|null $currency
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function balancePerCurrency(Account $account, Carbon $date): array
|
||||
public function balance(Account $account, Carbon $date, ?TransactionCurrency $currency = null): string
|
||||
{
|
||||
// abuse chart properties:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($account->id);
|
||||
$cache->addProperty('balance-per-currency');
|
||||
$cache->addProperty('balance');
|
||||
$cache->addProperty($date);
|
||||
$cache->addProperty($currency ? $currency->id : 0);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
$query = $account->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
|
||||
->groupBy('transactions.transaction_currency_id');
|
||||
$balances = $query->get(['transactions.transaction_currency_id', DB::raw('SUM(transactions.amount) as sum_for_currency')]);
|
||||
$return = [];
|
||||
/** @var stdClass $entry */
|
||||
foreach ($balances as $entry) {
|
||||
$return[(int)$entry->transaction_currency_id] = (string)$entry->sum_for_currency;
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
if (null === $currency) {
|
||||
$currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user);
|
||||
}
|
||||
$cache->store($return);
|
||||
// first part: get all balances in own currency:
|
||||
$transactions = $account->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
|
||||
->where('transactions.transaction_currency_id', $currency->id)
|
||||
->get(['transactions.amount'])->toArray();
|
||||
$nativeBalance = $this->sumTransactions($transactions, 'amount');
|
||||
// get all balances in foreign currency:
|
||||
$transactions = $account->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
|
||||
->where('transactions.foreign_currency_id', $currency->id)
|
||||
->where('transactions.transaction_currency_id', '!=', $currency->id)
|
||||
->get(['transactions.foreign_amount'])->toArray();
|
||||
$foreignBalance = $this->sumTransactions($transactions, 'foreign_amount');
|
||||
$balance = bcadd($nativeBalance, $foreignBalance);
|
||||
$virtual = null === $account->virtual_balance ? '0' : (string)$account->virtual_balance;
|
||||
$balance = bcadd($balance, $virtual);
|
||||
|
||||
return $return;
|
||||
$cache->store($balance);
|
||||
|
||||
return $balance;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method always ignores the virtual balance.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $date
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
@@ -286,8 +274,8 @@ class Steam
|
||||
/**
|
||||
* Same as above, but also groups per currency.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $date
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -315,11 +303,42 @@ class Steam
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function balancePerCurrency(Account $account, Carbon $date): array
|
||||
{
|
||||
// abuse chart properties:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($account->id);
|
||||
$cache->addProperty('balance-per-currency');
|
||||
$cache->addProperty($date);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
$query = $account->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
|
||||
->groupBy('transactions.transaction_currency_id');
|
||||
$balances = $query->get(['transactions.transaction_currency_id', DB::raw('SUM(transactions.amount) as sum_for_currency')]);
|
||||
$return = [];
|
||||
/** @var stdClass $entry */
|
||||
foreach ($balances as $entry) {
|
||||
$return[(int)$entry->transaction_currency_id] = (string)$entry->sum_for_currency;
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* https://stackoverflow.com/questions/1642614/how-to-ceil-floor-and-round-bcmath-numbers
|
||||
*
|
||||
* @param null|string $number
|
||||
* @param int $precision
|
||||
* @param null|string $number
|
||||
* @param int $precision
|
||||
* @return string
|
||||
*/
|
||||
public function bcround(?string $number, int $precision = 0): string
|
||||
@@ -338,17 +357,17 @@ class Steam
|
||||
// Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision));
|
||||
if (str_contains($number, '.')) {
|
||||
if ($number[0] !== '-') {
|
||||
return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision);
|
||||
return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision);
|
||||
}
|
||||
|
||||
return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision);
|
||||
return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision);
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -410,37 +429,7 @@ class Steam
|
||||
}
|
||||
|
||||
/**
|
||||
* https://framework.zend.com/downloads/archives
|
||||
*
|
||||
* Convert a scientific notation to float
|
||||
* Additionally fixed a problem with PHP <= 5.2.x with big integers
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function floatalize(string $value): string
|
||||
{
|
||||
$value = strtoupper($value);
|
||||
if (!str_contains($value, 'E')) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$number = substr($value, 0, strpos($value, 'E'));
|
||||
if (str_contains($number, '.')) {
|
||||
$post = strlen(substr($number, strpos($number, '.') + 1));
|
||||
$mantis = substr($value, strpos($value, 'E') + 1);
|
||||
if ($mantis < 0) {
|
||||
$post += abs((int)$mantis);
|
||||
}
|
||||
// TODO careless float could break financial math.
|
||||
return number_format((float)$value, $post, '.', '');
|
||||
}
|
||||
// TODO careless float could break financial math.
|
||||
return number_format((float)$value, 0, '.', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ipAddress
|
||||
* @param string $ipAddress
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
@@ -455,24 +444,7 @@ class Steam
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's language.
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function getLanguage(): string // get preference
|
||||
{
|
||||
$preference = app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data;
|
||||
if (!is_string($preference)) {
|
||||
throw new FireflyException(sprintf('Preference "language" must be a string, but is unexpectedly a "%s".', gettype($preference)));
|
||||
}
|
||||
return $preference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $accounts
|
||||
* @param array $accounts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -518,7 +490,24 @@ class Steam
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $locale
|
||||
* Get user's language.
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function getLanguage(): string // get preference
|
||||
{
|
||||
$preference = app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data;
|
||||
if (!is_string($preference)) {
|
||||
throw new FireflyException(sprintf('Preference "language" must be a string, but is unexpectedly a "%s".', gettype($preference)));
|
||||
}
|
||||
return $preference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $locale
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -551,8 +540,8 @@ class Steam
|
||||
/**
|
||||
* Make sure URL is safe.
|
||||
*
|
||||
* @param string $unknownUrl
|
||||
* @param string $safeUrl
|
||||
* @param string $unknownUrl
|
||||
* @param string $safeUrl
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -577,7 +566,7 @@ class Steam
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $amount
|
||||
* @param string $amount
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -596,7 +585,37 @@ class Steam
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $amount
|
||||
* https://framework.zend.com/downloads/archives
|
||||
*
|
||||
* Convert a scientific notation to float
|
||||
* Additionally fixed a problem with PHP <= 5.2.x with big integers
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function floatalize(string $value): string
|
||||
{
|
||||
$value = strtoupper($value);
|
||||
if (!str_contains($value, 'E')) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$number = substr($value, 0, strpos($value, 'E'));
|
||||
if (str_contains($number, '.')) {
|
||||
$post = strlen(substr($number, strpos($number, '.') + 1));
|
||||
$mantis = substr($value, strpos($value, 'E') + 1);
|
||||
if ($mantis < 0) {
|
||||
$post += abs((int)$mantis);
|
||||
}
|
||||
// TODO careless float could break financial math.
|
||||
return number_format((float)$value, $post, '.', '');
|
||||
}
|
||||
// TODO careless float could break financial math.
|
||||
return number_format((float)$value, 0, '.', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $amount
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
@@ -610,7 +629,7 @@ class Steam
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param string $string
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@@ -643,7 +662,7 @@ class Steam
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $amount
|
||||
* @param string $amount
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -664,23 +683,4 @@ class Steam
|
||||
|
||||
return $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $transactions
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sumTransactions(array $transactions, string $key): string
|
||||
{
|
||||
$sum = '0';
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$value = (string)($transaction[$key] ?? '0');
|
||||
$value = '' === $value ? '0' : $value;
|
||||
$sum = bcadd($sum, $value);
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,21 +44,22 @@ class OAuthKeys
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function generateKeys(): void
|
||||
public static function verifyKeysRoutine(): void
|
||||
{
|
||||
Artisan::registerCommand(new KeysCommand());
|
||||
Artisan::call('passport:keys');
|
||||
}
|
||||
if (!self::keysInDatabase() && !self::hasKeyFiles()) {
|
||||
self::generateKeys();
|
||||
self::storeKeysInDB();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasKeyFiles(): bool
|
||||
{
|
||||
$private = storage_path('oauth-private.key');
|
||||
$public = storage_path('oauth-public.key');
|
||||
return;
|
||||
}
|
||||
if (self::keysInDatabase() && !self::hasKeyFiles()) {
|
||||
self::restoreKeysFromDB();
|
||||
|
||||
return file_exists($private) && file_exists($public);
|
||||
return;
|
||||
}
|
||||
if (!self::keysInDatabase() && self::hasKeyFiles()) {
|
||||
self::storeKeysInDB();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +74,7 @@ class OAuthKeys
|
||||
try {
|
||||
$privateKey = (string)app('fireflyconfig')->get(self::PRIVATE_KEY)?->data;
|
||||
$publicKey = (string)app('fireflyconfig')->get(self::PUBLIC_KEY)?->data;
|
||||
} catch (ContainerExceptionInterface|NotFoundExceptionInterface|FireflyException $e) {
|
||||
} catch (ContainerExceptionInterface | NotFoundExceptionInterface | FireflyException $e) {
|
||||
Log::error(sprintf('Could not validate keysInDatabase(): %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
@@ -85,6 +86,37 @@ class OAuthKeys
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasKeyFiles(): bool
|
||||
{
|
||||
$private = storage_path('oauth-private.key');
|
||||
$public = storage_path('oauth-public.key');
|
||||
|
||||
return file_exists($private) && file_exists($public);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function generateKeys(): void
|
||||
{
|
||||
Artisan::registerCommand(new KeysCommand());
|
||||
Artisan::call('passport:keys');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function storeKeysInDB(): void
|
||||
{
|
||||
$private = storage_path('oauth-private.key');
|
||||
$public = storage_path('oauth-public.key');
|
||||
app('fireflyconfig')->set(self::PRIVATE_KEY, Crypt::encrypt(file_get_contents($private)));
|
||||
app('fireflyconfig')->set(self::PUBLIC_KEY, Crypt::encrypt(file_get_contents($public)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws ContainerExceptionInterface
|
||||
@@ -114,36 +146,4 @@ class OAuthKeys
|
||||
file_put_contents($public, $publicContent);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function storeKeysInDB(): void
|
||||
{
|
||||
$private = storage_path('oauth-private.key');
|
||||
$public = storage_path('oauth-public.key');
|
||||
app('fireflyconfig')->set(self::PRIVATE_KEY, Crypt::encrypt(file_get_contents($private)));
|
||||
app('fireflyconfig')->set(self::PUBLIC_KEY, Crypt::encrypt(file_get_contents($public)));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function verifyKeysRoutine(): void
|
||||
{
|
||||
if (!self::keysInDatabase() && !self::hasKeyFiles()) {
|
||||
self::generateKeys();
|
||||
self::storeKeysInDB();
|
||||
|
||||
return;
|
||||
}
|
||||
if (self::keysInDatabase() && !self::hasKeyFiles()) {
|
||||
self::restoreKeysFromDB();
|
||||
|
||||
return;
|
||||
}
|
||||
if (!self::keysInDatabase() && self::hasKeyFiles()) {
|
||||
self::storeKeysInDB();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,18 +46,6 @@ class AmountFormat extends AbstractExtension
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return [
|
||||
$this->formatAmountByAccount(),
|
||||
$this->formatAmountBySymbol(),
|
||||
$this->formatAmountByCurrency(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFilter
|
||||
*/
|
||||
@@ -74,6 +62,34 @@ class AmountFormat extends AbstractExtension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFilter
|
||||
*/
|
||||
protected function formatAmountPlain(): TwigFilter
|
||||
{
|
||||
return new TwigFilter(
|
||||
'formatAmountPlain',
|
||||
static function (string $string): string {
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
|
||||
return app('amount')->formatAnything($currency, $string, false);
|
||||
},
|
||||
['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return [
|
||||
$this->formatAmountByAccount(),
|
||||
$this->formatAmountBySymbol(),
|
||||
$this->formatAmountByCurrency(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Will format the amount by the currency related to the given account.
|
||||
*
|
||||
@@ -96,24 +112,6 @@ class AmountFormat extends AbstractExtension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will format the amount by the currency related to the given account.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function formatAmountByCurrency(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'formatAmountByCurrency',
|
||||
static function (TransactionCurrency $currency, string $amount, bool $coloured = null): string {
|
||||
$coloured = $coloured ?? true;
|
||||
|
||||
return app('amount')->formatAnything($currency, $amount, $coloured);
|
||||
},
|
||||
['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will format the amount by the currency related to the given account.
|
||||
*
|
||||
@@ -137,16 +135,18 @@ class AmountFormat extends AbstractExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFilter
|
||||
* Will format the amount by the currency related to the given account.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function formatAmountPlain(): TwigFilter
|
||||
protected function formatAmountByCurrency(): TwigFunction
|
||||
{
|
||||
return new TwigFilter(
|
||||
'formatAmountPlain',
|
||||
static function (string $string): string {
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
return new TwigFunction(
|
||||
'formatAmountByCurrency',
|
||||
static function (TransactionCurrency $currency, string $amount, bool $coloured = null): string {
|
||||
$coloured = $coloured ?? true;
|
||||
|
||||
return app('amount')->formatAnything($currency, $string, false);
|
||||
return app('amount')->formatAnything($currency, $amount, $coloured);
|
||||
},
|
||||
['is_safe' => ['html']]
|
||||
);
|
||||
|
||||
@@ -53,99 +53,6 @@ class General extends AbstractExtension
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return [
|
||||
$this->phpdate(),
|
||||
$this->activeRouteStrict(),
|
||||
$this->activeRoutePartial(),
|
||||
$this->activeRoutePartialObjectType(),
|
||||
$this->menuOpenRoutePartial(),
|
||||
$this->formatDate(),
|
||||
$this->getMetaField(),
|
||||
$this->hasRole(),
|
||||
$this->getRootSearchOperator(),
|
||||
$this->carbonize(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return "active" when a part of the route matches the argument.
|
||||
* ie. "accounts" will match "accounts.index".
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function activeRoutePartial(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'activeRoutePartial',
|
||||
static function (): string {
|
||||
$args = func_get_args();
|
||||
$route = $args[0]; // name of the route.
|
||||
$name = Route::getCurrentRoute()->getName() ?? '';
|
||||
if (str_contains($name, $route)) {
|
||||
return 'active';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return "active" when the current route matches the first argument (even partly)
|
||||
* but, the variable $objectType has been set and matches the second argument.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function activeRoutePartialObjectType(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'activeRoutePartialObjectType',
|
||||
static function ($context): string {
|
||||
[, $route, $objectType] = func_get_args();
|
||||
$activeObjectType = $context['objectType'] ?? false;
|
||||
|
||||
if ($objectType === $activeObjectType
|
||||
&& false !== stripos(
|
||||
Route::getCurrentRoute()->getName(),
|
||||
$route
|
||||
)) {
|
||||
return 'active';
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
['needs_context' => true]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return "active" when the current route matches the given argument
|
||||
* exactly.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function activeRouteStrict(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'activeRouteStrict',
|
||||
static function (): string {
|
||||
$args = func_get_args();
|
||||
$route = $args[0]; // name of the route.
|
||||
|
||||
if (Route::getCurrentRoute()->getName() === $route) {
|
||||
return 'active';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show account balance. Only used on the front page of Firefly III.
|
||||
*
|
||||
@@ -167,36 +74,6 @@ class General extends AbstractExtension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function carbonize(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'carbonize',
|
||||
static function (string $date): Carbon {
|
||||
return new Carbon($date, config('app.timezone'));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a string as a thing by converting it to a Carbon first.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function formatDate(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'formatDate',
|
||||
function (string $date, string $format): string {
|
||||
$carbon = new Carbon($date);
|
||||
|
||||
return $carbon->isoFormat($format);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to convert 1024 to 1kb etc.
|
||||
*
|
||||
@@ -222,104 +99,6 @@ class General extends AbstractExtension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFunction
|
||||
* TODO remove me when layout v1 is deprecated.
|
||||
*/
|
||||
protected function getMetaField(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'accountGetMetaField',
|
||||
static function (Account $account, string $field): string {
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$result = $repository->getMetaValue($account, $field);
|
||||
if (null === $result) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected function getRootSearchOperator(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'getRootSearchOperator',
|
||||
static function (string $operator): string {
|
||||
$result = OperatorQuerySearch::getRootOperator($operator);
|
||||
|
||||
return str_replace('-', 'not_', $result);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return true if the user is of role X.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function hasRole(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'hasRole',
|
||||
static function (string $role): bool {
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
if ($repository->hasRole(auth()->user(), $role)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFilter
|
||||
*/
|
||||
protected function markdown(): TwigFilter
|
||||
{
|
||||
return new TwigFilter(
|
||||
'markdown',
|
||||
static function (string $text): string {
|
||||
$converter = new GithubFlavoredMarkdownConverter(
|
||||
[
|
||||
'allow_unsafe_links' => false,
|
||||
'max_nesting_level' => 3,
|
||||
'html_input' => 'escape',
|
||||
]
|
||||
);
|
||||
|
||||
return (string)$converter->convert($text);
|
||||
},
|
||||
['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return "menu-open" when a part of the route matches the argument.
|
||||
* ie. "accounts" will match "accounts.index".
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function menuOpenRoutePartial(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'menuOpenRoutePartial',
|
||||
static function (): string {
|
||||
$args = func_get_args();
|
||||
$route = $args[0]; // name of the route.
|
||||
$name = Route::getCurrentRoute()->getName() ?? '';
|
||||
if (str_contains($name, $route)) {
|
||||
return 'menu-open';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show icon with attachment.
|
||||
*
|
||||
@@ -398,6 +177,28 @@ class General extends AbstractExtension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFilter
|
||||
*/
|
||||
protected function markdown(): TwigFilter
|
||||
{
|
||||
return new TwigFilter(
|
||||
'markdown',
|
||||
static function (string $text): string {
|
||||
$converter = new GithubFlavoredMarkdownConverter(
|
||||
[
|
||||
'allow_unsafe_links' => false,
|
||||
'max_nesting_level' => 3,
|
||||
'html_input' => 'escape',
|
||||
]
|
||||
);
|
||||
|
||||
return (string)$converter->convert($text);
|
||||
},
|
||||
['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show URL host name
|
||||
*
|
||||
@@ -416,6 +217,25 @@ class General extends AbstractExtension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return [
|
||||
$this->phpdate(),
|
||||
$this->activeRouteStrict(),
|
||||
$this->activeRoutePartial(),
|
||||
$this->activeRoutePartialObjectType(),
|
||||
$this->menuOpenRoutePartial(),
|
||||
$this->formatDate(),
|
||||
$this->getMetaField(),
|
||||
$this->hasRole(),
|
||||
$this->getRootSearchOperator(),
|
||||
$this->carbonize(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic example thing for some views.
|
||||
*
|
||||
@@ -430,4 +250,184 @@ class General extends AbstractExtension
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return "active" when the current route matches the given argument
|
||||
* exactly.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function activeRouteStrict(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'activeRouteStrict',
|
||||
static function (): string {
|
||||
$args = func_get_args();
|
||||
$route = $args[0]; // name of the route.
|
||||
|
||||
if (Route::getCurrentRoute()->getName() === $route) {
|
||||
return 'active';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return "active" when a part of the route matches the argument.
|
||||
* ie. "accounts" will match "accounts.index".
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function activeRoutePartial(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'activeRoutePartial',
|
||||
static function (): string {
|
||||
$args = func_get_args();
|
||||
$route = $args[0]; // name of the route.
|
||||
$name = Route::getCurrentRoute()->getName() ?? '';
|
||||
if (str_contains($name, $route)) {
|
||||
return 'active';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return "active" when the current route matches the first argument (even partly)
|
||||
* but, the variable $objectType has been set and matches the second argument.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function activeRoutePartialObjectType(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'activeRoutePartialObjectType',
|
||||
static function ($context): string {
|
||||
[, $route, $objectType] = func_get_args();
|
||||
$activeObjectType = $context['objectType'] ?? false;
|
||||
|
||||
if ($objectType === $activeObjectType
|
||||
&& false !== stripos(
|
||||
Route::getCurrentRoute()->getName(),
|
||||
$route
|
||||
)) {
|
||||
return 'active';
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
['needs_context' => true]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return "menu-open" when a part of the route matches the argument.
|
||||
* ie. "accounts" will match "accounts.index".
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function menuOpenRoutePartial(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'menuOpenRoutePartial',
|
||||
static function (): string {
|
||||
$args = func_get_args();
|
||||
$route = $args[0]; // name of the route.
|
||||
$name = Route::getCurrentRoute()->getName() ?? '';
|
||||
if (str_contains($name, $route)) {
|
||||
return 'menu-open';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a string as a thing by converting it to a Carbon first.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function formatDate(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'formatDate',
|
||||
function (string $date, string $format): string {
|
||||
$carbon = new Carbon($date);
|
||||
|
||||
return $carbon->isoFormat($format);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFunction
|
||||
* TODO remove me when layout v1 is deprecated.
|
||||
*/
|
||||
protected function getMetaField(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'accountGetMetaField',
|
||||
static function (Account $account, string $field): string {
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$result = $repository->getMetaValue($account, $field);
|
||||
if (null === $result) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return true if the user is of role X.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function hasRole(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'hasRole',
|
||||
static function (string $role): bool {
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
if ($repository->hasRole(auth()->user(), $role)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected function getRootSearchOperator(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'getRootSearchOperator',
|
||||
static function (string $operator): string {
|
||||
$result = OperatorQuerySearch::getRootOperator($operator);
|
||||
|
||||
return str_replace('-', 'not_', $result);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFunction
|
||||
*/
|
||||
protected function carbonize(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'carbonize',
|
||||
static function (string $date): Carbon {
|
||||
return new Carbon($date, config('app.timezone'));
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,25 +33,15 @@ use Twig\TwigFunction;
|
||||
class Rule extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* @return TwigFunction
|
||||
* @return array
|
||||
*/
|
||||
public function allActionTriggers(): TwigFunction
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return new TwigFunction(
|
||||
'allRuleActions',
|
||||
static function () {
|
||||
// array of valid values for actions
|
||||
$ruleActions = array_keys(Config::get('firefly.rule-actions'));
|
||||
$possibleActions = [];
|
||||
foreach ($ruleActions as $key) {
|
||||
$possibleActions[$key] = (string)trans('firefly.rule_action_'.$key.'_choice');
|
||||
}
|
||||
unset($ruleActions);
|
||||
asort($possibleActions);
|
||||
|
||||
return $possibleActions;
|
||||
}
|
||||
);
|
||||
return [
|
||||
$this->allJournalTriggers(),
|
||||
$this->allRuleTriggers(),
|
||||
$this->allActionTriggers(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,7 +72,7 @@ class Rule extends AbstractExtension
|
||||
$possibleTriggers = [];
|
||||
foreach ($ruleTriggers as $key) {
|
||||
if ('user_action' !== $key) {
|
||||
$possibleTriggers[$key] = (string)trans('firefly.rule_trigger_'.$key.'_choice');
|
||||
$possibleTriggers[$key] = (string)trans('firefly.rule_trigger_' . $key . '_choice');
|
||||
}
|
||||
}
|
||||
unset($ruleTriggers);
|
||||
@@ -94,14 +84,24 @@ class Rule extends AbstractExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return TwigFunction
|
||||
*/
|
||||
public function getFunctions(): array
|
||||
public function allActionTriggers(): TwigFunction
|
||||
{
|
||||
return [
|
||||
$this->allJournalTriggers(),
|
||||
$this->allRuleTriggers(),
|
||||
$this->allActionTriggers(),
|
||||
];
|
||||
return new TwigFunction(
|
||||
'allRuleActions',
|
||||
static function () {
|
||||
// array of valid values for actions
|
||||
$ruleActions = array_keys(Config::get('firefly.rule-actions'));
|
||||
$possibleActions = [];
|
||||
foreach ($ruleActions as $key) {
|
||||
$possibleActions[$key] = (string)trans('firefly.rule_action_' . $key . '_choice');
|
||||
}
|
||||
unset($ruleActions);
|
||||
asort($possibleActions);
|
||||
|
||||
return $possibleActions;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,201 @@ class TransactionGroupTwig extends AbstractExtension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate normal amount for transaction from a transaction group.
|
||||
*
|
||||
* @param array $array
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function normalJournalArrayAmount(array $array): string
|
||||
{
|
||||
$type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL;
|
||||
$amount = $array['amount'] ?? '0';
|
||||
$colored = true;
|
||||
$sourceType = $array['source_account_type'] ?? 'invalid';
|
||||
$amount = $this->signAmount($amount, $type, $sourceType);
|
||||
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$colored = false;
|
||||
}
|
||||
|
||||
$result = app('amount')->formatFlat($array['currency_symbol'], (int)$array['currency_decimal_places'], $amount, $colored);
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $amount
|
||||
* @param string $transactionType
|
||||
* @param string $sourceType
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function signAmount(string $amount, string $transactionType, string $sourceType): string
|
||||
{
|
||||
// withdrawals stay negative
|
||||
if ($transactionType !== TransactionType::WITHDRAWAL) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
// opening balance and it comes from initial balance? its expense.
|
||||
if ($transactionType === TransactionType::OPENING_BALANCE && AccountType::INITIAL_BALANCE !== $sourceType) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
// reconciliation and it comes from reconciliation?
|
||||
if ($transactionType === TransactionType::RECONCILIATION && AccountType::RECONCILIATION !== $sourceType) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
return $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate foreign amount for transaction from a transaction group.
|
||||
*
|
||||
* @param array $array
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function foreignJournalArrayAmount(array $array): string
|
||||
{
|
||||
$type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL;
|
||||
$amount = $array['foreign_amount'] ?? '0';
|
||||
$colored = true;
|
||||
|
||||
$sourceType = $array['source_account_type'] ?? 'invalid';
|
||||
$amount = $this->signAmount($amount, $type, $sourceType);
|
||||
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$colored = false;
|
||||
}
|
||||
$result = app('amount')->formatFlat($array['foreign_currency_symbol'], (int)$array['foreign_currency_decimal_places'], $amount, $colored);
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the amount for a single journal object.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
public function journalObjectAmount(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'journalObjectAmount',
|
||||
function (TransactionJournal $journal): string {
|
||||
$result = $this->normalJournalObjectAmount($journal);
|
||||
// now append foreign amount, if any.
|
||||
if ($this->journalObjectHasForeign($journal)) {
|
||||
$foreign = $this->foreignJournalObjectAmount($journal);
|
||||
$result = sprintf('%s (%s)', $result, $foreign);
|
||||
}
|
||||
|
||||
return $result;
|
||||
},
|
||||
['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate normal amount for transaction from a transaction group.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function normalJournalObjectAmount(TransactionJournal $journal): string
|
||||
{
|
||||
$type = $journal->transactionType->type;
|
||||
$first = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
$currency = $journal->transactionCurrency;
|
||||
$amount = $first->amount ?? '0';
|
||||
$colored = true;
|
||||
$sourceType = $first->account()->first()->accountType()->first()->type;
|
||||
|
||||
$amount = $this->signAmount($amount, $type, $sourceType);
|
||||
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$colored = false;
|
||||
}
|
||||
$result = app('amount')->formatFlat($currency->symbol, (int)$currency->decimal_places, $amount, $colored);
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function journalObjectHasForeign(TransactionJournal $journal): bool
|
||||
{
|
||||
/** @var Transaction $first */
|
||||
$first = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
|
||||
return '' !== $first->foreign_amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate foreign amount for journal from a transaction group.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function foreignJournalObjectAmount(TransactionJournal $journal): string
|
||||
{
|
||||
$type = $journal->transactionType->type;
|
||||
/** @var Transaction $first */
|
||||
$first = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
$currency = $first->foreignCurrency;
|
||||
$amount = '' === $first->foreign_amount ? '0' : $first->foreign_amount;
|
||||
$colored = true;
|
||||
$sourceType = $first->account()->first()->accountType()->first()->type;
|
||||
|
||||
$amount = $this->signAmount($amount, $type, $sourceType);
|
||||
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$colored = false;
|
||||
}
|
||||
$result = app('amount')->formatFlat($currency->symbol, (int)$currency->decimal_places, $amount, $colored);
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFunction
|
||||
*/
|
||||
public function journalHasMeta(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'journalHasMeta',
|
||||
static function (int $journalId, string $metaField) {
|
||||
$count = DB::table('journal_meta')
|
||||
->where('name', $metaField)
|
||||
->where('transaction_journal_id', $journalId)
|
||||
->whereNull('deleted_at')
|
||||
->count();
|
||||
|
||||
return 1 === $count;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFunction
|
||||
*/
|
||||
@@ -119,199 +314,4 @@ class TransactionGroupTwig extends AbstractExtension
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFunction
|
||||
*/
|
||||
public function journalHasMeta(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'journalHasMeta',
|
||||
static function (int $journalId, string $metaField) {
|
||||
$count = DB::table('journal_meta')
|
||||
->where('name', $metaField)
|
||||
->where('transaction_journal_id', $journalId)
|
||||
->whereNull('deleted_at')
|
||||
->count();
|
||||
|
||||
return 1 === $count;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the amount for a single journal object.
|
||||
*
|
||||
* @return TwigFunction
|
||||
*/
|
||||
public function journalObjectAmount(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'journalObjectAmount',
|
||||
function (TransactionJournal $journal): string {
|
||||
$result = $this->normalJournalObjectAmount($journal);
|
||||
// now append foreign amount, if any.
|
||||
if ($this->journalObjectHasForeign($journal)) {
|
||||
$foreign = $this->foreignJournalObjectAmount($journal);
|
||||
$result = sprintf('%s (%s)', $result, $foreign);
|
||||
}
|
||||
|
||||
return $result;
|
||||
},
|
||||
['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate foreign amount for transaction from a transaction group.
|
||||
*
|
||||
* @param array $array
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function foreignJournalArrayAmount(array $array): string
|
||||
{
|
||||
$type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL;
|
||||
$amount = $array['foreign_amount'] ?? '0';
|
||||
$colored = true;
|
||||
|
||||
$sourceType = $array['source_account_type'] ?? 'invalid';
|
||||
$amount = $this->signAmount($amount, $type, $sourceType);
|
||||
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$colored = false;
|
||||
}
|
||||
$result = app('amount')->formatFlat($array['foreign_currency_symbol'], (int)$array['foreign_currency_decimal_places'], $amount, $colored);
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate foreign amount for journal from a transaction group.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function foreignJournalObjectAmount(TransactionJournal $journal): string
|
||||
{
|
||||
$type = $journal->transactionType->type;
|
||||
/** @var Transaction $first */
|
||||
$first = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
$currency = $first->foreignCurrency;
|
||||
$amount = '' === $first->foreign_amount ? '0' : $first->foreign_amount;
|
||||
$colored = true;
|
||||
$sourceType = $first->account()->first()->accountType()->first()->type;
|
||||
|
||||
$amount = $this->signAmount($amount, $type, $sourceType);
|
||||
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$colored = false;
|
||||
}
|
||||
$result = app('amount')->formatFlat($currency->symbol, (int)$currency->decimal_places, $amount, $colored);
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function journalObjectHasForeign(TransactionJournal $journal): bool
|
||||
{
|
||||
/** @var Transaction $first */
|
||||
$first = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
|
||||
return '' !== $first->foreign_amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate normal amount for transaction from a transaction group.
|
||||
*
|
||||
* @param array $array
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function normalJournalArrayAmount(array $array): string
|
||||
{
|
||||
$type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL;
|
||||
$amount = $array['amount'] ?? '0';
|
||||
$colored = true;
|
||||
$sourceType = $array['source_account_type'] ?? 'invalid';
|
||||
$amount = $this->signAmount($amount, $type, $sourceType);
|
||||
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$colored = false;
|
||||
}
|
||||
|
||||
$result = app('amount')->formatFlat($array['currency_symbol'], (int)$array['currency_decimal_places'], $amount, $colored);
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate normal amount for transaction from a transaction group.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function normalJournalObjectAmount(TransactionJournal $journal): string
|
||||
{
|
||||
$type = $journal->transactionType->type;
|
||||
$first = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
$currency = $journal->transactionCurrency;
|
||||
$amount = $first->amount ?? '0';
|
||||
$colored = true;
|
||||
$sourceType = $first->account()->first()->accountType()->first()->type;
|
||||
|
||||
$amount = $this->signAmount($amount, $type, $sourceType);
|
||||
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$colored = false;
|
||||
}
|
||||
$result = app('amount')->formatFlat($currency->symbol, (int)$currency->decimal_places, $amount, $colored);
|
||||
if ($type === TransactionType::TRANSFER) {
|
||||
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $amount
|
||||
* @param string $transactionType
|
||||
* @param string $sourceType
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function signAmount(string $amount, string $transactionType, string $sourceType): string
|
||||
{
|
||||
// withdrawals stay negative
|
||||
if ($transactionType !== TransactionType::WITHDRAWAL) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
// opening balance and it comes from initial balance? its expense.
|
||||
if ($transactionType === TransactionType::OPENING_BALANCE && AccountType::INITIAL_BALANCE !== $sourceType) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
// reconciliation and it comes from reconciliation?
|
||||
if ($transactionType === TransactionType::RECONCILIATION && AccountType::RECONCILIATION !== $sourceType) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
return $amount;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user