mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 10:47:00 +00:00 
			
		
		
		
	Compare commits
	
		
			27 Commits
		
	
	
		
			develop-20
			...
			develop-20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 33668a3688 | ||
|  | 5414a70abb | ||
|  | ad09c851f6 | ||
|  | c57f36820b | ||
|  | 6bb2702e07 | ||
|  | b1dbd3ee17 | ||
|  | 2d41db349a | ||
|  | 6b73b9327a | ||
|  | e3ea54329d | ||
|  | 686a76f32c | ||
|  | cdafb82a49 | ||
|  | 0075f10f98 | ||
|  | b70c0e4ab3 | ||
|  | 01aca092a1 | ||
|  | 8e6449ec12 | ||
|  | 984c4e2449 | ||
|  | 002c5485f5 | ||
|  | 12d74f15c0 | ||
|  | 2e87e179f0 | ||
|  | a861126c0f | ||
|  | 8f5e58e8ad | ||
|  | 6c26f1f677 | ||
|  | d7caaca5e4 | ||
|  | 835c81f329 | ||
|  | 1615b0cb29 | ||
|  | c07a279c81 | ||
|  | 1478dae316 | 
| @@ -23,6 +23,7 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Factory; | ||||
| 
 | ||||
| use FireflyIII\Events\Model\PiggyBank\ChangedAmount; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| @@ -237,20 +238,46 @@ class PiggyBankFactory | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /** @var array $info */ | ||||
|         foreach ($accounts as $info) { | ||||
|             $account = $this->accountRepository->find((int) ($info['account_id'] ?? 0)); | ||||
|             if (null === $account) { | ||||
|                 Log::debug(sprintf('Account #%d not found, skipping.', (int) ($info['account_id'] ?? 0))); | ||||
| 
 | ||||
|                 continue; | ||||
|             } | ||||
|             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']]; | ||||
|                 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']) { | ||||
|                 // 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']; | ||||
|                 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)) { | ||||
|                 $toBeLinked[$account->id] ??= []; | ||||
| @@ -258,6 +285,11 @@ class PiggyBankFactory | ||||
|             } | ||||
|         } | ||||
|         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 | ||||
|     { | ||||
|         Log::debug('RevenueAccounts'); | ||||
|         Log::debug('ExpenseAccounts'); | ||||
| 
 | ||||
|         /** @var Carbon $start */ | ||||
|         $start         = clone session('start', today(config('app.timezone'))->startOfMonth()); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end           = clone session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         $start->startOfDay(); | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         $cache         = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
| @@ -97,7 +100,6 @@ class AccountController extends Controller | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
|         $start->subDay(); | ||||
| 
 | ||||
|         // prep some vars:
 | ||||
|         $currencies    = []; | ||||
| @@ -557,6 +559,10 @@ class AccountController extends Controller | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end           = clone session('end', today(config('app.timezone'))->endOfMonth()); | ||||
| 
 | ||||
|         $start->startOfDay(); | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         $cache         = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
| @@ -565,7 +571,6 @@ class AccountController extends Controller | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
|         $start->subDay(); | ||||
| 
 | ||||
|         // prep some vars:
 | ||||
|         $currencies    = []; | ||||
|   | ||||
| @@ -78,13 +78,14 @@ class EditController extends Controller | ||||
|         $startDate    = $piggyBank->start_date?->format('Y-m-d'); | ||||
| 
 | ||||
|         $preFilled    = [ | ||||
|             'name'          => $piggyBank->name, | ||||
|             'target_amount' => app('steam')->bcround($piggyBank->target_amount, $piggyBank->transactionCurrency->decimal_places), | ||||
|             'target_date'   => $targetDate, | ||||
|             'start_date'    => $startDate, | ||||
|             'accounts'      => [], | ||||
|             'object_group'  => null !== $piggyBank->objectGroups->first() ? $piggyBank->objectGroups->first()->title : '', | ||||
|             'notes'         => null === $note ? '' : $note->text, | ||||
|             'name'                    => $piggyBank->name, | ||||
|             'transaction_currency_id' => (int) $piggyBank->transaction_currency_id, | ||||
|             'target_amount'           => app('steam')->bcround($piggyBank->target_amount, $piggyBank->transactionCurrency->decimal_places), | ||||
|             'target_date'             => $targetDate, | ||||
|             'start_date'              => $startDate, | ||||
|             'accounts'                => [], | ||||
|             'object_group'            => null !== $piggyBank->objectGroups->first() ? $piggyBank->objectGroups->first()->title : '', | ||||
|             'notes'                   => null === $note ? '' : $note->text, | ||||
|         ]; | ||||
|         foreach ($piggyBank->accounts as $account) { | ||||
|             $preFilled['accounts'][] = $account->id; | ||||
|   | ||||
| @@ -32,11 +32,11 @@ use Symfony\Component\HttpFoundation\Request; | ||||
| class TrustProxies extends Middleware | ||||
| { | ||||
|     // After...
 | ||||
|     protected $headers | ||||
|         = Request::HEADER_X_FORWARDED_FOR | ||||
|     protected $headers = Request::HEADER_X_FORWARDED_FOR | ||||
|         | Request::HEADER_X_FORWARDED_HOST | ||||
|         | Request::HEADER_X_FORWARDED_PORT | ||||
|         | Request::HEADER_X_FORWARDED_PROTO | ||||
|         | Request::HEADER_X_FORWARDED_PREFIX | ||||
|         | Request::HEADER_X_FORWARDED_AWS_ELB; | ||||
| 
 | ||||
|     /** | ||||
|   | ||||
| @@ -49,12 +49,13 @@ class PiggyBankUpdateRequest extends FormRequest | ||||
|     { | ||||
|         $accounts = $this->get('accounts'); | ||||
|         $data     = [ | ||||
|             'name'               => $this->convertString('name'), | ||||
|             'start_date'         => $this->getCarbonDate('start_date'), | ||||
|             'target_amount'      => trim($this->convertString('target_amount')), | ||||
|             'target_date'        => $this->getCarbonDate('target_date'), | ||||
|             'notes'              => $this->stringWithNewlines('notes'), | ||||
|             'object_group_title' => $this->convertString('object_group'), | ||||
|             'name'                    => $this->convertString('name'), | ||||
|             'start_date'              => $this->getCarbonDate('start_date'), | ||||
|             'target_amount'           => trim($this->convertString('target_amount')), | ||||
|             'target_date'             => $this->getCarbonDate('target_date'), | ||||
|             'transaction_currency_id' => $this->convertInteger('transaction_currency_id'), | ||||
|             'notes'                   => $this->stringWithNewlines('notes'), | ||||
|             'object_group_title'      => $this->convertString('object_group'), | ||||
|         ]; | ||||
|         if (!is_array($accounts)) { | ||||
|             $accounts = []; | ||||
| @@ -75,15 +76,16 @@ class PiggyBankUpdateRequest extends FormRequest | ||||
|         $piggy = $this->route()->parameter('piggyBank'); | ||||
| 
 | ||||
|         return [ | ||||
|             'name'          => sprintf('required|min:1|max:255|uniquePiggyBankForUser:%d', $piggy->id), | ||||
|             'accounts'      => 'required|array', | ||||
|             'accounts.*'    => 'required|belongsToUser:accounts', | ||||
|             'target_amount' => ['nullable', new IsValidPositiveAmount()], | ||||
|             'start_date'    => 'date', | ||||
|             'target_date'   => 'date|nullable', | ||||
|             'order'         => 'integer|max:32768|min:1', | ||||
|             'object_group'  => 'min:0|max:255', | ||||
|             'notes'         => 'min:1|max:32768|nullable', | ||||
|             'name'                    => sprintf('required|min:1|max:255|uniquePiggyBankForUser:%d', $piggy->id), | ||||
|             'accounts'                => 'required|array', | ||||
|             'accounts.*'              => 'required|belongsToUser:accounts', | ||||
|             'target_amount'           => ['nullable', new IsValidPositiveAmount()], | ||||
|             'start_date'              => 'date', | ||||
|             'transaction_currency_id' => 'exists:transaction_currencies,id', | ||||
|             'target_date'             => 'date|nullable', | ||||
|             'order'                   => 'integer|max:32768|min:1', | ||||
|             '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\PiggyBank; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups; | ||||
| use FireflyIII\Support\Http\Api\ExchangeRateConverter; | ||||
| @@ -223,6 +224,8 @@ trait ModifiesPiggyBanks | ||||
|         $factory       = new PiggyBankFactory(); | ||||
|         $factory->user = $this->user; | ||||
| 
 | ||||
|         // the piggy bank currency is set or updated FIRST, if it exists.
 | ||||
| 
 | ||||
|         $factory->linkToAccountIds($piggyBank, $data['accounts'] ?? []); | ||||
| 
 | ||||
| 
 | ||||
| @@ -280,6 +283,13 @@ trait ModifiesPiggyBanks | ||||
|         if (array_key_exists('name', $data) && '' !== $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']) { | ||||
|             $piggyBank->target_amount = $data['target_amount']; | ||||
|         } | ||||
|   | ||||
| @@ -57,6 +57,7 @@ use FireflyIII\Support\Facades\Steam; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use League\Csv\CannotInsertRecord; | ||||
| use League\Csv\Exception; | ||||
| 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. | ||||
| 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 | ||||
| 
 | ||||
| ### Added | ||||
|   | ||||
| @@ -78,7 +78,7 @@ return [ | ||||
|         'running_balance_column' => env('USE_RUNNING_BALANCE', false), | ||||
|         // see cer.php for exchange rates feature flag.
 | ||||
|     ], | ||||
|     'version'                      => 'develop/2025-04-20', | ||||
|     'version'                      => 'develop/2025-04-21', | ||||
|     'api_version'                  => '2.1.0', // field is no longer used.
 | ||||
|     'db_version'                   => 25, | ||||
| 
 | ||||
|   | ||||
| @@ -216,7 +216,7 @@ export default { | ||||
|           } | ||||
|         }, | ||||
|         selectedItem: function (e) { | ||||
|           console.log('In SelectedItem()'); | ||||
|           // console.log('In SelectedItem()'); | ||||
|           if (typeof this.name === 'undefined') { | ||||
|             // console.log('Is undefined'); | ||||
|             return; | ||||
|   | ||||
| @@ -540,12 +540,18 @@ export default { | ||||
|                     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 ('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_name = transaction.foreign_currency_name; | ||||
|                 result.destination_account.currency_code = transaction.foreign_currency_code; | ||||
|                 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. | ||||
|                 for (const key in this.currencies) { | ||||
|                     if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) { | ||||
|  | ||||
|                         if ( | ||||
|                             parseInt(this.currencies[key].id) === parseInt(this.destination.currency_id) | ||||
|                         ) { | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
|                     <div class="box-body"> | ||||
|                         {{ ExpandedForm.text('name') }} | ||||
|                         {{ 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'|_   }) }} | ||||
|  | ||||
|                     </div> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user