Update various code for sqlite compatibility.

This commit is contained in:
James Cole
2024-12-28 13:36:25 +01:00
parent 42dc8486e9
commit 507040f1fd
9 changed files with 76 additions and 67 deletions

View File

@@ -103,10 +103,10 @@ class BasicController extends Controller
$billData = $this->getBillInformation($start, $end);
$spentData = $this->getLeftToSpendInfo($start, $end);
$netWorthData = $this->getNetWorthInfo($start, $end);
// $balanceData = [];
// $billData = [];
// $spentData = [];
// $netWorthData = [];
// $balanceData = [];
// $billData = [];
// $spentData = [];
// $netWorthData = [];
$total = array_merge($balanceData, $billData, $spentData, $netWorthData);
// give new keys
@@ -276,13 +276,13 @@ class BasicController extends Controller
*/
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
{
Log::debug(sprintf('Now in getLeftToSpendInfo("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
$return = [];
$today = today(config('app.timezone'));
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
$budgets = $this->budgetRepository->getActiveBudgets();
$spent = $this->opsRepository->sumExpenses($start, $end, null, $budgets);
$days = (int) $today->diffInDays($end, true) + 1;
Log::debug(sprintf('Now in getLeftToSpendInfo("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
foreach ($spent as $row) {
// either an amount was budgeted or 0 is available.

View File

@@ -45,7 +45,6 @@ class ReportsIntegrity extends Command
return 1;
}
$commands = [
// 'firefly-iii:add-timezones-to-dates',
'integrity:empty-objects',
'integrity:total-sums',
];

View File

@@ -32,6 +32,7 @@ use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
use FireflyIII\User;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Spatie\Period\Boundaries;
@@ -45,20 +46,20 @@ class BudgetLimitHandler
{
public function created(Created $event): void
{
app('log')->debug(sprintf('BudgetLimitHandler::created(#%s)', $event->budgetLimit->id));
Log::debug(sprintf('BudgetLimitHandler::created(#%s)', $event->budgetLimit->id));
$this->updateAvailableBudget($event->budgetLimit);
}
private function updateAvailableBudget(BudgetLimit $budgetLimit): void
{
app('log')->debug(sprintf('Now in updateAvailableBudget(#%d)', $budgetLimit->id));
Log::debug(sprintf('Now in updateAvailableBudget(limit #%d)', $budgetLimit->id));
$budget = Budget::find($budgetLimit->budget_id);
if (null === $budget) {
app('log')->warning('Budget is null, probably deleted, find deleted version.');
Log::warning('Budget is null, probably deleted, find deleted version.');
$budget = Budget::withTrashed()->find($budgetLimit->budget_id);
}
if (null === $budget) {
app('log')->warning('Budget is still null, cannot continue, will delete budget limit.');
Log::warning('Budget is still null, cannot continue, will delete budget limit.');
$budgetLimit->forceDelete();
return;
@@ -69,7 +70,7 @@ class BudgetLimitHandler
// sanity check. It happens when the budget has been deleted so the original user is unknown.
if (null === $user) {
app('log')->warning('User is null, cannot continue.');
Log::warning('User is null, cannot continue.');
$budgetLimit->forceDelete();
return;
@@ -82,7 +83,7 @@ class BudgetLimitHandler
try {
$viewRange = app('preferences')->getForUser($user, 'viewRange', '1M')->data;
} catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) {
app('log')->error($e->getMessage());
Log::error($e->getMessage());
$viewRange = '1M';
}
// safety catch
@@ -97,7 +98,7 @@ class BudgetLimitHandler
// limit period in total is:
$limitPeriod = Period::make($start, $end, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE());
app('log')->debug(sprintf('Limit period is from %s to %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
Log::debug(sprintf('Limit period is from %s to %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
// from the start until the end of the budget limit, need to loop!
$current = clone $start;
@@ -106,16 +107,14 @@ class BudgetLimitHandler
// create or find AB for this particular period, and set the amount accordingly.
/** @var null|AvailableBudget $availableBudget */
$availableBudget = $user->availableBudgets()->where('start_date', $current->format('Y-m-d'))->where(
'end_date',
$currentEnd->format('Y-m-d')
)->where('transaction_currency_id', $budgetLimit->transaction_currency_id)->first();
$availableBudget = $user->availableBudgets()->where('start_date', $current->format('Y-m-d'))->where('end_date', $currentEnd->format('Y-m-d'))->where('transaction_currency_id', $budgetLimit->transaction_currency_id)->first();
if (null !== $availableBudget) {
app('log')->debug('Found 1 AB, will update.');
Log::debug('Found 1 AB, will update.');
$this->calculateAmount($availableBudget);
}
if (null === $availableBudget) {
Log::debug('No AB found, will create.');
// if not exists:
$currentPeriod = Period::make($current, $currentEnd, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE());
$daily = $this->getDailyAmount($budgetLimit);
@@ -126,10 +125,10 @@ class BudgetLimitHandler
$amount = 0 === $budgetLimit->id ? '0' : $budgetLimit->amount;
}
if (0 === bccomp($amount, '0')) {
app('log')->debug('Amount is zero, will not create AB.');
Log::debug('Amount is zero, will not create AB.');
}
if (0 !== bccomp($amount, '0')) {
app('log')->debug(sprintf('Will create AB for period %s to %s', $current->format('Y-m-d'), $currentEnd->format('Y-m-d')));
Log::debug(sprintf('Will create AB for period %s to %s', $current->format('Y-m-d'), $currentEnd->format('Y-m-d')));
$availableBudget = new AvailableBudget(
[
'user_id' => $user->id,
@@ -143,7 +142,7 @@ class BudgetLimitHandler
]
);
$availableBudget->save();
app('log')->debug(sprintf('ID of new AB is #%d', $availableBudget->id));
Log::debug(sprintf('ID of new AB is #%d', $availableBudget->id));
}
}
@@ -158,7 +157,7 @@ class BudgetLimitHandler
$repository->setUser($availableBudget->user);
$newAmount = '0';
$abPeriod = Period::make($availableBudget->start_date, $availableBudget->end_date, Precision::DAY());
app('log')->debug(
Log::debug(
sprintf(
'Now at AB #%d, ("%s" to "%s")',
$availableBudget->id,
@@ -168,11 +167,11 @@ class BudgetLimitHandler
);
// have to recalculate everything just in case.
$set = $repository->getAllBudgetLimitsByCurrency($availableBudget->transactionCurrency, $availableBudget->start_date, $availableBudget->end_date);
app('log')->debug(sprintf('Found %d interesting budget limit(s).', $set->count()));
Log::debug(sprintf('Found %d interesting budget limit(s).', $set->count()));
/** @var BudgetLimit $budgetLimit */
foreach ($set as $budgetLimit) {
app('log')->debug(
Log::debug(
sprintf(
'Found interesting budget limit #%d ("%s" to "%s")',
$budgetLimit->id,
@@ -189,16 +188,16 @@ class BudgetLimitHandler
);
// if both equal each other, amount from this BL must be added to the AB
if ($limitPeriod->equals($abPeriod)) {
app('log')->debug('This budget limit is equal to the available budget period.');
Log::debug('This budget limit is equal to the available budget period.');
$newAmount = bcadd($newAmount, $budgetLimit->amount);
}
// if budget limit period is inside AB period, it can be added in full.
if (!$limitPeriod->equals($abPeriod) && $abPeriod->contains($limitPeriod)) {
app('log')->debug('This budget limit is smaller than the available budget period.');
Log::debug('This budget limit is smaller than the available budget period.');
$newAmount = bcadd($newAmount, $budgetLimit->amount);
}
if (!$limitPeriod->equals($abPeriod) && !$abPeriod->contains($limitPeriod) && $abPeriod->overlapsWith($limitPeriod)) {
app('log')->debug('This budget limit is something else entirely!');
Log::debug('This budget limit is something else entirely!');
$overlap = $abPeriod->overlap($limitPeriod);
if (null !== $overlap) {
$length = $overlap->length();
@@ -208,12 +207,12 @@ class BudgetLimitHandler
}
}
if (0 === bccomp('0', $newAmount)) {
app('log')->debug('New amount is zero, deleting AB.');
Log::debug('New amount is zero, deleting AB.');
$availableBudget->delete();
return;
}
app('log')->debug(sprintf('Concluded new amount for this AB must be %s', $newAmount));
Log::debug(sprintf('Concluded new amount for this AB must be %s', $newAmount));
$availableBudget->amount = app('steam')->bcround($newAmount, $availableBudget->transactionCurrency->decimal_places);
$availableBudget->save();
}
@@ -231,7 +230,7 @@ class BudgetLimitHandler
);
$days = $limitPeriod->length();
$amount = bcdiv($budgetLimit->amount, (string) $days, 12);
app('log')->debug(
Log::debug(
sprintf('Total amount for budget limit #%d is %s. Nr. of days is %d. Amount per day is %s', $budgetLimit->id, $budgetLimit->amount, $days, $amount)
);
@@ -240,7 +239,7 @@ class BudgetLimitHandler
public function deleted(Deleted $event): void
{
app('log')->debug(sprintf('BudgetLimitHandler::deleted(#%s)', $event->budgetLimit->id));
Log::debug(sprintf('BudgetLimitHandler::deleted(#%s)', $event->budgetLimit->id));
$budgetLimit = $event->budgetLimit;
$budgetLimit->id = 0;
$this->updateAvailableBudget($event->budgetLimit);
@@ -248,7 +247,7 @@ class BudgetLimitHandler
public function updated(Updated $event): void
{
app('log')->debug(sprintf('BudgetLimitHandler::updated(#%s)', $event->budgetLimit->id));
Log::debug(sprintf('BudgetLimitHandler::updated(#%s)', $event->budgetLimit->id));
$this->updateAvailableBudget($event->budgetLimit);
}
}

View File

@@ -46,6 +46,7 @@ class AvailableBudgetObserver
private function updateNativeAmount(AvailableBudget $availableBudget): void
{
if (!Amount::convertToNative($availableBudget->user)) {
Log::debug('Do not update native available amount of the available budget.');
return;
}
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($availableBudget->user->userGroup);

View File

@@ -46,6 +46,7 @@ class BudgetLimitObserver
private function updateNativeAmount(BudgetLimit $budgetLimit): void
{
if (!Amount::convertToNative($budgetLimit->budget->user)) {
Log::debug('Do not update native amount of the budget limit.');
return;
}
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($budgetLimit->budget->user->userGroup);

View File

@@ -62,8 +62,8 @@ class InstallController extends Controller
'migrate' => ['--seed' => true, '--force' => true],
'generate-keys' => [], // an exception :(
'firefly-iii:upgrade-database' => [],
'firefly-iii:correct-database' => [],
'firefly-iii:report-integrity' => [],
//'firefly-iii:correct-database' => [],
//'firefly-iii:report-integrity' => [],
'firefly-iii:set-latest-version' => ['--james-is-cool' => true],
'firefly-iii:verify-security-alerts' => [],
];

View File

@@ -68,8 +68,8 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
if (null !== $start && null !== $end) {
$query->where(
static function (Builder $q1) use ($start, $end): void { // @phpstan-ignore-line
$q1->where('start_date', '=', $start->format('Y-m-d'));
$q1->where('end_date', '=', $end->format('Y-m-d'));
$q1->where('start_date', '=', $start->format('Y-m-d H:i:s'));
$q1->where('end_date', '=', $end->format('Y-m-d H:i:s'));
}
);
}
@@ -128,12 +128,15 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
public function getAvailableBudgetWithCurrency(Carbon $start, Carbon $end): array
{
Log::debug(sprintf('Now in %s(%s, %s)',__METHOD__, $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
$return = [];
$availableBudgets = $this->user->availableBudgets()
->where('start_date', $start->format('Y-m-d'))
->where('end_date', $end->format('Y-m-d'))->get()
->where('start_date', $start->format('Y-m-d H:i:s'))
->where('end_date', $end->format('Y-m-d H:i:s'))->get()
;
Log::debug(sprintf('Found %d available budgets', $availableBudgets->count()));
// use native amount if necessary?
$convertToNative = Amount::convertToNative($this->user);
$default = Amount::getDefaultCurrency();
@@ -144,6 +147,7 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
$field = $convertToNative && $availableBudget->transaction_currency_id !== $default->id ? 'native_amount' : 'amount';
$return[$currencyId] ??= '0';
$return[$currencyId] = bcadd($return[$currencyId], $availableBudget->{$field});
Log::debug(sprintf('Add #%d %s (%s) for a total of %s', $currencyId, $availableBudget->{$field}, $field, $return[$currencyId]));
}
return $return;

View File

@@ -211,7 +211,7 @@ class OperationsRepository implements OperationsRepositoryInterface
?Collection $budgets = null,
?TransactionCurrency $currency = null
): array {
Log::debug('Start of sumExpenses.');
Log::debug(sprintf('Start of %s.', __METHOD__));
// this collector excludes all transfers TO liabilities (which are also withdrawals)
// because those expenses only become expenses once they move from the liability to the friend.

View File

@@ -28,9 +28,10 @@ use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\UserGroup;
use FireflyIII\Support\Facades\Preferences;
use FireflyIII\User;
use Illuminate\Support\Collection;
use FireflyIII\Support\Facades\Preferences;
use Illuminate\Support\Facades\Log;
/**
* Class Amount.
@@ -71,10 +72,14 @@ class Amount
public function convertToNative(?User $user = null): bool
{
if (null === $user) {
return Preferences::get('convert_to_native', false)->data && config('cer.enabled');
$result = Preferences::get('convert_to_native', false)->data && config('cer.enabled');
// Log::debug(sprintf('convertToNative [a]: %s', var_export($result, true)));
return $result;
}
return Preferences::getForUser($user, 'convert_to_native', false)->data && config('cer.enabled');
$result = Preferences::getForUser($user, 'convert_to_native', false)->data && config('cer.enabled');
//Log::debug(sprintf('convertToNative [b]: %s', var_export($result, true)));
return $result;
}
/**
@@ -83,16 +88,16 @@ class Amount
*/
public function getAmountFromJournalObject(TransactionJournal $journal): string
{
$convertToNative = $this->convertToNative();
$currency = $this->getDefaultCurrency();
$field = $convertToNative && $currency->id !== $journal->transaction_currency_id ? 'native_amount' : 'amount';
$convertToNative = $this->convertToNative();
$currency = $this->getDefaultCurrency();
$field = $convertToNative && $currency->id !== $journal->transaction_currency_id ? 'native_amount' : 'amount';
/** @var null|Transaction $sourceTransaction */
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
if (null === $sourceTransaction) {
return '0';
}
$amount = $sourceTransaction->{$field} ?? '0';
$amount = $sourceTransaction->{$field} ?? '0';
if ((int) $sourceTransaction->foreign_currency_id === $currency->id) {
// use foreign amount instead!
$amount = (string) $sourceTransaction->foreign_amount; // hard coded to be foreign amount.
@@ -111,15 +116,15 @@ class Amount
*/
public function formatFlat(string $symbol, int $decimalPlaces, string $amount, ?bool $coloured = null): string
{
$locale = app('steam')->getLocale();
$rounded = app('steam')->bcround($amount, $decimalPlaces);
$locale = app('steam')->getLocale();
$rounded = app('steam')->bcround($amount, $decimalPlaces);
$coloured ??= true;
$fmt = new \NumberFormatter($locale, \NumberFormatter::CURRENCY);
$fmt = new \NumberFormatter($locale, \NumberFormatter::CURRENCY);
$fmt->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, $symbol);
$fmt->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, $decimalPlaces);
$fmt->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, $decimalPlaces);
$result = (string) $fmt->format((float) $rounded); // intentional float
$result = (string) $fmt->format((float) $rounded); // intentional float
if (true === $coloured) {
if (1 === bccomp($rounded, '0')) {
@@ -165,7 +170,7 @@ class Amount
public function getDefaultCurrencyByUserGroup(UserGroup $userGroup): TransactionCurrency
{
$cache = new CacheProperties();
$cache = new CacheProperties();
$cache->addProperty('getDefaultCurrencyByGroup');
$cache->addProperty($userGroup->id);
if ($cache->has()) {
@@ -228,20 +233,20 @@ class Amount
private function getLocaleInfo(): array
{
// get config from preference, not from translation:
$locale = app('steam')->getLocale();
$array = app('steam')->getLocaleArray($locale);
$locale = app('steam')->getLocale();
$array = app('steam')->getLocaleArray($locale);
setlocale(LC_MONETARY, $array);
$info = localeconv();
$info = localeconv();
// correct variables
$info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes');
$info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes');
$info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes');
$info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes');
$info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space');
$info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space');
$info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space');
$info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space');
$fmt = new \NumberFormatter($locale, \NumberFormatter::CURRENCY);
$fmt = new \NumberFormatter($locale, \NumberFormatter::CURRENCY);
$info['mon_decimal_point'] = $fmt->getSymbol(\NumberFormatter::MONETARY_SEPARATOR_SYMBOL);
$info['mon_thousands_sep'] = $fmt->getSymbol(\NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL);
@@ -264,7 +269,7 @@ class Amount
public static function getAmountJsConfig(bool $sepBySpace, int $signPosn, string $sign, bool $csPrecedes): string
{
// negative first:
$space = ' ';
$space = ' ';
// require space between symbol and amount?
if (false === $sepBySpace) {
@@ -273,11 +278,11 @@ class Amount
// 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
$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
@@ -319,11 +324,11 @@ class Amount
}
// default is amount before currency
$format = $posA.$posD.'%v'.$space.$posB.'%s'.$posC.$posE;
$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;
$format = $posA . $posB . '%s' . $posC . $space . $posD . '%v' . $posE;
}
return $format;