Compare commits

..

15 Commits

Author SHA1 Message Date
github-actions[bot]
77095276e2 Merge pull request #11037 from firefly-iii/release-1759999962
🤖 Automatically merge the PR into the develop branch.
2025-10-09 10:52:52 +02:00
JC5
b77a8591dc 🤖 Auto commit for release 'develop' on 2025-10-09 2025-10-09 10:52:43 +02:00
James Cole
132d7d9ff8 Update some logging. 2025-10-09 06:27:15 +02:00
github-actions[bot]
a981e2c5cb Merge pull request #11034 from firefly-iii/release-1759932290
🤖 Automatically merge the PR into the develop branch.
2025-10-08 16:05:00 +02:00
JC5
77b88b7758 🤖 Auto commit for release 'develop' on 2025-10-08 2025-10-08 16:04:50 +02:00
James Cole
b9894eea57 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2025-10-08 15:58:43 +02:00
James Cole
469319a240 Remove plusses. 2025-10-08 15:56:33 +02:00
github-actions[bot]
5a55593e34 Merge pull request #11033 from firefly-iii/release-1759931464
🤖 Automatically merge the PR into the develop branch.
2025-10-08 15:51:16 +02:00
JC5
8979e5ad5a 🤖 Auto commit for release 'develop' on 2025-10-08 2025-10-08 15:51:04 +02:00
James Cole
3ab65c27ac Fix missing array indicator. 2025-10-08 15:47:03 +02:00
James Cole
a3cac6fd0f Fix #11031 2025-10-08 15:16:10 +02:00
James Cole
1acb5d8681 Merge pull request #11028 from codearena-bot/codearena/agent-a-6398119d-1759907698909
Adding Latin American Currency Support
2025-10-08 09:47:22 +02:00
mergify[bot]
f24cdc7897 Merge branch 'develop' into codearena/agent-a-6398119d-1759907698909 2025-10-08 07:23:07 +00:00
mergify[bot]
3582baf9f7 Merge branch 'develop' into codearena/agent-a-6398119d-1759907698909 2025-10-08 07:18:35 +00:00
codearena-bot
547a4e9dbb Update database/seeders/TransactionCurrencySeeder.php via CodeArena 2025-10-08 00:14:59 -07:00
10 changed files with 70 additions and 46 deletions

View File

@@ -4,6 +4,7 @@ Over time, many people have contributed to Firefly III. Their efforts are not al
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
## 2025
- codearena-bot
- Nicky De Maeyer
- Denis Iskandarov
- Lompi

View File

@@ -36,9 +36,9 @@ class PiggyBankEventFactory
{
public function create(TransactionJournal $journal, ?PiggyBank $piggyBank): void
{
app('log')->debug(sprintf('Now in PiggyBankEventCreate for a %s', $journal->transactionType->type));
Log::debug(sprintf('Now in PiggyBankEventCreate for a %s', $journal->transactionType->type));
if (!$piggyBank instanceof PiggyBank) {
app('log')->debug('Piggy bank is null');
Log::debug('Piggy bank is null');
return;
}
@@ -49,7 +49,7 @@ class PiggyBankEventFactory
$amount = $piggyRepos->getExactAmount($piggyBank, $journal);
if (0 === bccomp($amount, '0')) {
app('log')->debug('Amount is zero, will not create event.');
Log::debug('Amount is zero, will not create event.');
return;
}

View File

@@ -376,7 +376,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface, UserGroupInte
Log::debug(sprintf('leftOnAccount("%s","%s","%s")', $piggyBank->name, $account->name, $date->format('Y-m-d H:i:s')));
Log::debug(sprintf('leftOnAccount: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
// 2025-10-08 replace finalAccountBalance with accountsBalancesOptimized.
$balance = Steam::accountsBalancesOptimized(new Collection()->push($account), $date)[$account->id];
$balance = Steam::accountsBalancesOptimized(new Collection()->push($account), $date)[$account->id]['balance'];
// $balance = Steam::finalAccountBalance($account, $date)['balance'];
Log::debug(sprintf('Balance is: %s', $balance));

View File

@@ -139,7 +139,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
/** @var Rule $entry */
foreach ($set as $entry) {
if ($entry->order !== $count) {
app('log')->debug(sprintf('Rule #%d was on spot %d but must be on spot %d', $entry->id, $entry->order, $count));
Log::debug(sprintf('Rule #%d was on spot %d but must be on spot %d', $entry->id, $entry->order, $count));
$entry->order = $count;
$entry->save();
}
@@ -167,7 +167,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
if ($action->order !== $index) {
$action->order = $index;
$action->save();
app('log')->debug(sprintf('Rule action #%d was on spot %d but must be on spot %d', $action->id, $action->order, $index));
Log::debug(sprintf('Rule action #%d was on spot %d but must be on spot %d', $action->id, $action->order, $index));
}
++$index;
}
@@ -189,7 +189,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
if ($order !== $index) {
$trigger->order = $index;
$trigger->save();
app('log')->debug(sprintf('Rule trigger #%d was on spot %d but must be on spot %d', $trigger->id, $order, $index));
Log::debug(sprintf('Rule trigger #%d was on spot %d but must be on spot %d', $trigger->id, $order, $index));
}
++$index;
}
@@ -235,6 +235,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
public function getActiveStoreRules(RuleGroup $group): Collection
{
return $group->rules()
->orderBy('rules.order', 'ASC')
->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
->where('rule_triggers.trigger_type', 'user_action')
->where('rule_triggers.trigger_value', 'store-journal')
@@ -262,6 +263,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
[ // @phpstan-ignore-line
'rules' => static function (HasMany $query): void {
$query->orderBy('order', 'ASC');
$query->where('rules.active', true);
},
'rules.ruleTriggers' => static function (HasMany $query): void {
$query->orderBy('order', 'ASC');
@@ -275,23 +277,23 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
if (null === $filter) {
return $groups;
}
app('log')->debug(sprintf('Will filter getRuleGroupsWithRules on "%s".', $filter));
Log::debug(sprintf('Will filter getRuleGroupsWithRules on "%s".', $filter));
return $groups->map(
static function (RuleGroup $group) use ($filter) { // @phpstan-ignore-line
app('log')->debug(sprintf('Now filtering group #%d', $group->id));
Log::debug(sprintf('Now filtering group #%d', $group->id));
// filter the rules in the rule group:
$group->rules = $group->rules->filter(
static function (Rule $rule) use ($filter) {
app('log')->debug(sprintf('Now filtering rule #%d', $rule->id));
Log::debug(sprintf('Now filtering rule #%d', $rule->id));
foreach ($rule->ruleTriggers as $trigger) {
if ('user_action' === $trigger->trigger_type && $filter === $trigger->trigger_value) {
app('log')->debug(sprintf('Rule #%d triggers on %s, include it.', $rule->id, $filter));
Log::debug(sprintf('Rule #%d triggers on %s, include it.', $rule->id, $filter));
return true;
}
}
app('log')->debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
Log::debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
return false;
}
@@ -318,6 +320,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
[ // @phpstan-ignore-line
'rules' => static function (HasMany $query): void {
$query->orderBy('order', 'ASC');
$query->where('rules.active', true);
},
'rules.ruleTriggers' => static function (HasMany $query): void {
$query->orderBy('order', 'ASC');
@@ -331,23 +334,23 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
if (null === $filter) {
return $groups;
}
app('log')->debug(sprintf('Will filter getRuleGroupsWithRules on "%s".', $filter));
Log::debug(sprintf('Will filter getRuleGroupsWithRules on "%s".', $filter));
return $groups->map(
static function (RuleGroup $group) use ($filter) { // @phpstan-ignore-line
app('log')->debug(sprintf('Now filtering group #%d', $group->id));
Log::debug(sprintf('Now filtering group #%d', $group->id));
// filter the rules in the rule group:
$group->rules = $group->rules->filter(
static function (Rule $rule) use ($filter) {
app('log')->debug(sprintf('Now filtering rule #%d', $rule->id));
Log::debug(sprintf('Now filtering rule #%d', $rule->id));
foreach ($rule->ruleTriggers as $trigger) {
if ('user_action' === $trigger->trigger_type && $filter === $trigger->trigger_value) {
app('log')->debug(sprintf('Rule #%d triggers on %s, include it.', $rule->id, $filter));
Log::debug(sprintf('Rule #%d triggers on %s, include it.', $rule->id, $filter));
return true;
}
}
app('log')->debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
Log::debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
return false;
}
@@ -414,7 +417,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
->decrement('order')
;
$ruleGroup->order = $newOrder;
app('log')->debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
Log::debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
$ruleGroup->save();
return;
@@ -425,7 +428,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
->increment('order')
;
$ruleGroup->order = $newOrder;
app('log')->debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
Log::debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
$ruleGroup->save();
}

View File

@@ -59,9 +59,7 @@ class UpdatePiggyBank implements ActionInterface
$piggyBank = $this->findPiggyBank($user, $actionValue);
if (!$piggyBank instanceof PiggyBank) {
Log::info(
sprintf('No piggy bank named "%s", cant execute action #%d of rule #%d', $actionValue, $this->action->id, $this->action->rule_id)
);
Log::info(sprintf('No piggy bank named "%s", cant execute action #%d of rule #%d', $actionValue, $this->action->id, $this->action->rule_id));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_piggy', ['name' => $actionValue])));
return false;

View File

@@ -506,9 +506,23 @@ class SearchRuleEngine implements RuleEngineInterface
*/
private function fireGroup(RuleGroup $group): void
{
Log::debug(sprintf('Going to fire group #%d with %d rule(s)', $group->id, $group->rules->count()));
$rules = $group->rules()->orderBy('order', 'ASC')->get();
$rules = [];
if ($group->relationLoaded('rules')) {
Log::debug('Group rules have been pre-loaded, do not reload them.');
$rules = $group->rules;
}
if (!$group->relationLoaded('rules')) {
Log::debug('Group rules have NOT been pre-loaded, load them NOW.');
$rules = $group->rules()
->orderBy('rules.order', 'ASC')
// ->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
// ->where('rule_triggers.trigger_type', 'user_action')
// ->where('rule_triggers.trigger_value', 'store-journal')
->where('rules.active', true)
->get(['rules.*'])
;
}
Log::debug(sprintf('Going to fire group #%d with %d rule(s)', $group->id, $rules->count()));
/** @var Rule $rule */
foreach ($rules as $rule) {

26
composer.lock generated
View File

@@ -2485,34 +2485,34 @@
},
{
"name": "lcobucci/clock",
"version": "3.3.1",
"version": "3.4.0",
"source": {
"type": "git",
"url": "https://github.com/lcobucci/clock.git",
"reference": "db3713a61addfffd615b79bf0bc22f0ccc61b86b"
"reference": "f91d84f65cb3e974988bbe872b5da8ca132a155f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/lcobucci/clock/zipball/db3713a61addfffd615b79bf0bc22f0ccc61b86b",
"reference": "db3713a61addfffd615b79bf0bc22f0ccc61b86b",
"url": "https://api.github.com/repos/lcobucci/clock/zipball/f91d84f65cb3e974988bbe872b5da8ca132a155f",
"reference": "f91d84f65cb3e974988bbe872b5da8ca132a155f",
"shasum": ""
},
"require": {
"php": "~8.2.0 || ~8.3.0 || ~8.4.0",
"php": "~8.3.0 || ~8.4.0",
"psr/clock": "^1.0"
},
"provide": {
"psr/clock-implementation": "1.0"
},
"require-dev": {
"infection/infection": "^0.29",
"infection/infection": "^0.31",
"lcobucci/coding-standard": "^11.1.0",
"phpstan/extension-installer": "^1.3.1",
"phpstan/phpstan": "^1.10.25",
"phpstan/phpstan-deprecation-rules": "^1.1.3",
"phpstan/phpstan-phpunit": "^1.3.13",
"phpstan/phpstan-strict-rules": "^1.5.1",
"phpunit/phpunit": "^11.3.6"
"phpstan/phpstan": "^2.0.0",
"phpstan/phpstan-deprecation-rules": "^2.0.0",
"phpstan/phpstan-phpunit": "^2.0.0",
"phpstan/phpstan-strict-rules": "^2.0.0",
"phpunit/phpunit": "^12.0.0"
},
"type": "library",
"autoload": {
@@ -2533,7 +2533,7 @@
"description": "Yet another clock abstraction",
"support": {
"issues": "https://github.com/lcobucci/clock/issues",
"source": "https://github.com/lcobucci/clock/tree/3.3.1"
"source": "https://github.com/lcobucci/clock/tree/3.4.0"
},
"funding": [
{
@@ -2545,7 +2545,7 @@
"type": "patreon"
}
],
"time": "2024-09-24T20:45:14+00:00"
"time": "2025-10-08T18:00:48+00:00"
},
{
"name": "lcobucci/jwt",

View File

@@ -78,8 +78,8 @@ return [
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
// see cer.php for exchange rates feature flag.
],
'version' => 'develop/2025-10-08',
'build_time' => 1759908015,
'version' => 'develop/2025-10-09',
'build_time' => 1759999856,
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used.

View File

@@ -53,6 +53,10 @@ class TransactionCurrencySeeder extends Seeder
$currencies[] = ['code' => 'BRL', 'name' => 'Brazilian real', 'symbol' => 'R$', 'decimal_places' => 2];
$currencies[] = ['code' => 'CAD', 'name' => 'Canadian dollar', 'symbol' => 'C$', 'decimal_places' => 2];
$currencies[] = ['code' => 'MXN', 'name' => 'Mexican peso', 'symbol' => 'MX$', 'decimal_places' => 2];
$currencies[] = ['code' => 'PEN', 'name' => 'Peruvian Sol', 'symbol' => 'S/', 'decimal_places' => 2];
$currencies[] = ['code' => 'ARS', 'name' => 'Argentinian Peso', 'symbol' => '$', 'decimal_places' => 2];
$currencies[] = ['code' => 'COP', 'name' => 'Colombian Peso', 'symbol' => '$', 'decimal_places' => 2];
$currencies[] = ['code' => 'CLP', 'name' => 'Chilean Peso', 'symbol' => '$', 'decimal_places' => 2];
// oceanian currencies
$currencies[] = ['code' => 'IDR', 'name' => 'Indonesian rupiah', 'symbol' => 'Rp', 'decimal_places' => 2];

16
package-lock.json generated
View File

@@ -4075,9 +4075,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
"version": "2.8.13",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.13.tgz",
"integrity": "sha512-7s16KR8io8nIBWQyCYhmFhd+ebIzb9VKTzki+wOJXHTxTnV6+mFGH3+Jwn1zoKaY9/H9T/0BcKCZnzXljPnpSQ==",
"version": "2.8.14",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.14.tgz",
"integrity": "sha512-GM9c0cWWR8Ga7//Ves/9KRgTS8nLausCkP3CGiFLrnwA2CDUluXgaQqvrULoR2Ujrd/mz/lkX87F5BHFsNr5sQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -7908,13 +7908,17 @@
"license": "MIT"
},
"node_modules/loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
"integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz",
"integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.11.5"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/loader-utils": {