mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-11-19 08:00:19 +00:00
Merge pull request #10170 from firefly-iii/develop
🤖 Automatically merge the PR into the main branch.
This commit is contained in:
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Factory;
|
namespace FireflyIII\Factory;
|
||||||
|
|
||||||
|
use FireflyIII\Events\Model\PiggyBank\ChangedAmount;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
@@ -237,20 +238,46 @@ class PiggyBankFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @var array $info */
|
/** @var array $info */
|
||||||
foreach ($accounts as $info) {
|
foreach ($accounts as $info) {
|
||||||
$account = $this->accountRepository->find((int) ($info['account_id'] ?? 0));
|
$account = $this->accountRepository->find((int) ($info['account_id'] ?? 0));
|
||||||
if (null === $account) {
|
if (null === $account) {
|
||||||
|
Log::debug(sprintf('Account #%d not found, skipping.', (int) ($info['account_id'] ?? 0)));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (array_key_exists('current_amount', $info) && null !== $info['current_amount']) {
|
if (array_key_exists('current_amount', $info) && null !== $info['current_amount']) {
|
||||||
|
// an amount is set, first check out if there is a difference with the previous amount.
|
||||||
|
$previous = $toBeLinked[$account->id]['current_amount'] ?? '0';
|
||||||
|
$diff = bcsub($info['current_amount'], $previous);
|
||||||
|
|
||||||
|
// create event for difference.
|
||||||
|
if (0 !== bccomp($diff, '0')) {
|
||||||
|
Log::debug(sprintf('[a] Will save event for difference %s (previous value was %s)', $diff, $previous));
|
||||||
|
event(new ChangedAmount($piggyBank, $diff, null, null));
|
||||||
|
}
|
||||||
|
|
||||||
$toBeLinked[$account->id] = ['current_amount' => $info['current_amount']];
|
$toBeLinked[$account->id] = ['current_amount' => $info['current_amount']];
|
||||||
Log::debug(sprintf('[a] Will link account #%d with amount %s', $account->id, $info['current_amount']));
|
Log::debug(sprintf('[a] Will link account #%d with amount %s', $account->id, $info['current_amount']));
|
||||||
}
|
}
|
||||||
if (array_key_exists('current_amount', $info) && null === $info['current_amount']) {
|
if (array_key_exists('current_amount', $info) && null === $info['current_amount']) {
|
||||||
|
// an amount is set, first check out if there is a difference with the previous amount.
|
||||||
|
$previous = $toBeLinked[$account->id]['current_amount'] ?? '0';
|
||||||
|
$diff = bcsub('0', $previous);
|
||||||
|
|
||||||
|
// create event for difference.
|
||||||
|
if (0 !== bccomp($diff, '0')) {
|
||||||
|
Log::debug(sprintf('[b] Will save event for difference %s (previous value was %s)', $diff, $previous));
|
||||||
|
event(new ChangedAmount($piggyBank, $diff, null, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
// no amount set, use previous amount or go to ZERO.
|
||||||
$toBeLinked[$account->id] = ['current_amount' => $toBeLinked[$account->id]['current_amount'] ?? '0'];
|
$toBeLinked[$account->id] = ['current_amount' => $toBeLinked[$account->id]['current_amount'] ?? '0'];
|
||||||
Log::debug(sprintf('[b] Will link account #%d with amount %s', $account->id, $toBeLinked[$account->id]['current_amount'] ?? '0'));
|
Log::debug(sprintf('[b] Will link account #%d with amount %s', $account->id, $toBeLinked[$account->id]['current_amount'] ?? '0'));
|
||||||
|
|
||||||
|
// create event:
|
||||||
|
Log::debug('linkToAccountIds: Trigger change for positive amount [b].');
|
||||||
|
event(new ChangedAmount($piggyBank, $toBeLinked[$account->id]['current_amount'], null, null));
|
||||||
}
|
}
|
||||||
if (!array_key_exists('current_amount', $info)) {
|
if (!array_key_exists('current_amount', $info)) {
|
||||||
$toBeLinked[$account->id] ??= [];
|
$toBeLinked[$account->id] ??= [];
|
||||||
@@ -258,6 +285,11 @@ class PiggyBankFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log::debug(sprintf('Link information: %s', json_encode($toBeLinked)));
|
Log::debug(sprintf('Link information: %s', json_encode($toBeLinked)));
|
||||||
$piggyBank->accounts()->sync($toBeLinked);
|
if (0 !== count($toBeLinked)) {
|
||||||
|
$piggyBank->accounts()->sync($toBeLinked);
|
||||||
|
}
|
||||||
|
if (0 === count($toBeLinked)) {
|
||||||
|
Log::warning('No accounts to link to piggy bank, will not change whatever is there now.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,13 +82,16 @@ class AccountController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function expenseAccounts(): JsonResponse
|
public function expenseAccounts(): JsonResponse
|
||||||
{
|
{
|
||||||
Log::debug('RevenueAccounts');
|
Log::debug('ExpenseAccounts');
|
||||||
|
|
||||||
/** @var Carbon $start */
|
/** @var Carbon $start */
|
||||||
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty($start);
|
$cache->addProperty($start);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
@@ -97,7 +100,6 @@ class AccountController extends Controller
|
|||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return response()->json($cache->get());
|
return response()->json($cache->get());
|
||||||
}
|
}
|
||||||
$start->subDay();
|
|
||||||
|
|
||||||
// prep some vars:
|
// prep some vars:
|
||||||
$currencies = [];
|
$currencies = [];
|
||||||
@@ -557,6 +559,10 @@ class AccountController extends Controller
|
|||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
|
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty($start);
|
$cache->addProperty($start);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
@@ -565,7 +571,6 @@ class AccountController extends Controller
|
|||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return response()->json($cache->get());
|
return response()->json($cache->get());
|
||||||
}
|
}
|
||||||
$start->subDay();
|
|
||||||
|
|
||||||
// prep some vars:
|
// prep some vars:
|
||||||
$currencies = [];
|
$currencies = [];
|
||||||
|
|||||||
@@ -78,13 +78,14 @@ class EditController extends Controller
|
|||||||
$startDate = $piggyBank->start_date?->format('Y-m-d');
|
$startDate = $piggyBank->start_date?->format('Y-m-d');
|
||||||
|
|
||||||
$preFilled = [
|
$preFilled = [
|
||||||
'name' => $piggyBank->name,
|
'name' => $piggyBank->name,
|
||||||
'target_amount' => app('steam')->bcround($piggyBank->target_amount, $piggyBank->transactionCurrency->decimal_places),
|
'transaction_currency_id' => (int) $piggyBank->transaction_currency_id,
|
||||||
'target_date' => $targetDate,
|
'target_amount' => app('steam')->bcround($piggyBank->target_amount, $piggyBank->transactionCurrency->decimal_places),
|
||||||
'start_date' => $startDate,
|
'target_date' => $targetDate,
|
||||||
'accounts' => [],
|
'start_date' => $startDate,
|
||||||
'object_group' => null !== $piggyBank->objectGroups->first() ? $piggyBank->objectGroups->first()->title : '',
|
'accounts' => [],
|
||||||
'notes' => null === $note ? '' : $note->text,
|
'object_group' => null !== $piggyBank->objectGroups->first() ? $piggyBank->objectGroups->first()->title : '',
|
||||||
|
'notes' => null === $note ? '' : $note->text,
|
||||||
];
|
];
|
||||||
foreach ($piggyBank->accounts as $account) {
|
foreach ($piggyBank->accounts as $account) {
|
||||||
$preFilled['accounts'][] = $account->id;
|
$preFilled['accounts'][] = $account->id;
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
class TrustProxies extends Middleware
|
class TrustProxies extends Middleware
|
||||||
{
|
{
|
||||||
// After...
|
// After...
|
||||||
protected $headers
|
protected $headers = Request::HEADER_X_FORWARDED_FOR
|
||||||
= Request::HEADER_X_FORWARDED_FOR
|
|
||||||
| Request::HEADER_X_FORWARDED_HOST
|
| Request::HEADER_X_FORWARDED_HOST
|
||||||
| Request::HEADER_X_FORWARDED_PORT
|
| Request::HEADER_X_FORWARDED_PORT
|
||||||
| Request::HEADER_X_FORWARDED_PROTO
|
| Request::HEADER_X_FORWARDED_PROTO
|
||||||
|
| Request::HEADER_X_FORWARDED_PREFIX
|
||||||
| Request::HEADER_X_FORWARDED_AWS_ELB;
|
| Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -49,12 +49,13 @@ class PiggyBankUpdateRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
$accounts = $this->get('accounts');
|
$accounts = $this->get('accounts');
|
||||||
$data = [
|
$data = [
|
||||||
'name' => $this->convertString('name'),
|
'name' => $this->convertString('name'),
|
||||||
'start_date' => $this->getCarbonDate('start_date'),
|
'start_date' => $this->getCarbonDate('start_date'),
|
||||||
'target_amount' => trim($this->convertString('target_amount')),
|
'target_amount' => trim($this->convertString('target_amount')),
|
||||||
'target_date' => $this->getCarbonDate('target_date'),
|
'target_date' => $this->getCarbonDate('target_date'),
|
||||||
'notes' => $this->stringWithNewlines('notes'),
|
'transaction_currency_id' => $this->convertInteger('transaction_currency_id'),
|
||||||
'object_group_title' => $this->convertString('object_group'),
|
'notes' => $this->stringWithNewlines('notes'),
|
||||||
|
'object_group_title' => $this->convertString('object_group'),
|
||||||
];
|
];
|
||||||
if (!is_array($accounts)) {
|
if (!is_array($accounts)) {
|
||||||
$accounts = [];
|
$accounts = [];
|
||||||
@@ -75,15 +76,16 @@ class PiggyBankUpdateRequest extends FormRequest
|
|||||||
$piggy = $this->route()->parameter('piggyBank');
|
$piggy = $this->route()->parameter('piggyBank');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'name' => sprintf('required|min:1|max:255|uniquePiggyBankForUser:%d', $piggy->id),
|
'name' => sprintf('required|min:1|max:255|uniquePiggyBankForUser:%d', $piggy->id),
|
||||||
'accounts' => 'required|array',
|
'accounts' => 'required|array',
|
||||||
'accounts.*' => 'required|belongsToUser:accounts',
|
'accounts.*' => 'required|belongsToUser:accounts',
|
||||||
'target_amount' => ['nullable', new IsValidPositiveAmount()],
|
'target_amount' => ['nullable', new IsValidPositiveAmount()],
|
||||||
'start_date' => 'date',
|
'start_date' => 'date',
|
||||||
'target_date' => 'date|nullable',
|
'transaction_currency_id' => 'exists:transaction_currencies,id',
|
||||||
'order' => 'integer|max:32768|min:1',
|
'target_date' => 'date|nullable',
|
||||||
'object_group' => 'min:0|max:255',
|
'order' => 'integer|max:32768|min:1',
|
||||||
'notes' => 'min:1|max:32768|nullable',
|
'object_group' => 'min:0|max:255',
|
||||||
|
'notes' => 'min:1|max:32768|nullable',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ use FireflyIII\Models\Account;
|
|||||||
use FireflyIII\Models\Note;
|
use FireflyIII\Models\Note;
|
||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\Transaction;
|
||||||
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
|
use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
|
||||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||||
@@ -223,6 +224,8 @@ trait ModifiesPiggyBanks
|
|||||||
$factory = new PiggyBankFactory();
|
$factory = new PiggyBankFactory();
|
||||||
$factory->user = $this->user;
|
$factory->user = $this->user;
|
||||||
|
|
||||||
|
// the piggy bank currency is set or updated FIRST, if it exists.
|
||||||
|
|
||||||
$factory->linkToAccountIds($piggyBank, $data['accounts'] ?? []);
|
$factory->linkToAccountIds($piggyBank, $data['accounts'] ?? []);
|
||||||
|
|
||||||
|
|
||||||
@@ -280,6 +283,13 @@ trait ModifiesPiggyBanks
|
|||||||
if (array_key_exists('name', $data) && '' !== $data['name']) {
|
if (array_key_exists('name', $data) && '' !== $data['name']) {
|
||||||
$piggyBank->name = $data['name'];
|
$piggyBank->name = $data['name'];
|
||||||
}
|
}
|
||||||
|
if (array_key_exists('transaction_currency_id', $data) && is_int($data['transaction_currency_id'])) {
|
||||||
|
$currency = TransactionCurrency::find($data['transaction_currency_id']);
|
||||||
|
if (null !== $currency) {
|
||||||
|
$piggyBank->transaction_currency_id = $currency->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (array_key_exists('target_amount', $data) && '' !== $data['target_amount']) {
|
if (array_key_exists('target_amount', $data) && '' !== $data['target_amount']) {
|
||||||
$piggyBank->target_amount = $data['target_amount'];
|
$piggyBank->target_amount = $data['target_amount'];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ use FireflyIII\Support\Facades\Steam;
|
|||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
use League\Csv\CannotInsertRecord;
|
use League\Csv\CannotInsertRecord;
|
||||||
use League\Csv\Exception;
|
use League\Csv\Exception;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|||||||
10
changelog.md
10
changelog.md
@@ -3,6 +3,16 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
## 6.2.12 - 2025-04-21
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- [Issue 9755](https://github.com/firefly-iii/firefly-iii/issues/9755) (Unable to create transactions with non-native currency accounts when "display amounts in native currency" is enabled) reported by @dicksonleong
|
||||||
|
- [Issue 9867](https://github.com/firefly-iii/firefly-iii/issues/9867) (Transactions from Jan 31 being counted in February) reported by @edbingo
|
||||||
|
- [Issue 9878](https://github.com/firefly-iii/firefly-iii/issues/9878) (Piggy bank currency - wrong setting displayed or setting not saved) reported by @dethegeek
|
||||||
|
- [Issue 10068](https://github.com/firefly-iii/firefly-iii/issues/10068) (Export Data isn't exporting all transactions in the data) reported by @firsttiger
|
||||||
|
- [Discussion 10162](https://github.com/orgs/firefly-iii/discussions/10162) (Reverse proxy and `X-Forwarded-Prefix` header) started by @frenchu
|
||||||
|
|
||||||
## 6.2.11 - 2025-04-21
|
## 6.2.11 - 2025-04-21
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ return [
|
|||||||
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
|
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
|
||||||
// see cer.php for exchange rates feature flag.
|
// see cer.php for exchange rates feature flag.
|
||||||
],
|
],
|
||||||
'version' => '6.2.11',
|
'version' => '6.2.12',
|
||||||
'api_version' => '2.1.0', // field is no longer used.
|
'api_version' => '2.1.0', // field is no longer used.
|
||||||
'db_version' => 25,
|
'db_version' => 25,
|
||||||
|
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectedItem: function (e) {
|
selectedItem: function (e) {
|
||||||
console.log('In SelectedItem()');
|
// console.log('In SelectedItem()');
|
||||||
if (typeof this.name === 'undefined') {
|
if (typeof this.name === 'undefined') {
|
||||||
// console.log('Is undefined');
|
// console.log('Is undefined');
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -540,12 +540,18 @@ export default {
|
|||||||
allowed_types: window.expectedSourceTypes.destination[this.ucFirst(transaction.type)]
|
allowed_types: window.expectedSourceTypes.destination[this.ucFirst(transaction.type)]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// console.log('Destination currency id is ' + result.destination_account.currency_id);
|
||||||
// if transaction type is transfer, the destination currency_id etc. MUST match the actual account currency info.
|
// if transaction type is transfer, the destination currency_id etc. MUST match the actual account currency info.
|
||||||
if ('transfer' === transaction.type && null !== transaction.foreign_currency_code) {
|
// OR if the transaction type is a withdrawal, and the destination account is a liability account, same as above.
|
||||||
|
if (
|
||||||
|
('transfer' === transaction.type && null !== transaction.foreign_currency_code) ||
|
||||||
|
('withdrawal' === transaction.type && ['Loan', 'Debt', 'Mortgage'].includes(transaction.destination_type) && null !== transaction.foreign_currency_code)
|
||||||
|
) {
|
||||||
result.destination_account.currency_id = transaction.foreign_currency_id;
|
result.destination_account.currency_id = transaction.foreign_currency_id;
|
||||||
result.destination_account.currency_name = transaction.foreign_currency_name;
|
result.destination_account.currency_name = transaction.foreign_currency_name;
|
||||||
result.destination_account.currency_code = transaction.foreign_currency_code;
|
result.destination_account.currency_code = transaction.foreign_currency_code;
|
||||||
result.destination_account.currency_decimal_places = transaction.foreign_currency_decimal_places;
|
result.destination_account.currency_decimal_places = transaction.foreign_currency_decimal_places;
|
||||||
|
// console.log('Set destination currency_id to ' + result.destination_account.currency_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,6 @@ export default {
|
|||||||
// lock dropdown list on currencyID of destination.
|
// lock dropdown list on currencyID of destination.
|
||||||
for (const key in this.currencies) {
|
for (const key in this.currencies) {
|
||||||
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
parseInt(this.currencies[key].id) === parseInt(this.destination.currency_id)
|
parseInt(this.currencies[key].id) === parseInt(this.destination.currency_id)
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
{{ ExpandedForm.text('name') }}
|
{{ ExpandedForm.text('name') }}
|
||||||
{{ ExpandedForm.amountNoCurrency('target_amount') }}
|
{{ ExpandedForm.amountNoCurrency('target_amount') }}
|
||||||
{{ CurrencyForm.currencyList('transaction_currency_id', null, {helpText:'piggy_default_currency'|_}) }}
|
{{ CurrencyForm.currencyList('transaction_currency_id', preFilled.transaction_currency_id, {helpText:'piggy_default_currency'|_}) }}
|
||||||
{{ AccountForm.assetLiabilityMultiAccountList('accounts', preFilled.accounts, {label: 'saveOnAccounts'|_, helpText: 'piggy_account_currency_match'|_ }) }}
|
{{ AccountForm.assetLiabilityMultiAccountList('accounts', preFilled.accounts, {label: 'saveOnAccounts'|_, helpText: 'piggy_account_currency_match'|_ }) }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user