Merge branch 'main' into develop

This commit is contained in:
James Cole
2023-10-22 08:05:48 +02:00
31 changed files with 765 additions and 323 deletions

37
.github/label-actions.yml vendored Normal file
View 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
View 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

View File

@@ -31,6 +31,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\CurrencyTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use JsonException;
@@ -81,13 +82,12 @@ class ShowController extends Controller
$pageSize = $this->parameters->get('limit');
$collection = $this->repository->getAll();
$count = $collection->count();
// slice them:
$currencies = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($currencies, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.currencies.index') . $this->buildParams());
$manager = $this->getManager();
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
@@ -113,10 +113,15 @@ class ShowController extends Controller
*/
public function show(TransactionCurrency $currency): JsonResponse
{
/** @var User $user */
$user = auth()->user();
$manager = $this->getManager();
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
// update fields with user info.
$currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
@@ -138,9 +143,13 @@ class ShowController extends Controller
*/
public function showDefault(): JsonResponse
{
/** @var User $user */
$user = auth()->user();
$manager = $this->getManager();
$currency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $currency);
$currency = app('amount')->getDefaultCurrencyByUser($user);
// update fields with user info.
$currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);

View File

@@ -31,6 +31,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\CurrencyTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use JsonException;
use League\Fractal\Resource\Item;
@@ -79,12 +80,14 @@ class StoreController extends Controller
{
$currency = $this->repository->store($request->getAll());
if (true === $request->boolean('default')) {
app('preferences')->set('currencyPreference', $currency->code);
$this->repository->makeDefault($currency);
app('preferences')->mark();
}
$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 */
$transformer = app(CurrencyTransformer::class);

View File

@@ -32,6 +32,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\CurrencyTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use JsonException;
use League\Fractal\Resource\Item;
@@ -82,11 +83,12 @@ class UpdateController extends Controller
if ($this->repository->currencyInUse($currency)) {
return response()->json([], 409);
}
/** @var User $user */
$user = auth()->user();
$this->repository->disable($currency);
$manager = $this->getManager();
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
$currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
@@ -110,14 +112,15 @@ class UpdateController extends Controller
*/
public function makeDefault(TransactionCurrency $currency): JsonResponse
{
/** @var User $user */
$user = auth()->user();
$this->repository->enable($currency);
$this->repository->makeDefault($currency);
app('preferences')->set('currencyPreference', $currency->code);
app('preferences')->mark();
$manager = $this->getManager();
$this->parameters->set('defaultCurrency', $currency);
$currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
@@ -144,9 +147,10 @@ class UpdateController extends Controller
{
$this->repository->enable($currency);
$manager = $this->getManager();
/** @var User $user */
$user = auth()->user();
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
$currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
@@ -173,17 +177,15 @@ class UpdateController extends Controller
public function update(UpdateRequest $request, TransactionCurrency $currency): JsonResponse
{
$data = $request->getAll();
/** @var User $user */
$user = auth()->user();
$currency = $this->repository->update($currency, $data);
if (true === $request->boolean('default')) {
app('preferences')->set('currencyPreference', $currency->code);
app('preferences')->mark();
}
$manager = $this->getManager();
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
$currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);

View File

@@ -57,7 +57,6 @@ class UpdateRequest extends FormRequest
];
return $this->getAllData($fields);
// return $return;
}
/**

View File

@@ -129,20 +129,7 @@ class AccountCurrencies extends Command
$accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
// get user's currency preference:
$defaultCurrencyCode = app('preferences')->getForUser($user, 'currencyPreference', $systemCurrencyCode)->data;
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;
}
$defaultCurrency = app('amount')->getDefaultCurrencyByUser($user);
/** @var Account $account */
foreach ($accounts as $account) {

View 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());
}
}

View File

@@ -10,6 +10,7 @@ use Illuminate\Console\Command;
*/
class UpgradeSkeleton extends Command
{
use ShowsFriendlyMessages;
public const CONFIG_NAME = '480_some_name';
/**
* The console command description.

View File

@@ -100,34 +100,7 @@ class CurrencyController extends Controller
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.
@@ -206,57 +179,6 @@ class CurrencyController extends Controller
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.
@@ -299,60 +221,6 @@ class CurrencyController extends Controller
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.
*

View File

@@ -118,9 +118,6 @@ class HomeController extends Controller
*/
public function index(AccountRepositoryInterface $repository): mixed
{
if ('v3' === config('firefly.layout')) {
return view('pwa');
}
$types = config('firefly.accountTypesByIdentifier.asset');
$count = $repository->count($types);
Log::channel('audit')->info('User visits homepage.');

View File

@@ -59,9 +59,7 @@ class JavascriptController extends Controller
$accounts = $repository->getAccountsByType(
[AccountType::DEFAULT, AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD]
);
$preference = app('preferences')->get('currencyPreference', config('firefly.default_currency', 'EUR'));
$default = $currencyRepository->findByCodeNull((string)$preference->data);
$default = app('amount')->getDefaultCurrency();
$data = ['accounts' => []];
/** @var Account $account */

View File

@@ -114,7 +114,7 @@ class NewUserController extends Controller
$this->createCashWalletAccount($currency, $language); // create cash wallet account
// store currency preference:
app('preferences')->set('currencyPreference', $currency->code);
$currencyRepository->makeDefault($currency);
// store frontpage preferences:
$accounts = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();

View 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'));
}
}

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Http\Middleware;
use Closure;
use FireflyIII\Models\Account;
use FireflyIII\Models\Bill;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\Webhook;
@@ -68,6 +69,10 @@ class InterestingMessage
Preferences::mark();
$this->handleWebhookMessage($request);
}
if ($this->currencyMessage($request)) {
Preferences::mark();
$this->handleCurrencyMessage($request);
}
return $next($request);
}
@@ -221,10 +226,57 @@ class InterestingMessage
private function webhookMessage(Request $request): bool
{
// get parameters from request.
$billId = $request->get('webhook_id');
$webhookId = $request->get('webhook_id');
$message = $request->get('message');
return null !== $billId && null !== $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');
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]));
}
}
/**

View File

@@ -24,8 +24,10 @@ declare(strict_types=1);
namespace FireflyIII\Models;
use Eloquent;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
@@ -40,6 +42,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @property Carbon|null $updated_at
* @property Carbon|null $deleted_at
* @property bool $enabled
* @property bool $userDefault
* @property bool $userEnabled
* @property string $code
* @property string $name
* @property string $symbol
@@ -107,6 +111,39 @@ class TransactionCurrency extends Model
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
*/

View File

@@ -30,6 +30,7 @@ use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Support\Carbon;
@@ -129,6 +130,16 @@ class UserGroup extends Model
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.
*

View File

@@ -140,8 +140,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface
}
// is the default currency for the user or the system
$defaultCode = app('preferences')->getForUser($this->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data;
if ($currency->code === $defaultCode) {
$count = $this->user->currencies()->where('transaction_currencies.id', $currency->id)->wherePivot('user_default', 1)->count();
if ($count > 0) {
Log::info('Is the default currency of the user, return true.');
return 'current_default';
@@ -166,11 +166,25 @@ class CurrencyRepository implements CurrencyRepositoryInterface
}
/**
* Returns ALL currencies, regardless of whether they are enabled or not.
*
* @return 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
{
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
{
$this->user->currencies()->detach($currency->id);
$currency->enabled = false;
$currency->save();
}
@@ -216,15 +237,13 @@ class CurrencyRepository implements CurrencyRepositoryInterface
public function ensureMinimalEnabledCurrencies(): void
{
// if no currencies are enabled, enable the first one in the DB (usually the EUR)
if (0 === $this->get()->count()) {
/** @var TransactionCurrency $first */
$first = $this->getAll()->first();
if (null === $first) {
if (0 === $this->user->currencies()->count()) {
$euro = app('amount')->getSystemCurrency();
if (null === $euro) {
throw new FireflyException('No currencies found. You broke Firefly III');
}
Log::channel('audit')->info(sprintf('Auto-enabled currency %s.', $first->code));
$this->enable($first);
app('preferences')->set('currencyPreference', $first->code);
Log::channel('audit')->info(sprintf('Auto-enabled currency %s.', $euro->code));
$this->enable($euro);
app('preferences')->mark();
}
}
@@ -235,7 +254,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface
*/
public function enable(TransactionCurrency $currency): void
{
$currency->enabled = true;
$this->user->currencies()->syncWithoutDetaching([$currency->id]);
$currency->enabled = false;
$currency->save();
}
@@ -442,6 +462,14 @@ class CurrencyRepository implements CurrencyRepositoryInterface
return null;
}
/**
* @inheritDoc
*/
public function getUserCurrencies(User $user): Collection
{
return $user->currencies()->get();
}
/**
* @inheritDoc
*/
@@ -507,6 +535,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
*/
public function store(array $data): TransactionCurrency
{
throw new FireflyException(sprintf('Method "%s" needs a refactor.', __METHOD__));
/** @var TransactionCurrencyFactory $factory */
$factory = app(TransactionCurrencyFactory::class);
$result = $factory->create($data);
@@ -526,9 +555,61 @@ class CurrencyRepository implements CurrencyRepositoryInterface
*/
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 */
$service = app(CurrencyUpdateService::class);
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]]);
}
}

View File

@@ -204,6 +204,20 @@ interface CurrencyRepositoryInterface
*/
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
*

View File

@@ -418,10 +418,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
if (null !== $currencyPreference) {
$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;
$return[$journalId] = $return[$journalId] ?? [];

View File

@@ -52,14 +52,13 @@ class CurrencyUpdateService
$currency->name = e($data['name']);
}
if (array_key_exists('enabled', $data) && is_bool($data['enabled'])) {
$currency->enabled = (bool)$data['enabled'];
}
$currency->enabled = false;
if (array_key_exists('decimal_places', $data) && is_int($data['decimal_places'])) {
$currency->decimal_places = (int)$data['decimal_places'];
}
unset($currency->userEnabled);
unset($currency->userDefault);
$currency->save();
return $currency;

View File

@@ -108,33 +108,9 @@ class Amount
*/
public function getCurrencies(): Collection
{
return TransactionCurrency::where('enabled', true)->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');
/** @var User $user */
$user = auth()->user();
return $user->currencies()->orderBy('code','ASC')->get();
}
/**
@@ -163,22 +139,14 @@ class Amount
if ($cache->has()) {
return $cache->get();
}
$currencyPreference = app('preferences')->getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR'));
$currencyPrefStr = $currencyPreference ? $currencyPreference->data : 'EUR';
// at this point the currency preference could be encrypted, if coming from an old version.
$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();
$default = $user->currencies()->where('user_default', true)->first();
if(null === $default) {
$default = $this->getSystemCurrency();
$user->currencies()->sync([$default->id => ['user_default' => true]]);
}
$cache->store($currency);
$cache->store($default);
return $currency;
return $default;
}
/**

View File

@@ -60,6 +60,9 @@ class Preferences
*/
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 */
$user = auth()->user();
if (null === $user) {
@@ -82,6 +85,9 @@ class Preferences
*/
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']);
if (null !== $preference && null === $preference->data) {
$preference->delete();
@@ -108,6 +114,9 @@ class Preferences
*/
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);
if (Cache::has($fullName)) {
Cache::forget($fullName);
@@ -123,6 +132,9 @@ class Preferences
*/
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);
Cache::forget($key);
Cache::put($key, '', 5);
@@ -138,6 +150,9 @@ class Preferences
*/
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);
Cache::forget($fullName);
/** @var Preference|null $pref */
@@ -185,6 +200,9 @@ class Preferences
*/
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();
}
@@ -220,6 +238,9 @@ class Preferences
*/
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 */
$user = auth()->user();
if (null === $user) {
@@ -243,6 +264,9 @@ class Preferences
*/
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);
}
@@ -283,6 +307,9 @@ class Preferences
*/
public function set(string $name, $value): Preference
{
if('currencyPreference' === $name) {
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
}
$user = auth()->user();
if (null === $user) {
// make new preference, return it:

View File

@@ -34,23 +34,16 @@ class CurrencyTransformer extends AbstractTransformer
* Transform the currency.
*
* @param TransactionCurrency $currency
*
* @return 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 [
'id' => (int)$currency->id,
'created_at' => $currency->created_at->toAtomString(),
'updated_at' => $currency->updated_at->toAtomString(),
'default' => $isDefault,
'enabled' => $currency->enabled,
'default' => $currency->userDefault,
'enabled' => $currency->userEnabled,
'name' => $currency->name,
'code' => $currency->code,
'symbol' => $currency->symbol,

View File

@@ -46,6 +46,7 @@ use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\Tag;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\UserGroup;
@@ -231,6 +232,16 @@ class User extends Authenticatable
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
*

View File

@@ -114,7 +114,7 @@ return [
],
'version' => '6.0.27',
'api_version' => '2.0.10',
'db_version' => 20,
'db_version' => 21,
// generic settings
'maxUploadSize' => 1073741824, // 1 GB

View File

@@ -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');
}
};

View File

@@ -24,55 +24,85 @@
$(function () {
"use strict";
$('.make_default').on('click', setDefaultCurrency);
$('.enable-currency').on('click', enableCurrency);
$('.disable-currency').on('click', disableCurrency);
});
function setDefaultCurrency(e) {
var button = $(e.currentTarget);
var currencyId = parseInt(button.data('id'));
var currencyCode = button.data('code');
$.post(makeDefaultUrl, {
_token: token,
id: currencyId
}).done(function (data) {
// lame but it works
location.reload();
}).fail(function () {
console.error('I failed :(');
var params = {
default: true,
enabled: true
}
$.ajax({
url: updateCurrencyUrl + '/' + currencyCode,
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;
}
function enableCurrency(e) {
var button = $(e.currentTarget);
var currencyId = parseInt(button.data('id'));
var currencyCode = button.data('code');
$.post(enableCurrencyUrl, {
_token: token,
id: currencyId
}).done(function (data) {
// lame but it works
location.reload();
}).fail(function () {
console.error('I failed :(');
var params = {
enabled: true
}
$.ajax({
url: updateCurrencyUrl + '/' + currencyCode,
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=enable_failed&code=' + currencyCode;
},
success: function () {
window.location = redirectUrl + '?message=enabled&code=' + currencyCode;
}
});
return false;
}
function disableCurrency(e) {
var button = $(e.currentTarget);
var currencyId = parseInt(button.data('id'));
var currencyCode = button.data('code');
$.post(disableCurrencyUrl, {
_token: token,
id: currencyId
}).done(function (data) {
// lame but it works
location.reload();
}).fail(function () {
console.error('I failed :(');
var params = {
enabled: false
}
$.ajax({
url: updateCurrencyUrl + '/' + currencyCode,
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=disable_failed&code=' + currencyCode;
},
success: function () {
window.location = redirectUrl + '?message=disabled&code=' + currencyCode;
}
});
return false;
}

View File

@@ -1583,7 +1583,8 @@ return [
'create_currency' => 'Create a new currency',
'store_currency' => 'Store new 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_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.',
@@ -1609,7 +1610,9 @@ return [
'disable_currency' => 'Disable',
'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',
'could_not_enable_currency' => 'Could not enable currency ":name". Please review the logs.',
'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:
'mandatoryFields' => 'Mandatory fields',

View File

@@ -26,62 +26,64 @@
<table class="table table-hover">
<thead>
<tr>
{% if isOwner %}
<th>&nbsp;</th>
{% endif %}
<th>{{ 'currency'|_ }}</th>
<th>{{ 'number_of_decimals'|_ }}</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{% for currency in currencies %}
<tr>
{% if isOwner %}
<td>
<div class="btn-group btn-group-xs">
{% if isOwner %}
<a class="btn btn-default" href="{{ route('currencies.edit',currency.id) }}"><span
class="fa fa-fw fa-pencil"></span></a>
<a class="btn btn-danger" href="{{ route('currencies.delete',currency.id) }}"><span
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>
</td>
{% endif %}
<td>
{% if currency.enabled == false %}
{% if currency.userEnabled == false %}
<span class="text-muted">
{% endif %}
{{ currency.name }} ({{ currency.code }}) ({{ currency.symbol|raw }})
{% if currency.id == defaultCurrency.id %}
<span class="label label-success" id="default-currency">{{ 'default_currency'|_ }}</span>
{% endif %}
{% if currency.enabled == false %}
{% if currency.userEnabled == false %}
<span class="label label-default">{{ 'currency_is_disabled'|_ }}</span>
{% endif %}
{% if currency.userEnabled == false %}
</span>
<br><small class="text-danger">{{ 'currency_is_disabled'|_ }}</small>
{% endif %}
</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>
{% endfor %}
</tbody>
@@ -100,9 +102,8 @@
{% endblock %}
{% block scripts %}
<script type="text/javascript" nonce="{{ JS_NONCE }}">
var makeDefaultUrl = "{{ route('currencies.default') }}";
var disableCurrencyUrl = "{{ route('currencies.disable') }}";
var enableCurrencyUrl = "{{ route('currencies.enable') }}";
var redirectUrl = "{{ route('currencies.index') }}";
var updateCurrencyUrl = "{{ route('api.v1.currencies.update', ['']) }}";
</script>
<script type="text/javascript" src="v1/js/ff/currencies/index.js?v={{ FF_VERSION }}" nonce="{{ JS_NONCE }}"></script>
{% endblock %}

View File

@@ -333,19 +333,16 @@ Route::group(
* Currency Controller.
*/
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 () {
Route::get('', ['uses' => 'CurrencyController@index', 'as' => 'index']);
Route::get('create', ['uses' => 'CurrencyController@create', 'as' => 'create']);
Route::get('edit/{currency}', ['uses' => 'CurrencyController@edit', 'as' => 'edit']);
Route::get('delete/{currency}', ['uses' => 'CurrencyController@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::get('', ['uses' => 'IndexController@index', 'as' => 'index']);
Route::get('create', ['uses' => 'CreateController@create', 'as' => 'create']);
Route::get('edit/{currency}', ['uses' => 'EditController@edit', 'as' => 'edit']);
Route::get('delete/{currency}', ['uses' => 'DeleteController@delete', 'as' => 'delete']);
Route::post('store', ['uses' => 'CurrencyController@store', 'as' => 'store']);
Route::post('update/{currency}', ['uses' => 'CurrencyController@update', 'as' => 'update']);
Route::post('destroy/{currency}', ['uses' => 'CurrencyController@destroy', 'as' => 'destroy']);
Route::post('store', ['uses' => 'CreateController@store', 'as' => 'store']);
Route::post('update/{currency}', ['uses' => 'EditController@update', 'as' => 'update']);
Route::post('destroy/{currency}', ['uses' => 'EditController@destroy', 'as' => 'destroy']);
}
);