mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-28 06:15:39 +00:00
Compare commits
17 Commits
develop-20
...
develop-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b58d809063 | ||
|
|
9e34314dbc | ||
|
|
e4aa218b5f | ||
|
|
31722477d4 | ||
|
|
ec82105433 | ||
|
|
146e164f04 | ||
|
|
7d37c93988 | ||
|
|
73dffacd9a | ||
|
|
d37304fa68 | ||
|
|
62f4da6063 | ||
|
|
760da08ab7 | ||
|
|
e68c4d4408 | ||
|
|
46a200aa1f | ||
|
|
c422039335 | ||
|
|
5971d155ef | ||
|
|
9e373a9b0d | ||
|
|
4fb61646b4 |
60
.github/workflows/release.yml
vendored
60
.github/workflows/release.yml
vendored
@@ -168,7 +168,7 @@ jobs:
|
|||||||
|
|
||||||
# if this is a develop build, slightly different variable names.
|
# if this is a develop build, slightly different variable names.
|
||||||
if [[ "develop" == "$version" ]]; then
|
if [[ "develop" == "$version" ]]; then
|
||||||
[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
#[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
||||||
releaseName=$version-$(date +'%Y%m%d')
|
releaseName=$version-$(date +'%Y%m%d')
|
||||||
originalName=$releaseName
|
originalName=$releaseName
|
||||||
zipName=FireflyIII-develop.zip
|
zipName=FireflyIII-develop.zip
|
||||||
@@ -177,7 +177,7 @@ jobs:
|
|||||||
|
|
||||||
# if this is a branch build, also slightly different variable names.
|
# if this is a branch build, also slightly different variable names.
|
||||||
if [[ "$version" == branch* ]]; then
|
if [[ "$version" == branch* ]]; then
|
||||||
[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
#[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
||||||
# branch builds overrule develop
|
# branch builds overrule develop
|
||||||
releaseName=$version-$(date +'%Y%m%d')
|
releaseName=$version-$(date +'%Y%m%d')
|
||||||
originalName=$releaseName
|
originalName=$releaseName
|
||||||
@@ -229,7 +229,7 @@ jobs:
|
|||||||
# describe the development release.
|
# describe the development release.
|
||||||
if [[ "develop" == "$version" ]]; then
|
if [[ "develop" == "$version" ]]; then
|
||||||
echo 'Develop release.'
|
echo 'Develop release.'
|
||||||
rm output.txt
|
rm -f output.txt
|
||||||
touch output.txt
|
touch output.txt
|
||||||
sudo chown -R runner:docker output.txt
|
sudo chown -R runner:docker output.txt
|
||||||
echo "Weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt
|
echo "Weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt
|
||||||
@@ -244,7 +244,7 @@ jobs:
|
|||||||
# describe a branch release
|
# describe a branch release
|
||||||
if [[ "$version" == branch* ]]; then
|
if [[ "$version" == branch* ]]; then
|
||||||
echo 'Branch release.'
|
echo 'Branch release.'
|
||||||
rm output.txt
|
rm -f output.txt
|
||||||
touch output.txt
|
touch output.txt
|
||||||
sudo chown -R runner:docker output.txt
|
sudo chown -R runner:docker output.txt
|
||||||
echo "Irregular BRANCH release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
|
echo "Irregular BRANCH release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
|
||||||
@@ -257,9 +257,45 @@ jobs:
|
|||||||
echo ":warning: Please be careful with this branch pre-release, as it may not work as expected." >> output.txt
|
echo ":warning: Please be careful with this branch pre-release, as it may not work as expected." >> output.txt
|
||||||
fi
|
fi
|
||||||
# describe the main release
|
# describe the main release
|
||||||
if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]]; then
|
if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]] && [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then
|
||||||
sudo chown -R runner:docker output.txt
|
|
||||||
echo 'Main release.'
|
echo 'Main release.'
|
||||||
|
sudo chown -R runner:docker output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo '### Instructions' >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||||
|
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||||
|
echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# describe alpha release
|
||||||
|
if [[ "$version" == *alpha* ]]; then
|
||||||
|
echo 'ALPHA release.'
|
||||||
|
rm -f output.txt
|
||||||
|
touch output.txt
|
||||||
|
sudo chown -R runner:docker output.txt
|
||||||
|
echo "Very early ALPHA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo '### Instructions' >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||||
|
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||||
|
echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# describe beta release
|
||||||
|
if [[ "$version" == *beta* ]]; then
|
||||||
|
echo 'BETA release.'
|
||||||
|
rm -f output.txt
|
||||||
|
touch output.txt
|
||||||
|
sudo chown -R runner:docker output.txt
|
||||||
|
echo "Very early BETA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||||
echo '' >> output.txt
|
echo '' >> output.txt
|
||||||
echo '### Instructions' >> output.txt
|
echo '### Instructions' >> output.txt
|
||||||
echo '' >> output.txt
|
echo '' >> output.txt
|
||||||
@@ -336,12 +372,12 @@ jobs:
|
|||||||
gh release upload $releaseName HEAD.txt
|
gh release upload $releaseName HEAD.txt
|
||||||
|
|
||||||
# remove all temporary files
|
# remove all temporary files
|
||||||
rm output.txt
|
rm -f output.txt
|
||||||
rm HEAD.txt
|
rm -f HEAD.txt
|
||||||
rm $zipName
|
rm -f $zipName
|
||||||
rm $zipName.sha256
|
rm -f $zipName.sha256
|
||||||
rm $tarName
|
rm -f $tarName
|
||||||
rm $tarName.sha256
|
rm -f $tarName.sha256
|
||||||
|
|
||||||
# merge main back into develop
|
# merge main back into develop
|
||||||
git checkout develop
|
git checkout develop
|
||||||
|
|||||||
@@ -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.
|
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
|
||||||
|
|
||||||
## 2024
|
## 2024
|
||||||
|
- TasneemTantawy
|
||||||
- Antônio Franco
|
- Antônio Franco
|
||||||
- yparitcher
|
- yparitcher
|
||||||
- Jhon Pedroza
|
- Jhon Pedroza
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
|
|||||||
use FireflyIII\Enums\AccountTypeEnum;
|
use FireflyIII\Enums\AccountTypeEnum;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\AccountType;
|
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Facades\Steam;
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
@@ -86,7 +85,7 @@ class AccountController extends Controller
|
|||||||
foreach ($result as $account) {
|
foreach ($result as $account) {
|
||||||
$nameWithBalance = $account->name;
|
$nameWithBalance = $account->name;
|
||||||
$currency = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
$currency = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
|
$useCurrency = $currency;
|
||||||
if (in_array($account->accountType->type, $this->balanceTypes, true)) {
|
if (in_array($account->accountType->type, $this->balanceTypes, true)) {
|
||||||
$balance = Steam::finalAccountBalance($account, $date);
|
$balance = Steam::finalAccountBalance($account, $date);
|
||||||
$key = $this->convertToNative && $currency->id !== $this->defaultCurrency->id ? 'native_balance' : 'balance';
|
$key = $this->convertToNative && $currency->id !== $this->defaultCurrency->id ? 'native_balance' : 'balance';
|
||||||
@@ -116,7 +115,7 @@ class AccountController extends Controller
|
|||||||
usort(
|
usort(
|
||||||
$return,
|
$return,
|
||||||
static function (array $left, array $right) {
|
static function (array $left, array $right) {
|
||||||
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
|
$order = [AccountTypeEnum::ASSET->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::EXPENSE->value];
|
||||||
$posA = (int) array_search($left['type'], $order, true);
|
$posA = (int) array_search($left['type'], $order, true);
|
||||||
$posB = (int) array_search($right['type'], $order, true);
|
$posB = (int) array_search($right['type'], $order, true);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Api\V2\Request\Chart;
|
namespace FireflyIII\Api\V2\Request\Chart;
|
||||||
|
|
||||||
use FireflyIII\Enums\UserRoleEnum;
|
use FireflyIII\Enums\UserRoleEnum;
|
||||||
use FireflyIII\Support\Http\Api\ParsesQueryFilters;
|
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
@@ -40,7 +39,6 @@ class ChartRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
use ChecksLogin;
|
use ChecksLogin;
|
||||||
use ConvertsDataTypes;
|
use ConvertsDataTypes;
|
||||||
use ParsesQueryFilters;
|
|
||||||
use ValidatesUserGroupTrait;
|
use ValidatesUserGroupTrait;
|
||||||
|
|
||||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ class BudgetLimitHandler
|
|||||||
);
|
);
|
||||||
$availableBudget->save();
|
$availableBudget->save();
|
||||||
Log::debug(sprintf('ID of new AB is #%d', $availableBudget->id));
|
Log::debug(sprintf('ID of new AB is #%d', $availableBudget->id));
|
||||||
|
$this->calculateAmount($availableBudget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class AvailableBudgetObserver
|
|||||||
{
|
{
|
||||||
public function created(AvailableBudget $availableBudget): void
|
public function created(AvailableBudget $availableBudget): void
|
||||||
{
|
{
|
||||||
Log::debug('Observe "created" of an available budget.');
|
// Log::debug('Observe "created" of an available budget.');
|
||||||
$this->updateNativeAmount($availableBudget);
|
$this->updateNativeAmount($availableBudget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ class AvailableBudgetObserver
|
|||||||
private function updateNativeAmount(AvailableBudget $availableBudget): void
|
private function updateNativeAmount(AvailableBudget $availableBudget): void
|
||||||
{
|
{
|
||||||
if (!Amount::convertToNative($availableBudget->user)) {
|
if (!Amount::convertToNative($availableBudget->user)) {
|
||||||
Log::debug('Do not update native available amount of the available budget.');
|
// Log::debug('Do not update native available amount of the available budget.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class BudgetLimitObserver
|
|||||||
private function updateNativeAmount(BudgetLimit $budgetLimit): void
|
private function updateNativeAmount(BudgetLimit $budgetLimit): void
|
||||||
{
|
{
|
||||||
if (!Amount::convertToNative($budgetLimit->budget->user)) {
|
if (!Amount::convertToNative($budgetLimit->budget->user)) {
|
||||||
Log::debug('Do not update native amount of the budget limit.');
|
// Log::debug('Do not update native amount of the budget limit.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ class CreateController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create(Request $request, string $objectType)
|
public function create(Request $request, string $objectType)
|
||||||
{
|
{
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
|
||||||
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
|
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
|
||||||
$subTitle = (string) trans(sprintf('firefly.make_new_%s_account', $objectType));
|
$subTitle = (string) trans(sprintf('firefly.make_new_%s_account', $objectType));
|
||||||
$roles = $this->getRoles();
|
$roles = $this->getRoles();
|
||||||
@@ -106,7 +105,7 @@ class CreateController extends Controller
|
|||||||
$request->session()->flash(
|
$request->session()->flash(
|
||||||
'preFilled',
|
'preFilled',
|
||||||
[
|
[
|
||||||
'currency_id' => $defaultCurrency->id,
|
'currency_id' => $this->defaultCurrency->id,
|
||||||
'include_net_worth' => $hasOldInput ? (bool) $request->old('include_net_worth') : true,
|
'include_net_worth' => $hasOldInput ? (bool) $request->old('include_net_worth') : true,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ class EditController extends Controller
|
|||||||
$openingBalanceAmount = '';
|
$openingBalanceAmount = '';
|
||||||
}
|
}
|
||||||
$openingBalanceDate = $repository->getOpeningBalanceDate($account);
|
$openingBalanceDate = $repository->getOpeningBalanceDate($account);
|
||||||
$currency = $this->repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
$currency = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
|
|
||||||
// include this account in net-worth charts?
|
// include this account in net-worth charts?
|
||||||
$includeNetWorth = $repository->getMetaValue($account, 'include_net_worth');
|
$includeNetWorth = $repository->getMetaValue($account, 'include_net_worth');
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class ReconcileController extends Controller
|
|||||||
|
|
||||||
return redirect(route('accounts.index', [config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type))]));
|
return redirect(route('accounts.index', [config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type))]));
|
||||||
}
|
}
|
||||||
$currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
$currency = $this->accountRepos->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
|
|
||||||
// no start or end:
|
// no start or end:
|
||||||
$range = app('navigation')->getViewRange(false);
|
$range = app('navigation')->getViewRange(false);
|
||||||
@@ -197,7 +197,7 @@ class ReconcileController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$reconciliation = $this->accountRepos->getReconciliation($account);
|
$reconciliation = $this->accountRepos->getReconciliation($account);
|
||||||
$currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
$currency = $this->accountRepos->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
$source = $reconciliation;
|
$source = $reconciliation;
|
||||||
$destination = $account;
|
$destination = $account;
|
||||||
if (1 === bccomp($difference, '0')) {
|
if (1 === bccomp($difference, '0')) {
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
|||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Facades\Amount;
|
|
||||||
use FireflyIII\Support\Facades\Steam;
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Controllers\PeriodOverview;
|
use FireflyIII\Support\Http\Controllers\PeriodOverview;
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
@@ -101,7 +100,7 @@ class ShowController extends Controller
|
|||||||
$page = (int) $request->get('page');
|
$page = (int) $request->get('page');
|
||||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||||
$accountCurrency = $this->repository->getAccountCurrency($account);
|
$accountCurrency = $this->repository->getAccountCurrency($account);
|
||||||
$currency = $accountCurrency ?? Amount::getDefaultCurrency();
|
$currency = $accountCurrency ?? $this->defaultCurrency;
|
||||||
$fStart = $start->isoFormat($this->monthAndDayFormat);
|
$fStart = $start->isoFormat($this->monthAndDayFormat);
|
||||||
$fEnd = $end->isoFormat($this->monthAndDayFormat);
|
$fEnd = $end->isoFormat($this->monthAndDayFormat);
|
||||||
$subTitle = (string) trans('firefly.journals_in_period_for_account', ['name' => $account->name, 'start' => $fStart, 'end' => $fEnd]);
|
$subTitle = (string) trans('firefly.journals_in_period_for_account', ['name' => $account->name, 'start' => $fStart, 'end' => $fEnd]);
|
||||||
@@ -178,7 +177,7 @@ class ShowController extends Controller
|
|||||||
$subTitleIcon = config('firefly.subIconsByIdentifier.'.$account->accountType->type);
|
$subTitleIcon = config('firefly.subIconsByIdentifier.'.$account->accountType->type);
|
||||||
$page = (int) $request->get('page');
|
$page = (int) $request->get('page');
|
||||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||||
$currency = $this->repository->getAccountCurrency($account) ?? Amount::getDefaultCurrency();
|
$currency = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
$subTitle = (string) trans('firefly.all_journals_for_account', ['name' => $account->name]);
|
$subTitle = (string) trans('firefly.all_journals_for_account', ['name' => $account->name]);
|
||||||
$periods = new Collection();
|
$periods = new Collection();
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class CreateController extends Controller
|
|||||||
$periods[$current] = (string) trans('firefly.repeat_freq_'.$current);
|
$periods[$current] = (string) trans('firefly.repeat_freq_'.$current);
|
||||||
}
|
}
|
||||||
$subTitle = (string) trans('firefly.create_new_bill');
|
$subTitle = (string) trans('firefly.create_new_bill');
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$defaultCurrency = $this->defaultCurrency;
|
||||||
|
|
||||||
// put previous url in session if not redirect from store (not "create another").
|
// put previous url in session if not redirect from store (not "create another").
|
||||||
if (true !== session('bills.create.fromStore')) {
|
if (true !== session('bills.create.fromStore')) {
|
||||||
|
|||||||
@@ -85,11 +85,10 @@ class EditController extends Controller
|
|||||||
$this->rememberPreviousUrl('bills.edit.url');
|
$this->rememberPreviousUrl('bills.edit.url');
|
||||||
}
|
}
|
||||||
|
|
||||||
$currency = app('amount')->getDefaultCurrency();
|
$bill->amount_min = app('steam')->bcround($bill->amount_min, $bill->transactionCurrency->decimal_places);
|
||||||
$bill->amount_min = app('steam')->bcround($bill->amount_min, $currency->decimal_places);
|
$bill->amount_max = app('steam')->bcround($bill->amount_max, $bill->transactionCurrency->decimal_places);
|
||||||
$bill->amount_max = app('steam')->bcround($bill->amount_max, $currency->decimal_places);
|
|
||||||
$rules = $this->repository->getRulesForBill($bill);
|
$rules = $this->repository->getRulesForBill($bill);
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$defaultCurrency = $this->defaultCurrency;
|
||||||
|
|
||||||
// code to handle active-checkboxes
|
// code to handle active-checkboxes
|
||||||
$hasOldInput = null !== $request->old('_token');
|
$hasOldInput = null !== $request->old('_token');
|
||||||
|
|||||||
@@ -86,11 +86,10 @@ class CreateController extends Controller
|
|||||||
'half_year' => (string) trans('firefly.auto_budget_period_half_year'),
|
'half_year' => (string) trans('firefly.auto_budget_period_half_year'),
|
||||||
'yearly' => (string) trans('firefly.auto_budget_period_yearly'),
|
'yearly' => (string) trans('firefly.auto_budget_period_yearly'),
|
||||||
];
|
];
|
||||||
$currency = app('amount')->getDefaultCurrency();
|
|
||||||
|
|
||||||
$preFilled = [
|
$preFilled = [
|
||||||
'auto_budget_period' => $hasOldInput ? (bool) $request->old('auto_budget_period') : 'monthly',
|
'auto_budget_period' => $hasOldInput ? (bool) $request->old('auto_budget_period') : 'monthly',
|
||||||
'auto_budget_currency_id' => $hasOldInput ? (int) $request->old('auto_budget_currency_id') : $currency->id,
|
'auto_budget_currency_id' => $hasOldInput ? (int) $request->old('auto_budget_currency_id') : $this->defaultCurrency->id,
|
||||||
];
|
];
|
||||||
|
|
||||||
$request->session()->flash('preFilled', $preFilled);
|
$request->session()->flash('preFilled', $preFilled);
|
||||||
|
|||||||
@@ -91,10 +91,9 @@ class EditController extends Controller
|
|||||||
|
|
||||||
// code to handle active-checkboxes
|
// code to handle active-checkboxes
|
||||||
$hasOldInput = null !== $request->old('_token');
|
$hasOldInput = null !== $request->old('_token');
|
||||||
$currency = app('amount')->getDefaultCurrency();
|
|
||||||
$preFilled = [
|
$preFilled = [
|
||||||
'active' => $hasOldInput ? (bool) $request->old('active') : $budget->active,
|
'active' => $hasOldInput ? (bool) $request->old('active') : $budget->active,
|
||||||
'auto_budget_currency_id' => $hasOldInput ? (int) $request->old('auto_budget_currency_id') : $currency->id,
|
'auto_budget_currency_id' => $hasOldInput ? (int) $request->old('auto_budget_currency_id') : $this->defaultCurrency->id,
|
||||||
];
|
];
|
||||||
if (null !== $autoBudget) {
|
if (null !== $autoBudget) {
|
||||||
$amount = $hasOldInput ? $request->old('auto_budget_amount') : $autoBudget->amount;
|
$amount = $hasOldInput ? $request->old('auto_budget_amount') : $autoBudget->amount;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ use Illuminate\Contracts\View\Factory;
|
|||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,7 +107,6 @@ class IndexController extends Controller
|
|||||||
$end ??= session('end', today(config('app.timezone'))->endOfMonth());
|
$end ??= session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
}
|
}
|
||||||
|
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
|
||||||
$currencies = $this->currencyRepository->get();
|
$currencies = $this->currencyRepository->get();
|
||||||
$budgeted = '0';
|
$budgeted = '0';
|
||||||
$spent = '0';
|
$spent = '0';
|
||||||
@@ -119,14 +119,14 @@ class IndexController extends Controller
|
|||||||
// get all available budgets:
|
// get all available budgets:
|
||||||
$availableBudgets = $this->getAllAvailableBudgets($start, $end);
|
$availableBudgets = $this->getAllAvailableBudgets($start, $end);
|
||||||
// get all active budgets:
|
// get all active budgets:
|
||||||
$budgets = $this->getAllBudgets($start, $end, $currencies, $defaultCurrency);
|
$budgets = $this->getAllBudgets($start, $end, $currencies, $this->defaultCurrency);
|
||||||
$sums = $this->getSums($budgets);
|
$sums = $this->getSums($budgets);
|
||||||
|
|
||||||
// get budgeted for default currency:
|
// get budgeted for default currency:
|
||||||
if (0 === count($availableBudgets)) {
|
if (0 === count($availableBudgets)) {
|
||||||
$budgeted = $this->blRepository->budgeted($start, $end, $defaultCurrency);
|
$budgeted = $this->blRepository->budgeted($start, $end, $this->defaultCurrency);
|
||||||
$spentArr = $this->opsRepository->sumExpenses($start, $end, null, null, $defaultCurrency);
|
$spentArr = $this->opsRepository->sumExpenses($start, $end, null, null, $this->defaultCurrency);
|
||||||
$spent = $spentArr[$defaultCurrency->id]['sum'] ?? '0';
|
$spent = $spentArr[$this->defaultCurrency->id]['sum'] ?? '0';
|
||||||
unset($spentArr);
|
unset($spentArr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,6 +136,7 @@ class IndexController extends Controller
|
|||||||
|
|
||||||
// get all inactive budgets, and simply list them:
|
// get all inactive budgets, and simply list them:
|
||||||
$inactive = $this->repository->getInactiveBudgets();
|
$inactive = $this->repository->getInactiveBudgets();
|
||||||
|
$defaultCurrency = $this->defaultCurrency;
|
||||||
|
|
||||||
return view(
|
return view(
|
||||||
'budgets.index',
|
'budgets.index',
|
||||||
@@ -162,6 +163,7 @@ class IndexController extends Controller
|
|||||||
|
|
||||||
private function getAllAvailableBudgets(Carbon $start, Carbon $end): array
|
private function getAllAvailableBudgets(Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
|
Log::debug(sprintf('Start of getAllAvailableBudgets("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
||||||
$converter = new ExchangeRateConverter();
|
$converter = new ExchangeRateConverter();
|
||||||
// get all available budgets.
|
// get all available budgets.
|
||||||
$ab = $this->abRepository->get($start, $end);
|
$ab = $this->abRepository->get($start, $end);
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ class AccountController extends Controller
|
|||||||
$currencies = [];
|
$currencies = [];
|
||||||
$chartData = [];
|
$chartData = [];
|
||||||
$tempData = [];
|
$tempData = [];
|
||||||
$default = Amount::getDefaultCurrency();
|
|
||||||
|
|
||||||
// grab all accounts and names
|
// grab all accounts and names
|
||||||
$accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::EXPENSE->value]);
|
$accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::EXPENSE->value]);
|
||||||
@@ -138,13 +137,13 @@ class AccountController extends Controller
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
|
// Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
|
||||||
$searchCode = $this->convertToNative ? $default->code : $key;
|
$searchCode = $this->convertToNative ? $this->defaultCurrency->code : $key;
|
||||||
Log::debug(sprintf('Search code is %s', $searchCode));
|
// Log::debug(sprintf('Search code is %s', $searchCode));
|
||||||
// see if there is an accompanying start amount.
|
// see if there is an accompanying start amount.
|
||||||
// grab the difference and find the currency.
|
// grab the difference and find the currency.
|
||||||
$startBalance = ($startBalances[$account->id][$key] ?? '0');
|
$startBalance = ($startBalances[$account->id][$key] ?? '0');
|
||||||
Log::debug(sprintf('Start balance is %s', $startBalance));
|
// Log::debug(sprintf('Start balance is %s', $startBalance));
|
||||||
$diff = bcsub($endBalance, $startBalance);
|
$diff = bcsub($endBalance, $startBalance);
|
||||||
$currencies[$searchCode] ??= $this->currencyRepository->findByCode($searchCode);
|
$currencies[$searchCode] ??= $this->currencyRepository->findByCode($searchCode);
|
||||||
if (0 !== bccomp($diff, '0')) {
|
if (0 !== bccomp($diff, '0')) {
|
||||||
@@ -562,7 +561,6 @@ class AccountController extends Controller
|
|||||||
$currencies = [];
|
$currencies = [];
|
||||||
$chartData = [];
|
$chartData = [];
|
||||||
$tempData = [];
|
$tempData = [];
|
||||||
$default = Amount::getDefaultCurrency();
|
|
||||||
|
|
||||||
// grab all accounts and names
|
// grab all accounts and names
|
||||||
$accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::REVENUE->value]);
|
$accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::REVENUE->value]);
|
||||||
@@ -598,13 +596,13 @@ class AccountController extends Controller
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
|
// Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
|
||||||
$searchCode = $this->convertToNative ? $default->code : $key;
|
$searchCode = $this->convertToNative ? $this->defaultCurrency->code : $key;
|
||||||
Log::debug(sprintf('Search code is %s', $searchCode));
|
// Log::debug(sprintf('Search code is %s', $searchCode));
|
||||||
// see if there is an accompanying start amount.
|
// see if there is an accompanying start amount.
|
||||||
// grab the difference and find the currency.
|
// grab the difference and find the currency.
|
||||||
$startBalance = ($startBalances[$account->id][$key] ?? '0');
|
$startBalance = ($startBalances[$account->id][$key] ?? '0');
|
||||||
Log::debug(sprintf('Start balance is %s', $startBalance));
|
// Log::debug(sprintf('Start balance is %s', $startBalance));
|
||||||
$diff = bcsub($endBalance, $startBalance);
|
$diff = bcsub($endBalance, $startBalance);
|
||||||
$currencies[$searchCode] ??= $this->currencyRepository->findByCode($searchCode);
|
$currencies[$searchCode] ??= $this->currencyRepository->findByCode($searchCode);
|
||||||
if (0 !== bccomp($diff, '0')) {
|
if (0 !== bccomp($diff, '0')) {
|
||||||
|
|||||||
@@ -465,7 +465,7 @@ class BudgetController extends Controller
|
|||||||
$chartGenerator->setStart($start);
|
$chartGenerator->setStart($start);
|
||||||
$chartGenerator->setEnd($end);
|
$chartGenerator->setEnd($end);
|
||||||
$chartGenerator->convertToNative = $this->convertToNative;
|
$chartGenerator->convertToNative = $this->convertToNative;
|
||||||
$chartGenerator->default = Amount::getDefaultCurrency();
|
$chartGenerator->default = $this->defaultCurrency;
|
||||||
|
|
||||||
$chartData = $chartGenerator->generate();
|
$chartData = $chartGenerator->generate();
|
||||||
$data = $this->generator->multiSet($chartData);
|
$data = $this->generator->multiSet($chartData);
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ abstract class Controller extends BaseController
|
|||||||
$this->defaultCurrency =null;
|
$this->defaultCurrency =null;
|
||||||
// get shown-intro-preference:
|
// get shown-intro-preference:
|
||||||
if (auth()->check()) {
|
if (auth()->check()) {
|
||||||
$this->defaultCurrency = app('amount')->getDefaultCurrency();
|
$this->defaultCurrency = Amount::getDefaultCurrency();
|
||||||
$language = Steam::getLanguage();
|
$language = Steam::getLanguage();
|
||||||
$locale = Steam::getLocale();
|
$locale = Steam::getLocale();
|
||||||
$darkMode = app('preferences')->get('darkMode', 'browser')->data;
|
$darkMode = app('preferences')->get('darkMode', 'browser')->data;
|
||||||
|
|||||||
@@ -78,8 +78,7 @@ class BoxController extends Controller
|
|||||||
$incomes = [];
|
$incomes = [];
|
||||||
$expenses = [];
|
$expenses = [];
|
||||||
$sums = [];
|
$sums = [];
|
||||||
$currency = app('amount')->getDefaultCurrency();
|
$currency = $this->defaultCurrency;
|
||||||
|
|
||||||
|
|
||||||
// collect income of user:
|
// collect income of user:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
@@ -91,7 +90,7 @@ class BoxController extends Controller
|
|||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($set as $journal) {
|
foreach ($set as $journal) {
|
||||||
$currencyId = $this->convertToNative ? $currency->id : (int) $journal['currency_id'];
|
$currencyId = $this->convertToNative && $this->defaultCurrency->id !== (int) $journal['currency_id'] ? $this->defaultCurrency->id : (int) $journal['currency_id'];
|
||||||
$amount = Amount::getAmountFromJournal($journal);
|
$amount = Amount::getAmountFromJournal($journal);
|
||||||
$incomes[$currencyId] ??= '0';
|
$incomes[$currencyId] ??= '0';
|
||||||
$incomes[$currencyId] = bcadd($incomes[$currencyId], app('steam')->positive($amount));
|
$incomes[$currencyId] = bcadd($incomes[$currencyId], app('steam')->positive($amount));
|
||||||
@@ -109,7 +108,7 @@ class BoxController extends Controller
|
|||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($set as $journal) {
|
foreach ($set as $journal) {
|
||||||
$currencyId = $this->convertToNative ? $currency->id : (int) $journal['currency_id'];
|
$currencyId = $this->convertToNative ? $this->defaultCurrency->id : (int) $journal['currency_id'];
|
||||||
$amount = Amount::getAmountFromJournal($journal);
|
$amount = Amount::getAmountFromJournal($journal);
|
||||||
$expenses[$currencyId] ??= '0';
|
$expenses[$currencyId] ??= '0';
|
||||||
$expenses[$currencyId] = bcadd($expenses[$currencyId], $amount);
|
$expenses[$currencyId] = bcadd($expenses[$currencyId], $amount);
|
||||||
@@ -126,10 +125,10 @@ class BoxController extends Controller
|
|||||||
$expenses[$currencyId] = app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false);
|
$expenses[$currencyId] = app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false);
|
||||||
}
|
}
|
||||||
if (0 === count($sums)) {
|
if (0 === count($sums)) {
|
||||||
$currency = app('amount')->getDefaultCurrency();
|
$currency = $this->defaultCurrency;
|
||||||
$sums[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
$sums[$this->defaultCurrency->id] = app('amount')->formatAnything($this->defaultCurrency, '0', false);
|
||||||
$incomes[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
$incomes[$this->defaultCurrency->id] = app('amount')->formatAnything($this->defaultCurrency, '0', false);
|
||||||
$expenses[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
$expenses[$this->defaultCurrency->id] = app('amount')->formatAnything($this->defaultCurrency, '0', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = [
|
$response = [
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class ReconcileController extends Controller
|
|||||||
{
|
{
|
||||||
$startBalance = $request->get('startBalance');
|
$startBalance = $request->get('startBalance');
|
||||||
$endBalance = $request->get('endBalance');
|
$endBalance = $request->get('endBalance');
|
||||||
$accountCurrency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
$accountCurrency = $this->accountRepos->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
$amount = '0';
|
$amount = '0';
|
||||||
$clearedAmount = '0';
|
$clearedAmount = '0';
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ class ReconcileController extends Controller
|
|||||||
$startDate->subDay();
|
$startDate->subDay();
|
||||||
$end->endOfDay();
|
$end->endOfDay();
|
||||||
|
|
||||||
$currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
$currency = $this->accountRepos->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
$startBalance = Steam::finalAccountBalance($account, $startDate)['balance'];
|
$startBalance = Steam::finalAccountBalance($account, $startDate)['balance'];
|
||||||
$endBalance = Steam::finalAccountBalance($account, $end)['balance'];
|
$endBalance = Steam::finalAccountBalance($account, $end)['balance'];
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Http\Controllers;
|
namespace FireflyIII\Http\Controllers;
|
||||||
|
|
||||||
|
use FireflyIII\Events\Preferences\UserGroupChangedDefaultCurrency;
|
||||||
use FireflyIII\Events\Test\UserTestNotificationChannel;
|
use FireflyIII\Events\Test\UserTestNotificationChannel;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Http\Requests\PreferencesRequest;
|
use FireflyIII\Http\Requests\PreferencesRequest;
|
||||||
@@ -35,6 +36,7 @@ use Illuminate\Contracts\View\Factory;
|
|||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Routing\Redirector;
|
use Illuminate\Routing\Redirector;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -258,6 +260,11 @@ class PreferencesController extends Controller
|
|||||||
|
|
||||||
// convert native
|
// convert native
|
||||||
$convertToNative = 1 === (int) $request->get('convertToNative');
|
$convertToNative = 1 === (int) $request->get('convertToNative');
|
||||||
|
if ($convertToNative && !$this->convertToNative) {
|
||||||
|
// set to true!
|
||||||
|
Log::debug('User sets convertToNative to true.');
|
||||||
|
event(new UserGroupChangedDefaultCurrency(auth()->user()->userGroup));
|
||||||
|
}
|
||||||
app('preferences')->set('convert_to_native', $convertToNative);
|
app('preferences')->set('convert_to_native', $convertToNative);
|
||||||
|
|
||||||
// custom fiscal year
|
// custom fiscal year
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ class CreateController extends Controller
|
|||||||
{
|
{
|
||||||
$budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets());
|
$budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets());
|
||||||
$bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills());
|
$bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills());
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$defaultCurrency = $this->defaultCurrency;
|
||||||
$tomorrow = today(config('app.timezone'));
|
$tomorrow = today(config('app.timezone'));
|
||||||
$oldRepetitionType = $request->old('repetition_type');
|
$oldRepetitionType = $request->old('repetition_type');
|
||||||
$tomorrow->addDay();
|
$tomorrow->addDay();
|
||||||
@@ -129,7 +129,7 @@ class CreateController extends Controller
|
|||||||
{
|
{
|
||||||
$budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets());
|
$budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets());
|
||||||
$bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills());
|
$bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills());
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$defaultCurrency = $this->defaultCurrency;
|
||||||
$tomorrow = today(config('app.timezone'));
|
$tomorrow = today(config('app.timezone'));
|
||||||
$oldRepetitionType = $request->old('repetition_type');
|
$oldRepetitionType = $request->old('repetition_type');
|
||||||
$tomorrow->addDay();
|
$tomorrow->addDay();
|
||||||
|
|||||||
@@ -62,8 +62,6 @@ class InstallController extends Controller
|
|||||||
'migrate' => ['--seed' => true, '--force' => true],
|
'migrate' => ['--seed' => true, '--force' => true],
|
||||||
'generate-keys' => [], // an exception :(
|
'generate-keys' => [], // an exception :(
|
||||||
'firefly-iii:upgrade-database' => [],
|
'firefly-iii:upgrade-database' => [],
|
||||||
// 'firefly-iii:correct-database' => [],
|
|
||||||
// 'firefly-iii:report-integrity' => [],
|
|
||||||
'firefly-iii:set-latest-version' => ['--james-is-cool' => true],
|
'firefly-iii:set-latest-version' => ['--james-is-cool' => true],
|
||||||
'firefly-iii:verify-security-alerts' => [],
|
'firefly-iii:verify-security-alerts' => [],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -216,15 +216,14 @@ class ConvertController extends Controller
|
|||||||
private function getLiabilities(): array
|
private function getLiabilities(): array
|
||||||
{
|
{
|
||||||
// make repositories
|
// make repositories
|
||||||
$accountList = $this->accountRepository->getActiveAccountsByType([AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
|
$accountList = $this->accountRepository->getActiveAccountsByType([AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$grouped = [];
|
||||||
$grouped = [];
|
|
||||||
|
|
||||||
// group accounts:
|
// group accounts:
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($accountList as $account) {
|
foreach ($accountList as $account) {
|
||||||
$balance = Steam::finalAccountBalance($account, today()->endOfDay())['balance'];
|
$balance = Steam::finalAccountBalance($account, today()->endOfDay())['balance'];
|
||||||
$currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency;
|
$currency = $this->accountRepository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
$role = 'l_'.$account->accountType->type;
|
$role = 'l_'.$account->accountType->type;
|
||||||
$key = (string) trans('firefly.opt_group_'.$role);
|
$key = (string) trans('firefly.opt_group_'.$role);
|
||||||
$grouped[$key][$account->id] = $account->name.' ('.app('amount')->formatAnything($currency, $balance, false).')';
|
$grouped[$key][$account->id] = $account->name.' ('.app('amount')->formatAnything($currency, $balance, false).')';
|
||||||
@@ -239,15 +238,14 @@ class ConvertController extends Controller
|
|||||||
private function getAssetAccounts(): array
|
private function getAssetAccounts(): array
|
||||||
{
|
{
|
||||||
// make repositories
|
// make repositories
|
||||||
$accountList = $this->accountRepository->getActiveAccountsByType([AccountType::ASSET]);
|
$accountList = $this->accountRepository->getActiveAccountsByType([AccountType::ASSET]);
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$grouped = [];
|
||||||
$grouped = [];
|
|
||||||
|
|
||||||
// group accounts:
|
// group accounts:
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($accountList as $account) {
|
foreach ($accountList as $account) {
|
||||||
$balance = Steam::finalAccountBalance($account, today()->endOfDay())['balance'];
|
$balance = Steam::finalAccountBalance($account, today()->endOfDay())['balance'];
|
||||||
$currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency;
|
$currency = $this->accountRepository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
$role = (string) $this->accountRepository->getMetaValue($account, 'account_role');
|
$role = (string) $this->accountRepository->getMetaValue($account, 'account_role');
|
||||||
if ('' === $role) {
|
if ('' === $role) {
|
||||||
$role = 'no_account_type';
|
$role = 'no_account_type';
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ class CreateController extends Controller
|
|||||||
$optionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
|
$optionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
|
||||||
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
|
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
|
||||||
$accountToTypes = config('firefly.account_to_transaction');
|
$accountToTypes = config('firefly.account_to_transaction');
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$defaultCurrency = $this->defaultCurrency;
|
||||||
$previousUrl = $this->rememberPreviousUrl('transactions.create.url');
|
$previousUrl = $this->rememberPreviousUrl('transactions.create.url');
|
||||||
$parts = parse_url($previousUrl);
|
$parts = parse_url($previousUrl);
|
||||||
$search = sprintf('?%s', $parts['query'] ?? '');
|
$search = sprintf('?%s', $parts['query'] ?? '');
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class EditController extends Controller
|
|||||||
$title = $transactionGroup->transactionJournals()->count() > 1 ? $transactionGroup->title : $transactionGroup->transactionJournals()->first()->description;
|
$title = $transactionGroup->transactionJournals()->count() > 1 ? $transactionGroup->title : $transactionGroup->transactionJournals()->first()->description;
|
||||||
$subTitle = (string) trans('firefly.edit_transaction_title', ['description' => $title]);
|
$subTitle = (string) trans('firefly.edit_transaction_title', ['description' => $title]);
|
||||||
$subTitleIcon = 'fa-plus';
|
$subTitleIcon = 'fa-plus';
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$defaultCurrency = $this->defaultCurrency;
|
||||||
$cash = $repository->getCashAccount();
|
$cash = $repository->getCashAccount();
|
||||||
$previousUrl = $this->rememberPreviousUrl('transactions.edit.url');
|
$previousUrl = $this->rememberPreviousUrl('transactions.edit.url');
|
||||||
$parts = parse_url($previousUrl);
|
$parts = parse_url($previousUrl);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace FireflyIII\Http\Middleware;
|
|||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Http\Controllers\RequestInformation;
|
use FireflyIII\Support\Http\Controllers\RequestInformation;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
@@ -108,7 +109,7 @@ class Range
|
|||||||
setlocale(LC_TIME, $localeArray);
|
setlocale(LC_TIME, $localeArray);
|
||||||
$moneyResult = setlocale(LC_MONETARY, $localeArray);
|
$moneyResult = setlocale(LC_MONETARY, $localeArray);
|
||||||
|
|
||||||
// send error to view, if could not set money format
|
// send error to view, if it could not set money format
|
||||||
if (false === $moneyResult) {
|
if (false === $moneyResult) {
|
||||||
app('log')->error('Could not set locale. The following array doesnt work: ', $localeArray);
|
app('log')->error('Could not set locale. The following array doesnt work: ', $localeArray);
|
||||||
app('view')->share('invalidMonetaryLocale', true);
|
app('view')->share('invalidMonetaryLocale', true);
|
||||||
@@ -117,7 +118,7 @@ class Range
|
|||||||
// save some formats:
|
// save some formats:
|
||||||
$monthAndDayFormat = (string) trans('config.month_and_day_js', [], $locale);
|
$monthAndDayFormat = (string) trans('config.month_and_day_js', [], $locale);
|
||||||
$dateTimeFormat = (string) trans('config.date_time_js', [], $locale);
|
$dateTimeFormat = (string) trans('config.date_time_js', [], $locale);
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$defaultCurrency = Amount::getDefaultCurrency();
|
||||||
|
|
||||||
// also format for moment JS:
|
// also format for moment JS:
|
||||||
$madMomentJS = (string) trans('config.month_and_day_moment_js', [], $locale);
|
$madMomentJS = (string) trans('config.month_and_day_moment_js', [], $locale);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ namespace FireflyIII\Http\Requests;
|
|||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
use FireflyIII\Rules\IsValidPositiveAmount;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
@@ -125,7 +126,7 @@ class PiggyBankStoreRequest extends FormRequest
|
|||||||
$currencyId = (int) ($data['transaction_currency_id'] ?? 0);
|
$currencyId = (int) ($data['transaction_currency_id'] ?? 0);
|
||||||
$currency = TransactionCurrency::find($currencyId);
|
$currency = TransactionCurrency::find($currencyId);
|
||||||
if (null === $currency) {
|
if (null === $currency) {
|
||||||
return app('amount')->getDefaultCurrency();
|
return Amount::getDefaultCurrency();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $currency;
|
return $currency;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ use FireflyIII\Models\PiggyBank;
|
|||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
use FireflyIII\Rules\IsValidPositiveAmount;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
@@ -128,7 +129,7 @@ class PiggyBankUpdateRequest extends FormRequest
|
|||||||
$currencyId = (int) ($data['transaction_currency_id'] ?? 0);
|
$currencyId = (int) ($data['transaction_currency_id'] ?? 0);
|
||||||
$currency = TransactionCurrency::find($currencyId);
|
$currency = TransactionCurrency::find($currencyId);
|
||||||
if (null === $currency) {
|
if (null === $currency) {
|
||||||
return app('amount')->getDefaultCurrency();
|
return Amount::getDefaultCurrency();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $currency;
|
return $currency;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Models;
|
namespace FireflyIII\Models;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
|
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
|
||||||
use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
|
use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
@@ -101,4 +102,20 @@ class AvailableBudget extends Model
|
|||||||
get: static fn ($value) => (int) $value,
|
get: static fn ($value) => (int) $value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function startDate(): Attribute
|
||||||
|
{
|
||||||
|
return Attribute::make(
|
||||||
|
get: fn (string $value) => Carbon::parse($value),
|
||||||
|
set: fn (Carbon $value) => $value->format('Y-m-d'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function endDate(): Attribute
|
||||||
|
{
|
||||||
|
return Attribute::make(
|
||||||
|
get: fn (string $value) => Carbon::parse($value),
|
||||||
|
set: fn (Carbon $value) => $value->format('Y-m-d'),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,16 +38,16 @@ class RecurrenceRepetition extends Model
|
|||||||
use ReturnsIntegerIdTrait;
|
use ReturnsIntegerIdTrait;
|
||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
#[\Deprecated]
|
#[\Deprecated] /** @deprecated */
|
||||||
public const int WEEKEND_DO_NOTHING = 1;
|
public const int WEEKEND_DO_NOTHING = 1;
|
||||||
|
|
||||||
#[\Deprecated]
|
#[\Deprecated] /** @deprecated */
|
||||||
public const int WEEKEND_SKIP_CREATION = 2;
|
public const int WEEKEND_SKIP_CREATION = 2;
|
||||||
|
|
||||||
#[\Deprecated]
|
#[\Deprecated] /** @deprecated */
|
||||||
public const int WEEKEND_TO_FRIDAY = 3;
|
public const int WEEKEND_TO_FRIDAY = 3;
|
||||||
|
|
||||||
#[\Deprecated]
|
#[\Deprecated] /** @deprecated */
|
||||||
public const int WEEKEND_TO_MONDAY = 4;
|
public const int WEEKEND_TO_MONDAY = 4;
|
||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
|
|||||||
@@ -83,15 +83,17 @@ class ReturnsAvailableChannels
|
|||||||
|
|
||||||
private static function returnUserChannels(User $user): array
|
private static function returnUserChannels(User $user): array
|
||||||
{
|
{
|
||||||
|
Log::debug(sprintf('Checking channels for user #%d', $user->id));
|
||||||
$channels = ['mail'];
|
$channels = ['mail'];
|
||||||
$slackUrl = app('preferences')->getEncryptedForUser($user, 'slack_webhook_url', '')->data;
|
$slackUrl = (string) app('preferences')->getEncryptedForUser($user, 'slack_webhook_url', '')->data;
|
||||||
if (UrlValidator::isValidWebhookURL($slackUrl)) {
|
if (UrlValidator::isValidWebhookURL($slackUrl)) {
|
||||||
$channels[] = 'slack';
|
$channels[] = 'slack';
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate presence of of Ntfy settings.
|
// validate presence of of Ntfy settings.
|
||||||
if ('' !== (string) app('preferences')->getEncryptedForUser($user, 'ntfy_topic', '')->data) {
|
$ntfyTopic = (string) app('preferences')->getEncryptedForUser($user, 'ntfy_topic', '')->data;
|
||||||
Log::debug('Enabled ntfy.');
|
if ('' !== $ntfyTopic) {
|
||||||
|
Log::debug(sprintf('Enabled ntfy, "%s"', $ntfyTopic));
|
||||||
$channels[] = NtfyChannel::class;
|
$channels[] = NtfyChannel::class;
|
||||||
}
|
}
|
||||||
if ('' === (string) app('preferences')->getEncryptedForUser($user, 'ntfy_topic', '')->data) {
|
if ('' === (string) app('preferences')->getEncryptedForUser($user, 'ntfy_topic', '')->data) {
|
||||||
|
|||||||
@@ -550,9 +550,9 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
foreach ($set as $transactionJournal) {
|
foreach ($set as $transactionJournal) {
|
||||||
$setAmount = bcadd($setAmount, Amount::getAmountFromJournalObject($transactionJournal));
|
$setAmount = bcadd($setAmount, Amount::getAmountFromJournalObject($transactionJournal));
|
||||||
}
|
}
|
||||||
Log::debug(sprintf('Bill #%d ("%s") with %d transaction(s) and sum %s %s', $bill->id, $bill->name, $set->count(), $currency->code, $setAmount));
|
// Log::debug(sprintf('Bill #%d ("%s") with %d transaction(s) and sum %s %s', $bill->id, $bill->name, $set->count(), $currency->code, $setAmount));
|
||||||
$return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $setAmount);
|
$return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $setAmount);
|
||||||
Log::debug(sprintf('Total sum is now %s', $return[$currency->id]['sum']));
|
// Log::debug(sprintf('Total sum is now %s', $return[$currency->id]['sum']));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
@@ -586,11 +586,11 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
|
|
||||||
$minField = $convertToNative && $bill->transactionCurrency->id !== $default->id ? 'native_amount_min' : 'amount_min';
|
$minField = $convertToNative && $bill->transactionCurrency->id !== $default->id ? 'native_amount_min' : 'amount_min';
|
||||||
$maxField = $convertToNative && $bill->transactionCurrency->id !== $default->id ? 'native_amount_max' : 'amount_max';
|
$maxField = $convertToNative && $bill->transactionCurrency->id !== $default->id ? 'native_amount_max' : 'amount_max';
|
||||||
Log::debug(sprintf('min field is %s, max field is %s', $minField, $maxField));
|
// Log::debug(sprintf('min field is %s, max field is %s', $minField, $maxField));
|
||||||
|
|
||||||
if ($total > 0) {
|
if ($total > 0) {
|
||||||
$currency = $convertToNative && $bill->transactionCurrency->id !== $default->id ? $default : $bill->transactionCurrency;
|
$currency = $convertToNative && $bill->transactionCurrency->id !== $default->id ? $default : $bill->transactionCurrency;
|
||||||
$average = bcdiv(bcadd($bill->{$maxField}, $bill->{$minField}), '2');
|
$average = bcdiv(bcadd($bill->{$maxField} ?? '0', $bill->{$minField} ?? '0'), '2');
|
||||||
Log::debug(sprintf('Amount to pay is %s %s (%d times)', $currency->code, $average, $total));
|
Log::debug(sprintf('Amount to pay is %s %s (%d times)', $currency->code, $average, $total));
|
||||||
$return[$currency->id] ??= [
|
$return[$currency->id] ??= [
|
||||||
'id' => (string) $currency->id,
|
'id' => (string) $currency->id,
|
||||||
|
|||||||
@@ -64,17 +64,19 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function get(?Carbon $start = null, ?Carbon $end = null): Collection
|
public function get(?Carbon $start = null, ?Carbon $end = null): Collection
|
||||||
{
|
{
|
||||||
$query = $this->user->availableBudgets()->with(['transactionCurrency']);
|
$query = $this->user->availableBudgets()->with(['transactionCurrency']);
|
||||||
if (null !== $start && null !== $end) {
|
if (null !== $start && null !== $end) {
|
||||||
$query->where(
|
$query->where(
|
||||||
static function (Builder $q1) use ($start, $end): void { // @phpstan-ignore-line
|
static function (Builder $q1) use ($start, $end): void { // @phpstan-ignore-line
|
||||||
$q1->where('start_date', '=', $start->format('Y-m-d H:i:s'));
|
$q1->where('start_date', '=', $start->format('Y-m-d'));
|
||||||
$q1->where('end_date', '=', $end->format('Y-m-d H:i:s'));
|
$q1->where('end_date', '=', $end->format('Y-m-d'));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
$result = $query->get(['available_budgets.*']);
|
||||||
|
Log::debug(sprintf('Found %d available budgets between %s and %s', $result->count(), $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
||||||
|
|
||||||
return $query->get(['available_budgets.*']);
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -131,8 +133,8 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
|||||||
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')));
|
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 = [];
|
$return = [];
|
||||||
$availableBudgets = $this->user->availableBudgets()
|
$availableBudgets = $this->user->availableBudgets()
|
||||||
->where('start_date', $start->format('Y-m-d H:i:s'))
|
->where('start_date', $start->format('Y-m-d'))
|
||||||
->where('end_date', $end->format('Y-m-d H:i:s'))->get()
|
->where('end_date', $end->format('Y-m-d'))->get()
|
||||||
;
|
;
|
||||||
|
|
||||||
Log::debug(sprintf('Found %d available budgets', $availableBudgets->count()));
|
Log::debug(sprintf('Found %d available budgets', $availableBudgets->count()));
|
||||||
@@ -214,9 +216,9 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
|||||||
$availableBudget = new AvailableBudget();
|
$availableBudget = new AvailableBudget();
|
||||||
$availableBudget->user()->associate($this->user);
|
$availableBudget->user()->associate($this->user);
|
||||||
$availableBudget->transactionCurrency()->associate($currency);
|
$availableBudget->transactionCurrency()->associate($currency);
|
||||||
$availableBudget->start_date = $start->startOfDay()->format('Y-m-d'); // @phpstan-ignore-line
|
$availableBudget->start_date = $start->startOfDay();
|
||||||
$availableBudget->start_date_tz = $start->format('e');
|
$availableBudget->start_date_tz = $start->format('e');
|
||||||
$availableBudget->end_date = $end->endOfDay()->format('Y-m-d'); // @phpstan-ignore-line
|
$availableBudget->end_date = $end->endOfDay();
|
||||||
$availableBudget->end_date_tz = $end->format('e');
|
$availableBudget->end_date_tz = $end->format('e');
|
||||||
}
|
}
|
||||||
$availableBudget->amount = $amount;
|
$availableBudget->amount = $amount;
|
||||||
@@ -249,9 +251,9 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
|||||||
'user_group_id' => $this->user->user_group_id,
|
'user_group_id' => $this->user->user_group_id,
|
||||||
'transaction_currency_id' => $data['currency_id'],
|
'transaction_currency_id' => $data['currency_id'],
|
||||||
'amount' => $data['amount'],
|
'amount' => $data['amount'],
|
||||||
'start_date' => $start->format('Y-m-d'),
|
'start_date' => $start,
|
||||||
'start_date_tz' => $start->format('e'),
|
'start_date_tz' => $start->format('e'),
|
||||||
'end_date' => $end->format('Y-m-d'),
|
'end_date' => $end,
|
||||||
'end_date_tz' => $end->format('e'),
|
'end_date_tz' => $end->format('e'),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
@@ -273,7 +275,7 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
|||||||
$start = $data['start'];
|
$start = $data['start'];
|
||||||
if ($start instanceof Carbon) {
|
if ($start instanceof Carbon) {
|
||||||
$start = $data['start']->startOfDay();
|
$start = $data['start']->startOfDay();
|
||||||
$availableBudget->start_date = $start->format('Y-m-d');
|
$availableBudget->start_date = $start;
|
||||||
$availableBudget->start_date_tz = $start->format('e');
|
$availableBudget->start_date_tz = $start->format('e');
|
||||||
$availableBudget->save();
|
$availableBudget->save();
|
||||||
}
|
}
|
||||||
@@ -283,7 +285,7 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
|||||||
$end = $data['end'];
|
$end = $data['end'];
|
||||||
if ($end instanceof Carbon) {
|
if ($end instanceof Carbon) {
|
||||||
$end = $data['end']->endOfDay();
|
$end = $data['end']->endOfDay();
|
||||||
$availableBudget->end_date = $end->format('Y-m-d');
|
$availableBudget->end_date = $end;
|
||||||
$availableBudget->end_date_tz = $end->format('e');
|
$availableBudget->end_date_tz = $end->format('e');
|
||||||
$availableBudget->save();
|
$availableBudget->save();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
$amount = '' === $amount ? '0' : $amount;
|
$amount = '' === $amount ? '0' : $amount;
|
||||||
$sum = bcadd($sum, $amount);
|
$sum = bcadd($sum, $amount);
|
||||||
}
|
}
|
||||||
Log::debug(sprintf('Current amount in piggy bank #%d ("%s") is %s', $piggyBank->id, $piggyBank->name, $sum));
|
// Log::debug(sprintf('Current amount in piggy bank #%d ("%s") is %s', $piggyBank->id, $piggyBank->name, $sum));
|
||||||
|
|
||||||
return $sum;
|
return $sum;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,6 +210,10 @@ class Preferences
|
|||||||
try {
|
try {
|
||||||
$result->data = decrypt($result->data);
|
$result->data = decrypt($result->data);
|
||||||
} catch (DecryptException $e) {
|
} catch (DecryptException $e) {
|
||||||
|
if ('The MAC is invalid.' === $e->getMessage()) {
|
||||||
|
Log::debug('Set data to NULL');
|
||||||
|
$result->data = null;
|
||||||
|
}
|
||||||
Log::error(sprintf('Could not decrypt preference "%s": %s', $name, $e->getMessage()));
|
Log::error(sprintf('Could not decrypt preference "%s": %s', $name, $e->getMessage()));
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
@@ -230,6 +234,10 @@ class Preferences
|
|||||||
try {
|
try {
|
||||||
$result->data = decrypt($result->data);
|
$result->data = decrypt($result->data);
|
||||||
} catch (DecryptException $e) {
|
} catch (DecryptException $e) {
|
||||||
|
if ('The MAC is invalid.' === $e->getMessage()) {
|
||||||
|
Log::debug('Set data to NULL');
|
||||||
|
$result->data = null;
|
||||||
|
}
|
||||||
Log::error(sprintf('Could not decrypt preference "%s": %s', $name, $e->getMessage()));
|
Log::error(sprintf('Could not decrypt preference "%s": %s', $name, $e->getMessage()));
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class TransactionSummarizer
|
|||||||
'currency_decimal_places' => $currencyDecimalPlaces,
|
'currency_decimal_places' => $currencyDecimalPlaces,
|
||||||
];
|
];
|
||||||
$array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->{$method}($amount));
|
$array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->{$method}($amount));
|
||||||
Log::debug(sprintf('Journal #%d adds amount %s %s', $journal['transaction_journal_id'], $currencyCode, $amount));
|
// Log::debug(sprintf('Journal #%d adds amount %s %s', $journal['transaction_journal_id'], $currencyCode, $amount));
|
||||||
}
|
}
|
||||||
Log::debug('End of sumExpenses.', $array);
|
Log::debug('End of sumExpenses.', $array);
|
||||||
|
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ class Steam
|
|||||||
if ($native->id === $accountCurrency?->id) {
|
if ($native->id === $accountCurrency?->id) {
|
||||||
$return['balance'] = bcadd('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance, $return['balance']);
|
$return['balance'] = bcadd('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance, $return['balance']);
|
||||||
}
|
}
|
||||||
Log::debug(sprintf('balance is (%s only) %s (with virtual balance)', $native->code, $this->bcround($return['balance'], 2)));
|
// Log::debug(sprintf('balance is (%s only) %s (with virtual balance)', $native->code, $this->bcround($return['balance'], 2)));
|
||||||
|
|
||||||
// native balance
|
// native balance
|
||||||
$return['native_balance'] = (string) $account->transactions()
|
$return['native_balance'] = (string) $account->transactions()
|
||||||
@@ -342,7 +342,7 @@ class Steam
|
|||||||
;
|
;
|
||||||
// plus native virtual balance.
|
// plus native virtual balance.
|
||||||
$return['native_balance'] = bcadd('' === (string) $account->native_virtual_balance ? '0' : $account->native_virtual_balance, $return['native_balance']);
|
$return['native_balance'] = bcadd('' === (string) $account->native_virtual_balance ? '0' : $account->native_virtual_balance, $return['native_balance']);
|
||||||
Log::debug(sprintf('native_balance is (all transactions to %s) %s (with virtual balance)', $native->code, $this->bcround($return['native_balance'])));
|
// Log::debug(sprintf('native_balance is (all transactions to %s) %s (with virtual balance)', $native->code, $this->bcround($return['native_balance'])));
|
||||||
|
|
||||||
// plus foreign transactions in THIS currency.
|
// plus foreign transactions in THIS currency.
|
||||||
$sum = (string) $account->transactions()
|
$sum = (string) $account->transactions()
|
||||||
@@ -354,7 +354,7 @@ class Steam
|
|||||||
;
|
;
|
||||||
$return['native_balance'] = bcadd($return['native_balance'], $sum);
|
$return['native_balance'] = bcadd($return['native_balance'], $sum);
|
||||||
|
|
||||||
Log::debug(sprintf('Foreign amount transactions add (%s only) %s, total native_balance is now %s', $native->code, $this->bcround($sum), $this->bcround($return['native_balance'])));
|
// Log::debug(sprintf('Foreign amount transactions add (%s only) %s, total native_balance is now %s', $native->code, $this->bcround($sum), $this->bcround($return['native_balance'])));
|
||||||
}
|
}
|
||||||
|
|
||||||
// balance(s) in other (all) currencies.
|
// balance(s) in other (all) currencies.
|
||||||
@@ -365,12 +365,12 @@ class Steam
|
|||||||
->get(['transaction_currencies.code', 'transactions.amount'])->toArray()
|
->get(['transaction_currencies.code', 'transactions.amount'])->toArray()
|
||||||
;
|
;
|
||||||
$others = $this->groupAndSumTransactions($array, 'code', 'amount');
|
$others = $this->groupAndSumTransactions($array, 'code', 'amount');
|
||||||
Log::debug('All balances are (joined)', $others);
|
// Log::debug('All balances are (joined)', $others);
|
||||||
// if the account has no own currency preference, drop balance in favor of native balance
|
// if the account has no own currency preference, drop balance in favor of native balance
|
||||||
if ($hasCurrency && !$convertToNative) {
|
if ($hasCurrency && !$convertToNative) {
|
||||||
$return['balance'] = $others[$currency->code] ?? '0';
|
$return['balance'] = $others[$currency->code] ?? '0';
|
||||||
$return['native_balance'] = $others[$currency->code] ?? '0';
|
$return['native_balance'] = $others[$currency->code] ?? '0';
|
||||||
Log::debug(sprintf('Set balance + native_balance to %s', $return['balance']));
|
// Log::debug(sprintf('Set balance + native_balance to %s', $return['balance']));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the currency is the same as the native currency, set the native_balance to the balance for consistency.
|
// if the currency is the same as the native currency, set the native_balance to the balance for consistency.
|
||||||
@@ -379,16 +379,15 @@ class Steam
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
if (!$hasCurrency && array_key_exists('balance', $return) && array_key_exists('native_balance', $return)) {
|
if (!$hasCurrency && array_key_exists('balance', $return) && array_key_exists('native_balance', $return)) {
|
||||||
Log::debug('Account has no currency preference, dropping balance in favor of native balance.');
|
// Log::debug('Account has no currency preference, dropping balance in favor of native balance.');
|
||||||
$sum = bcadd($return['balance'], $return['native_balance']);
|
$sum = bcadd($return['balance'], $return['native_balance']);
|
||||||
Log::debug(sprintf('%s + %s = %s', $return['balance'], $return['native_balance'], $sum));
|
// Log::debug(sprintf('%s + %s = %s', $return['balance'], $return['native_balance'], $sum));
|
||||||
$return['native_balance'] = $sum;
|
$return['native_balance'] = $sum;
|
||||||
unset($return['balance']);
|
unset($return['balance']);
|
||||||
}
|
}
|
||||||
$final = array_merge($return, $others);
|
|
||||||
Log::debug('Return is', $final);
|
|
||||||
|
|
||||||
return $final;
|
return array_merge($return, $others);
|
||||||
|
// Log::debug('Return is', $final);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function filterAccountBalances(array $total, Account $account, bool $convertToNative, ?TransactionCurrency $currency = null): array
|
public function filterAccountBalances(array $total, Account $account, bool $convertToNative, ?TransactionCurrency $currency = null): array
|
||||||
|
|||||||
40
composer.lock
generated
40
composer.lock
generated
@@ -6364,16 +6364,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "spatie/laravel-package-tools",
|
"name": "spatie/laravel-package-tools",
|
||||||
"version": "1.17.0",
|
"version": "1.18.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/spatie/laravel-package-tools.git",
|
"url": "https://github.com/spatie/laravel-package-tools.git",
|
||||||
"reference": "9ab30fd24f677e5aa370ea4cf6b41c517d16cf85"
|
"reference": "8332205b90d17164913244f4a8e13ab7e6761d29"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/9ab30fd24f677e5aa370ea4cf6b41c517d16cf85",
|
"url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/8332205b90d17164913244f4a8e13ab7e6761d29",
|
||||||
"reference": "9ab30fd24f677e5aa370ea4cf6b41c517d16cf85",
|
"reference": "8332205b90d17164913244f4a8e13ab7e6761d29",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -6412,7 +6412,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/spatie/laravel-package-tools/issues",
|
"issues": "https://github.com/spatie/laravel-package-tools/issues",
|
||||||
"source": "https://github.com/spatie/laravel-package-tools/tree/1.17.0"
|
"source": "https://github.com/spatie/laravel-package-tools/tree/1.18.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -6420,7 +6420,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-12-09T16:29:14+00:00"
|
"time": "2024-12-30T13:13:39+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "spatie/period",
|
"name": "spatie/period",
|
||||||
@@ -10287,20 +10287,20 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "barryvdh/reflection-docblock",
|
"name": "barryvdh/reflection-docblock",
|
||||||
"version": "v2.2.0",
|
"version": "v2.3.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/barryvdh/ReflectionDocBlock.git",
|
"url": "https://github.com/barryvdh/ReflectionDocBlock.git",
|
||||||
"reference": "db125e8df4329bd45f2da405aab007f502f38531"
|
"reference": "818be8de6af4d16ef3ad51ea9234b3d37026ee5f"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/db125e8df4329bd45f2da405aab007f502f38531",
|
"url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/818be8de6af4d16ef3ad51ea9234b3d37026ee5f",
|
||||||
"reference": "db125e8df4329bd45f2da405aab007f502f38531",
|
"reference": "818be8de6af4d16ef3ad51ea9234b3d37026ee5f",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.3"
|
"php": ">=7.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^8.5.14|^9"
|
"phpunit/phpunit": "^8.5.14|^9"
|
||||||
@@ -10312,7 +10312,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "2.2.x-dev"
|
"dev-master": "2.3.x-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -10333,9 +10333,9 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.2.0"
|
"source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.3.0"
|
||||||
},
|
},
|
||||||
"time": "2024-12-28T10:00:03+00:00"
|
"time": "2024-12-30T10:35:04+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "cloudcreativity/json-api-testing",
|
"name": "cloudcreativity/json-api-testing",
|
||||||
@@ -11147,16 +11147,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/php-parser",
|
"name": "nikic/php-parser",
|
||||||
"version": "v5.3.1",
|
"version": "v5.4.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||||
"reference": "8eea230464783aa9671db8eea6f8c6ac5285794b"
|
"reference": "447a020a1f875a434d62f2a401f53b82a396e494"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b",
|
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494",
|
||||||
"reference": "8eea230464783aa9671db8eea6f8c6ac5285794b",
|
"reference": "447a020a1f875a434d62f2a401f53b82a396e494",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -11199,9 +11199,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1"
|
"source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0"
|
||||||
},
|
},
|
||||||
"time": "2024-10-08T18:51:32+00:00"
|
"time": "2024-12-30T11:07:19+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phar-io/manifest",
|
"name": "phar-io/manifest",
|
||||||
|
|||||||
@@ -28,47 +28,48 @@ return [
|
|||||||
'download_enabled' => env('ENABLE_EXTERNAL_RATES', false),
|
'download_enabled' => env('ENABLE_EXTERNAL_RATES', false),
|
||||||
|
|
||||||
// if currencies are added, default rates must be added as well!
|
// if currencies are added, default rates must be added as well!
|
||||||
// last exchange rate update: 6-6-2022
|
// last exchange rate update: 2024-12-30
|
||||||
// source: https://www.xe.com/currencyconverter/
|
// source: https://www.xe.com/currencyconverter/
|
||||||
'date' => '2022-06-06',
|
'date' => '2024-12-30',
|
||||||
|
|
||||||
// all rates are from EUR to $currency:
|
// all rates are from EUR to $currency:
|
||||||
'rates' => [
|
'rates' => [
|
||||||
// europa
|
// europa
|
||||||
'EUR' => 1,
|
'EUR' => 1,
|
||||||
'HUF' => 387.9629,
|
'HUF' => 410.79798,
|
||||||
'GBP' => 0.85420754,
|
'GBP' => 0.82858703,
|
||||||
'UAH' => 31.659752,
|
'UAH' => 43.485934,
|
||||||
'PLN' => 4.581788,
|
'PLN' => 4.2708542,
|
||||||
'TRY' => 17.801397,
|
'TRY' => 36.804124,
|
||||||
'DKK' => 7.4389753,
|
'DKK' => 7.4591,
|
||||||
|
'RON' => 4.9768699,
|
||||||
|
|
||||||
// Americas
|
// Americas
|
||||||
'USD' => 1.0722281,
|
'USD' => 1.0430046,
|
||||||
'BRL' => 5.0973173,
|
'BRL' => 6.4639113,
|
||||||
'CAD' => 1.3459969,
|
'CAD' => 1.5006908,
|
||||||
'MXN' => 20.899824,
|
'MXN' => 21.249542,
|
||||||
|
|
||||||
// Oceania currencies
|
// Oceania currencies
|
||||||
'IDR' => 15466.299,
|
'IDR' => 16860.057,
|
||||||
'AUD' => 1.4838549,
|
'AUD' => 1.6705648,
|
||||||
'NZD' => 1.6425829,
|
'NZD' => 1.8436945,
|
||||||
|
|
||||||
// africa
|
// africa
|
||||||
'EGP' => 19.99735,
|
'EGP' => 53.038174,
|
||||||
'MAD' => 10.573307,
|
'MAD' => 10.521629,
|
||||||
'ZAR' => 16.413167,
|
'ZAR' => 19.460263,
|
||||||
|
|
||||||
// asia
|
// asia
|
||||||
'JPY' => 140.15257,
|
'JPY' => 164.74767,
|
||||||
'RMB' => 7.1194265,
|
'RMB' => 7.6138994,
|
||||||
'CNY' => 1,
|
'CNY' => 7.6138994,
|
||||||
'RUB' => 66.000895,
|
'RUB' => 108.56771,
|
||||||
'INR' => 83.220481,
|
'INR' => 89.157391,
|
||||||
|
|
||||||
// int
|
// int
|
||||||
'ILS' => 3.5712508,
|
'ILS' => 3.8428028,
|
||||||
'CHF' => 1.0323891,
|
'CHF' => 0.94044969,
|
||||||
'HRK' => 7.5220845,
|
'HRK' => 7.5345, // replaced by EUR
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -81,7 +81,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' => 'develop/2024-12-30',
|
'version' => 'develop/2024-12-31',
|
||||||
'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,
|
||||||
|
|
||||||
|
|||||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -12114,9 +12114,9 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/yaml": {
|
"node_modules/yaml": {
|
||||||
"version": "2.6.1",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
|
||||||
"integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==",
|
"integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"apply_rules_checkbox": "Regeln anwenden",
|
"apply_rules_checkbox": "Regeln anwenden",
|
||||||
"fire_webhooks_checkbox": "Webhooks abfeuern",
|
"fire_webhooks_checkbox": "Webhooks abfeuern",
|
||||||
"no_budget_pointer": "Sie scheinen noch keine Budgets festgelegt zu haben. Sie sollten einige davon auf der Seite <a href=\"budgets\">Budgets<\/a> anlegen. Budgets k\u00f6nnen Ihnen dabei helfen, den \u00dcberblick \u00fcber die Ausgaben zu behalten.",
|
"no_budget_pointer": "Sie scheinen noch keine Budgets festgelegt zu haben. Sie sollten einige davon auf der Seite <a href=\"budgets\">Budgets<\/a> anlegen. Budgets k\u00f6nnen Ihnen dabei helfen, den \u00dcberblick \u00fcber die Ausgaben zu behalten.",
|
||||||
"no_bill_pointer": "Sie scheinen noch kein Abonnement zu haben. Sie sollten einige auf der Seite <a href=\"subscriptions\">Abonnement<\/a> erstellen. Abonnements k\u00f6nnen Ihnen helfen, den \u00dcberblick \u00fcber Ihre Ausgaben zu behalten.",
|
"no_bill_pointer": "You seem to have no subscription yet. You should create some on the <a href=\"subscriptions\">subscription<\/a>-page. Subscriptions can help you keep track of expenses.",
|
||||||
"source_account": "Quellkonto",
|
"source_account": "Quellkonto",
|
||||||
"hidden_fields_preferences": "Sie k\u00f6nnen weitere Buchungsoptionen in Ihren <a href=\"preferences\">Einstellungen<\/a> aktivieren.",
|
"hidden_fields_preferences": "Sie k\u00f6nnen weitere Buchungsoptionen in Ihren <a href=\"preferences\">Einstellungen<\/a> aktivieren.",
|
||||||
"destination_account": "Zielkonto",
|
"destination_account": "Zielkonto",
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"is_reconciled_fields_dropped": "Da diese Buchung abgeglichen ist, k\u00f6nnen Sie weder die Konten noch den\/die Betrag\/Betr\u00e4ge aktualisieren.",
|
"is_reconciled_fields_dropped": "Da diese Buchung abgeglichen ist, k\u00f6nnen Sie weder die Konten noch den\/die Betrag\/Betr\u00e4ge aktualisieren.",
|
||||||
"tags": "Schlagw\u00f6rter",
|
"tags": "Schlagw\u00f6rter",
|
||||||
"no_budget": "(kein Budget)",
|
"no_budget": "(kein Budget)",
|
||||||
"no_bill": "(kein Abonnement)",
|
"no_bill": "(no subscription)",
|
||||||
"category": "Kategorie",
|
"category": "Kategorie",
|
||||||
"attachments": "Anh\u00e4nge",
|
"attachments": "Anh\u00e4nge",
|
||||||
"notes": "Notizen",
|
"notes": "Notizen",
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
"destination_account_reconciliation": "Sie k\u00f6nnen das Zielkonto einer Kontenausgleichsbuchung nicht bearbeiten.",
|
"destination_account_reconciliation": "Sie k\u00f6nnen das Zielkonto einer Kontenausgleichsbuchung nicht bearbeiten.",
|
||||||
"source_account_reconciliation": "Sie k\u00f6nnen das Quellkonto einer Kontenausgleichsbuchung nicht bearbeiten.",
|
"source_account_reconciliation": "Sie k\u00f6nnen das Quellkonto einer Kontenausgleichsbuchung nicht bearbeiten.",
|
||||||
"budget": "Budget",
|
"budget": "Budget",
|
||||||
"bill": "Abonnement",
|
"bill": "Subscription",
|
||||||
"you_create_withdrawal": "Sie haben eine Ausgabe erstellt.",
|
"you_create_withdrawal": "Sie haben eine Ausgabe erstellt.",
|
||||||
"you_create_transfer": "Sie erstellen eine Umbuchung.",
|
"you_create_transfer": "Sie erstellen eine Umbuchung.",
|
||||||
"you_create_deposit": "Sie haben eine Einnahme erstellt.",
|
"you_create_deposit": "Sie haben eine Einnahme erstellt.",
|
||||||
@@ -130,15 +130,15 @@
|
|||||||
"response": "Antwort",
|
"response": "Antwort",
|
||||||
"visit_webhook_url": "Webhook-URL besuchen",
|
"visit_webhook_url": "Webhook-URL besuchen",
|
||||||
"reset_webhook_secret": "Webhook Secret zur\u00fccksetzen",
|
"reset_webhook_secret": "Webhook Secret zur\u00fccksetzen",
|
||||||
"header_exchange_rates": "Wechselkurse",
|
"header_exchange_rates": "Exchange rates",
|
||||||
"exchange_rates_intro": "Firefly III unterst\u00fctzt das Herunterladen und Verwenden von Wechselkursen. Lesen Sie mehr dar\u00fcber in <a href=\u201ehttps:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\u201c>der Dokumentation<\/a>.",
|
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||||
"exchange_rates_from_to": "Zwischen {from} und {to} (und umgekehrt)",
|
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||||
"exchange_rates_intro_rates": "Firefly III verwendet die folgenden Wechselkurse. Der Kehrwert wird automatisch berechnet, wenn er nicht angegeben wurde. Wenn f\u00fcr das Datum der Transaktion kein Wechselkurs vorhanden ist, sucht Firefly III in der Vergangenheit nach einem Kurs. Wenn keine vorhanden sind, wird der Kurs \u201e1\u201c verwendet.",
|
"exchange_rates_intro_rates": "Firefly III uses the following exchange rates. The inverse is automatically calculated when it is not provided. If no exchange rate exists for the date of the transaction, Firefly III will go back in time to find one. If none are present, the rate \"1\" will be used.",
|
||||||
"header_exchange_rates_rates": "Wechselkurse",
|
"header_exchange_rates_rates": "Exchange rates",
|
||||||
"header_exchange_rates_table": "Tabelle mit Wechselkursen",
|
"header_exchange_rates_table": "Table with exchange rates",
|
||||||
"help_rate_form": "An diesem Tag, wie viele {to} werden Sie f\u00fcr {from} bekommen?",
|
"help_rate_form": "On this day, how many {to} will you get for one {from}?",
|
||||||
"add_new_rate": "Neuen Wechselkurs hinzuf\u00fcgen",
|
"add_new_rate": "Add a new exchange rate",
|
||||||
"save_new_rate": "Neuen Kurs speichern"
|
"save_new_rate": "Save new rate"
|
||||||
},
|
},
|
||||||
"form": {
|
"form": {
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
"webhook_delivery": "Zustellung",
|
"webhook_delivery": "Zustellung",
|
||||||
"from_currency_to_currency": "{from} → {to}",
|
"from_currency_to_currency": "{from} → {to}",
|
||||||
"to_currency_from_currency": "{to} → {from}",
|
"to_currency_from_currency": "{to} → {from}",
|
||||||
"rate": "Kurs"
|
"rate": "Rate"
|
||||||
},
|
},
|
||||||
"list": {
|
"list": {
|
||||||
"active": "Aktiv?",
|
"active": "Aktiv?",
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"apply_rules_checkbox": "Regels toepassen",
|
"apply_rules_checkbox": "Regels toepassen",
|
||||||
"fire_webhooks_checkbox": "Webhooks starten",
|
"fire_webhooks_checkbox": "Webhooks starten",
|
||||||
"no_budget_pointer": "Je hebt nog geen budgetten. Maak er een aantal op de <a href=\"budgets\">budgetten<\/a>-pagina. Met budgetten kan je je uitgaven beter bijhouden.",
|
"no_budget_pointer": "Je hebt nog geen budgetten. Maak er een aantal op de <a href=\"budgets\">budgetten<\/a>-pagina. Met budgetten kan je je uitgaven beter bijhouden.",
|
||||||
"no_bill_pointer": "Je hebt nog geen abonnementen. Maak er een aantal op de <a href=\"subscriptions\">abonnementenpagina<\/a>. Met abonnementen kan je uitgaven bijhouden.",
|
"no_bill_pointer": "You seem to have no subscription yet. You should create some on the <a href=\"subscriptions\">subscription<\/a>-page. Subscriptions can help you keep track of expenses.",
|
||||||
"source_account": "Bronrekening",
|
"source_account": "Bronrekening",
|
||||||
"hidden_fields_preferences": "Je kan meer transactieopties inschakelen in je <a href=\"preferences\">instellingen<\/a>.",
|
"hidden_fields_preferences": "Je kan meer transactieopties inschakelen in je <a href=\"preferences\">instellingen<\/a>.",
|
||||||
"destination_account": "Doelrekening",
|
"destination_account": "Doelrekening",
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"is_reconciled_fields_dropped": "Omdat deze transactie al is afgestemd, kan je het bedrag noch de rekeningen wijzigen.",
|
"is_reconciled_fields_dropped": "Omdat deze transactie al is afgestemd, kan je het bedrag noch de rekeningen wijzigen.",
|
||||||
"tags": "Tags",
|
"tags": "Tags",
|
||||||
"no_budget": "(geen budget)",
|
"no_budget": "(geen budget)",
|
||||||
"no_bill": "(geen abonnement)",
|
"no_bill": "(no subscription)",
|
||||||
"category": "Categorie",
|
"category": "Categorie",
|
||||||
"attachments": "Bijlagen",
|
"attachments": "Bijlagen",
|
||||||
"notes": "Notities",
|
"notes": "Notities",
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
"destination_account_reconciliation": "Je kan de doelrekening van een afstemming niet wijzigen.",
|
"destination_account_reconciliation": "Je kan de doelrekening van een afstemming niet wijzigen.",
|
||||||
"source_account_reconciliation": "Je kan de bronrekening van een afstemming niet wijzigen.",
|
"source_account_reconciliation": "Je kan de bronrekening van een afstemming niet wijzigen.",
|
||||||
"budget": "Budget",
|
"budget": "Budget",
|
||||||
"bill": "Abonnement",
|
"bill": "Subscription",
|
||||||
"you_create_withdrawal": "Je maakt een uitgave.",
|
"you_create_withdrawal": "Je maakt een uitgave.",
|
||||||
"you_create_transfer": "Je maakt een overschrijving.",
|
"you_create_transfer": "Je maakt een overschrijving.",
|
||||||
"you_create_deposit": "Je maakt inkomsten.",
|
"you_create_deposit": "Je maakt inkomsten.",
|
||||||
@@ -130,15 +130,15 @@
|
|||||||
"response": "Reactie",
|
"response": "Reactie",
|
||||||
"visit_webhook_url": "Bezoek URL van webhook",
|
"visit_webhook_url": "Bezoek URL van webhook",
|
||||||
"reset_webhook_secret": "Reset webhook-geheim",
|
"reset_webhook_secret": "Reset webhook-geheim",
|
||||||
"header_exchange_rates": "Wisselkoersen",
|
"header_exchange_rates": "Exchange rates",
|
||||||
"exchange_rates_intro": "Firefly III kan wisselkoersen downloaden en gebruiken. Lees hier meer over in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">de documentatie<\/a>.",
|
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||||
"exchange_rates_from_to": "Tussen {from} en {to} (en andersom)",
|
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||||
"exchange_rates_intro_rates": "Firefly III gebruikt de volgende wisselkoersen. De inverse berekent zichzelf als deze niet is opgegeven. Als er geen wisselkoers bestaat voor de datum van de transactie, gaat Firefly III terug in de tijd om er een te vinden. Als er geen aanwezig is, zal de koers \"1\" gebruikt worden.",
|
"exchange_rates_intro_rates": "Firefly III uses the following exchange rates. The inverse is automatically calculated when it is not provided. If no exchange rate exists for the date of the transaction, Firefly III will go back in time to find one. If none are present, the rate \"1\" will be used.",
|
||||||
"header_exchange_rates_rates": "Wisselkoersen",
|
"header_exchange_rates_rates": "Exchange rates",
|
||||||
"header_exchange_rates_table": "Tabel met wisselkoersen",
|
"header_exchange_rates_table": "Table with exchange rates",
|
||||||
"help_rate_form": "Hoeveel {to} krijg je op deze dag voor \u00e9\u00e9n {from}?",
|
"help_rate_form": "On this day, how many {to} will you get for one {from}?",
|
||||||
"add_new_rate": "Nieuwe wisselkoers toevoegen",
|
"add_new_rate": "Add a new exchange rate",
|
||||||
"save_new_rate": "Nieuwe wisselkoers opslaan"
|
"save_new_rate": "Save new rate"
|
||||||
},
|
},
|
||||||
"form": {
|
"form": {
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
"webhook_delivery": "Bericht",
|
"webhook_delivery": "Bericht",
|
||||||
"from_currency_to_currency": "{from} → {to}",
|
"from_currency_to_currency": "{from} → {to}",
|
||||||
"to_currency_from_currency": "{to} → {from}",
|
"to_currency_from_currency": "{to} → {from}",
|
||||||
"rate": "Wisselkoers"
|
"rate": "Rate"
|
||||||
},
|
},
|
||||||
"list": {
|
"list": {
|
||||||
"active": "Actief?",
|
"active": "Actief?",
|
||||||
|
|||||||
@@ -46,13 +46,16 @@ final class BillControllerTest extends TestCase
|
|||||||
|
|
||||||
protected function createAuthenticatedUser(): User
|
protected function createAuthenticatedUser(): User
|
||||||
{
|
{
|
||||||
$userGroup = UserGroup::create(['title' => 'Test Group']);
|
$userGroup = UserGroup::create(['title' => 'Test Group']);
|
||||||
|
|
||||||
return User::create([
|
$user = User::create([
|
||||||
'email' => 'test@email.com',
|
'email' => 'test@email.com',
|
||||||
'password' => 'password',
|
'password' => 'password',
|
||||||
'user_group_id' => $userGroup->id,
|
|
||||||
]);
|
]);
|
||||||
|
$user->user_group_id = $userGroup->id;
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createTestBills(int $count, User $user): void
|
private function createTestBills(int $count, User $user): void
|
||||||
|
|||||||
@@ -46,13 +46,16 @@ final class BudgetControllerTest extends TestCase
|
|||||||
|
|
||||||
protected function createAuthenticatedUser(): User
|
protected function createAuthenticatedUser(): User
|
||||||
{
|
{
|
||||||
$userGroup = UserGroup::create(['title' => 'Test Group']);
|
$userGroup = UserGroup::create(['title' => 'Test Group']);
|
||||||
|
|
||||||
return User::create([
|
$user = User::create([
|
||||||
'email' => 'test@email.com',
|
'email' => 'test@email.com',
|
||||||
'password' => 'password',
|
'password' => 'password',
|
||||||
'user_group_id' => $userGroup->id,
|
|
||||||
]);
|
]);
|
||||||
|
$user->user_group_id = $userGroup->id;
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createTestBudgets(int $count, User $user): void
|
private function createTestBudgets(int $count, User $user): void
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ use FireflyIII\Models\Category;
|
|||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use Tests\integration\TestCase;
|
use Tests\integration\TestCase;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
|
use FireflyIII\Models\UserGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CategoryControllerTest
|
* Class CategoryControllerTest
|
||||||
@@ -45,10 +46,16 @@ final class CategoryControllerTest extends TestCase
|
|||||||
|
|
||||||
protected function createAuthenticatedUser(): User
|
protected function createAuthenticatedUser(): User
|
||||||
{
|
{
|
||||||
return User::create([
|
$userGroup = UserGroup::create(['title' => 'Test Group']);
|
||||||
'email' => 'test@email.com',
|
|
||||||
'password' => 'password',
|
$user = User::create([
|
||||||
|
'email' => 'test@email.com',
|
||||||
|
'password' => 'password',
|
||||||
]);
|
]);
|
||||||
|
$user->user_group_id = $userGroup->id;
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createTestCategories(int $count, User $user): void
|
private function createTestCategories(int $count, User $user): void
|
||||||
|
|||||||
183
tests/integration/Api/Autocomplete/CurrencyControllerTest.php
Normal file
183
tests/integration/Api/Autocomplete/CurrencyControllerTest.php
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CurrencyControllerTest.php
|
||||||
|
* Copyright (c) 2024 tasnim0tantawi
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\integration\Api\Autocomplete;
|
||||||
|
|
||||||
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Tests\integration\TestCase;
|
||||||
|
use FireflyIII\User;
|
||||||
|
use FireflyIII\Models\UserGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class CurrencyControllerTest
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class CurrencyControllerTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \FireflyIII\Api\V1\Controllers\Autocomplete\CurrencyController
|
||||||
|
*/
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
protected function createAuthenticatedUser(): User
|
||||||
|
{
|
||||||
|
$userGroup = UserGroup::create(['title' => 'Test Group']);
|
||||||
|
|
||||||
|
|
||||||
|
$user = User::create([
|
||||||
|
'email' => 'test@email.com',
|
||||||
|
'password' => 'password',
|
||||||
|
]);
|
||||||
|
$user->user_group_id = $userGroup->id;
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createTestCurrencies(int $count, bool $enabled): void
|
||||||
|
{
|
||||||
|
for ($i = 1; $i <= $count; ++$i) {
|
||||||
|
$currency = TransactionCurrency::create([
|
||||||
|
'name' => 'Currency '.$i,
|
||||||
|
'code' => 'CUR'.$i,
|
||||||
|
'symbol' => 'C'.$i,
|
||||||
|
'decimal_places' => $i,
|
||||||
|
'enabled' => $enabled,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGivenAnUnauthenticatedRequestWhenCallingTheCurrenciesEndpointThenReturns401HttpCode(): void
|
||||||
|
{
|
||||||
|
// test API
|
||||||
|
$response = $this->get(route('api.v1.autocomplete.currencies'), ['Accept' => 'application/json']);
|
||||||
|
$response->assertStatus(401);
|
||||||
|
$response->assertHeader('Content-Type', 'application/json');
|
||||||
|
$response->assertContent('{"message":"Unauthenticated","exception":"AuthenticationException"}');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGivenAuthenticatedRequestWhenCallingTheCurrenciesEndpointThenReturns200HttpCode(): void
|
||||||
|
{
|
||||||
|
// act as a user
|
||||||
|
$user = $this->createAuthenticatedUser();
|
||||||
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
// test API
|
||||||
|
$response = $this->get(route('api.v1.autocomplete.currencies'), ['Accept' => 'application/json']);
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertHeader('Content-Type', 'application/json');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGivenAuthenticatedRequestWhenCallingTheCurrenciesEndpointThenReturnsACollectionOfEnabledCurrencies(): void
|
||||||
|
{
|
||||||
|
// act as a user
|
||||||
|
$user = $this->createAuthenticatedUser();
|
||||||
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
// create test data
|
||||||
|
$this->createTestCurrencies(10, true);
|
||||||
|
|
||||||
|
// test API
|
||||||
|
$response = $this->get(route('api.v1.autocomplete.currencies'), ['Accept' => 'application/json']);
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertHeader('Content-Type', 'application/json');
|
||||||
|
$response->assertJsonFragment(['name' => 'Currency 1']);
|
||||||
|
$response->assertJsonFragment(['code' => 'CUR1']);
|
||||||
|
$response->assertJsonStructure([
|
||||||
|
'*' => [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'code',
|
||||||
|
'symbol',
|
||||||
|
'decimal_places',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertJsonCount(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGivenAuthenticatedRequestWhenCallingTheCurrenciesEndpointDoesNotReturnDisabledCurrencies(): void
|
||||||
|
{
|
||||||
|
// act as a user
|
||||||
|
$user = $this->createAuthenticatedUser();
|
||||||
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
// create test data
|
||||||
|
$this->createTestCurrencies(10, false);
|
||||||
|
|
||||||
|
// test API
|
||||||
|
$response = $this->get(route('api.v1.autocomplete.currencies'), ['Accept' => 'application/json']);
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertHeader('Content-Type', 'application/json');
|
||||||
|
$response->assertJsonCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGivenAuthenticatedRequestWhenCallingTheCurrenciesEndpointWithQueryThenReturnsCurrenciesWithLimit(): void
|
||||||
|
{
|
||||||
|
// act as a user
|
||||||
|
$user = $this->createAuthenticatedUser();
|
||||||
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
// create test data
|
||||||
|
$this->createTestCurrencies(5, true);
|
||||||
|
|
||||||
|
// test API
|
||||||
|
$response = $this->get(route('api.v1.autocomplete.currencies', ['query' => 'Currency 1']), ['Accept' => 'application/json']);
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertHeader('Content-Type', 'application/json');
|
||||||
|
$response->assertJsonFragment(['name' => 'Currency 1']);
|
||||||
|
$response->assertJsonStructure([
|
||||||
|
'*' => [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'code',
|
||||||
|
'symbol',
|
||||||
|
'decimal_places',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertJsonCount(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGivenAuthenticatedRequestWhenCallingTheCurrenciesEndpointWithQueryThenReturnsCurrenciesThatMatchQuery(): void
|
||||||
|
{
|
||||||
|
$user = $this->createAuthenticatedUser();
|
||||||
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
$this->createTestCurrencies(20, true);
|
||||||
|
$response = $this->get(route('api.v1.autocomplete.currencies', [
|
||||||
|
'query' => 'Currency 1',
|
||||||
|
'limit' => 20,
|
||||||
|
]), ['Accept' => 'application/json']);
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertHeader('Content-Type', 'application/json');
|
||||||
|
// Currency 1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 (11)
|
||||||
|
$response->assertJsonCount(11);
|
||||||
|
}
|
||||||
|
}
|
||||||
156
tests/integration/Api/Autocomplete/ObjectGroupControllerTest.php
Normal file
156
tests/integration/Api/Autocomplete/ObjectGroupControllerTest.php
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ObjectGroupControllerTest.php
|
||||||
|
* Copyright (c) 2024 tasnim0tantawi
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\integration\Api\Autocomplete;
|
||||||
|
|
||||||
|
use FireflyIII\Models\ObjectGroup;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Tests\integration\TestCase;
|
||||||
|
use FireflyIII\User;
|
||||||
|
use FireflyIII\Models\UserGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ObjectGroupControllerTest
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class ObjectGroupControllerTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \FireflyIII\Api\V1\Controllers\Autocomplete\ObjectGroupController
|
||||||
|
*/
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
protected function createAuthenticatedUser(): User
|
||||||
|
{
|
||||||
|
$userGroup = UserGroup::create(['title' => 'Test Group']);
|
||||||
|
|
||||||
|
|
||||||
|
$user = User::create([
|
||||||
|
'email' => 'test@email.com',
|
||||||
|
'password' => 'password',
|
||||||
|
]);
|
||||||
|
$user->user_group_id = $userGroup->id;
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createTestObjectGroups(int $count, User $user): void
|
||||||
|
{
|
||||||
|
for ($i = 1; $i <= $count; ++$i) {
|
||||||
|
$objectGroup = ObjectGroup::create([
|
||||||
|
'title' => 'Object Group '.$i,
|
||||||
|
'order' => $i,
|
||||||
|
'user_group_id' => $user->user_group_id,
|
||||||
|
'user_id' => $user->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGivenAnUnauthenticatedRequestWhenCallingTheObjectGroupEndpointThenReturn401HttpCode(): void
|
||||||
|
{
|
||||||
|
$response = $this->get(route('api.v1.autocomplete.object-groups'), ['Accept' => 'application/json']);
|
||||||
|
$response->assertStatus(401);
|
||||||
|
$response->assertHeader('Content-Type', 'application/json');
|
||||||
|
$response->assertContent('{"message":"Unauthenticated","exception":"AuthenticationException"}');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGivenAuthenticatedRequestWhenCallingTheObjectGroupsEndpointThenReturns200HttpCode(): void
|
||||||
|
{
|
||||||
|
// act as a user
|
||||||
|
$user = $this->createAuthenticatedUser();
|
||||||
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
// test API
|
||||||
|
$response = $this->get(route('api.v1.autocomplete.object-groups'), ['Accept' => 'application/json']);
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertHeader('Content-Type', 'application/json');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGivenAuthenticatedRequestWhenCallingTheObjectGroupsEndpointThenReturnsObjectGroups(): void
|
||||||
|
{
|
||||||
|
$user = $this->createAuthenticatedUser();
|
||||||
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
$this->createTestObjectGroups(5, $user);
|
||||||
|
$response = $this->get(route('api.v1.autocomplete.object-groups'), ['Accept' => 'application/json']);
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertHeader('Content-Type', 'application/json');
|
||||||
|
$response->assertJsonCount(5);
|
||||||
|
$response->assertJsonFragment(['title' => 'Object Group 1']);
|
||||||
|
$response->assertJsonStructure([
|
||||||
|
'*' => [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'title',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGivenAuthenticatedRequestWhenCallingTheObjectGroupsEndpointWithQueryThenReturnsObjectGroupsWithLimit(): void
|
||||||
|
{
|
||||||
|
$user = $this->createAuthenticatedUser();
|
||||||
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
$this->createTestObjectGroups(5, $user);
|
||||||
|
$response = $this->get(route('api.v1.autocomplete.object-groups', [
|
||||||
|
'query' => 'Object Group',
|
||||||
|
'limit' => 3,
|
||||||
|
]), ['Accept' => 'application/json']);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertHeader('Content-Type', 'application/json');
|
||||||
|
$response->assertJsonCount(3);
|
||||||
|
$response->assertJsonFragment(['name' => 'Object Group 1']);
|
||||||
|
$response->assertJsonStructure([
|
||||||
|
'*' => [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'title',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGivenAuthenticatedRequestWhenCallingTheObjectGroupsEndpointWithQueryThenReturnsObjectGroupsThatMatchQuery(): void
|
||||||
|
{
|
||||||
|
$user = $this->createAuthenticatedUser();
|
||||||
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
$this->createTestObjectGroups(20, $user);
|
||||||
|
$response = $this->get(route('api.v1.autocomplete.object-groups', [
|
||||||
|
'query' => 'Object Group 1',
|
||||||
|
'limit' => 20,
|
||||||
|
]), ['Accept' => 'application/json']);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertHeader('Content-Type', 'application/json');
|
||||||
|
// Object Group 1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 (11)
|
||||||
|
$response->assertJsonCount(11);
|
||||||
|
$response->assertJsonMissing(['name' => 'Object Group 2']);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user