mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-14 16:13:54 +00:00
Merge branch 'main' into develop
This commit is contained in:
37
.github/label-actions.yml
vendored
Normal file
37
.github/label-actions.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Configuration for Label Actions - https://github.com/dessant/label-actions
|
||||||
|
|
||||||
|
# The `feature` label is added to issues
|
||||||
|
feature:
|
||||||
|
issues:
|
||||||
|
# Post a comment, `{issue-author}` is an optional placeholder
|
||||||
|
comment: |
|
||||||
|
Hi there! This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
This issue has been marked as a feature request. The requested (new) feature will become a part of Firefly III or the data importer in due course.
|
||||||
|
|
||||||
|
If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
|
|
||||||
|
enhancement:
|
||||||
|
issues:
|
||||||
|
# Post a comment, `{issue-author}` is an optional placeholder
|
||||||
|
comment: |
|
||||||
|
Hi there! This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
This issue has been marked as an enhancement. The requested enhancement to an existing feature will become a part of Firefly III or the data importer in due course.
|
||||||
|
|
||||||
|
If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
|
|
||||||
|
# The `solved` label is added to discussions
|
||||||
|
triage:
|
||||||
|
issues:
|
||||||
|
# Post a comment, `{issue-author}` is an optional placeholder
|
||||||
|
comment: |
|
||||||
|
Hi there! This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
This issue has been marked as being in triage. The root cause is not known yet, or the issue needs more investigation. You can help by sharing debug information (from `/debug`) if you also have this issue or when you haven't already done so.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
21
.github/workflows/label-actions.yml
vendored
Normal file
21
.github/workflows/label-actions.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
name: 'Label Actions'
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [labeled, unlabeled]
|
||||||
|
pull_request_target:
|
||||||
|
types: [labeled, unlabeled]
|
||||||
|
discussion:
|
||||||
|
types: [labeled, unlabeled]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
discussions: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
action:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: dessant/label-actions@v3
|
@@ -31,6 +31,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
|||||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
use FireflyIII\Transformers\CurrencyTransformer;
|
use FireflyIII\Transformers\CurrencyTransformer;
|
||||||
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use JsonException;
|
use JsonException;
|
||||||
@@ -81,13 +82,12 @@ class ShowController extends Controller
|
|||||||
$pageSize = $this->parameters->get('limit');
|
$pageSize = $this->parameters->get('limit');
|
||||||
$collection = $this->repository->getAll();
|
$collection = $this->repository->getAll();
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
|
|
||||||
// slice them:
|
// slice them:
|
||||||
$currencies = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$currencies = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
$paginator = new LengthAwarePaginator($currencies, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($currencies, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.currencies.index') . $this->buildParams());
|
$paginator->setPath(route('api.v1.currencies.index') . $this->buildParams());
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
|
||||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
|
||||||
|
|
||||||
/** @var CurrencyTransformer $transformer */
|
/** @var CurrencyTransformer $transformer */
|
||||||
$transformer = app(CurrencyTransformer::class);
|
$transformer = app(CurrencyTransformer::class);
|
||||||
@@ -113,10 +113,15 @@ class ShowController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function show(TransactionCurrency $currency): JsonResponse
|
public function show(TransactionCurrency $currency): JsonResponse
|
||||||
{
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
||||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
||||||
|
|
||||||
|
// update fields with user info.
|
||||||
|
$currency->refreshForUser($user);
|
||||||
|
|
||||||
/** @var CurrencyTransformer $transformer */
|
/** @var CurrencyTransformer $transformer */
|
||||||
$transformer = app(CurrencyTransformer::class);
|
$transformer = app(CurrencyTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
@@ -138,9 +143,13 @@ class ShowController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function showDefault(): JsonResponse
|
public function showDefault(): JsonResponse
|
||||||
{
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$currency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
$currency = app('amount')->getDefaultCurrencyByUser($user);
|
||||||
$this->parameters->set('defaultCurrency', $currency);
|
|
||||||
|
// update fields with user info.
|
||||||
|
$currency->refreshForUser($user);
|
||||||
|
|
||||||
/** @var CurrencyTransformer $transformer */
|
/** @var CurrencyTransformer $transformer */
|
||||||
$transformer = app(CurrencyTransformer::class);
|
$transformer = app(CurrencyTransformer::class);
|
||||||
|
@@ -31,6 +31,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
|||||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
use FireflyIII\Transformers\CurrencyTransformer;
|
use FireflyIII\Transformers\CurrencyTransformer;
|
||||||
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use JsonException;
|
use JsonException;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
@@ -79,12 +80,14 @@ class StoreController extends Controller
|
|||||||
{
|
{
|
||||||
$currency = $this->repository->store($request->getAll());
|
$currency = $this->repository->store($request->getAll());
|
||||||
if (true === $request->boolean('default')) {
|
if (true === $request->boolean('default')) {
|
||||||
app('preferences')->set('currencyPreference', $currency->code);
|
$this->repository->makeDefault($currency);
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
}
|
}
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
|
||||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
$currency->refreshForUser($user);
|
||||||
|
|
||||||
/** @var CurrencyTransformer $transformer */
|
/** @var CurrencyTransformer $transformer */
|
||||||
$transformer = app(CurrencyTransformer::class);
|
$transformer = app(CurrencyTransformer::class);
|
||||||
|
@@ -32,6 +32,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
|||||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
use FireflyIII\Transformers\CurrencyTransformer;
|
use FireflyIII\Transformers\CurrencyTransformer;
|
||||||
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use JsonException;
|
use JsonException;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
@@ -82,11 +83,12 @@ class UpdateController extends Controller
|
|||||||
if ($this->repository->currencyInUse($currency)) {
|
if ($this->repository->currencyInUse($currency)) {
|
||||||
return response()->json([], 409);
|
return response()->json([], 409);
|
||||||
}
|
}
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
$this->repository->disable($currency);
|
$this->repository->disable($currency);
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
$currency->refreshForUser($user);
|
||||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
|
||||||
|
|
||||||
/** @var CurrencyTransformer $transformer */
|
/** @var CurrencyTransformer $transformer */
|
||||||
$transformer = app(CurrencyTransformer::class);
|
$transformer = app(CurrencyTransformer::class);
|
||||||
@@ -110,14 +112,15 @@ class UpdateController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function makeDefault(TransactionCurrency $currency): JsonResponse
|
public function makeDefault(TransactionCurrency $currency): JsonResponse
|
||||||
{
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
$this->repository->enable($currency);
|
$this->repository->enable($currency);
|
||||||
|
$this->repository->makeDefault($currency);
|
||||||
|
|
||||||
app('preferences')->set('currencyPreference', $currency->code);
|
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
|
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
$currency->refreshForUser($user);
|
||||||
$this->parameters->set('defaultCurrency', $currency);
|
|
||||||
|
|
||||||
/** @var CurrencyTransformer $transformer */
|
/** @var CurrencyTransformer $transformer */
|
||||||
$transformer = app(CurrencyTransformer::class);
|
$transformer = app(CurrencyTransformer::class);
|
||||||
@@ -144,9 +147,10 @@ class UpdateController extends Controller
|
|||||||
{
|
{
|
||||||
$this->repository->enable($currency);
|
$this->repository->enable($currency);
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
$currency->refreshForUser($user);
|
||||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
|
||||||
|
|
||||||
/** @var CurrencyTransformer $transformer */
|
/** @var CurrencyTransformer $transformer */
|
||||||
$transformer = app(CurrencyTransformer::class);
|
$transformer = app(CurrencyTransformer::class);
|
||||||
@@ -172,18 +176,16 @@ class UpdateController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function update(UpdateRequest $request, TransactionCurrency $currency): JsonResponse
|
public function update(UpdateRequest $request, TransactionCurrency $currency): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getAll();
|
$data = $request->getAll();
|
||||||
|
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
$currency = $this->repository->update($currency, $data);
|
$currency = $this->repository->update($currency, $data);
|
||||||
|
|
||||||
if (true === $request->boolean('default')) {
|
app('preferences')->mark();
|
||||||
app('preferences')->set('currencyPreference', $currency->code);
|
|
||||||
app('preferences')->mark();
|
|
||||||
}
|
|
||||||
|
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
$currency->refreshForUser($user);
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
|
||||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
|
||||||
|
|
||||||
/** @var CurrencyTransformer $transformer */
|
/** @var CurrencyTransformer $transformer */
|
||||||
$transformer = app(CurrencyTransformer::class);
|
$transformer = app(CurrencyTransformer::class);
|
||||||
|
@@ -57,7 +57,6 @@ class UpdateRequest extends FormRequest
|
|||||||
];
|
];
|
||||||
|
|
||||||
return $this->getAllData($fields);
|
return $this->getAllData($fields);
|
||||||
// return $return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -129,20 +129,7 @@ class AccountCurrencies extends Command
|
|||||||
$accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
$accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||||
|
|
||||||
// get user's currency preference:
|
// get user's currency preference:
|
||||||
$defaultCurrencyCode = app('preferences')->getForUser($user, 'currencyPreference', $systemCurrencyCode)->data;
|
$defaultCurrency = app('amount')->getDefaultCurrencyByUser($user);
|
||||||
if (!is_string($defaultCurrencyCode)) {
|
|
||||||
$defaultCurrencyCode = $systemCurrencyCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var TransactionCurrency|null $defaultCurrency */
|
|
||||||
$defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first();
|
|
||||||
|
|
||||||
if (null === $defaultCurrency) {
|
|
||||||
Log::error(sprintf('Users currency pref "%s" does not exist!', $defaultCurrencyCode));
|
|
||||||
$this->friendlyError(sprintf('User has a preference for "%s", but this currency does not exist.', $defaultCurrencyCode));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
|
153
app/Console/Commands/Upgrade/UpgradeCurrencyPreferences.php
Normal file
153
app/Console/Commands/Upgrade/UpgradeCurrencyPreferences.php
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Console\Commands\Upgrade;
|
||||||
|
|
||||||
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
|
use FireflyIII\Models\Preference;
|
||||||
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
|
use FireflyIII\Models\UserGroup;
|
||||||
|
use FireflyIII\User;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class UpgradeCurrencyPreferences
|
||||||
|
* TODO DONT FORGET TO ADD THIS TO THE DOCKER BUILD
|
||||||
|
*/
|
||||||
|
class UpgradeCurrencyPreferences extends Command
|
||||||
|
{
|
||||||
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
|
public const CONFIG_NAME = '610_upgrade_currency_prefs';
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Upgrade user currency preferences';
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'firefly-iii:upgrade-currency-preferences {--F|force : Force the execution of this command.}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||||
|
$this->friendlyInfo('This command has already been executed.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
$this->runUpgrade();
|
||||||
|
|
||||||
|
$this->friendlyPositive('Currency preferences migrated.');
|
||||||
|
|
||||||
|
//$this->markAsExecuted();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function isExecuted(): bool
|
||||||
|
{
|
||||||
|
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
||||||
|
if (null !== $configVar) {
|
||||||
|
return (bool)$configVar->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param User $user
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function getPreference(User $user): string
|
||||||
|
{
|
||||||
|
$preference = Preference::where('user_id', $user->id)->where('name', 'currencyPreference')->first(['id', 'user_id', 'name', 'data', 'updated_at', 'created_at']);
|
||||||
|
|
||||||
|
if (null !== $preference) {
|
||||||
|
return (string)$preference->data;
|
||||||
|
}
|
||||||
|
return 'EUR';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private function markAsExecuted(): void
|
||||||
|
{
|
||||||
|
app('fireflyconfig')->set(self::CONFIG_NAME, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function runUpgrade(): void
|
||||||
|
{
|
||||||
|
$groups = UserGroup::get();
|
||||||
|
/** @var UserGroup $group */
|
||||||
|
foreach ($groups as $group) {
|
||||||
|
$this->upgradeGroupPreferences($group);
|
||||||
|
}
|
||||||
|
|
||||||
|
$users = User::get();
|
||||||
|
/** @var User $user */
|
||||||
|
foreach ($users as $user) {
|
||||||
|
$this->upgradeUserPreferences($user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param User $user
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function upgradeUserPreferences(User $user): void
|
||||||
|
{
|
||||||
|
$currencies = TransactionCurrency::get();
|
||||||
|
$enabled = new Collection();
|
||||||
|
/** @var TransactionCurrency $currency */
|
||||||
|
foreach ($currencies as $currency) {
|
||||||
|
if ($currency->enabled) {
|
||||||
|
$enabled->push($currency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$user->currencies()->sync($enabled->pluck('id')->toArray());
|
||||||
|
|
||||||
|
// set the default currency for the user and for the group:
|
||||||
|
$preference = $this->getPreference($user);
|
||||||
|
$defaultCurrency = TransactionCurrency::where('code', $preference)->first();
|
||||||
|
if (null === $currency) {
|
||||||
|
// get EUR
|
||||||
|
$defaultCurrency = TransactionCurrency::where('code', 'EUR')->first();
|
||||||
|
}
|
||||||
|
$user->currencies()->updateExistingPivot($defaultCurrency->id, ['user_default' => true]);
|
||||||
|
$user->userGroup->currencies()->updateExistingPivot($defaultCurrency->id, ['group_default' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param UserGroup $group
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function upgradeGroupPreferences(UserGroup $group)
|
||||||
|
{
|
||||||
|
$currencies = TransactionCurrency::get();
|
||||||
|
$enabled = new Collection();
|
||||||
|
/** @var TransactionCurrency $currency */
|
||||||
|
foreach ($currencies as $currency) {
|
||||||
|
if ($currency->enabled) {
|
||||||
|
$enabled->push($currency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$group->currencies()->sync($enabled->pluck('id')->toArray());
|
||||||
|
}
|
||||||
|
}
|
@@ -10,6 +10,7 @@ use Illuminate\Console\Command;
|
|||||||
*/
|
*/
|
||||||
class UpgradeSkeleton extends Command
|
class UpgradeSkeleton extends Command
|
||||||
{
|
{
|
||||||
|
use ShowsFriendlyMessages;
|
||||||
public const CONFIG_NAME = '480_some_name';
|
public const CONFIG_NAME = '480_some_name';
|
||||||
/**
|
/**
|
||||||
* The console command description.
|
* The console command description.
|
||||||
|
@@ -100,34 +100,7 @@ class CurrencyController extends Controller
|
|||||||
return view('currencies.create', compact('subTitleIcon', 'subTitle'));
|
return view('currencies.create', compact('subTitleIcon', 'subTitle'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Make currency the default currency.
|
|
||||||
*
|
|
||||||
* @param Request $request
|
|
||||||
*
|
|
||||||
* @return RedirectResponse|Redirector
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
|
||||||
public function defaultCurrency(Request $request)
|
|
||||||
{
|
|
||||||
$currencyId = (int)$request->get('id');
|
|
||||||
if ($currencyId > 0) {
|
|
||||||
// valid currency?
|
|
||||||
$currency = $this->repository->find($currencyId);
|
|
||||||
if (null !== $currency) {
|
|
||||||
app('preferences')->set('currencyPreference', $currency->code);
|
|
||||||
app('preferences')->mark();
|
|
||||||
Log::channel('audit')->info(sprintf('Make %s the default currency.', $currency->code));
|
|
||||||
|
|
||||||
$this->repository->enable($currency);
|
|
||||||
$request->session()->flash('success', (string)trans('firefly.new_default_currency', ['name' => $currency->name]));
|
|
||||||
|
|
||||||
return redirect(route('currencies.index'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect(route('currencies.index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a currency.
|
* Deletes a currency.
|
||||||
@@ -206,57 +179,6 @@ class CurrencyController extends Controller
|
|||||||
return redirect($this->getPreviousUrl('currencies.delete.url'));
|
return redirect($this->getPreviousUrl('currencies.delete.url'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Request $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
|
||||||
public function disableCurrency(Request $request): JsonResponse
|
|
||||||
{
|
|
||||||
$currencyId = (int)$request->get('id');
|
|
||||||
$currency = $this->repository->find($currencyId);
|
|
||||||
|
|
||||||
// valid currency?
|
|
||||||
if (null === $currency) {
|
|
||||||
return response()->json([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
app('preferences')->mark();
|
|
||||||
|
|
||||||
// user must be "owner"
|
|
||||||
/** @var User $user */
|
|
||||||
$user = auth()->user();
|
|
||||||
if (!$this->userRepository->hasRole($user, 'owner')) {
|
|
||||||
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
|
|
||||||
Log::channel('audit')->info(sprintf('Tried to disable currency %s but is not site owner.', $currency->code));
|
|
||||||
return response()->json([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// currency cannot be in use.
|
|
||||||
if ($this->repository->currencyInUse($currency)) {
|
|
||||||
$location = $this->repository->currencyInUseAt($currency);
|
|
||||||
$message = (string)trans(sprintf('firefly.cannot_disable_currency_%s', $location), ['name' => e($currency->name)]);
|
|
||||||
|
|
||||||
$request->session()->flash('error', $message);
|
|
||||||
Log::channel('audit')->info(sprintf('Tried to disable currency %s but is in use.', $currency->code));
|
|
||||||
return response()->json([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// currency disabled!
|
|
||||||
$this->repository->disable($currency);
|
|
||||||
Log::channel('audit')->info(sprintf('Disabled currency %s.', $currency->code));
|
|
||||||
|
|
||||||
$this->repository->ensureMinimalEnabledCurrencies();
|
|
||||||
|
|
||||||
// extra warning
|
|
||||||
if ('EUR' === $currency->code) {
|
|
||||||
session()->flash('warning', (string)trans('firefly.disable_EUR_side_effects'));
|
|
||||||
}
|
|
||||||
|
|
||||||
session()->flash('success', (string)trans('firefly.currency_is_now_disabled', ['name' => $currency->name]));
|
|
||||||
return response()->json([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edit a currency.
|
* Edit a currency.
|
||||||
@@ -299,60 +221,6 @@ class CurrencyController extends Controller
|
|||||||
return view('currencies.edit', compact('currency', 'subTitle', 'subTitleIcon'));
|
return view('currencies.edit', compact('currency', 'subTitle', 'subTitleIcon'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Request $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
|
||||||
public function enableCurrency(Request $request): JsonResponse
|
|
||||||
{
|
|
||||||
$currencyId = (int)$request->get('id');
|
|
||||||
if ($currencyId > 0) {
|
|
||||||
// valid currency?
|
|
||||||
$currency = $this->repository->find($currencyId);
|
|
||||||
if (null !== $currency) {
|
|
||||||
app('preferences')->mark();
|
|
||||||
|
|
||||||
$this->repository->enable($currency);
|
|
||||||
session()->flash('success', (string)trans('firefly.currency_is_now_enabled', ['name' => $currency->name]));
|
|
||||||
Log::channel('audit')->info(sprintf('Enabled currency %s.', $currency->code));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return response()->json([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show overview of currencies.
|
|
||||||
*
|
|
||||||
* @param Request $request
|
|
||||||
*
|
|
||||||
* @return Factory|View
|
|
||||||
* @throws ContainerExceptionInterface
|
|
||||||
* @throws NotFoundExceptionInterface
|
|
||||||
*/
|
|
||||||
public function index(Request $request)
|
|
||||||
{
|
|
||||||
/** @var User $user */
|
|
||||||
$user = auth()->user();
|
|
||||||
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
|
|
||||||
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
|
|
||||||
$collection = $this->repository->getAll();
|
|
||||||
$total = $collection->count();
|
|
||||||
$collection = $collection->slice(($page - 1) * $pageSize, $pageSize);
|
|
||||||
$currencies = new LengthAwarePaginator($collection, $total, $pageSize, $page);
|
|
||||||
$currencies->setPath(route('currencies.index'));
|
|
||||||
|
|
||||||
$defaultCurrency = $this->repository->getCurrencyByPreference(app('preferences')->get('currencyPreference', config('firefly.default_currency', 'EUR')));
|
|
||||||
$isOwner = true;
|
|
||||||
if (!$this->userRepository->hasRole($user, 'owner')) {
|
|
||||||
$request->session()->flash('info', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
|
|
||||||
$isOwner = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('currencies.index', compact('currencies', 'defaultCurrency', 'isOwner'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store new currency.
|
* Store new currency.
|
||||||
*
|
*
|
||||||
|
@@ -118,9 +118,6 @@ class HomeController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(AccountRepositoryInterface $repository): mixed
|
public function index(AccountRepositoryInterface $repository): mixed
|
||||||
{
|
{
|
||||||
if ('v3' === config('firefly.layout')) {
|
|
||||||
return view('pwa');
|
|
||||||
}
|
|
||||||
$types = config('firefly.accountTypesByIdentifier.asset');
|
$types = config('firefly.accountTypesByIdentifier.asset');
|
||||||
$count = $repository->count($types);
|
$count = $repository->count($types);
|
||||||
Log::channel('audit')->info('User visits homepage.');
|
Log::channel('audit')->info('User visits homepage.');
|
||||||
|
@@ -56,13 +56,11 @@ class JavascriptController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function accounts(AccountRepositoryInterface $repository, CurrencyRepositoryInterface $currencyRepository): Response
|
public function accounts(AccountRepositoryInterface $repository, CurrencyRepositoryInterface $currencyRepository): Response
|
||||||
{
|
{
|
||||||
$accounts = $repository->getAccountsByType(
|
$accounts = $repository->getAccountsByType(
|
||||||
[AccountType::DEFAULT, AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD]
|
[AccountType::DEFAULT, AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD]
|
||||||
);
|
);
|
||||||
$preference = app('preferences')->get('currencyPreference', config('firefly.default_currency', 'EUR'));
|
$default = app('amount')->getDefaultCurrency();
|
||||||
$default = $currencyRepository->findByCodeNull((string)$preference->data);
|
$data = ['accounts' => []];
|
||||||
|
|
||||||
$data = ['accounts' => []];
|
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
|
@@ -114,7 +114,7 @@ class NewUserController extends Controller
|
|||||||
$this->createCashWalletAccount($currency, $language); // create cash wallet account
|
$this->createCashWalletAccount($currency, $language); // create cash wallet account
|
||||||
|
|
||||||
// store currency preference:
|
// store currency preference:
|
||||||
app('preferences')->set('currencyPreference', $currency->code);
|
$currencyRepository->makeDefault($currency);
|
||||||
|
|
||||||
// store frontpage preferences:
|
// store frontpage preferences:
|
||||||
$accounts = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
|
$accounts = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
|
||||||
|
87
app/Http/Controllers/TransactionCurrency/IndexController.php
Normal file
87
app/Http/Controllers/TransactionCurrency/IndexController.php
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Http\Controllers\TransactionCurrency;
|
||||||
|
|
||||||
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
|
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||||
|
use FireflyIII\User;
|
||||||
|
use Illuminate\Contracts\View\Factory;
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
use Illuminate\Routing\Redirector;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\View\View;
|
||||||
|
use Psr\Container\ContainerExceptionInterface;
|
||||||
|
use Psr\Container\NotFoundExceptionInterface;
|
||||||
|
|
||||||
|
class IndexController extends Controller
|
||||||
|
{
|
||||||
|
protected CurrencyRepositoryInterface $repository;
|
||||||
|
protected UserRepositoryInterface $userRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CurrencyController constructor.
|
||||||
|
*
|
||||||
|
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->middleware(
|
||||||
|
function ($request, $next) {
|
||||||
|
app('view')->share('title', (string)trans('firefly.currencies'));
|
||||||
|
app('view')->share('mainTitleIcon', 'fa-usd');
|
||||||
|
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||||
|
$this->userRepository = app(UserRepositoryInterface::class);
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show overview of currencies.
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
*
|
||||||
|
* @return Factory|View
|
||||||
|
* @throws ContainerExceptionInterface
|
||||||
|
* @throws NotFoundExceptionInterface
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
|
||||||
|
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
|
||||||
|
$collection = $this->repository->getAll();
|
||||||
|
$total = $collection->count();
|
||||||
|
$collection = $collection->slice(($page - 1) * $pageSize, $pageSize);
|
||||||
|
|
||||||
|
// order so default is on top:
|
||||||
|
$collection = $collection->sortBy(
|
||||||
|
function (TransactionCurrency $currency) {
|
||||||
|
$default = true === $currency->userDefault ? 0 : 1;
|
||||||
|
$enabled = true === $currency->userEnabled ? 0 : 1;
|
||||||
|
return sprintf('%s-%s-%s',$default, $enabled, $currency->code);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$currencies = new LengthAwarePaginator($collection, $total, $pageSize, $page);
|
||||||
|
$currencies->setPath(route('currencies.index'));
|
||||||
|
$isOwner = true;
|
||||||
|
if (!$this->userRepository->hasRole($user, 'owner')) {
|
||||||
|
$request->session()->flash('info', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
|
||||||
|
$isOwner = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('currencies.index', compact('currencies', 'isOwner'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Http\Middleware;
|
|||||||
use Closure;
|
use Closure;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Models\TransactionGroup;
|
use FireflyIII\Models\TransactionGroup;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Models\Webhook;
|
use FireflyIII\Models\Webhook;
|
||||||
@@ -68,6 +69,10 @@ class InterestingMessage
|
|||||||
Preferences::mark();
|
Preferences::mark();
|
||||||
$this->handleWebhookMessage($request);
|
$this->handleWebhookMessage($request);
|
||||||
}
|
}
|
||||||
|
if ($this->currencyMessage($request)) {
|
||||||
|
Preferences::mark();
|
||||||
|
$this->handleCurrencyMessage($request);
|
||||||
|
}
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
@@ -221,10 +226,57 @@ class InterestingMessage
|
|||||||
private function webhookMessage(Request $request): bool
|
private function webhookMessage(Request $request): bool
|
||||||
{
|
{
|
||||||
// get parameters from request.
|
// get parameters from request.
|
||||||
$billId = $request->get('webhook_id');
|
$webhookId = $request->get('webhook_id');
|
||||||
|
$message = $request->get('message');
|
||||||
|
|
||||||
|
return null !== $webhookId && null !== $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Request $request
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function currencyMessage(Request $request): bool
|
||||||
|
{
|
||||||
|
// get parameters from request.
|
||||||
|
$code = $request->get('code');
|
||||||
$message = $request->get('message');
|
$message = $request->get('message');
|
||||||
|
|
||||||
return null !== $billId && null !== $message;
|
return null !== $code && null !== $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handleCurrencyMessage(Request $request): void
|
||||||
|
{
|
||||||
|
// params:
|
||||||
|
// get parameters from request.
|
||||||
|
$code = $request->get('code');
|
||||||
|
$message = $request->get('message');
|
||||||
|
|
||||||
|
/** @var TransactionCurrency $webhook */
|
||||||
|
$currency = TransactionCurrency::whereCode($code)->first();
|
||||||
|
|
||||||
|
if (null === $currency) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ('enabled' === $message) {
|
||||||
|
session()->flash('success', (string)trans('firefly.currency_is_now_enabled', ['name' => $currency->name]));
|
||||||
|
}
|
||||||
|
if ('enable_failed' === $message) {
|
||||||
|
session()->flash('error', (string)trans('firefly.could_not_enable_currency', ['name' => $currency->name]));
|
||||||
|
}
|
||||||
|
if ('disabled' === $message) {
|
||||||
|
session()->flash('success', (string)trans('firefly.currency_is_now_disabled', ['name' => $currency->name]));
|
||||||
|
}
|
||||||
|
if ('disable_failed' === $message) {
|
||||||
|
session()->flash('error', (string)trans('firefly.could_not_disable_currency', ['name' => $currency->name]));
|
||||||
|
}
|
||||||
|
if ('default' === $message) {
|
||||||
|
session()->flash('success', (string)trans('firefly.new_default_currency', ['name' => $currency->name]));
|
||||||
|
}
|
||||||
|
if ('default_failed' === $message) {
|
||||||
|
session()->flash('error', (string)trans('firefly.default_currency_failed', ['name' => $currency->name]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -24,8 +24,10 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Models;
|
namespace FireflyIII\Models;
|
||||||
|
|
||||||
use Eloquent;
|
use Eloquent;
|
||||||
|
use FireflyIII\User;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Database\Query\Builder;
|
use Illuminate\Database\Query\Builder;
|
||||||
@@ -40,6 +42,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|||||||
* @property Carbon|null $updated_at
|
* @property Carbon|null $updated_at
|
||||||
* @property Carbon|null $deleted_at
|
* @property Carbon|null $deleted_at
|
||||||
* @property bool $enabled
|
* @property bool $enabled
|
||||||
|
* @property bool $userDefault
|
||||||
|
* @property bool $userEnabled
|
||||||
* @property string $code
|
* @property string $code
|
||||||
* @property string $name
|
* @property string $name
|
||||||
* @property string $symbol
|
* @property string $symbol
|
||||||
@@ -107,6 +111,39 @@ class TransactionCurrency extends Model
|
|||||||
throw new NotFoundHttpException();
|
throw new NotFoundHttpException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param User $user
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function refreshForUser(User $user)
|
||||||
|
{
|
||||||
|
$current = $user->currencies()->where('transaction_currencies.id', $this->id)->first();
|
||||||
|
$default = app('amount')->getDefaultCurrencyByUser($user);
|
||||||
|
$this->userDefault = (int)$default->id === (int)$this->id;
|
||||||
|
$this->userEnabled = null !== $current;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link to users
|
||||||
|
*
|
||||||
|
* @return BelongsToMany
|
||||||
|
*/
|
||||||
|
public function users(): BelongsToMany
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(User::class)->withTimestamps()->withPivot('user_default');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link to user groups
|
||||||
|
*
|
||||||
|
* @return BelongsToMany
|
||||||
|
*/
|
||||||
|
public function userGroups(): BelongsToMany
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(UserGroup::class)->withTimestamps()->withPivot('group_default');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany
|
* @return HasMany
|
||||||
*/
|
*/
|
||||||
|
@@ -30,6 +30,7 @@ use FireflyIII\User;
|
|||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
@@ -129,6 +130,16 @@ class UserGroup extends Model
|
|||||||
return $this->hasMany(Account::class);
|
return $this->hasMany(Account::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link to currencies
|
||||||
|
*
|
||||||
|
* @return BelongsToMany
|
||||||
|
*/
|
||||||
|
public function currencies(): BelongsToMany
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(TransactionCurrency::class)->withTimestamps()->withPivot('group_default');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link to attachments.
|
* Link to attachments.
|
||||||
*
|
*
|
||||||
|
@@ -140,8 +140,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
// is the default currency for the user or the system
|
// is the default currency for the user or the system
|
||||||
$defaultCode = app('preferences')->getForUser($this->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data;
|
$count = $this->user->currencies()->where('transaction_currencies.id', $currency->id)->wherePivot('user_default', 1)->count();
|
||||||
if ($currency->code === $defaultCode) {
|
if ($count > 0) {
|
||||||
Log::info('Is the default currency of the user, return true.');
|
Log::info('Is the default currency of the user, return true.');
|
||||||
|
|
||||||
return 'current_default';
|
return 'current_default';
|
||||||
@@ -166,11 +166,25 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns ALL currencies, regardless of whether they are enabled or not.
|
||||||
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function getAll(): Collection
|
public function getAll(): Collection
|
||||||
{
|
{
|
||||||
return TransactionCurrency::orderBy('code', 'ASC')->get();
|
$all = TransactionCurrency::orderBy('code', 'ASC')->get();
|
||||||
|
$local = $this->get();
|
||||||
|
return $all->map(function (TransactionCurrency $current) use ($local) {
|
||||||
|
$hasId = $local->contains(function (TransactionCurrency $entry) use ($current) {
|
||||||
|
return (int)$entry->id === (int)$current->id;
|
||||||
|
});
|
||||||
|
$isDefault = $local->contains(function (TransactionCurrency $entry) use ($current) {
|
||||||
|
return 1 === (int)$entry->pivot->user_default && (int)$entry->id === (int)$current->id;
|
||||||
|
});
|
||||||
|
$current->userEnabled = $hasId;
|
||||||
|
$current->userDefault = $isDefault;
|
||||||
|
return $current;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -178,7 +192,13 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function get(): Collection
|
public function get(): Collection
|
||||||
{
|
{
|
||||||
return TransactionCurrency::where('enabled', true)->orderBy('code', 'ASC')->get();
|
$all = $this->user->currencies()->orderBy('code', 'ASC')->withPivot(['user_default'])->get();
|
||||||
|
$all->map(function (TransactionCurrency $current) {
|
||||||
|
$current->userEnabled = true;
|
||||||
|
$current->userDefault = 1 === (int)$current->pivot->user_default;
|
||||||
|
return $current;
|
||||||
|
});
|
||||||
|
return $all;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,6 +226,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function disable(TransactionCurrency $currency): void
|
public function disable(TransactionCurrency $currency): void
|
||||||
{
|
{
|
||||||
|
$this->user->currencies()->detach($currency->id);
|
||||||
$currency->enabled = false;
|
$currency->enabled = false;
|
||||||
$currency->save();
|
$currency->save();
|
||||||
}
|
}
|
||||||
@@ -216,15 +237,13 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
|||||||
public function ensureMinimalEnabledCurrencies(): void
|
public function ensureMinimalEnabledCurrencies(): void
|
||||||
{
|
{
|
||||||
// if no currencies are enabled, enable the first one in the DB (usually the EUR)
|
// if no currencies are enabled, enable the first one in the DB (usually the EUR)
|
||||||
if (0 === $this->get()->count()) {
|
if (0 === $this->user->currencies()->count()) {
|
||||||
/** @var TransactionCurrency $first */
|
$euro = app('amount')->getSystemCurrency();
|
||||||
$first = $this->getAll()->first();
|
if (null === $euro) {
|
||||||
if (null === $first) {
|
|
||||||
throw new FireflyException('No currencies found. You broke Firefly III');
|
throw new FireflyException('No currencies found. You broke Firefly III');
|
||||||
}
|
}
|
||||||
Log::channel('audit')->info(sprintf('Auto-enabled currency %s.', $first->code));
|
Log::channel('audit')->info(sprintf('Auto-enabled currency %s.', $euro->code));
|
||||||
$this->enable($first);
|
$this->enable($euro);
|
||||||
app('preferences')->set('currencyPreference', $first->code);
|
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +254,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function enable(TransactionCurrency $currency): void
|
public function enable(TransactionCurrency $currency): void
|
||||||
{
|
{
|
||||||
$currency->enabled = true;
|
$this->user->currencies()->syncWithoutDetaching([$currency->id]);
|
||||||
|
$currency->enabled = false;
|
||||||
$currency->save();
|
$currency->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,6 +462,14 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getUserCurrencies(User $user): Collection
|
||||||
|
{
|
||||||
|
return $user->currencies()->get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@@ -507,6 +535,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function store(array $data): TransactionCurrency
|
public function store(array $data): TransactionCurrency
|
||||||
{
|
{
|
||||||
|
throw new FireflyException(sprintf('Method "%s" needs a refactor.', __METHOD__));
|
||||||
/** @var TransactionCurrencyFactory $factory */
|
/** @var TransactionCurrencyFactory $factory */
|
||||||
$factory = app(TransactionCurrencyFactory::class);
|
$factory = app(TransactionCurrencyFactory::class);
|
||||||
$result = $factory->create($data);
|
$result = $factory->create($data);
|
||||||
@@ -526,9 +555,61 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function update(TransactionCurrency $currency, array $data): TransactionCurrency
|
public function update(TransactionCurrency $currency, array $data): TransactionCurrency
|
||||||
{
|
{
|
||||||
|
app('log')->debug('Now in update()');
|
||||||
|
// can be true, false, null
|
||||||
|
$enabled = array_key_exists('enabled', $data) ? $data['enabled'] : null;
|
||||||
|
// can be true, false, but method only responds to "true".
|
||||||
|
$default = array_key_exists('default', $data) ? $data['default'] : false;
|
||||||
|
|
||||||
|
// remove illegal combo's:
|
||||||
|
if (false === $enabled && true === $default) {
|
||||||
|
$enabled = true;
|
||||||
|
}
|
||||||
|
if (false === $default) {
|
||||||
|
app('log')->warning(sprintf('Set default=false will NOT do anything for currency %s', $currency->code));
|
||||||
|
}
|
||||||
|
|
||||||
|
// update currency with current user specific settings
|
||||||
|
$currency->refreshForUser($this->user);
|
||||||
|
|
||||||
|
// currency is enabled, must be disabled.
|
||||||
|
if (false === $enabled) {
|
||||||
|
app('log')->debug(sprintf('Disabled currency %s for user #%d', $currency->code, $this->user->id));
|
||||||
|
$this->user->currencies()->detach($currency->id);
|
||||||
|
}
|
||||||
|
// currency must be enabled
|
||||||
|
if (true === $enabled) {
|
||||||
|
app('log')->debug(sprintf('Enabled currency %s for user #%d', $currency->code, $this->user->id));
|
||||||
|
$this->user->currencies()->detach($currency->id);
|
||||||
|
$this->user->currencies()->syncWithoutDetaching([$currency->id => ['user_default' => false]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// currency must be made default.
|
||||||
|
if (true === $default) {
|
||||||
|
app('log')->debug(sprintf('Enabled + made default currency %s for user #%d', $currency->code, $this->user->id));
|
||||||
|
$this->user->currencies()->detach($currency->id);
|
||||||
|
foreach ($this->user->currencies()->get() as $item) {
|
||||||
|
$this->user->currencies()->updateExistingPivot($item->id, ['user_default' => false]);
|
||||||
|
}
|
||||||
|
$this->user->currencies()->syncWithoutDetaching([$currency->id => ['user_default' => true]]);
|
||||||
|
}
|
||||||
|
|
||||||
/** @var CurrencyUpdateService $service */
|
/** @var CurrencyUpdateService $service */
|
||||||
$service = app(CurrencyUpdateService::class);
|
$service = app(CurrencyUpdateService::class);
|
||||||
|
|
||||||
return $service->update($currency, $data);
|
return $service->update($currency, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function makeDefault(TransactionCurrency $currency): void
|
||||||
|
{
|
||||||
|
app('log')->debug(sprintf('Enabled + made default currency %s for user #%d', $currency->code, $this->user->id));
|
||||||
|
$this->user->currencies()->detach($currency->id);
|
||||||
|
foreach ($this->user->currencies()->get() as $item) {
|
||||||
|
$this->user->currencies()->updateExistingPivot($item->id, ['user_default' => false]);
|
||||||
|
}
|
||||||
|
$this->user->currencies()->syncWithoutDetaching([$currency->id => ['user_default' => true]]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -204,6 +204,20 @@ interface CurrencyRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getExchangeRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): ?CurrencyExchangeRate;
|
public function getExchangeRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): ?CurrencyExchangeRate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param TransactionCurrency $currency
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function makeDefault(TransactionCurrency $currency): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param User $user
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function getUserCurrencies(User $user): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TransactionCurrency $currency
|
* @param TransactionCurrency $currency
|
||||||
*
|
*
|
||||||
|
@@ -418,10 +418,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
|
|||||||
if (null !== $currencyPreference) {
|
if (null !== $currencyPreference) {
|
||||||
$currency = TransactionCurrency::where('id', $currencyPreference->data)->first();
|
$currency = TransactionCurrency::where('id', $currencyPreference->data)->first();
|
||||||
}
|
}
|
||||||
if (null === $currencyPreference) {
|
|
||||||
$currencyCode = app('preferences')->getForUser($this->user, 'currencyPreference', 'EUR')->data;
|
|
||||||
$currency = TransactionCurrency::where('code', $currencyCode)->first();
|
|
||||||
}
|
|
||||||
$journalId = (int)$row->transaction_journal_id;
|
$journalId = (int)$row->transaction_journal_id;
|
||||||
$return[$journalId] = $return[$journalId] ?? [];
|
$return[$journalId] = $return[$journalId] ?? [];
|
||||||
|
|
||||||
|
@@ -52,14 +52,13 @@ class CurrencyUpdateService
|
|||||||
$currency->name = e($data['name']);
|
$currency->name = e($data['name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('enabled', $data) && is_bool($data['enabled'])) {
|
$currency->enabled = false;
|
||||||
$currency->enabled = (bool)$data['enabled'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists('decimal_places', $data) && is_int($data['decimal_places'])) {
|
if (array_key_exists('decimal_places', $data) && is_int($data['decimal_places'])) {
|
||||||
$currency->decimal_places = (int)$data['decimal_places'];
|
$currency->decimal_places = (int)$data['decimal_places'];
|
||||||
}
|
}
|
||||||
|
unset($currency->userEnabled);
|
||||||
|
unset($currency->userDefault);
|
||||||
$currency->save();
|
$currency->save();
|
||||||
|
|
||||||
return $currency;
|
return $currency;
|
||||||
|
@@ -108,33 +108,9 @@ class Amount
|
|||||||
*/
|
*/
|
||||||
public function getCurrencies(): Collection
|
public function getCurrencies(): Collection
|
||||||
{
|
{
|
||||||
return TransactionCurrency::where('enabled', true)->orderBy('code', 'ASC')->get();
|
/** @var User $user */
|
||||||
}
|
$user = auth()->user();
|
||||||
|
return $user->currencies()->orderBy('code','ASC')->get();
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
* @throws FireflyException
|
|
||||||
* @throws ContainerExceptionInterface
|
|
||||||
* @throws NotFoundExceptionInterface
|
|
||||||
*/
|
|
||||||
public function getCurrencyCode(): string
|
|
||||||
{
|
|
||||||
$cache = new CacheProperties();
|
|
||||||
$cache->addProperty('getCurrencyCode');
|
|
||||||
if ($cache->has()) {
|
|
||||||
return $cache->get();
|
|
||||||
}
|
|
||||||
$currencyPreference = app('preferences')->get('currencyPreference', config('firefly.default_currency', 'EUR'));
|
|
||||||
|
|
||||||
$currency = TransactionCurrency::where('code', $currencyPreference->data)->first();
|
|
||||||
if ($currency) {
|
|
||||||
$cache->store($currency->code);
|
|
||||||
|
|
||||||
return $currency->code;
|
|
||||||
}
|
|
||||||
$cache->store(config('firefly.default_currency', 'EUR'));
|
|
||||||
|
|
||||||
return (string)config('firefly.default_currency', 'EUR');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -163,22 +139,14 @@ class Amount
|
|||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return $cache->get();
|
return $cache->get();
|
||||||
}
|
}
|
||||||
$currencyPreference = app('preferences')->getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR'));
|
$default = $user->currencies()->where('user_default', true)->first();
|
||||||
$currencyPrefStr = $currencyPreference ? $currencyPreference->data : 'EUR';
|
if(null === $default) {
|
||||||
|
$default = $this->getSystemCurrency();
|
||||||
// at this point the currency preference could be encrypted, if coming from an old version.
|
$user->currencies()->sync([$default->id => ['user_default' => true]]);
|
||||||
$currencyCode = $this->tryDecrypt((string)$currencyPrefStr);
|
|
||||||
|
|
||||||
// could still be json encoded:
|
|
||||||
/** @var TransactionCurrency|null $currency */
|
|
||||||
$currency = TransactionCurrency::where('code', $currencyCode)->first();
|
|
||||||
if (null === $currency) {
|
|
||||||
// get EUR
|
|
||||||
$currency = TransactionCurrency::where('code', 'EUR')->first();
|
|
||||||
}
|
}
|
||||||
$cache->store($currency);
|
$cache->store($default);
|
||||||
|
|
||||||
return $currency;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -60,6 +60,9 @@ class Preferences
|
|||||||
*/
|
*/
|
||||||
public function get(string $name, $default = null): ?Preference
|
public function get(string $name, $default = null): ?Preference
|
||||||
{
|
{
|
||||||
|
if('currencyPreference' === $name) {
|
||||||
|
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
||||||
|
}
|
||||||
/** @var User|null $user */
|
/** @var User|null $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if (null === $user) {
|
if (null === $user) {
|
||||||
@@ -82,6 +85,9 @@ class Preferences
|
|||||||
*/
|
*/
|
||||||
public function getForUser(User $user, string $name, $default = null): ?Preference
|
public function getForUser(User $user, string $name, $default = null): ?Preference
|
||||||
{
|
{
|
||||||
|
if('currencyPreference' === $name) {
|
||||||
|
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
||||||
|
}
|
||||||
$preference = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'user_id', 'name', 'data', 'updated_at', 'created_at']);
|
$preference = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'user_id', 'name', 'data', 'updated_at', 'created_at']);
|
||||||
if (null !== $preference && null === $preference->data) {
|
if (null !== $preference && null === $preference->data) {
|
||||||
$preference->delete();
|
$preference->delete();
|
||||||
@@ -108,6 +114,9 @@ class Preferences
|
|||||||
*/
|
*/
|
||||||
public function delete(string $name): bool
|
public function delete(string $name): bool
|
||||||
{
|
{
|
||||||
|
if('currencyPreference' === $name) {
|
||||||
|
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
||||||
|
}
|
||||||
$fullName = sprintf('preference%s%s', auth()->user()->id, $name);
|
$fullName = sprintf('preference%s%s', auth()->user()->id, $name);
|
||||||
if (Cache::has($fullName)) {
|
if (Cache::has($fullName)) {
|
||||||
Cache::forget($fullName);
|
Cache::forget($fullName);
|
||||||
@@ -123,6 +132,9 @@ class Preferences
|
|||||||
*/
|
*/
|
||||||
public function forget(User $user, string $name): void
|
public function forget(User $user, string $name): void
|
||||||
{
|
{
|
||||||
|
if('currencyPreference' === $name) {
|
||||||
|
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
||||||
|
}
|
||||||
$key = sprintf('preference%s%s', $user->id, $name);
|
$key = sprintf('preference%s%s', $user->id, $name);
|
||||||
Cache::forget($key);
|
Cache::forget($key);
|
||||||
Cache::put($key, '', 5);
|
Cache::put($key, '', 5);
|
||||||
@@ -138,6 +150,9 @@ class Preferences
|
|||||||
*/
|
*/
|
||||||
public function setForUser(User $user, string $name, $value): Preference
|
public function setForUser(User $user, string $name, $value): Preference
|
||||||
{
|
{
|
||||||
|
if('currencyPreference' === $name) {
|
||||||
|
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
||||||
|
}
|
||||||
$fullName = sprintf('preference%s%s', $user->id, $name);
|
$fullName = sprintf('preference%s%s', $user->id, $name);
|
||||||
Cache::forget($fullName);
|
Cache::forget($fullName);
|
||||||
/** @var Preference|null $pref */
|
/** @var Preference|null $pref */
|
||||||
@@ -185,6 +200,9 @@ class Preferences
|
|||||||
*/
|
*/
|
||||||
public function findByName(string $name): Collection
|
public function findByName(string $name): Collection
|
||||||
{
|
{
|
||||||
|
if('currencyPreference' === $name) {
|
||||||
|
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
||||||
|
}
|
||||||
return Preference::where('name', $name)->get();
|
return Preference::where('name', $name)->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,6 +238,9 @@ class Preferences
|
|||||||
*/
|
*/
|
||||||
public function getFresh(string $name, $default = null): ?Preference
|
public function getFresh(string $name, $default = null): ?Preference
|
||||||
{
|
{
|
||||||
|
if('currencyPreference' === $name) {
|
||||||
|
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
||||||
|
}
|
||||||
/** @var User|null $user */
|
/** @var User|null $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if (null === $user) {
|
if (null === $user) {
|
||||||
@@ -243,6 +264,9 @@ class Preferences
|
|||||||
*/
|
*/
|
||||||
public function getFreshForUser(User $user, string $name, $default = null): ?Preference
|
public function getFreshForUser(User $user, string $name, $default = null): ?Preference
|
||||||
{
|
{
|
||||||
|
if('currencyPreference' === $name) {
|
||||||
|
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
||||||
|
}
|
||||||
return $this->getForUser($user, $name, $default);
|
return $this->getForUser($user, $name, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,6 +307,9 @@ class Preferences
|
|||||||
*/
|
*/
|
||||||
public function set(string $name, $value): Preference
|
public function set(string $name, $value): Preference
|
||||||
{
|
{
|
||||||
|
if('currencyPreference' === $name) {
|
||||||
|
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
||||||
|
}
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if (null === $user) {
|
if (null === $user) {
|
||||||
// make new preference, return it:
|
// make new preference, return it:
|
||||||
|
@@ -34,23 +34,16 @@ class CurrencyTransformer extends AbstractTransformer
|
|||||||
* Transform the currency.
|
* Transform the currency.
|
||||||
*
|
*
|
||||||
* @param TransactionCurrency $currency
|
* @param TransactionCurrency $currency
|
||||||
*
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function transform(TransactionCurrency $currency): array
|
public function transform(TransactionCurrency $currency): array
|
||||||
{
|
{
|
||||||
$isDefault = false;
|
|
||||||
$defaultCurrency = $this->parameters->get('defaultCurrency');
|
|
||||||
if (null !== $defaultCurrency) {
|
|
||||||
$isDefault = (int)$defaultCurrency->id === (int)$currency->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => (int)$currency->id,
|
'id' => (int)$currency->id,
|
||||||
'created_at' => $currency->created_at->toAtomString(),
|
'created_at' => $currency->created_at->toAtomString(),
|
||||||
'updated_at' => $currency->updated_at->toAtomString(),
|
'updated_at' => $currency->updated_at->toAtomString(),
|
||||||
'default' => $isDefault,
|
'default' => $currency->userDefault,
|
||||||
'enabled' => $currency->enabled,
|
'enabled' => $currency->userEnabled,
|
||||||
'name' => $currency->name,
|
'name' => $currency->name,
|
||||||
'code' => $currency->code,
|
'code' => $currency->code,
|
||||||
'symbol' => $currency->symbol,
|
'symbol' => $currency->symbol,
|
||||||
|
11
app/User.php
11
app/User.php
@@ -46,6 +46,7 @@ use FireflyIII\Models\Rule;
|
|||||||
use FireflyIII\Models\RuleGroup;
|
use FireflyIII\Models\RuleGroup;
|
||||||
use FireflyIII\Models\Tag;
|
use FireflyIII\Models\Tag;
|
||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\Transaction;
|
||||||
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Models\TransactionGroup;
|
use FireflyIII\Models\TransactionGroup;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Models\UserGroup;
|
use FireflyIII\Models\UserGroup;
|
||||||
@@ -231,6 +232,16 @@ class User extends Authenticatable
|
|||||||
return $this->hasMany(Account::class);
|
return $this->hasMany(Account::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link to currencies
|
||||||
|
*
|
||||||
|
* @return BelongsToMany
|
||||||
|
*/
|
||||||
|
public function currencies(): BelongsToMany
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(TransactionCurrency::class)->withTimestamps()->withPivot('user_default');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link to attachments
|
* Link to attachments
|
||||||
*
|
*
|
||||||
|
@@ -114,7 +114,7 @@ return [
|
|||||||
],
|
],
|
||||||
'version' => '6.0.27',
|
'version' => '6.0.27',
|
||||||
'api_version' => '2.0.10',
|
'api_version' => '2.0.10',
|
||||||
'db_version' => 20,
|
'db_version' => 21,
|
||||||
|
|
||||||
// generic settings
|
// generic settings
|
||||||
'maxUploadSize' => 1073741824, // 1 GB
|
'maxUploadSize' => 1073741824, // 1 GB
|
||||||
|
@@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
// transaction_currency_user
|
||||||
|
if (!Schema::hasTable('transaction_currency_user')) {
|
||||||
|
try {
|
||||||
|
Schema::create('transaction_currency_user', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->integer('user_id', false, true);
|
||||||
|
$table->integer('transaction_currency_id', false, true);
|
||||||
|
$table->boolean('user_default')->default(false);
|
||||||
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
|
$table->foreign('transaction_currency_id')->references('id')->on('transaction_currencies')->onDelete('cascade');
|
||||||
|
$table->unique(['user_id', 'transaction_currency_id'],'unique_combo');
|
||||||
|
});
|
||||||
|
} catch (QueryException $e) {
|
||||||
|
app('log')->error(sprintf('Could not create table "transaction_currency_user": %s', $e->getMessage()));
|
||||||
|
app('log')->error('If this table exists already (see the error message), this is not a problem. Other errors? Please open a discussion on GitHub.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction_currency_user_group
|
||||||
|
if (!Schema::hasTable('transaction_currency_user_group')) {
|
||||||
|
try {
|
||||||
|
Schema::create('transaction_currency_user_group', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->bigInteger('user_group_id', false, true);
|
||||||
|
$table->integer('transaction_currency_id', false, true);
|
||||||
|
$table->boolean('group_default')->default(false);
|
||||||
|
$table->foreign('user_group_id')->references('id')->on('user_groups')->onDelete('cascade');
|
||||||
|
$table->foreign('transaction_currency_id')->references('id')->on('transaction_currencies')->onDelete('cascade');
|
||||||
|
$table->unique(['user_group_id', 'transaction_currency_id'],'unique_combo');
|
||||||
|
});
|
||||||
|
} catch (QueryException $e) {
|
||||||
|
app('log')->error(sprintf('Could not create table "transaction_currency_user_group": %s', $e->getMessage()));
|
||||||
|
app('log')->error('If this table exists already (see the error message), this is not a problem. Other errors? Please open a discussion on GitHub.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('transaction_currency_user');
|
||||||
|
Schema::dropIfExists('transaction_currency_user_group');
|
||||||
|
}
|
||||||
|
};
|
@@ -24,55 +24,85 @@
|
|||||||
$(function () {
|
$(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
$('.make_default').on('click', setDefaultCurrency);
|
$('.make_default').on('click', setDefaultCurrency);
|
||||||
|
|
||||||
$('.enable-currency').on('click', enableCurrency);
|
$('.enable-currency').on('click', enableCurrency);
|
||||||
$('.disable-currency').on('click', disableCurrency);
|
$('.disable-currency').on('click', disableCurrency);
|
||||||
});
|
});
|
||||||
|
|
||||||
function setDefaultCurrency(e) {
|
function setDefaultCurrency(e) {
|
||||||
var button = $(e.currentTarget);
|
var button = $(e.currentTarget);
|
||||||
var currencyId = parseInt(button.data('id'));
|
var currencyCode = button.data('code');
|
||||||
|
|
||||||
$.post(makeDefaultUrl, {
|
var params = {
|
||||||
_token: token,
|
default: true,
|
||||||
id: currencyId
|
enabled: true
|
||||||
}).done(function (data) {
|
}
|
||||||
// lame but it works
|
|
||||||
location.reload();
|
$.ajax({
|
||||||
}).fail(function () {
|
url: updateCurrencyUrl + '/' + currencyCode,
|
||||||
console.error('I failed :(');
|
data: JSON.stringify(params),
|
||||||
|
type: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content'),
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
window.location = redirectUrl + '?message=default_failed&code=' + currencyCode;
|
||||||
|
},
|
||||||
|
success: function () {
|
||||||
|
window.location = redirectUrl + '?message=default&code=' + currencyCode;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function enableCurrency(e) {
|
function enableCurrency(e) {
|
||||||
var button = $(e.currentTarget);
|
var button = $(e.currentTarget);
|
||||||
var currencyId = parseInt(button.data('id'));
|
var currencyCode = button.data('code');
|
||||||
|
|
||||||
$.post(enableCurrencyUrl, {
|
var params = {
|
||||||
_token: token,
|
enabled: true
|
||||||
id: currencyId
|
}
|
||||||
}).done(function (data) {
|
|
||||||
// lame but it works
|
$.ajax({
|
||||||
location.reload();
|
url: updateCurrencyUrl + '/' + currencyCode,
|
||||||
}).fail(function () {
|
data: JSON.stringify(params),
|
||||||
console.error('I failed :(');
|
type: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content'),
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
window.location = redirectUrl + '?message=enable_failed&code=' + currencyCode;
|
||||||
|
},
|
||||||
|
success: function () {
|
||||||
|
window.location = redirectUrl + '?message=enabled&code=' + currencyCode;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function disableCurrency(e) {
|
function disableCurrency(e) {
|
||||||
var button = $(e.currentTarget);
|
var button = $(e.currentTarget);
|
||||||
var currencyId = parseInt(button.data('id'));
|
var currencyCode = button.data('code');
|
||||||
|
|
||||||
$.post(disableCurrencyUrl, {
|
var params = {
|
||||||
_token: token,
|
enabled: false
|
||||||
id: currencyId
|
}
|
||||||
}).done(function (data) {
|
|
||||||
// lame but it works
|
$.ajax({
|
||||||
location.reload();
|
url: updateCurrencyUrl + '/' + currencyCode,
|
||||||
}).fail(function () {
|
data: JSON.stringify(params),
|
||||||
console.error('I failed :(');
|
type: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content'),
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
window.location = redirectUrl + '?message=disable_failed&code=' + currencyCode;
|
||||||
|
},
|
||||||
|
success: function () {
|
||||||
|
window.location = redirectUrl + '?message=disabled&code=' + currencyCode;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -1583,7 +1583,8 @@ return [
|
|||||||
'create_currency' => 'Create a new currency',
|
'create_currency' => 'Create a new currency',
|
||||||
'store_currency' => 'Store new currency',
|
'store_currency' => 'Store new currency',
|
||||||
'update_currency' => 'Update currency',
|
'update_currency' => 'Update currency',
|
||||||
'new_default_currency' => ':name is now the default currency.',
|
'new_default_currency' => '":name" is now the default currency.',
|
||||||
|
'default_currency_failed' => 'Could not make ":name" the default currency. Please check the logs.',
|
||||||
'cannot_delete_currency' => 'Cannot delete :name because it is still in use.',
|
'cannot_delete_currency' => 'Cannot delete :name because it is still in use.',
|
||||||
'cannot_delete_fallback_currency' => ':name is the system fallback currency and can\'t be deleted.',
|
'cannot_delete_fallback_currency' => ':name is the system fallback currency and can\'t be deleted.',
|
||||||
'cannot_disable_currency_journals' => 'Cannot disable :name because transactions are still using it.',
|
'cannot_disable_currency_journals' => 'Cannot disable :name because transactions are still using it.',
|
||||||
@@ -1609,7 +1610,9 @@ return [
|
|||||||
'disable_currency' => 'Disable',
|
'disable_currency' => 'Disable',
|
||||||
'currencies_default_disabled' => 'Most of these currencies are disabled by default. To use them, you must enable them first.',
|
'currencies_default_disabled' => 'Most of these currencies are disabled by default. To use them, you must enable them first.',
|
||||||
'currency_is_now_enabled' => 'Currency ":name" has been enabled',
|
'currency_is_now_enabled' => 'Currency ":name" has been enabled',
|
||||||
|
'could_not_enable_currency' => 'Could not enable currency ":name". Please review the logs.',
|
||||||
'currency_is_now_disabled' => 'Currency ":name" has been disabled',
|
'currency_is_now_disabled' => 'Currency ":name" has been disabled',
|
||||||
|
'could_not_disable_currency' => 'Could not disable currency ":name". Perhaps it is still in use?',
|
||||||
|
|
||||||
// forms:
|
// forms:
|
||||||
'mandatoryFields' => 'Mandatory fields',
|
'mandatoryFields' => 'Mandatory fields',
|
||||||
|
@@ -26,62 +26,64 @@
|
|||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
{% if isOwner %}
|
<th> </th>
|
||||||
<th> </th>
|
|
||||||
{% endif %}
|
|
||||||
<th>{{ 'currency'|_ }}</th>
|
<th>{{ 'currency'|_ }}</th>
|
||||||
<th>{{ 'number_of_decimals'|_ }}</th>
|
<th>{{ 'number_of_decimals'|_ }}</th>
|
||||||
<th> </th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for currency in currencies %}
|
{% for currency in currencies %}
|
||||||
<tr>
|
<tr>
|
||||||
{% if isOwner %}
|
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group btn-group-xs">
|
<div class="btn-group btn-group-xs">
|
||||||
|
{% if isOwner %}
|
||||||
<a class="btn btn-default" href="{{ route('currencies.edit',currency.id) }}"><span
|
<a class="btn btn-default" href="{{ route('currencies.edit',currency.id) }}"><span
|
||||||
class="fa fa-fw fa-pencil"></span></a>
|
class="fa fa-fw fa-pencil"></span></a>
|
||||||
<a class="btn btn-danger" href="{{ route('currencies.delete',currency.id) }}"><span
|
<a class="btn btn-danger" href="{{ route('currencies.delete',currency.id) }}"><span
|
||||||
class="fa fa-fw fa-trash"></span></a>
|
class="fa fa-fw fa-trash"></span></a>
|
||||||
|
{% endif %}
|
||||||
|
{# Disable the currency. #}
|
||||||
|
{% if currency.userEnabled %}
|
||||||
|
<a class="btn btn-default disable-currency" data-code="{{ currency.code }}"
|
||||||
|
href="#">
|
||||||
|
<span class="fa fa-fw fa-square-o"></span>
|
||||||
|
{{ 'disable_currency'|_ }}</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Enable the currency. #}
|
||||||
|
{% if not currency.userEnabled %}
|
||||||
|
<a class="btn btn-default enable-currency" data-code="{{ currency.code }}"
|
||||||
|
href="#">
|
||||||
|
<span class="fa fa-fw fa-check-square-o"></span>
|
||||||
|
{{ 'enable_currency'|_ }}</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Make currency default. #}
|
||||||
|
{% if currency.id != defaultCurrency.id %}
|
||||||
|
<button data-code="{{ currency.code }}" class="make_default btn btn-default"><span
|
||||||
|
class="fa fa-fw fa-star"></span> {{ 'make_default_currency'|_ }}</button>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
{% endif %}
|
|
||||||
<td>
|
<td>
|
||||||
{% if currency.enabled == false %}
|
{% if currency.userEnabled == false %}
|
||||||
<span class="text-muted">
|
<span class="text-muted">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ currency.name }} ({{ currency.code }}) ({{ currency.symbol|raw }})
|
{{ currency.name }} ({{ currency.code }}) ({{ currency.symbol|raw }})
|
||||||
{% if currency.id == defaultCurrency.id %}
|
{% if currency.id == defaultCurrency.id %}
|
||||||
<span class="label label-success" id="default-currency">{{ 'default_currency'|_ }}</span>
|
<span class="label label-success" id="default-currency">{{ 'default_currency'|_ }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if currency.enabled == false %}
|
{% if currency.userEnabled == false %}
|
||||||
|
|
||||||
|
<span class="label label-default">{{ 'currency_is_disabled'|_ }}</span>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if currency.userEnabled == false %}
|
||||||
</span>
|
</span>
|
||||||
<br><small class="text-danger">{{ 'currency_is_disabled'|_ }}</small>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>{{ currency.decimal_places }}</td>
|
<td>{{ currency.decimal_places }}</td>
|
||||||
<td class="buttons">
|
|
||||||
<div class="btn-group">
|
|
||||||
{% if currency.id != defaultCurrency.id %}
|
|
||||||
<button data-id="{{ currency.id }}" class="make_default btn btn-default"><span
|
|
||||||
class="fa fa-fw fa-star"></span> {{ 'make_default_currency'|_ }}</button>
|
|
||||||
{% endif %}
|
|
||||||
{% if currency.enabled %}
|
|
||||||
<a class="btn btn-default disable-currency" data-id="{{ currency.id }}"
|
|
||||||
href="#">
|
|
||||||
<span class="fa fa-fw fa-square-o"></span>
|
|
||||||
{{ 'disable_currency'|_ }}</a>
|
|
||||||
{% endif %}
|
|
||||||
{% if not currency.enabled %}
|
|
||||||
<a class="btn btn-default enable-currency" data-id="{{ currency.id }}"
|
|
||||||
href="#">
|
|
||||||
<span class="fa fa-fw fa-check-square-o"></span>
|
|
||||||
{{ 'enable_currency'|_ }}</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -100,9 +102,8 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script type="text/javascript" nonce="{{ JS_NONCE }}">
|
<script type="text/javascript" nonce="{{ JS_NONCE }}">
|
||||||
var makeDefaultUrl = "{{ route('currencies.default') }}";
|
var redirectUrl = "{{ route('currencies.index') }}";
|
||||||
var disableCurrencyUrl = "{{ route('currencies.disable') }}";
|
var updateCurrencyUrl = "{{ route('api.v1.currencies.update', ['']) }}";
|
||||||
var enableCurrencyUrl = "{{ route('currencies.enable') }}";
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="v1/js/ff/currencies/index.js?v={{ FF_VERSION }}" nonce="{{ JS_NONCE }}"></script>
|
<script type="text/javascript" src="v1/js/ff/currencies/index.js?v={{ FF_VERSION }}" nonce="{{ JS_NONCE }}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -333,19 +333,16 @@ Route::group(
|
|||||||
* Currency Controller.
|
* Currency Controller.
|
||||||
*/
|
*/
|
||||||
Route::group(
|
Route::group(
|
||||||
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'currencies', 'as' => 'currencies.'],
|
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers\TransactionCurrency', 'prefix' => 'currencies', 'as' => 'currencies.'],
|
||||||
static function () {
|
static function () {
|
||||||
Route::get('', ['uses' => 'CurrencyController@index', 'as' => 'index']);
|
Route::get('', ['uses' => 'IndexController@index', 'as' => 'index']);
|
||||||
Route::get('create', ['uses' => 'CurrencyController@create', 'as' => 'create']);
|
Route::get('create', ['uses' => 'CreateController@create', 'as' => 'create']);
|
||||||
Route::get('edit/{currency}', ['uses' => 'CurrencyController@edit', 'as' => 'edit']);
|
Route::get('edit/{currency}', ['uses' => 'EditController@edit', 'as' => 'edit']);
|
||||||
Route::get('delete/{currency}', ['uses' => 'CurrencyController@delete', 'as' => 'delete']);
|
Route::get('delete/{currency}', ['uses' => 'DeleteController@delete', 'as' => 'delete']);
|
||||||
Route::post('default', ['uses' => 'CurrencyController@defaultCurrency', 'as' => 'default']);
|
|
||||||
Route::post('enable', ['uses' => 'CurrencyController@enableCurrency', 'as' => 'enable']);
|
|
||||||
Route::post('disable', ['uses' => 'CurrencyController@disableCurrency', 'as' => 'disable']);
|
|
||||||
|
|
||||||
Route::post('store', ['uses' => 'CurrencyController@store', 'as' => 'store']);
|
Route::post('store', ['uses' => 'CreateController@store', 'as' => 'store']);
|
||||||
Route::post('update/{currency}', ['uses' => 'CurrencyController@update', 'as' => 'update']);
|
Route::post('update/{currency}', ['uses' => 'EditController@update', 'as' => 'update']);
|
||||||
Route::post('destroy/{currency}', ['uses' => 'CurrencyController@destroy', 'as' => 'destroy']);
|
Route::post('destroy/{currency}', ['uses' => 'EditController@destroy', 'as' => 'destroy']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user