mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-05 04:03:26 +00:00
Code cleanup
This commit is contained in:
@@ -57,16 +57,16 @@ class HomeController extends Controller
|
||||
public function index()
|
||||
{
|
||||
Log::channel('audit')->info('User visits admin index.');
|
||||
$title = (string) trans('firefly.administration');
|
||||
$title = (string)trans('firefly.administration');
|
||||
$mainTitleIcon = 'fa-hand-spock-o';
|
||||
$email = auth()->user()->email;
|
||||
$pref = app('preferences')->get('remote_guard_alt_email', null);
|
||||
if(null !== $pref && is_string($pref->data)) {
|
||||
$email = auth()->user()->email;
|
||||
$pref = app('preferences')->get('remote_guard_alt_email', null);
|
||||
if (null !== $pref && is_string($pref->data)) {
|
||||
$email = $pref->data;
|
||||
}
|
||||
Log::debug('Email is ', [$email]);
|
||||
|
||||
return prefixView('admin.index', compact('title', 'mainTitleIcon','email'));
|
||||
return prefixView('admin.index', compact('title', 'mainTitleIcon', 'email'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +84,7 @@ class HomeController extends Controller
|
||||
$ipAddress = $request->ip();
|
||||
Log::debug(sprintf('Now in testMessage() controller. IP is %s', $ipAddress));
|
||||
event(new AdminRequestedTestMessage($user, $ipAddress));
|
||||
session()->flash('info', (string) trans('firefly.send_test_triggered'));
|
||||
session()->flash('info', (string)trans('firefly.send_test_triggered'));
|
||||
|
||||
return redirect(route('admin.index'));
|
||||
}
|
||||
|
@@ -31,6 +31,7 @@ use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\View\View;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
@@ -53,7 +54,7 @@ class LinkController extends Controller
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.administration'));
|
||||
app('view')->share('title', (string)trans('firefly.administration'));
|
||||
app('view')->share('mainTitleIcon', 'fa-hand-spock-o');
|
||||
$this->repository = app(LinkTypeRepositoryInterface::class);
|
||||
|
||||
@@ -66,13 +67,13 @@ class LinkController extends Controller
|
||||
/**
|
||||
* Make a new link form.
|
||||
*
|
||||
* @return Factory|\Illuminate\View\View
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
Log::channel('audit')->info('User visits link index.');
|
||||
|
||||
$subTitle = (string) trans('firefly.create_new_link_type');
|
||||
$subTitle = (string)trans('firefly.create_new_link_type');
|
||||
$subTitleIcon = 'fa-link';
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
@@ -89,22 +90,22 @@ class LinkController extends Controller
|
||||
* @param Request $request
|
||||
* @param LinkType $linkType
|
||||
*
|
||||
* @return Factory|RedirectResponse|Redirector|\Illuminate\View\View
|
||||
* @return Factory|RedirectResponse|Redirector|View
|
||||
*/
|
||||
public function delete(Request $request, LinkType $linkType)
|
||||
{
|
||||
if (!$linkType->editable) {
|
||||
$request->session()->flash('error', (string) trans('firefly.cannot_edit_link_type', ['name' => e($linkType->name)]));
|
||||
$request->session()->flash('error', (string)trans('firefly.cannot_edit_link_type', ['name' => e($linkType->name)]));
|
||||
|
||||
return redirect(route('admin.links.index'));
|
||||
}
|
||||
|
||||
Log::channel('audit')->info(sprintf('User wants to delete link type #%d', $linkType->id));
|
||||
$subTitle = (string) trans('firefly.delete_link_type', ['name' => $linkType->name]);
|
||||
$subTitle = (string)trans('firefly.delete_link_type', ['name' => $linkType->name]);
|
||||
$otherTypes = $this->repository->get();
|
||||
$count = $this->repository->countJournals($linkType);
|
||||
$moveTo = [];
|
||||
$moveTo[0] = (string) trans('firefly.do_not_save_connection');
|
||||
$moveTo[0] = (string)trans('firefly.do_not_save_connection');
|
||||
|
||||
/** @var LinkType $otherType */
|
||||
foreach ($otherTypes as $otherType) {
|
||||
@@ -131,10 +132,10 @@ class LinkController extends Controller
|
||||
{
|
||||
Log::channel('audit')->info(sprintf('User destroyed link type #%d', $linkType->id));
|
||||
$name = $linkType->name;
|
||||
$moveTo = $this->repository->findNull((int) $request->get('move_link_type_before_delete'));
|
||||
$moveTo = $this->repository->findNull((int)$request->get('move_link_type_before_delete'));
|
||||
$this->repository->destroy($linkType, $moveTo);
|
||||
|
||||
$request->session()->flash('success', (string) trans('firefly.deleted_link_type', ['name' => $name]));
|
||||
$request->session()->flash('success', (string)trans('firefly.deleted_link_type', ['name' => $name]));
|
||||
app('preferences')->mark();
|
||||
|
||||
return redirect($this->getPreviousUri('link-types.delete.uri'));
|
||||
@@ -146,16 +147,16 @@ class LinkController extends Controller
|
||||
* @param Request $request
|
||||
* @param LinkType $linkType
|
||||
*
|
||||
* @return Factory|RedirectResponse|Redirector|\Illuminate\View\View
|
||||
* @return Factory|RedirectResponse|Redirector|View
|
||||
*/
|
||||
public function edit(Request $request, LinkType $linkType)
|
||||
{
|
||||
if (!$linkType->editable) {
|
||||
$request->session()->flash('error', (string) trans('firefly.cannot_edit_link_type', ['name' => e($linkType->name)]));
|
||||
$request->session()->flash('error', (string)trans('firefly.cannot_edit_link_type', ['name' => e($linkType->name)]));
|
||||
|
||||
return redirect(route('admin.links.index'));
|
||||
}
|
||||
$subTitle = (string) trans('firefly.edit_link_type', ['name' => $linkType->name]);
|
||||
$subTitle = (string)trans('firefly.edit_link_type', ['name' => $linkType->name]);
|
||||
$subTitleIcon = 'fa-link';
|
||||
|
||||
Log::channel('audit')->info(sprintf('User wants to edit link type #%d', $linkType->id));
|
||||
@@ -172,11 +173,11 @@ class LinkController extends Controller
|
||||
/**
|
||||
* Show index of all links.
|
||||
*
|
||||
* @return Factory|\Illuminate\View\View
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$subTitle = (string) trans('firefly.journal_link_configuration');
|
||||
$subTitle = (string)trans('firefly.journal_link_configuration');
|
||||
$subTitleIcon = 'fa-link';
|
||||
$linkTypes = $this->repository->get();
|
||||
|
||||
@@ -195,11 +196,11 @@ class LinkController extends Controller
|
||||
*
|
||||
* @param LinkType $linkType
|
||||
*
|
||||
* @return Factory|\Illuminate\View\View
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function show(LinkType $linkType)
|
||||
{
|
||||
$subTitle = (string) trans('firefly.overview_for_link', ['name' => $linkType->name]);
|
||||
$subTitle = (string)trans('firefly.overview_for_link', ['name' => $linkType->name]);
|
||||
$subTitleIcon = 'fa-link';
|
||||
$links = $this->repository->getJournalLinks($linkType);
|
||||
|
||||
@@ -226,9 +227,9 @@ class LinkController extends Controller
|
||||
|
||||
Log::channel('audit')->info('User stored new link type.', $linkType->toArray());
|
||||
|
||||
$request->session()->flash('success', (string) trans('firefly.stored_new_link_type', ['name' => $linkType->name]));
|
||||
$request->session()->flash('success', (string)trans('firefly.stored_new_link_type', ['name' => $linkType->name]));
|
||||
$redirect = redirect($this->getPreviousUri('link-types.create.uri'));
|
||||
if (1 === (int) $request->get('create_another')) {
|
||||
if (1 === (int)$request->get('create_another')) {
|
||||
// set value so create routine will not overwrite URL:
|
||||
$request->session()->put('link-types.create.fromStore', true);
|
||||
|
||||
@@ -250,7 +251,7 @@ class LinkController extends Controller
|
||||
public function update(LinkTypeFormRequest $request, LinkType $linkType)
|
||||
{
|
||||
if (!$linkType->editable) {
|
||||
$request->session()->flash('error', (string) trans('firefly.cannot_edit_link_type', ['name' => e($linkType->name)]));
|
||||
$request->session()->flash('error', (string)trans('firefly.cannot_edit_link_type', ['name' => e($linkType->name)]));
|
||||
|
||||
return redirect(route('admin.links.index'));
|
||||
}
|
||||
@@ -264,10 +265,10 @@ class LinkController extends Controller
|
||||
|
||||
Log::channel('audit')->info(sprintf('User update link type #%d.', $linkType->id), $data);
|
||||
|
||||
$request->session()->flash('success', (string) trans('firefly.updated_link_type', ['name' => $linkType->name]));
|
||||
$request->session()->flash('success', (string)trans('firefly.updated_link_type', ['name' => $linkType->name]));
|
||||
app('preferences')->mark();
|
||||
$redirect = redirect($this->getPreviousUri('link-types.edit.uri'));
|
||||
if (1 === (int) $request->get('return_to_edit')) {
|
||||
if (1 === (int)$request->get('return_to_edit')) {
|
||||
// set value so edit routine will not overwrite URL:
|
||||
$request->session()->put('link-types.edit.fromUpdate', true);
|
||||
|
||||
|
@@ -48,7 +48,7 @@ class UserController extends Controller
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.administration'));
|
||||
app('view')->share('title', (string)trans('firefly.administration'));
|
||||
app('view')->share('mainTitleIcon', 'fa-hand-spock-o');
|
||||
$this->repository = app(UserRepositoryInterface::class);
|
||||
|
||||
@@ -63,6 +63,7 @@ class UserController extends Controller
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|RedirectResponse|Redirector|\Illuminate\View\View
|
||||
*/
|
||||
public function delete(User $user)
|
||||
@@ -73,7 +74,7 @@ class UserController extends Controller
|
||||
return redirect(route('admin.users'));
|
||||
}
|
||||
|
||||
$subTitle = (string) trans('firefly.delete_user', ['email' => $user->email]);
|
||||
$subTitle = (string)trans('firefly.delete_user', ['email' => $user->email]);
|
||||
|
||||
return prefixView('admin.users.delete', compact('user', 'subTitle'));
|
||||
}
|
||||
@@ -93,7 +94,7 @@ class UserController extends Controller
|
||||
return redirect(route('admin.users'));
|
||||
}
|
||||
$this->repository->destroy($user);
|
||||
session()->flash('success', (string) trans('firefly.user_deleted'));
|
||||
session()->flash('success', (string)trans('firefly.user_deleted'));
|
||||
|
||||
return redirect(route('admin.users'));
|
||||
}
|
||||
@@ -117,15 +118,15 @@ class UserController extends Controller
|
||||
}
|
||||
session()->forget('users.edit.fromUpdate');
|
||||
|
||||
$subTitle = (string) trans('firefly.edit_user', ['email' => $user->email]);
|
||||
$subTitle = (string)trans('firefly.edit_user', ['email' => $user->email]);
|
||||
$subTitleIcon = 'fa-user-o';
|
||||
$currentUser = auth()->user();
|
||||
$isAdmin = $this->repository->hasRole($user, 'owner');
|
||||
$codes = [
|
||||
'' => (string) trans('firefly.no_block_code'),
|
||||
'bounced' => (string) trans('firefly.block_code_bounced'),
|
||||
'expired' => (string) trans('firefly.block_code_expired'),
|
||||
'email_changed' => (string) trans('firefly.block_code_email_changed'),
|
||||
'' => (string)trans('firefly.no_block_code'),
|
||||
'bounced' => (string)trans('firefly.block_code_bounced'),
|
||||
'expired' => (string)trans('firefly.block_code_expired'),
|
||||
'email_changed' => (string)trans('firefly.block_code_email_changed'),
|
||||
];
|
||||
|
||||
return prefixView('admin.users.edit', compact('user', 'canEditDetails', 'subTitle', 'subTitleIcon', 'codes', 'currentUser', 'isAdmin'));
|
||||
@@ -138,7 +139,7 @@ class UserController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$subTitle = (string) trans('firefly.user_administration');
|
||||
$subTitle = (string)trans('firefly.user_administration');
|
||||
$subTitleIcon = 'fa-users';
|
||||
$users = $this->repository->all();
|
||||
|
||||
@@ -162,9 +163,9 @@ class UserController extends Controller
|
||||
*/
|
||||
public function show(User $user)
|
||||
{
|
||||
$title = (string) trans('firefly.administration');
|
||||
$title = (string)trans('firefly.administration');
|
||||
$mainTitleIcon = 'fa-hand-spock-o';
|
||||
$subTitle = (string) trans('firefly.single_user_administration', ['email' => $user->email]);
|
||||
$subTitle = (string)trans('firefly.single_user_administration', ['email' => $user->email]);
|
||||
$subTitleIcon = 'fa-user';
|
||||
$information = $this->repository->getUserData($user);
|
||||
|
||||
@@ -211,10 +212,10 @@ class UserController extends Controller
|
||||
$this->repository->changeStatus($user, $data['blocked'], $data['blocked_code']);
|
||||
$this->repository->updateEmail($user, $data['email']);
|
||||
|
||||
session()->flash('success', (string) trans('firefly.updated_user', ['email' => $user->email]));
|
||||
session()->flash('success', (string)trans('firefly.updated_user', ['email' => $user->email]));
|
||||
app('preferences')->mark();
|
||||
$redirect = redirect($this->getPreviousUri('users.edit.uri'));
|
||||
if (1 === (int) $request->get('return_to_edit')) {
|
||||
if (1 === (int)$request->get('return_to_edit')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
session()->put('users.edit.fromUpdate', true);
|
||||
|
||||
|
@@ -88,7 +88,7 @@ class ForgotPasswordController extends Controller
|
||||
$user = User::where('email', $request->get('email'))->first();
|
||||
|
||||
if (null !== $user && $repository->hasRole($user, 'demo')) {
|
||||
return back()->withErrors(['email' => (string) trans('firefly.cannot_reset_demo_user')]);
|
||||
return back()->withErrors(['email' => (string)trans('firefly.cannot_reset_demo_user')]);
|
||||
}
|
||||
|
||||
// We will send the password reset link to this user. Once we have attempted
|
||||
@@ -125,7 +125,7 @@ class ForgotPasswordController extends Controller
|
||||
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
|
||||
$userCount = User::count();
|
||||
$allowRegistration = true;
|
||||
$pageTitle = (string) trans('firefly.forgot_pw_page_title');
|
||||
$pageTitle = (string)trans('firefly.forgot_pw_page_title');
|
||||
if (true === $singleUserMode && $userCount > 0) {
|
||||
$allowRegistration = false;
|
||||
}
|
||||
|
@@ -120,6 +120,64 @@ class LoginController extends Controller
|
||||
$this->sendFailedLoginResponse($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the user out of the application.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function logout(Request $request)
|
||||
{
|
||||
$authGuard = config('firefly.authentication_guard');
|
||||
$logoutUri = config('firefly.custom_logout_uri');
|
||||
if ('remote_user_guard' === $authGuard && '' !== $logoutUri) {
|
||||
return redirect($logoutUri);
|
||||
}
|
||||
if ('remote_user_guard' === $authGuard && '' === $logoutUri) {
|
||||
session()->flash('error', trans('firefly.cant_logout_guard'));
|
||||
}
|
||||
|
||||
// also logout current 2FA tokens.
|
||||
$cookieName = config('google2fa.cookie_name', 'google2fa_token');
|
||||
Cookie::forget($cookieName);
|
||||
|
||||
$this->guard()->logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
if ($response = $this->loggedOut($request)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return $request->wantsJson()
|
||||
? new \Illuminate\Http\Response('', 204)
|
||||
: redirect('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the failed login response instance.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
protected function sendFailedLoginResponse(Request $request)
|
||||
{
|
||||
$exception = ValidationException::withMessages(
|
||||
[
|
||||
$this->username() => [trans('auth.failed')],
|
||||
]
|
||||
);
|
||||
$exception->redirectTo = route('login');
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
@@ -163,63 +221,4 @@ class LoginController extends Controller
|
||||
return prefixView('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the failed login response instance.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
protected function sendFailedLoginResponse(Request $request)
|
||||
{
|
||||
$exception = ValidationException::withMessages(
|
||||
[
|
||||
$this->username() => [trans('auth.failed')],
|
||||
]
|
||||
);
|
||||
$exception->redirectTo = route('login');
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Log the user out of the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function logout(Request $request)
|
||||
{
|
||||
$authGuard = config('firefly.authentication_guard');
|
||||
$logoutUri = config('firefly.custom_logout_uri');
|
||||
if ('remote_user_guard' === $authGuard && '' !== $logoutUri) {
|
||||
return redirect($logoutUri);
|
||||
}
|
||||
if ('remote_user_guard' === $authGuard && '' === $logoutUri) {
|
||||
session()->flash('error', trans('firefly.cant_logout_guard'));
|
||||
}
|
||||
|
||||
// also logout current 2FA tokens.
|
||||
$cookieName = config('google2fa.cookie_name', 'google2fa_token');
|
||||
Cookie::forget($cookieName);
|
||||
|
||||
$this->guard()->logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
if ($response = $this->loggedOut($request)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return $request->wantsJson()
|
||||
? new \Illuminate\Http\Response('', 204)
|
||||
: redirect('/');
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -108,7 +108,7 @@ class RegisterController extends Controller
|
||||
|
||||
$this->guard()->login($user);
|
||||
|
||||
session()->flash('success', (string) trans('firefly.registered'));
|
||||
session()->flash('success', (string)trans('firefly.registered'));
|
||||
|
||||
$this->registered($request, $user);
|
||||
|
||||
@@ -132,7 +132,7 @@ class RegisterController extends Controller
|
||||
$isDemoSite = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
|
||||
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
|
||||
$userCount = User::count();
|
||||
$pageTitle = (string) trans('firefly.register_page_title');
|
||||
$pageTitle = (string)trans('firefly.register_page_title');
|
||||
|
||||
if (true === $isDemoSite) {
|
||||
$allowRegistration = false;
|
||||
|
@@ -32,6 +32,7 @@ use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
@@ -76,7 +77,7 @@ class ResetPasswordController extends Controller
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Factory|JsonResponse|RedirectResponse|View
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws ValidationException
|
||||
*
|
||||
*/
|
||||
public function reset(Request $request)
|
||||
@@ -137,7 +138,7 @@ class ResetPasswordController extends Controller
|
||||
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
|
||||
$userCount = User::count();
|
||||
$allowRegistration = true;
|
||||
$pageTitle = (string) trans('firefly.reset_pw_page_title');
|
||||
$pageTitle = (string)trans('firefly.reset_pw_page_title');
|
||||
if (true === $singleUserMode && $userCount > 0) {
|
||||
$allowRegistration = false;
|
||||
}
|
||||
|
@@ -45,7 +45,7 @@ class TwoFactorController extends Controller
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$siteOwner = config('firefly.site_owner');
|
||||
$title = (string) trans('firefly.two_factor_forgot_title');
|
||||
$title = (string)trans('firefly.two_factor_forgot_title');
|
||||
|
||||
return prefixView('auth.lost-two-factor', compact('user', 'siteOwner', 'title'));
|
||||
}
|
||||
@@ -96,20 +96,26 @@ class TwoFactorController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Each MFA history has a timestamp and a code, saving the MFA entries for 5 minutes. So if the
|
||||
* submitted MFA code has been submitted in the last 5 minutes, it won't work despite being valid.
|
||||
*
|
||||
* @param string $mfaCode
|
||||
* @param array $mfaHistory
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function addToMFAHistory(string $mfaCode): void
|
||||
private function inMFAHistory(string $mfaCode, array $mfaHistory): bool
|
||||
{
|
||||
/** @var array $mfaHistory */
|
||||
$mfaHistory = Preferences::get('mfa_history', [])->data;
|
||||
$entry = [
|
||||
'time' => time(),
|
||||
'code' => $mfaCode,
|
||||
];
|
||||
$mfaHistory[] = $entry;
|
||||
$now = time();
|
||||
foreach ($mfaHistory as $entry) {
|
||||
$time = $entry['time'];
|
||||
$code = $entry['code'];
|
||||
if ($code === $mfaCode && $now - $time <= 300) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Preferences::set('mfa_history', $mfaHistory);
|
||||
$this->filterMFAHistory();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,26 +141,20 @@ class TwoFactorController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Each MFA history has a timestamp and a code, saving the MFA entries for 5 minutes. So if the
|
||||
* submitted MFA code has been submitted in the last 5 minutes, it won't work despite being valid.
|
||||
*
|
||||
* @param string $mfaCode
|
||||
* @param array $mfaHistory
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function inMFAHistory(string $mfaCode, array $mfaHistory): bool
|
||||
private function addToMFAHistory(string $mfaCode): void
|
||||
{
|
||||
$now = time();
|
||||
foreach ($mfaHistory as $entry) {
|
||||
$time = $entry['time'];
|
||||
$code = $entry['code'];
|
||||
if ($code === $mfaCode && $now - $time <= 300) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/** @var array $mfaHistory */
|
||||
$mfaHistory = Preferences::get('mfa_history', [])->data;
|
||||
$entry = [
|
||||
'time' => time(),
|
||||
'code' => $mfaCode,
|
||||
];
|
||||
$mfaHistory[] = $entry;
|
||||
|
||||
return false;
|
||||
Preferences::set('mfa_history', $mfaHistory);
|
||||
$this->filterMFAHistory();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -30,8 +30,11 @@ use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\BillStoreRequest;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
* Class CreateController
|
||||
@@ -52,7 +55,7 @@ class CreateController extends Controller
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.bills'));
|
||||
app('view')->share('title', (string)trans('firefly.bills'));
|
||||
app('view')->share('mainTitleIcon', 'fa-calendar-o');
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
@@ -67,7 +70,7 @@ class CreateController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
@@ -75,9 +78,9 @@ class CreateController extends Controller
|
||||
/** @var array $billPeriods */
|
||||
$billPeriods = config('firefly.bill_periods');
|
||||
foreach ($billPeriods as $current) {
|
||||
$periods[$current] = (string) trans('firefly.repeat_freq_' . $current);
|
||||
$periods[$current] = (string)trans('firefly.repeat_freq_' . $current);
|
||||
}
|
||||
$subTitle = (string) trans('firefly.create_new_bill');
|
||||
$subTitle = (string)trans('firefly.create_new_bill');
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
@@ -105,11 +108,11 @@ class CreateController extends Controller
|
||||
$bill = $this->repository->store($billData);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
$request->session()->flash('error', (string) trans('firefly.bill_store_error'));
|
||||
$request->session()->flash('error', (string)trans('firefly.bill_store_error'));
|
||||
|
||||
return redirect(route('bills.create'))->withInput();
|
||||
}
|
||||
$request->session()->flash('success', (string) trans('firefly.stored_new_bill', ['name' => $bill->name]));
|
||||
$request->session()->flash('success', (string)trans('firefly.stored_new_bill', ['name' => $bill->name]));
|
||||
app('preferences')->mark();
|
||||
|
||||
/** @var array $files */
|
||||
@@ -118,7 +121,7 @@ class CreateController extends Controller
|
||||
$this->attachments->saveAttachmentsForModel($bill, $files);
|
||||
}
|
||||
if (null !== $files && auth()->user()->hasRole('demo')) {
|
||||
session()->flash('info', (string) trans('firefly.no_att_demo_user'));
|
||||
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
|
||||
}
|
||||
|
||||
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
|
||||
|
@@ -54,7 +54,7 @@ class DeleteController extends Controller
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.bills'));
|
||||
app('view')->share('title', (string)trans('firefly.bills'));
|
||||
app('view')->share('mainTitleIcon', 'fa-calendar-o');
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
|
||||
@@ -62,6 +62,7 @@ class DeleteController extends Controller
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a bill.
|
||||
*
|
||||
@@ -73,7 +74,7 @@ class DeleteController extends Controller
|
||||
{
|
||||
// put previous url in session
|
||||
$this->rememberPreviousUri('bills.delete.uri');
|
||||
$subTitle = (string) trans('firefly.delete_bill', ['name' => $bill->name]);
|
||||
$subTitle = (string)trans('firefly.delete_bill', ['name' => $bill->name]);
|
||||
|
||||
return prefixView('bills.delete', compact('bill', 'subTitle'));
|
||||
}
|
||||
@@ -91,7 +92,7 @@ class DeleteController extends Controller
|
||||
$name = $bill->name;
|
||||
$this->repository->destroy($bill);
|
||||
|
||||
$request->session()->flash('success', (string) trans('firefly.deleted_bill', ['name' => $name]));
|
||||
$request->session()->flash('success', (string)trans('firefly.deleted_bill', ['name' => $name]));
|
||||
app('preferences')->mark();
|
||||
|
||||
return redirect($this->getPreviousUri('bills.delete.uri'));
|
||||
|
@@ -30,8 +30,11 @@ use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\BillUpdateRequest;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
* Class EditController
|
||||
@@ -52,7 +55,7 @@ class EditController extends Controller
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.bills'));
|
||||
app('view')->share('title', (string)trans('firefly.bills'));
|
||||
app('view')->share('mainTitleIcon', 'fa-calendar-o');
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
@@ -69,7 +72,7 @@ class EditController extends Controller
|
||||
* @param Request $request
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function edit(Request $request, Bill $bill)
|
||||
{
|
||||
@@ -78,10 +81,10 @@ class EditController extends Controller
|
||||
$billPeriods = config('firefly.bill_periods');
|
||||
|
||||
foreach ($billPeriods as $current) {
|
||||
$periods[$current] = (string) trans('firefly.' . $current);
|
||||
$periods[$current] = (string)trans('firefly.' . $current);
|
||||
}
|
||||
|
||||
$subTitle = (string) trans('firefly.edit_bill', ['name' => $bill->name]);
|
||||
$subTitle = (string)trans('firefly.edit_bill', ['name' => $bill->name]);
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (true !== session('bills.edit.fromUpdate')) {
|
||||
@@ -89,8 +92,8 @@ class EditController extends Controller
|
||||
}
|
||||
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
$bill->amount_min = round((float) $bill->amount_min, $currency->decimal_places);
|
||||
$bill->amount_max = round((float) $bill->amount_max, $currency->decimal_places);
|
||||
$bill->amount_min = round((float)$bill->amount_min, $currency->decimal_places);
|
||||
$bill->amount_max = round((float)$bill->amount_max, $currency->decimal_places);
|
||||
$rules = $this->repository->getRulesForBill($bill);
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
|
||||
@@ -100,7 +103,7 @@ class EditController extends Controller
|
||||
$preFilled = [
|
||||
'notes' => $this->repository->getNoteText($bill),
|
||||
'transaction_currency_id' => $bill->transaction_currency_id,
|
||||
'active' => $hasOldInput ? (bool) $request->old('active') : $bill->active,
|
||||
'active' => $hasOldInput ? (bool)$request->old('active') : $bill->active,
|
||||
'object_group' => $bill->objectGroups->first() ? $bill->objectGroups->first()->title : '',
|
||||
];
|
||||
|
||||
@@ -115,7 +118,7 @@ class EditController extends Controller
|
||||
* Update a bill.
|
||||
*
|
||||
* @param BillUpdateRequest $request
|
||||
* @param Bill $bill
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
@@ -124,7 +127,7 @@ class EditController extends Controller
|
||||
$billData = $request->getBillData();
|
||||
$bill = $this->repository->update($bill, $billData);
|
||||
|
||||
$request->session()->flash('success', (string) trans('firefly.updated_bill', ['name' => $bill->name]));
|
||||
$request->session()->flash('success', (string)trans('firefly.updated_bill', ['name' => $bill->name]));
|
||||
app('preferences')->mark();
|
||||
|
||||
/** @var array $files */
|
||||
@@ -133,7 +136,7 @@ class EditController extends Controller
|
||||
$this->attachments->saveAttachmentsForModel($bill, $files);
|
||||
}
|
||||
if (null !== $files && auth()->user()->hasRole('demo')) {
|
||||
session()->flash('info',(string)trans('firefly.no_att_demo_user'));
|
||||
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
|
||||
}
|
||||
|
||||
// flash messages
|
||||
@@ -142,7 +145,7 @@ class EditController extends Controller
|
||||
}
|
||||
$redirect = redirect($this->getPreviousUri('bills.edit.uri'));
|
||||
|
||||
if (1 === (int) $request->get('return_to_edit')) {
|
||||
if (1 === (int)$request->get('return_to_edit')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$request->session()->put('bills.edit.fromUpdate', true);
|
||||
|
||||
|
@@ -57,7 +57,7 @@ class IndexController extends Controller
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.bills'));
|
||||
app('view')->share('title', (string)trans('firefly.bills'));
|
||||
app('view')->share('mainTitleIcon', 'fa-calendar-o');
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
|
||||
@@ -96,7 +96,7 @@ class IndexController extends Controller
|
||||
$bills = [
|
||||
0 => [ // the index is the order, not the ID.
|
||||
'object_group_id' => 0,
|
||||
'object_group_title' => (string) trans('firefly.default_group_title_name'),
|
||||
'object_group_title' => (string)trans('firefly.default_group_title_name'),
|
||||
'bills' => [],
|
||||
],
|
||||
];
|
||||
@@ -105,7 +105,7 @@ class IndexController extends Controller
|
||||
/** @var Bill $bill */
|
||||
foreach ($collection as $bill) {
|
||||
$array = $transformer->transform($bill);
|
||||
$groupOrder = (int) $array['object_group_order'];
|
||||
$groupOrder = (int)$array['object_group_order'];
|
||||
// make group array if necessary:
|
||||
$bills[$groupOrder] = $bills[$groupOrder] ?? [
|
||||
'object_group_id' => $array['object_group_id'],
|
||||
@@ -179,8 +179,8 @@ class IndexController extends Controller
|
||||
];
|
||||
// only fill in avg when bill is active.
|
||||
if (count($bill['pay_dates']) > 0) {
|
||||
$avg = bcdiv(bcadd((string) $bill['amount_min'], (string) $bill['amount_max']), '2');
|
||||
$avg = bcmul($avg, (string) count($bill['pay_dates']));
|
||||
$avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2');
|
||||
$avg = bcmul($avg, (string)count($bill['pay_dates']));
|
||||
$sums[$groupOrder][$currencyId]['avg'] = bcadd($sums[$groupOrder][$currencyId]['avg'], $avg);
|
||||
}
|
||||
// fill in per period regardless:
|
||||
@@ -199,7 +199,7 @@ class IndexController extends Controller
|
||||
*/
|
||||
private function amountPerPeriod(array $bill, string $range): string
|
||||
{
|
||||
$avg = bcdiv(bcadd((string) $bill['amount_min'], (string) $bill['amount_max']), '2');
|
||||
$avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2');
|
||||
|
||||
Log::debug(sprintf('Amount per period for bill #%d "%s"', $bill['id'], $bill['name']));
|
||||
Log::debug(sprintf(sprintf('Average is %s', $avg)));
|
||||
@@ -211,7 +211,7 @@ class IndexController extends Controller
|
||||
'monthly' => '12',
|
||||
'weekly' => '52.17',
|
||||
];
|
||||
$yearAmount = bcmul($avg, bcdiv($multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1)));
|
||||
$yearAmount = bcmul($avg, bcdiv($multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1)));
|
||||
Log::debug(sprintf('Amount per year is %s (%s * %s / %s)', $yearAmount, $avg, $multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1)));
|
||||
|
||||
// per period:
|
||||
@@ -230,31 +230,9 @@ class IndexController extends Controller
|
||||
return $perPeriod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the order of a bill.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function setOrder(Request $request, Bill $bill): JsonResponse
|
||||
{
|
||||
$objectGroupTitle = (string) $request->get('objectGroupTitle');
|
||||
$newOrder = (int) $request->get('order');
|
||||
$this->repository->setOrder($bill, $newOrder);
|
||||
if ('' !== $objectGroupTitle) {
|
||||
$this->repository->setObjectGroup($bill, $objectGroupTitle);
|
||||
}
|
||||
if ('' === $objectGroupTitle) {
|
||||
$this->repository->removeObjectGroup($bill);
|
||||
}
|
||||
|
||||
return response()->json(['data' => 'OK']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $sums
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getTotals(array $sums): array
|
||||
@@ -289,4 +267,27 @@ class IndexController extends Controller
|
||||
|
||||
return $totals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the order of a bill.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function setOrder(Request $request, Bill $bill): JsonResponse
|
||||
{
|
||||
$objectGroupTitle = (string)$request->get('objectGroupTitle');
|
||||
$newOrder = (int)$request->get('order');
|
||||
$this->repository->setOrder($bill, $newOrder);
|
||||
if ('' !== $objectGroupTitle) {
|
||||
$this->repository->setObjectGroup($bill, $objectGroupTitle);
|
||||
}
|
||||
if ('' === $objectGroupTitle) {
|
||||
$this->repository->removeObjectGroup($bill);
|
||||
}
|
||||
|
||||
return response()->json(['data' => 'OK']);
|
||||
}
|
||||
}
|
||||
|
@@ -65,7 +65,7 @@ class ShowController extends Controller
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.bills'));
|
||||
app('view')->share('title', (string)trans('firefly.bills'));
|
||||
app('view')->share('mainTitleIcon', 'fa-calendar-o');
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
|
||||
@@ -87,7 +87,7 @@ class ShowController extends Controller
|
||||
{
|
||||
$total = 0;
|
||||
if (false === $bill->active) {
|
||||
$request->session()->flash('warning', (string) trans('firefly.cannot_scan_inactive_bill'));
|
||||
$request->session()->flash('warning', (string)trans('firefly.cannot_scan_inactive_bill'));
|
||||
|
||||
return redirect(route('bills.show', [$bill->id]));
|
||||
}
|
||||
@@ -97,7 +97,7 @@ class ShowController extends Controller
|
||||
$total = 0;
|
||||
}
|
||||
if (0 === $set->count()) {
|
||||
$request->session()->flash('error', (string) trans('firefly.no_rules_for_bill'));
|
||||
$request->session()->flash('error', (string)trans('firefly.no_rules_for_bill'));
|
||||
|
||||
return redirect(route('bills.show', [$bill->id]));
|
||||
}
|
||||
@@ -113,7 +113,7 @@ class ShowController extends Controller
|
||||
// file the rule(s)
|
||||
$ruleEngine->fire();
|
||||
|
||||
$request->session()->flash('success', (string) trans_choice('firefly.rescanned_bill', $total));
|
||||
$request->session()->flash('success', (string)trans_choice('firefly.rescanned_bill', $total));
|
||||
app('preferences')->mark();
|
||||
|
||||
return redirect(route('bills.show', [$bill->id]));
|
||||
@@ -138,8 +138,8 @@ class ShowController extends Controller
|
||||
/** @var Carbon $end */
|
||||
$end = session('end');
|
||||
$year = $start->year;
|
||||
$page = (int) $request->get('page');
|
||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||
$page = (int)$request->get('page');
|
||||
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
|
||||
$yearAverage = $this->repository->getYearAverage($bill, $start);
|
||||
$overallAverage = $this->repository->getOverallAverage($bill);
|
||||
$manager = new Manager();
|
||||
|
@@ -50,7 +50,7 @@ class AutoCompleteController extends Controller
|
||||
*/
|
||||
public function allJournalsWithID(Request $request): JsonResponse
|
||||
{
|
||||
$search = (string) $request->get('search');
|
||||
$search = (string)$request->get('search');
|
||||
/** @var JournalRepositoryInterface $repository */
|
||||
$repository = app(JournalRepositoryInterface::class);
|
||||
|
||||
@@ -61,7 +61,7 @@ class AutoCompleteController extends Controller
|
||||
$array = [];
|
||||
if (is_numeric($search)) {
|
||||
// search for group, not journal.
|
||||
$firstResult = $groupRepos->find((int) $search);
|
||||
$firstResult = $groupRepos->find((int)$search);
|
||||
if (null !== $firstResult) {
|
||||
// group may contain multiple journals, each a result:
|
||||
foreach ($firstResult->transactionJournals as $journal) {
|
||||
|
@@ -69,7 +69,7 @@ class BoxController extends Controller
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
$today = today(config('app.timezone'));
|
||||
$display = 2; // see method docs.
|
||||
$boxTitle = (string) trans('firefly.spent');
|
||||
$boxTitle = (string)trans('firefly.spent');
|
||||
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
@@ -96,21 +96,21 @@ class BoxController extends Controller
|
||||
// spent in this period, in budgets, for default currency.
|
||||
// also calculate spent per day.
|
||||
$spent = $opsRepository->sumExpenses($start, $end, null, null, $currency);
|
||||
$spentAmount = $spent[(int) $currency->id]['sum'] ?? '0';
|
||||
$spentAmount = $spent[(int)$currency->id]['sum'] ?? '0';
|
||||
|
||||
$days = $today->between($start, $end) ? $today->diffInDays($start) + 1 : $end->diffInDays($start) + 1;
|
||||
$spentPerDay = bcdiv($spentAmount, (string) $days);
|
||||
$days = $today->between($start, $end) ? $today->diffInDays($start) + 1 : $end->diffInDays($start) + 1;
|
||||
$spentPerDay = bcdiv($spentAmount, (string)$days);
|
||||
if ($availableBudgets->count() > 0) {
|
||||
$display = 0; // assume user overspent
|
||||
$boxTitle = (string) trans('firefly.overspent');
|
||||
$totalAvailableSum = (string) $availableBudgets->sum('amount');
|
||||
$boxTitle = (string)trans('firefly.overspent');
|
||||
$totalAvailableSum = (string)$availableBudgets->sum('amount');
|
||||
// calculate with available budget.
|
||||
$leftToSpendAmount = bcadd($totalAvailableSum, $spentAmount);
|
||||
if (1 === bccomp($leftToSpendAmount, '0')) {
|
||||
$boxTitle = (string) trans('firefly.left_to_spend');
|
||||
$boxTitle = (string)trans('firefly.left_to_spend');
|
||||
$days = $today->diffInDays($end) + 1;
|
||||
$display = 1; // not overspent
|
||||
$leftPerDayAmount = bcdiv($leftToSpendAmount, (string) $days);
|
||||
$leftPerDayAmount = bcdiv($leftToSpendAmount, (string)$days);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ class BoxController extends Controller
|
||||
$set = $collector->getExtractedJournals();
|
||||
/** @var array $journal */
|
||||
foreach ($set as $journal) {
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$amount = $journal['amount'] ?? '0';
|
||||
$incomes[$currencyId] = $incomes[$currencyId] ?? '0';
|
||||
$incomes[$currencyId] = bcadd($incomes[$currencyId], app('steam')->positive($amount));
|
||||
@@ -180,7 +180,7 @@ class BoxController extends Controller
|
||||
$set = $collector->getExtractedJournals();
|
||||
/** @var array $journal */
|
||||
foreach ($set as $journal) {
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$expenses[$currencyId] = $expenses[$currencyId] ?? '0';
|
||||
$expenses[$currencyId] = bcadd($expenses[$currencyId], $journal['amount'] ?? '0');
|
||||
$sums[$currencyId] = $sums[$currencyId] ?? '0';
|
||||
|
@@ -42,6 +42,7 @@ use Illuminate\Http\JsonResponse;
|
||||
class BudgetController extends Controller
|
||||
{
|
||||
use DateCalculation;
|
||||
|
||||
/** @var AvailableBudgetRepositoryInterface */
|
||||
private $abRepository;
|
||||
/** @var BudgetLimitRepositoryInterface */
|
||||
@@ -64,7 +65,7 @@ class BudgetController extends Controller
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.budgets'));
|
||||
app('view')->share('title', (string)trans('firefly.budgets'));
|
||||
app('view')->share('mainTitleIcon', 'fa-pie-chart');
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
|
@@ -115,7 +115,7 @@ class IntroController
|
||||
app('preferences')->set($key, false);
|
||||
app('preferences')->mark();
|
||||
|
||||
return response()->json(['message' => (string) trans('firefly.intro_boxes_after_refresh')]);
|
||||
return response()->json(['message' => (string)trans('firefly.intro_boxes_after_refresh')]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -64,7 +64,7 @@ class ReconcileController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('mainTitleIcon', 'fa-credit-card');
|
||||
app('view')->share('title', (string) trans('firefly.accounts'));
|
||||
app('view')->share('title', (string)trans('firefly.accounts'));
|
||||
$this->repository = app(JournalRepositoryInterface::class);
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
@@ -172,61 +172,6 @@ class ReconcileController extends Controller
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of transactions in a modal.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
*/
|
||||
public function transactions(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
if ($end->lt($start)) {
|
||||
[$end, $start] = [$start, $end];
|
||||
}
|
||||
$startDate = clone $start;
|
||||
$startDate->subDay();
|
||||
|
||||
$currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
||||
$startBalance = round((float) app('steam')->balance($account, $startDate), $currency->decimal_places);
|
||||
$endBalance = round((float) app('steam')->balance($account, $end), $currency->decimal_places);
|
||||
|
||||
// get the transactions
|
||||
$selectionStart = clone $start;
|
||||
$selectionStart->subDays(3);
|
||||
$selectionEnd = clone $end;
|
||||
$selectionEnd->addDays(3);
|
||||
|
||||
// grab transactions:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setAccounts(new Collection([$account]))
|
||||
->setRange($selectionStart, $selectionEnd)
|
||||
->withBudgetInformation()->withCategoryInformation()->withAccountInformation();
|
||||
$array = $collector->getExtractedJournals();
|
||||
$journals = $this->processTransactions($account, $array);
|
||||
|
||||
try {
|
||||
$html = prefixView(
|
||||
'accounts.reconcile.transactions',
|
||||
compact('account', 'journals', 'currency', 'start', 'end', 'selectionStart', 'selectionEnd')
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Could not render: %s', $e->getMessage()));
|
||||
$html = sprintf('Could not render accounts.reconcile.transactions: %s', $e->getMessage());
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return response()->json(['html' => $html, 'startBalance' => $startBalance, 'endBalance' => $endBalance]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param TransactionCurrency $currency
|
||||
@@ -267,11 +212,66 @@ class ReconcileController extends Controller
|
||||
return $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of transactions in a modal.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
*/
|
||||
public function transactions(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
if ($end->lt($start)) {
|
||||
[$end, $start] = [$start, $end];
|
||||
}
|
||||
$startDate = clone $start;
|
||||
$startDate->subDay();
|
||||
|
||||
$currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
||||
$startBalance = round((float)app('steam')->balance($account, $startDate), $currency->decimal_places);
|
||||
$endBalance = round((float)app('steam')->balance($account, $end), $currency->decimal_places);
|
||||
|
||||
// get the transactions
|
||||
$selectionStart = clone $start;
|
||||
$selectionStart->subDays(3);
|
||||
$selectionEnd = clone $end;
|
||||
$selectionEnd->addDays(3);
|
||||
|
||||
// grab transactions:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setAccounts(new Collection([$account]))
|
||||
->setRange($selectionStart, $selectionEnd)
|
||||
->withBudgetInformation()->withCategoryInformation()->withAccountInformation();
|
||||
$array = $collector->getExtractedJournals();
|
||||
$journals = $this->processTransactions($account, $array);
|
||||
|
||||
try {
|
||||
$html = prefixView(
|
||||
'accounts.reconcile.transactions',
|
||||
compact('account', 'journals', 'currency', 'start', 'end', 'selectionStart', 'selectionEnd')
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Could not render: %s', $e->getMessage()));
|
||||
$html = sprintf('Could not render accounts.reconcile.transactions: %s', $e->getMessage());
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return response()->json(['html' => $html, 'startBalance' => $startBalance, 'endBalance' => $endBalance]);
|
||||
}
|
||||
|
||||
/**
|
||||
* "fix" amounts to make it easier on the reconciliation overview:
|
||||
*
|
||||
* @param Account $account
|
||||
* @param array $array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function processTransactions(Account $account, array $array): array
|
||||
@@ -305,6 +305,7 @@ class ReconcileController extends Controller
|
||||
|
||||
$journals[] = $journal;
|
||||
}
|
||||
|
||||
return $journals;
|
||||
}
|
||||
}
|
||||
|
@@ -63,9 +63,9 @@ class RecurrenceController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return JsonResponse
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function events(Request $request): JsonResponse
|
||||
{
|
||||
@@ -73,10 +73,10 @@ class RecurrenceController extends Controller
|
||||
$start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
|
||||
$end = Carbon::createFromFormat('Y-m-d', $request->get('end'));
|
||||
$firstDate = Carbon::createFromFormat('Y-m-d', $request->get('first_date'));
|
||||
$endDate = '' !== (string) $request->get('end_date') ? Carbon::createFromFormat('Y-m-d', $request->get('end_date')) : null;
|
||||
$endsAt = (string) $request->get('ends');
|
||||
$endDate = '' !== (string)$request->get('end_date') ? Carbon::createFromFormat('Y-m-d', $request->get('end_date')) : null;
|
||||
$endsAt = (string)$request->get('ends');
|
||||
$repetitionType = explode(',', $request->get('type'))[0];
|
||||
$repetitions = (int) $request->get('reps');
|
||||
$repetitions = (int)$request->get('reps');
|
||||
$repetitionMoment = '';
|
||||
$start->startOfDay();
|
||||
|
||||
@@ -100,8 +100,8 @@ class RecurrenceController extends Controller
|
||||
$repetition = new RecurrenceRepetition;
|
||||
$repetition->repetition_type = $repetitionType;
|
||||
$repetition->repetition_moment = $repetitionMoment;
|
||||
$repetition->repetition_skip = (int) $request->get('skip');
|
||||
$repetition->weekend = (int) $request->get('weekend');
|
||||
$repetition->repetition_skip = (int)$request->get('skip');
|
||||
$repetition->weekend = (int)$request->get('weekend');
|
||||
$actualEnd = clone $end;
|
||||
|
||||
switch ($endsAt) {
|
||||
@@ -151,30 +151,30 @@ class RecurrenceController extends Controller
|
||||
$string = $request->get('date') ?? date('Y-m-d');
|
||||
$today = Carbon::now()->startOfDay();
|
||||
$date = Carbon::createFromFormat('Y-m-d', $string)->startOfDay();
|
||||
$preSelected = (string) $request->get('pre_select');
|
||||
$locale = app('steam')->getLocale();
|
||||
$preSelected = (string)$request->get('pre_select');
|
||||
$locale = app('steam')->getLocale();
|
||||
|
||||
Log::debug(sprintf('date = %s, today = %s. date > today? %s', $date->toAtomString(), $today->toAtomString(), var_export($date > $today, true)));
|
||||
Log::debug(sprintf('past = true? %s', var_export('true' === (string) $request->get('past'), true)));
|
||||
Log::debug(sprintf('past = true? %s', var_export('true' === (string)$request->get('past'), true)));
|
||||
|
||||
$result = [];
|
||||
if ($date > $today || 'true' === (string) $request->get('past')) {
|
||||
if ($date > $today || 'true' === (string)$request->get('past')) {
|
||||
Log::debug('Will fill dropdown.');
|
||||
$weekly = sprintf('weekly,%s', $date->dayOfWeekIso);
|
||||
$monthly = sprintf('monthly,%s', $date->day);
|
||||
$dayOfWeek = (string) trans(sprintf('config.dow_%s', $date->dayOfWeekIso));
|
||||
$dayOfWeek = (string)trans(sprintf('config.dow_%s', $date->dayOfWeekIso));
|
||||
$ndom = sprintf('ndom,%s,%s', $date->weekOfMonth, $date->dayOfWeekIso);
|
||||
$yearly = sprintf('yearly,%s', $date->format('Y-m-d'));
|
||||
$yearlyDate = $date->formatLocalized((string) trans('config.month_and_day_no_year', [], $locale));
|
||||
$yearlyDate = $date->formatLocalized((string)trans('config.month_and_day_no_year', [], $locale));
|
||||
$result = [
|
||||
'daily' => ['label' => (string) trans('firefly.recurring_daily'), 'selected' => 0 === strpos($preSelected, 'daily')],
|
||||
$weekly => ['label' => (string) trans('firefly.recurring_weekly', ['weekday' => $dayOfWeek]),
|
||||
'daily' => ['label' => (string)trans('firefly.recurring_daily'), 'selected' => 0 === strpos($preSelected, 'daily')],
|
||||
$weekly => ['label' => (string)trans('firefly.recurring_weekly', ['weekday' => $dayOfWeek]),
|
||||
'selected' => 0 === strpos($preSelected, 'weekly')],
|
||||
$monthly => ['label' => (string) trans('firefly.recurring_monthly', ['dayOfMonth' => $date->day]),
|
||||
$monthly => ['label' => (string)trans('firefly.recurring_monthly', ['dayOfMonth' => $date->day]),
|
||||
'selected' => 0 === strpos($preSelected, 'monthly')],
|
||||
$ndom => ['label' => (string) trans('firefly.recurring_ndom', ['weekday' => $dayOfWeek, 'dayOfMonth' => $date->weekOfMonth]),
|
||||
$ndom => ['label' => (string)trans('firefly.recurring_ndom', ['weekday' => $dayOfWeek, 'dayOfMonth' => $date->weekOfMonth]),
|
||||
'selected' => 0 === strpos($preSelected, 'ndom')],
|
||||
$yearly => ['label' => (string) trans('firefly.recurring_yearly', ['date' => $yearlyDate]),
|
||||
$yearly => ['label' => (string)trans('firefly.recurring_yearly', ['date' => $yearlyDate]),
|
||||
'selected' => 0 === strpos($preSelected, 'yearly')],
|
||||
];
|
||||
}
|
||||
|
@@ -44,11 +44,11 @@ class RuleController extends Controller
|
||||
*/
|
||||
public function action(Request $request): JsonResponse
|
||||
{
|
||||
$count = (int) $request->get('count') > 0 ? (int) $request->get('count') : 1;
|
||||
$count = (int)$request->get('count') > 0 ? (int)$request->get('count') : 1;
|
||||
$keys = array_keys(config('firefly.rule-actions'));
|
||||
$actions = [];
|
||||
foreach ($keys as $key) {
|
||||
$actions[$key] = (string) trans('firefly.rule_action_' . $key . '_choice');
|
||||
$actions[$key] = (string)trans('firefly.rule_action_' . $key . '_choice');
|
||||
}
|
||||
try {
|
||||
$view = prefixView('rules.partials.action', compact('actions', 'count'))->render();
|
||||
@@ -72,13 +72,13 @@ class RuleController extends Controller
|
||||
*/
|
||||
public function trigger(Request $request): JsonResponse
|
||||
{
|
||||
$count = (int) $request->get('count') > 0 ? (int) $request->get('count') : 1;
|
||||
$count = (int)$request->get('count') > 0 ? (int)$request->get('count') : 1;
|
||||
$operators = config('firefly.search.operators');
|
||||
$triggers = [];
|
||||
foreach ($operators as $key => $operator) {
|
||||
if ('user_action' !== $key && false === $operator['alias']) {
|
||||
|
||||
$triggers[$key] = (string) trans(sprintf('firefly.rule_trigger_%s_choice', $key));
|
||||
$triggers[$key] = (string)trans(sprintf('firefly.rule_trigger_%s_choice', $key));
|
||||
}
|
||||
}
|
||||
asort($triggers);
|
||||
|
@@ -59,7 +59,7 @@ class CreateController extends Controller
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.rules'));
|
||||
app('view')->share('title', (string)trans('firefly.rules'));
|
||||
app('view')->share('mainTitleIcon', 'fa-random');
|
||||
|
||||
$this->ruleRepos = app(RuleRepositoryInterface::class);
|
||||
@@ -88,7 +88,7 @@ class CreateController extends Controller
|
||||
$oldActions = [];
|
||||
|
||||
// build triggers from query, if present.
|
||||
$query = (string) $request->get('from_query');
|
||||
$query = (string)$request->get('from_query');
|
||||
if ('' !== $query) {
|
||||
$search = app(SearchInterface::class);
|
||||
$search->parseQuery($query);
|
||||
@@ -112,9 +112,9 @@ class CreateController extends Controller
|
||||
$subTitleIcon = 'fa-clone';
|
||||
|
||||
// title depends on whether or not there is a rule group:
|
||||
$subTitle = (string) trans('firefly.make_new_rule_no_group');
|
||||
$subTitle = (string)trans('firefly.make_new_rule_no_group');
|
||||
if (null !== $ruleGroup) {
|
||||
$subTitle = (string) trans('firefly.make_new_rule', ['title' => $ruleGroup->title]);
|
||||
$subTitle = (string)trans('firefly.make_new_rule', ['title' => $ruleGroup->title]);
|
||||
}
|
||||
|
||||
// flash old data
|
||||
@@ -142,14 +142,14 @@ class CreateController extends Controller
|
||||
*/
|
||||
public function createFromBill(Request $request, Bill $bill)
|
||||
{
|
||||
$request->session()->flash('info', (string) trans('firefly.instructions_rule_from_bill', ['name' => e($bill->name)]));
|
||||
$request->session()->flash('info', (string)trans('firefly.instructions_rule_from_bill', ['name' => e($bill->name)]));
|
||||
|
||||
$this->createDefaultRuleGroup();
|
||||
$this->createDefaultRule();
|
||||
$preFilled = [
|
||||
'strict' => true,
|
||||
'title' => (string) trans('firefly.new_rule_for_bill_title', ['name' => $bill->name]),
|
||||
'description' => (string) trans('firefly.new_rule_for_bill_description', ['name' => $bill->name]),
|
||||
'title' => (string)trans('firefly.new_rule_for_bill_title', ['name' => $bill->name]),
|
||||
'description' => (string)trans('firefly.new_rule_for_bill_description', ['name' => $bill->name]),
|
||||
];
|
||||
|
||||
// make triggers and actions from the bill itself.
|
||||
@@ -169,7 +169,7 @@ class CreateController extends Controller
|
||||
$subTitleIcon = 'fa-clone';
|
||||
|
||||
// title depends on whether or not there is a rule group:
|
||||
$subTitle = (string) trans('firefly.make_new_rule_no_group');
|
||||
$subTitle = (string)trans('firefly.make_new_rule_no_group');
|
||||
|
||||
// flash old data
|
||||
$request->session()->flash('preFilled', $preFilled);
|
||||
@@ -192,10 +192,10 @@ class CreateController extends Controller
|
||||
*/
|
||||
public function createFromJournal(Request $request, TransactionJournal $journal)
|
||||
{
|
||||
$request->session()->flash('info', (string) trans('firefly.instructions_rule_from_journal', ['name' => e($journal->name)]));
|
||||
$request->session()->flash('info', (string)trans('firefly.instructions_rule_from_journal', ['name' => e($journal->name)]));
|
||||
|
||||
$subTitleIcon = 'fa-clone';
|
||||
$subTitle = (string) trans('firefly.make_new_rule_no_group');
|
||||
$subTitle = (string)trans('firefly.make_new_rule_no_group');
|
||||
|
||||
// get triggers and actions for journal.
|
||||
$oldTriggers = $this->getTriggersForJournal($journal);
|
||||
@@ -207,8 +207,8 @@ class CreateController extends Controller
|
||||
// collect pre-filled information:
|
||||
$preFilled = [
|
||||
'strict' => true,
|
||||
'title' => (string) trans('firefly.new_rule_for_journal_title', ['description' => $journal->description]),
|
||||
'description' => (string) trans('firefly.new_rule_for_journal_description', ['description' => $journal->description]),
|
||||
'title' => (string)trans('firefly.new_rule_for_journal_title', ['description' => $journal->description]),
|
||||
'description' => (string)trans('firefly.new_rule_for_journal_description', ['description' => $journal->description]),
|
||||
];
|
||||
|
||||
// restore actions and triggers from old input:
|
||||
@@ -262,22 +262,22 @@ class CreateController extends Controller
|
||||
{
|
||||
$data = $request->getRuleData();
|
||||
$rule = $this->ruleRepos->store($data);
|
||||
session()->flash('success', (string) trans('firefly.stored_new_rule', ['title' => $rule->title]));
|
||||
session()->flash('success', (string)trans('firefly.stored_new_rule', ['title' => $rule->title]));
|
||||
app('preferences')->mark();
|
||||
|
||||
// redirect to show bill.
|
||||
if ('true' === $request->get('return_to_bill') && (int) $request->get('bill_id') > 0) {
|
||||
return redirect(route('bills.show', [(int) $request->get('bill_id')])); // @codeCoverageIgnore
|
||||
if ('true' === $request->get('return_to_bill') && (int)$request->get('bill_id') > 0) {
|
||||
return redirect(route('bills.show', [(int)$request->get('bill_id')])); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// redirect to new bill creation.
|
||||
if ((int) $request->get('bill_id') > 0) {
|
||||
if ((int)$request->get('bill_id') > 0) {
|
||||
return redirect($this->getPreviousUri('bills.create.uri')); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$redirect = redirect($this->getPreviousUri('rules.create.uri'));
|
||||
|
||||
if (1 === (int) $request->get('create_another')) {
|
||||
if (1 === (int)$request->get('create_another')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
session()->put('rules.create.fromStore', true);
|
||||
$redirect = redirect(route('rules.create', [$data['rule_group_id']]))->withInput();
|
||||
|
@@ -50,7 +50,7 @@ class DeleteController extends Controller
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.rules'));
|
||||
app('view')->share('title', (string)trans('firefly.rules'));
|
||||
app('view')->share('mainTitleIcon', 'fa-random');
|
||||
|
||||
$this->ruleRepos = app(RuleRepositoryInterface::class);
|
||||
@@ -69,7 +69,7 @@ class DeleteController extends Controller
|
||||
*/
|
||||
public function delete(Rule $rule)
|
||||
{
|
||||
$subTitle = (string) trans('firefly.delete_rule', ['title' => $rule->title]);
|
||||
$subTitle = (string)trans('firefly.delete_rule', ['title' => $rule->title]);
|
||||
|
||||
// put previous url in session
|
||||
$this->rememberPreviousUri('rules.delete.uri');
|
||||
@@ -89,7 +89,7 @@ class DeleteController extends Controller
|
||||
$title = $rule->title;
|
||||
$this->ruleRepos->destroy($rule);
|
||||
|
||||
session()->flash('success', (string) trans('firefly.deleted_rule', ['title' => $title]));
|
||||
session()->flash('success', (string)trans('firefly.deleted_rule', ['title' => $title]));
|
||||
app('preferences')->mark();
|
||||
|
||||
return redirect($this->getPreviousUri('rules.delete.uri'));
|
||||
|
@@ -37,8 +37,8 @@ use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\View\View;
|
||||
use Throwable;
|
||||
use Log;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class EditController
|
||||
@@ -60,7 +60,7 @@ class EditController extends Controller
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.rules'));
|
||||
app('view')->share('title', (string)trans('firefly.rules'));
|
||||
app('view')->share('mainTitleIcon', 'fa-random');
|
||||
|
||||
$this->ruleRepos = app(RuleRepositoryInterface::class);
|
||||
@@ -86,7 +86,7 @@ class EditController extends Controller
|
||||
$oldTriggers = [];
|
||||
|
||||
// build triggers from query, if present.
|
||||
$query = (string) $request->get('from_query');
|
||||
$query = (string)$request->get('from_query');
|
||||
if ('' !== $query) {
|
||||
$search = app(SearchInterface::class);
|
||||
$search->parseQuery($query);
|
||||
@@ -102,8 +102,8 @@ class EditController extends Controller
|
||||
|
||||
// has old input?
|
||||
if (count($request->old()) > 0) {
|
||||
$oldTriggers = $this->getPreviousTriggers($request);
|
||||
$oldActions = $this->getPreviousActions($request);
|
||||
$oldTriggers = $this->getPreviousTriggers($request);
|
||||
$oldActions = $this->getPreviousActions($request);
|
||||
}
|
||||
$triggerCount = count($oldTriggers);
|
||||
$actionCount = count($oldActions);
|
||||
@@ -118,15 +118,15 @@ class EditController extends Controller
|
||||
|
||||
$hasOldInput = null !== $request->old('_token');
|
||||
$preFilled = [
|
||||
'active' => $hasOldInput ? (bool) $request->old('active') : $rule->active,
|
||||
'stop_processing' => $hasOldInput ? (bool) $request->old('stop_processing') : $rule->stop_processing,
|
||||
'strict' => $hasOldInput ? (bool) $request->old('strict') : $rule->strict,
|
||||
'active' => $hasOldInput ? (bool)$request->old('active') : $rule->active,
|
||||
'stop_processing' => $hasOldInput ? (bool)$request->old('stop_processing') : $rule->stop_processing,
|
||||
'strict' => $hasOldInput ? (bool)$request->old('strict') : $rule->strict,
|
||||
|
||||
];
|
||||
|
||||
// get rule trigger for update / store-journal:
|
||||
$primaryTrigger = $this->ruleRepos->getPrimaryTrigger($rule);
|
||||
$subTitle = (string) trans('firefly.edit_rule', ['title' => $rule->title]);
|
||||
$subTitle = (string)trans('firefly.edit_rule', ['title' => $rule->title]);
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (true !== session('rules.edit.fromUpdate')) {
|
||||
@@ -139,35 +139,9 @@ class EditController extends Controller
|
||||
return prefixView('rules.rule.edit', compact('rule', 'subTitle', 'primaryTrigger', 'oldTriggers', 'oldActions', 'triggerCount', 'actionCount'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the rule.
|
||||
*
|
||||
* @param RuleFormRequest $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
public function update(RuleFormRequest $request, Rule $rule)
|
||||
{
|
||||
$data = $request->getRuleData();
|
||||
$this->ruleRepos->update($rule, $data);
|
||||
|
||||
session()->flash('success', (string) trans('firefly.updated_rule', ['title' => $rule->title]));
|
||||
app('preferences')->mark();
|
||||
$redirect = redirect($this->getPreviousUri('rules.edit.uri'));
|
||||
if (1 === (int) $request->get('return_to_edit')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
session()->put('rules.edit.fromUpdate', true);
|
||||
|
||||
$redirect = redirect(route('rules.edit', [$rule->id]))->withInput(['return_to_edit' => 1]);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $submittedOperators
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseFromOperators(array $submittedOperators): array
|
||||
@@ -179,7 +153,7 @@ class EditController extends Controller
|
||||
foreach ($operators as $key => $operator) {
|
||||
if ('user_action' !== $key && false === $operator['alias']) {
|
||||
|
||||
$triggers[$key] = (string) trans(sprintf('firefly.rule_trigger_%s_choice', $key));
|
||||
$triggers[$key] = (string)trans(sprintf('firefly.rule_trigger_%s_choice', $key));
|
||||
}
|
||||
}
|
||||
asort($triggers);
|
||||
@@ -206,4 +180,31 @@ class EditController extends Controller
|
||||
|
||||
return $renderedEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the rule.
|
||||
*
|
||||
* @param RuleFormRequest $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
public function update(RuleFormRequest $request, Rule $rule)
|
||||
{
|
||||
$data = $request->getRuleData();
|
||||
$this->ruleRepos->update($rule, $data);
|
||||
|
||||
session()->flash('success', (string)trans('firefly.updated_rule', ['title' => $rule->title]));
|
||||
app('preferences')->mark();
|
||||
$redirect = redirect($this->getPreviousUri('rules.edit.uri'));
|
||||
if (1 === (int)$request->get('return_to_edit')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
session()->put('rules.edit.fromUpdate', true);
|
||||
|
||||
$redirect = redirect(route('rules.edit', [$rule->id]))->withInput(['return_to_edit' => 1]);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Rule;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
@@ -55,7 +56,7 @@ class IndexController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.rules'));
|
||||
app('view')->share('title', (string)trans('firefly.rules'));
|
||||
app('view')->share('mainTitleIcon', 'fa-random');
|
||||
$this->ruleGroupRepos = app(RuleGroupRepositoryInterface::class);
|
||||
$this->ruleRepos = app(RuleRepositoryInterface::class);
|
||||
@@ -82,10 +83,26 @@ class IndexController extends Controller
|
||||
return prefixView('rules.index', compact('ruleGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Rule $rule
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function moveRule(Request $request, Rule $rule, RuleGroup $ruleGroup): JsonResponse
|
||||
{
|
||||
$order = (int)$request->get('order');
|
||||
$this->ruleRepos->moveRule($rule, $ruleGroup, (int)$order);
|
||||
|
||||
return response()->json([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function search(Rule $rule): RedirectResponse
|
||||
{
|
||||
@@ -96,19 +113,4 @@ class IndexController extends Controller
|
||||
return redirect($route);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Rule $rule
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function moveRule(Request $request, Rule $rule, RuleGroup $ruleGroup): JsonResponse
|
||||
{
|
||||
$order = (int) $request->get('order');
|
||||
$this->ruleRepos->moveRule($rule, $ruleGroup, (int) $order);
|
||||
|
||||
return response()->json([]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -62,10 +62,10 @@ class Authenticate
|
||||
* @param Closure $next
|
||||
* @param string[] ...$guards
|
||||
*
|
||||
* @throws AuthenticationException
|
||||
* @throws FireflyException
|
||||
* @return mixed
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
public function handle($request, Closure $next, ...$guards)
|
||||
{
|
||||
@@ -81,9 +81,9 @@ class Authenticate
|
||||
* @param $request
|
||||
* @param array $guards
|
||||
*
|
||||
* @throws AuthenticationException
|
||||
* @throws FireflyException
|
||||
* @return mixed
|
||||
* @throws FireflyException
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
protected function authenticate($request, array $guards)
|
||||
{
|
||||
@@ -97,10 +97,10 @@ class Authenticate
|
||||
// do an extra check on user object.
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$user = $this->auth->authenticate();
|
||||
if (1 === (int) $user->blocked) {
|
||||
$message = (string) trans('firefly.block_account_logout');
|
||||
if (1 === (int)$user->blocked) {
|
||||
$message = (string)trans('firefly.block_account_logout');
|
||||
if ('email_changed' === $user->blocked_code) {
|
||||
$message = (string) trans('firefly.email_changed_logout');
|
||||
$message = (string)trans('firefly.email_changed_logout');
|
||||
}
|
||||
app('session')->flash('logoutMessage', $message);
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
|
@@ -27,6 +27,7 @@ namespace FireflyIII\Http\Middleware;
|
||||
use Closure;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Support\System\GeneratesInstallationId;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -39,7 +40,7 @@ class InstallationId
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
@@ -51,7 +52,6 @@ class InstallationId
|
||||
{
|
||||
|
||||
|
||||
|
||||
$this->generateInstallationId();
|
||||
|
||||
return $next($request);
|
||||
|
@@ -44,12 +44,12 @@ class Installer
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @param Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
@@ -81,35 +81,11 @@ class Installer
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is access denied error.
|
||||
*
|
||||
* @param string $message
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAccessDenied(string $message): bool
|
||||
{
|
||||
return false !== stripos($message, 'Access denied');
|
||||
}
|
||||
|
||||
/**
|
||||
* Is no tables exist error.
|
||||
*
|
||||
* @param string $message
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function noTablesExist(string $message): bool
|
||||
{
|
||||
return false !== stripos($message, 'Base table or view not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the tables are created and accounted for.
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return bool
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function hasNoTables(): bool
|
||||
{
|
||||
@@ -136,6 +112,30 @@ class Installer
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is access denied error.
|
||||
*
|
||||
* @param string $message
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAccessDenied(string $message): bool
|
||||
{
|
||||
return false !== stripos($message, 'Access denied');
|
||||
}
|
||||
|
||||
/**
|
||||
* Is no tables exist error.
|
||||
*
|
||||
* @param string $message
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function noTablesExist(string $message): bool
|
||||
{
|
||||
return false !== stripos($message, 'Base table or view not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the "db_version" variable is correct.
|
||||
*
|
||||
@@ -144,8 +144,8 @@ class Installer
|
||||
private function oldDBVersion(): bool
|
||||
{
|
||||
// older version in config than database?
|
||||
$configVersion = (int) config('firefly.db_version');
|
||||
$dbVersion = (int) app('fireflyconfig')->getFresh('db_version', 1)->data;
|
||||
$configVersion = (int)config('firefly.db_version');
|
||||
$dbVersion = (int)app('fireflyconfig')->getFresh('db_version', 1)->data;
|
||||
if ($configVersion > $dbVersion) {
|
||||
Log::warning(
|
||||
sprintf(
|
||||
@@ -170,8 +170,8 @@ class Installer
|
||||
private function oldVersion(): bool
|
||||
{
|
||||
// version compare thing.
|
||||
$configVersion = (string) config('firefly.version');
|
||||
$dbVersion = (string) app('fireflyconfig')->getFresh('ff3_version', '1.0')->data;
|
||||
$configVersion = (string)config('firefly.version');
|
||||
$dbVersion = (string)app('fireflyconfig')->getFresh('ff3_version', '1.0')->data;
|
||||
if (1 === version_compare($configVersion, $dbVersion)) {
|
||||
Log::warning(
|
||||
sprintf(
|
||||
|
@@ -58,6 +58,15 @@ class InterestingMessage
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function testing(): bool
|
||||
{
|
||||
// ignore middleware in test environment.
|
||||
return 'testing' === config('app.env') || !auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
@@ -84,7 +93,7 @@ class InterestingMessage
|
||||
|
||||
// send message about newly created transaction group.
|
||||
/** @var TransactionGroup $group */
|
||||
$group = auth()->user()->transactionGroups()->with(['transactionJournals', 'transactionJournals.transactionType'])->find((int) $transactionGroupId);
|
||||
$group = auth()->user()->transactionGroups()->with(['transactionJournals', 'transactionJournals.transactionType'])->find((int)$transactionGroupId);
|
||||
|
||||
if (null === $group) {
|
||||
return;
|
||||
@@ -100,21 +109,12 @@ class InterestingMessage
|
||||
$title = $count > 1 ? $group->title : $journal->description;
|
||||
if ('created' === $message) {
|
||||
session()->flash('success_uri', route('transactions.show', [$transactionGroupId]));
|
||||
session()->flash('success', (string) trans('firefly.stored_journal', ['description' => $title]));
|
||||
session()->flash('success', (string)trans('firefly.stored_journal', ['description' => $title]));
|
||||
}
|
||||
if ('updated' === $message) {
|
||||
$type = strtolower($journal->transactionType->type);
|
||||
session()->flash('success_uri', route('transactions.show', [$transactionGroupId]));
|
||||
session()->flash('success', (string) trans(sprintf('firefly.updated_%s', $type), ['description' => $title]));
|
||||
session()->flash('success', (string)trans(sprintf('firefly.updated_%s', $type), ['description' => $title]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function testing(): bool
|
||||
{
|
||||
// ignore middleware in test environment.
|
||||
return 'testing' === config('app.env') || !auth()->check();
|
||||
}
|
||||
}
|
||||
|
@@ -53,7 +53,7 @@ class IsDemoUser
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
if ($repository->hasRole($user, 'demo')) {
|
||||
Log::info('User is a demo user.');
|
||||
$request->session()->flash('info', (string) trans('firefly.not_available_demo_user'));
|
||||
$request->session()->flash('info', (string)trans('firefly.not_available_demo_user'));
|
||||
$current = $request->url();
|
||||
$previous = $request->session()->previousUrl();
|
||||
if ($current !== $previous) {
|
||||
|
@@ -36,6 +36,7 @@ use Log;
|
||||
class Range
|
||||
{
|
||||
use RequestInformation;
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
@@ -61,51 +62,6 @@ class Range
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the list length.
|
||||
*/
|
||||
private function configureList(): void
|
||||
{
|
||||
$pref = app('preferences')->get('list-length', config('firefly.list_length', 10))->data;
|
||||
app('view')->share('listLength', $pref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the user's view.
|
||||
*/
|
||||
private function configureView(): void
|
||||
{
|
||||
// get locale preference:
|
||||
$language = app('steam')->getLanguage();
|
||||
$locale = app('steam')->getLocale();
|
||||
App::setLocale($language);
|
||||
Carbon::setLocale(substr($locale, 0, 2));
|
||||
|
||||
$localeArray = app('steam')->getLocaleArray($locale);
|
||||
|
||||
setlocale(LC_TIME, $localeArray);
|
||||
$moneyResult = setlocale(LC_MONETARY, $localeArray);
|
||||
|
||||
// send error to view if could not set money format
|
||||
if (false === $moneyResult) {
|
||||
Log::error('Could not set locale. The following array doesnt work: ', $localeArray);
|
||||
app('view')->share('invalidMonetaryLocale', true); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// save some formats:
|
||||
$monthAndDayFormat = (string) trans('config.month_and_day', [], $locale);
|
||||
$dateTimeFormat = (string) trans('config.date_time', [], $locale);
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
|
||||
// also format for moment JS:
|
||||
$madMomentJS = (string) trans('config.month_and_day_moment_js', [], $locale);
|
||||
|
||||
app('view')->share('madMomentJS', $madMomentJS);
|
||||
app('view')->share('monthAndDayFormat', $monthAndDayFormat);
|
||||
app('view')->share('dateTimeFormat', $dateTimeFormat);
|
||||
app('view')->share('defaultCurrency', $defaultCurrency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the range for the current view.
|
||||
*/
|
||||
@@ -133,4 +89,49 @@ class Range
|
||||
app('session')->put('first', $first);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the user's view.
|
||||
*/
|
||||
private function configureView(): void
|
||||
{
|
||||
// get locale preference:
|
||||
$language = app('steam')->getLanguage();
|
||||
$locale = app('steam')->getLocale();
|
||||
App::setLocale($language);
|
||||
Carbon::setLocale(substr($locale, 0, 2));
|
||||
|
||||
$localeArray = app('steam')->getLocaleArray($locale);
|
||||
|
||||
setlocale(LC_TIME, $localeArray);
|
||||
$moneyResult = setlocale(LC_MONETARY, $localeArray);
|
||||
|
||||
// send error to view if could not set money format
|
||||
if (false === $moneyResult) {
|
||||
Log::error('Could not set locale. The following array doesnt work: ', $localeArray);
|
||||
app('view')->share('invalidMonetaryLocale', true); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// save some formats:
|
||||
$monthAndDayFormat = (string)trans('config.month_and_day', [], $locale);
|
||||
$dateTimeFormat = (string)trans('config.date_time', [], $locale);
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
|
||||
// also format for moment JS:
|
||||
$madMomentJS = (string)trans('config.month_and_day_moment_js', [], $locale);
|
||||
|
||||
app('view')->share('madMomentJS', $madMomentJS);
|
||||
app('view')->share('monthAndDayFormat', $monthAndDayFormat);
|
||||
app('view')->share('dateTimeFormat', $dateTimeFormat);
|
||||
app('view')->share('defaultCurrency', $defaultCurrency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the list length.
|
||||
*/
|
||||
private function configureList(): void
|
||||
{
|
||||
$pref = app('preferences')->get('list-length', config('firefly.list_length', 10))->data;
|
||||
app('view')->share('listLength', $pref);
|
||||
}
|
||||
}
|
||||
|
@@ -39,8 +39,8 @@ class SecureHeaders
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
*
|
||||
* @throws Exception
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
@@ -48,9 +48,9 @@ class SecureHeaders
|
||||
$nonce = base64_encode(random_bytes(16));
|
||||
app('view')->share('JS_NONCE', $nonce);
|
||||
|
||||
$response = $next($request);
|
||||
$response = $next($request);
|
||||
$trackingScriptSrc = $this->getTrackingScriptSource();
|
||||
$csp = [
|
||||
$csp = [
|
||||
"default-src 'none'",
|
||||
"object-src 'self'",
|
||||
sprintf("script-src 'unsafe-inline' 'nonce-%1s' %2s", $nonce, $trackingScriptSrc),
|
||||
@@ -58,7 +58,10 @@ class SecureHeaders
|
||||
"base-uri 'self'",
|
||||
"font-src 'self' data:",
|
||||
"connect-src 'self'",
|
||||
sprintf("img-src 'self' data: https://a.tile.openstreetmap.org https://b.tile.openstreetmap.org https://c.tile.openstreetmap.org https://api.tiles.mapbox.com %s", $trackingScriptSrc),
|
||||
sprintf(
|
||||
"img-src 'self' data: https://a.tile.openstreetmap.org https://b.tile.openstreetmap.org https://c.tile.openstreetmap.org https://api.tiles.mapbox.com %s",
|
||||
$trackingScriptSrc
|
||||
),
|
||||
"manifest-src 'self'",
|
||||
];
|
||||
|
||||
@@ -106,8 +109,8 @@ class SecureHeaders
|
||||
*/
|
||||
private function getTrackingScriptSource(): string
|
||||
{
|
||||
if ('' !== (string) config('firefly.tracker_site_id') && '' !== (string) config('firefly.tracker_url')) {
|
||||
return (string) config('firefly.tracker_url');
|
||||
if ('' !== (string)config('firefly.tracker_site_id') && '' !== (string)config('firefly.tracker_url')) {
|
||||
return (string)config('firefly.tracker_url');
|
||||
}
|
||||
|
||||
return '';
|
||||
|
@@ -25,7 +25,6 @@ namespace FireflyIII\Http\Middleware;
|
||||
use Illuminate\Contracts\Session\Session;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Session\Middleware\StartSession;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class StartFireflySession.
|
||||
|
@@ -43,7 +43,7 @@ class TrustProxies extends Middleware
|
||||
*/
|
||||
public function __construct(Repository $config)
|
||||
{
|
||||
$trustedProxies = (string) config('firefly.trusted_proxies');
|
||||
$trustedProxies = (string)config('firefly.trusted_proxies');
|
||||
$this->proxies = explode(',', $trustedProxies);
|
||||
if ('**' === $trustedProxies) {
|
||||
$this->proxies = '**';
|
||||
|
@@ -41,12 +41,12 @@ class PiggyBankStoreRequest extends FormRequest
|
||||
public function getPiggyBankData(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->string('name'),
|
||||
'startdate' => $this->date('startdate'),
|
||||
'account_id' => $this->integer('account_id'),
|
||||
'targetamount' => $this->string('targetamount'),
|
||||
'targetdate' => $this->date('targetdate'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
'name' => $this->string('name'),
|
||||
'startdate' => $this->date('startdate'),
|
||||
'account_id' => $this->integer('account_id'),
|
||||
'targetamount' => $this->string('targetamount'),
|
||||
'targetdate' => $this->date('targetdate'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
'object_group_title' => $this->string('object_group'),
|
||||
];
|
||||
}
|
||||
|
@@ -127,11 +127,11 @@ class RecurrenceFormRequest extends FormRequest
|
||||
// replace category name with a new category:
|
||||
$factory = app(CategoryFactory::class);
|
||||
$factory->setUser(auth()->user());
|
||||
foreach($return['transactions'] as $index => $transaction) {
|
||||
$categoryName =$transaction['category_name'] ??null;
|
||||
if(null !== $categoryName) {
|
||||
foreach ($return['transactions'] as $index => $transaction) {
|
||||
$categoryName = $transaction['category_name'] ?? null;
|
||||
if (null !== $categoryName) {
|
||||
$category = $factory->findOrCreate(null, $categoryName);
|
||||
if(null !== $category) {
|
||||
if (null !== $category) {
|
||||
$return['transactions'][$index]['category_id'] = $category->id;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user