mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Code cleanup.
This commit is contained in:
parent
cfc2181a48
commit
44fb307da4
@ -44,7 +44,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
||||
* Generate the report.
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function generate(): string
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
||||
* Generates the report.
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function generate(): string
|
||||
{
|
||||
|
@ -64,7 +64,7 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
|
||||
* Generates the report.
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function generate(): string
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
|
||||
* Generates the report.
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function generate(): string
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
||||
* Generates the report.
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function generate(): string
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
|
||||
* Generates the report.
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function generate(): string
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ class YearReportGenerator implements ReportGeneratorInterface
|
||||
* Generates the report.
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function generate(): string
|
||||
{
|
||||
|
@ -70,8 +70,8 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
|
||||
* Generate the report.
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
* @throws \Throwable
|
||||
|
||||
|
||||
*/
|
||||
public function generate(): string
|
||||
{
|
||||
|
@ -32,7 +32,6 @@ use Log;
|
||||
/**
|
||||
* Trait UpdateTrait
|
||||
*
|
||||
* @package FireflyIII\Helpers\Update
|
||||
*/
|
||||
trait UpdateTrait
|
||||
{
|
||||
|
@ -177,6 +177,8 @@ class DebugController extends Controller
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function routes(): string
|
||||
{
|
||||
|
@ -130,6 +130,8 @@ class ExportController extends Controller
|
||||
* @param ExportJobRepositoryInterface $jobs
|
||||
*
|
||||
* @return JsonResponse
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function postIndex(ExportFormRequest $request, AccountRepositoryInterface $repository, ExportJobRepositoryInterface $jobs): JsonResponse
|
||||
{
|
||||
|
@ -68,6 +68,8 @@ class HelpController extends Controller
|
||||
* @param string $language
|
||||
*
|
||||
* @return string
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function getHelpText(string $route, string $language): string
|
||||
{
|
||||
|
@ -26,8 +26,6 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Events\RequestedVersionCheckStatus;
|
||||
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
|
||||
use FireflyIII\Http\Middleware\Installer;
|
||||
use FireflyIII\Http\Middleware\IsDemoUser;
|
||||
use FireflyIII\Http\Middleware\IsSandStormUser;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
@ -36,7 +34,6 @@ use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class HomeController.
|
||||
@ -52,9 +49,6 @@ class HomeController extends Controller
|
||||
app('view')->share('title', 'Firefly III');
|
||||
app('view')->share('mainTitleIcon', 'fa-fire');
|
||||
$this->middleware(Installer::class);
|
||||
$this->middleware(IsDemoUser::class)->except(['dateRange', 'index']);
|
||||
$this->middleware(IsSandStormUser::class)->only('routes');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +92,7 @@ class HomeController extends Controller
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
|
||||
*/
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
{
|
||||
@ -110,10 +104,7 @@ class HomeController extends Controller
|
||||
}
|
||||
$subTitle = (string)trans('firefly.welcomeBack');
|
||||
$transactions = [];
|
||||
$frontPage = app('preferences')->get(
|
||||
'frontPageAccounts',
|
||||
$repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET])->pluck('id')->toArray()
|
||||
);
|
||||
$frontPage = app('preferences')->get('frontPageAccounts', $repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray());
|
||||
/** @var Carbon $start */
|
||||
$start = session('start', Carbon::now()->startOfMonth());
|
||||
/** @var Carbon $end */
|
||||
@ -122,7 +113,6 @@ class HomeController extends Controller
|
||||
$accounts = $repository->getAccountsById($frontPage->data);
|
||||
$today = new Carbon;
|
||||
|
||||
// zero bills? Hide some elements from view.
|
||||
/** @var BillRepositoryInterface $billRepository */
|
||||
$billRepository = app(BillRepositoryInterface::class);
|
||||
$billCount = $billRepository->getBills()->count();
|
||||
@ -134,15 +124,11 @@ class HomeController extends Controller
|
||||
$transactions[] = [$set, $account];
|
||||
}
|
||||
|
||||
// fire check update event:
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
event(new RequestedVersionCheckStatus($user));
|
||||
|
||||
return view(
|
||||
'index',
|
||||
compact('count', 'subTitle', 'transactions', 'billCount', 'start', 'end', 'today')
|
||||
);
|
||||
return view('index', compact('count', 'subTitle', 'transactions', 'billCount', 'start', 'end', 'today'));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,13 +22,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Import;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use FireflyIII\Support\Binder\ImportProvider;
|
||||
use Illuminate\Http\Response as LaravelResponse;
|
||||
use Log;
|
||||
|
||||
@ -37,9 +36,10 @@ use Log;
|
||||
*/
|
||||
class IndexController extends Controller
|
||||
{
|
||||
/** @var array */
|
||||
public $providers;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
public $repository;
|
||||
|
||||
/** @var UserRepositoryInterface */
|
||||
public $userRepository;
|
||||
|
||||
@ -56,6 +56,7 @@ class IndexController extends Controller
|
||||
app('view')->share('title', (string)trans('firefly.import_index_title'));
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->userRepository = app(UserRepositoryInterface::class);
|
||||
$this->providers = ImportProvider::getProviders();
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@ -69,57 +70,44 @@ class IndexController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function create(string $importProvider)
|
||||
{
|
||||
Log::debug(sprintf('Will create job for provider "%s"', $importProvider));
|
||||
// can only create "fake" for demo user.
|
||||
$providers = array_keys($this->getProviders());
|
||||
if (!\in_array($importProvider, $providers, true)) {
|
||||
Log::error(sprintf('%s-provider is disabled. Cannot create job.', $importProvider));
|
||||
session()->flash('warning', (string)trans('import.cannot_create_for_provider', ['provider' => $importProvider]));
|
||||
|
||||
return redirect(route('import.index'));
|
||||
}
|
||||
|
||||
$importJob = $this->repository->create($importProvider);
|
||||
Log::debug(sprintf('Created job #%d for provider %s', $importJob->id, $importProvider));
|
||||
|
||||
$hasPreReq = (bool)config(sprintf('import.has_prereq.%s', $importProvider));
|
||||
$hasConfig = (bool)config(sprintf('import.has_job_config.%s', $importProvider));
|
||||
// if job provider has no prerequisites:
|
||||
if (false === $hasPreReq) {
|
||||
|
||||
Log::debug(sprintf('Created job #%d for provider %s', $importJob->id, $importProvider));
|
||||
|
||||
// no prerequisites and no config:
|
||||
if (false === $hasPreReq && false === $hasConfig) {
|
||||
Log::debug('Provider needs no configuration for job. Job is ready to start.');
|
||||
$this->repository->updateStatus($importJob, 'ready_to_run');
|
||||
Log::debug('Redirect to status-page.');
|
||||
|
||||
return redirect(route('import.job.status.index', [$importJob->key]));
|
||||
}
|
||||
|
||||
// no prerequisites but job has config:
|
||||
if (false === $hasPreReq && false !== $hasConfig) {
|
||||
Log::debug('Provider has no prerequisites. Continue.');
|
||||
// if job provider also has no configuration:
|
||||
if (false === $hasConfig) {
|
||||
// @codeCoverageIgnoreStart
|
||||
Log::debug('Provider needs no configuration for job. Job is ready to start.');
|
||||
$this->repository->updateStatus($importJob, 'ready_to_run');
|
||||
Log::debug('Redirect to status-page.');
|
||||
|
||||
return redirect(route('import.job.status.index', [$importJob->key]));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
// update job to say "has_prereq".
|
||||
$this->repository->setStatus($importJob, 'has_prereq');
|
||||
|
||||
// redirect to job configuration.
|
||||
Log::debug('Redirect to configuration.');
|
||||
|
||||
return redirect(route('import.job.configuration.index', [$importJob->key]));
|
||||
}
|
||||
|
||||
// job has prerequisites:
|
||||
Log::debug('Job provider has prerequisites.');
|
||||
// if need to set prerequisites, do that first.
|
||||
$class = (string)config(sprintf('import.prerequisites.%s', $importProvider));
|
||||
if (!class_exists($class)) {
|
||||
throw new FireflyException(sprintf('No class to handle prerequisites for "%s".', $importProvider)); // @codeCoverageIgnore
|
||||
}
|
||||
/** @var PrerequisitesInterface $providerPre */
|
||||
$providerPre = app($class);
|
||||
$providerPre = app((string)config(sprintf('import.prerequisites.%s', $importProvider)));
|
||||
$providerPre->setUser($importJob->user);
|
||||
|
||||
// and are not filled in:
|
||||
if (!$providerPre->isComplete()) {
|
||||
Log::debug('Job provider prerequisites are not yet filled in. Redirect to prerequisites-page.');
|
||||
|
||||
@ -128,8 +116,10 @@ class IndexController extends Controller
|
||||
}
|
||||
Log::debug('Prerequisites are complete.');
|
||||
|
||||
// update job to say "has_prereq".
|
||||
// but are filled in:
|
||||
$this->repository->setStatus($importJob, 'has_prereq');
|
||||
|
||||
// and has no config:
|
||||
if (false === $hasConfig) {
|
||||
// @codeCoverageIgnoreStart
|
||||
Log::debug('Provider has no configuration. Job is ready to start.');
|
||||
@ -139,6 +129,8 @@ class IndexController extends Controller
|
||||
return redirect(route('import.job.status.index', [$importJob->key]));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
// but also needs config:
|
||||
Log::debug('Job has configuration. Redirect to job-config.');
|
||||
|
||||
// Otherwise just redirect to job configuration.
|
||||
@ -184,62 +176,10 @@ class IndexController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$providers = $this->getProviders();
|
||||
$providers = $this->providers;
|
||||
$subTitle = (string)trans('import.index_breadcrumb');
|
||||
$subTitleIcon = 'fa-home';
|
||||
|
||||
return view('import.index', compact('subTitle', 'subTitleIcon', 'providers'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getProviders(): array
|
||||
{
|
||||
// get and filter all import routines:
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
/** @var array $config */
|
||||
$providerNames = array_keys(config('import.enabled'));
|
||||
$providers = [];
|
||||
$isDemoUser = $this->userRepository->hasRole($user, 'demo');
|
||||
$isDebug = (bool)config('app.debug');
|
||||
foreach ($providerNames as $providerName) {
|
||||
//Log::debug(sprintf('Now with provider %s', $providerName));
|
||||
// only consider enabled providers
|
||||
$enabled = (bool)config(sprintf('import.enabled.%s', $providerName));
|
||||
$allowedForDemo = (bool)config(sprintf('import.allowed_for_demo.%s', $providerName));
|
||||
$allowedForUser = (bool)config(sprintf('import.allowed_for_user.%s', $providerName));
|
||||
if (false === $enabled) {
|
||||
//Log::debug('Provider is not enabled. NEXT!');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (true === $isDemoUser && false === $allowedForDemo) {
|
||||
//Log::debug('User is demo and this provider is not allowed for demo user. NEXT!');
|
||||
continue;
|
||||
}
|
||||
if (false === $isDemoUser && false === $allowedForUser && false === $isDebug) {
|
||||
//Log::debug('User is not demo and this provider is not allowed for such users. NEXT!');
|
||||
continue; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$providers[$providerName] = [
|
||||
'has_prereq' => (bool)config('import.has_prereq.' . $providerName),
|
||||
];
|
||||
$class = (string)config(sprintf('import.prerequisites.%s', $providerName));
|
||||
$result = false;
|
||||
if ('' !== $class && class_exists($class)) {
|
||||
//Log::debug('Will not check prerequisites.');
|
||||
/** @var PrerequisitesInterface $object */
|
||||
$object = app($class);
|
||||
$object->setUser($user);
|
||||
$result = $object->isComplete();
|
||||
}
|
||||
$providers[$providerName]['prereq_complete'] = $result;
|
||||
}
|
||||
Log::debug(sprintf('Enabled providers: %s', json_encode(array_keys($providers))));
|
||||
|
||||
return $providers;
|
||||
}
|
||||
}
|
||||
|
@ -66,11 +66,13 @@ class JobConfigurationController extends Controller
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*
|
||||
*/
|
||||
public function index(ImportJob $importJob)
|
||||
{
|
||||
Log::debug('Now in JobConfigurationController::index()');
|
||||
// catch impossible status:
|
||||
$allowed = ['has_prereq', 'need_job_config'];
|
||||
if (null !== $importJob && !\in_array($importJob->status, $allowed, true)) {
|
||||
Log::debug(sprintf('Job has state "%s", but we only accept %s', $importJob->status, json_encode($allowed)));
|
||||
@ -91,10 +93,7 @@ class JobConfigurationController extends Controller
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
// create configuration class:
|
||||
$configurator = $this->makeConfigurator($importJob);
|
||||
|
||||
// is the job already configured?
|
||||
if ($configurator->configurationComplete()) {
|
||||
Log::debug('Config is complete, set status to ready_to_run.');
|
||||
$this->repository->updateStatus($importJob, 'ready_to_run');
|
||||
@ -119,6 +118,8 @@ class JobConfigurationController extends Controller
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function post(Request $request, ImportJob $importJob)
|
||||
{
|
||||
|
@ -22,7 +22,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Import;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
@ -68,7 +67,8 @@ class PrerequisitesController extends Controller
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function index(string $importProvider, ImportJob $importJob = null)
|
||||
{
|
||||
@ -83,9 +83,6 @@ class PrerequisitesController extends Controller
|
||||
|
||||
app('view')->share('subTitle', (string)trans('import.prerequisites_breadcrumb_' . $importProvider));
|
||||
$class = (string)config(sprintf('import.prerequisites.%s', $importProvider));
|
||||
if (!class_exists($class)) {
|
||||
throw new FireflyException(sprintf('No class to handle prerequisites for "%s".', $importProvider)); // @codeCoverageIgnore
|
||||
}
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
/** @var PrerequisitesInterface $object */
|
||||
@ -121,8 +118,8 @@ class PrerequisitesController extends Controller
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function post(Request $request, string $importProvider, ImportJob $importJob = null)
|
||||
{
|
||||
@ -139,9 +136,6 @@ class PrerequisitesController extends Controller
|
||||
|
||||
|
||||
$class = (string)config(sprintf('import.prerequisites.%s', $importProvider));
|
||||
if (!class_exists($class)) {
|
||||
throw new FireflyException(sprintf('Cannot find class %s', $class)); // @codeCoverageIgnore
|
||||
}
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
/** @var PrerequisitesInterface $object */
|
||||
|
@ -136,6 +136,7 @@ class JavascriptController extends Controller
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
private function getDateRangeConfig(): array
|
||||
{
|
||||
|
@ -39,6 +39,9 @@ use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class AutoCompleteController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class AutoCompleteController extends Controller
|
||||
{
|
||||
|
@ -22,13 +22,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Json;
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
@ -47,6 +47,8 @@ class BoxController extends Controller
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function available(BudgetRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
@ -99,6 +101,8 @@ class BoxController extends Controller
|
||||
* @param CurrencyRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function balance(CurrencyRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
@ -150,17 +154,18 @@ class BoxController extends Controller
|
||||
}
|
||||
|
||||
// format amounts:
|
||||
foreach ($sums as $currencyId => $amount) {
|
||||
$keys = array_keys($sums);
|
||||
foreach ($keys as $currencyId) {
|
||||
$currency = $repository->findNull($currencyId);
|
||||
$sums[$currencyId] = Amount::formatAnything($currency, $sums[$currencyId], false);
|
||||
$incomes[$currencyId] = Amount::formatAnything($currency, $incomes[$currencyId] ?? '0', false);
|
||||
$expenses[$currencyId] = Amount::formatAnything($currency, $expenses[$currencyId] ?? '0', false);
|
||||
$sums[$currencyId] = app('amount')->formatAnything($currency, $sums[$currencyId], false);
|
||||
$incomes[$currencyId] = app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false);
|
||||
$expenses[$currencyId] = app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false);
|
||||
}
|
||||
if (0 === \count($sums)) {
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
$sums[$currency->id] = Amount::formatAnything($currency, '0', false);
|
||||
$incomes[$currency->id] = Amount::formatAnything($currency, '0', false);
|
||||
$expenses[$currency->id] = Amount::formatAnything($currency, '0', false);
|
||||
$sums[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
||||
$incomes[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
||||
$expenses[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
||||
}
|
||||
|
||||
$response = [
|
||||
@ -214,28 +219,23 @@ class BoxController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @param CurrencyRepositoryInterface $currencyRepos
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function netWorth(AccountRepositoryInterface $repository, CurrencyRepositoryInterface $currencyRepos): JsonResponse
|
||||
public function netWorth(AccountRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$date = new Carbon(date('Y-m-d')); // needed so its per day.
|
||||
/** @var Carbon $start */
|
||||
$start = session('start', Carbon::now()->startOfMonth());
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
|
||||
// start and end in the future? use $end
|
||||
if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) {
|
||||
$date = $end;
|
||||
}
|
||||
// start and end in the past? use $end
|
||||
if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) {
|
||||
$date = $end;
|
||||
if ($this->notInSessionRange($date)) {
|
||||
/** @var Carbon $date */
|
||||
$date = session('end', Carbon::now()->endOfMonth());
|
||||
}
|
||||
|
||||
// start in the past, end in the future? use $date
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($date);
|
||||
@ -245,20 +245,13 @@ class BoxController extends Controller
|
||||
}
|
||||
$netWorth = [];
|
||||
$accounts = $repository->getActiveAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
|
||||
$balances = app('steam')->balancesByAccounts($accounts, $date);
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$accountCurrency = null;
|
||||
$accountCurrency = $this->getCurrencyOrDefault($account);
|
||||
$balance = $balances[$account->id] ?? '0';
|
||||
$currencyId = (int)$repository->getMetaValue($account, 'currency_id');
|
||||
if (0 !== $currencyId) {
|
||||
$accountCurrency = $currencyRepos->findNull($currencyId);
|
||||
}
|
||||
if (null === $accountCurrency) {
|
||||
$accountCurrency = $currency;
|
||||
}
|
||||
|
||||
// if the account is a credit card, subtract the virtual balance from the balance,
|
||||
// to better reflect that this is not money that is actually "yours".
|
||||
@ -287,4 +280,53 @@ class BoxController extends Controller
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
private function getCurrencyOrDefault(Account $account): TransactionCurrency
|
||||
{
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
/** @var CurrencyRepositoryInterface $currencyRepos */
|
||||
$currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
$accountCurrency = null;
|
||||
$currencyId = (int)$repository->getMetaValue($account, 'currency_id');
|
||||
if (0 !== $currencyId) {
|
||||
$accountCurrency = $currencyRepos->findNull($currencyId);
|
||||
}
|
||||
if (null === $accountCurrency) {
|
||||
$accountCurrency = $currency;
|
||||
}
|
||||
|
||||
return $accountCurrency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return bool
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function notInSessionRange(Carbon $date): bool
|
||||
{
|
||||
/** @var Carbon $start */
|
||||
$start = session('start', Carbon::now()->startOfMonth());
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
$result = false;
|
||||
if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) {
|
||||
$result = true;
|
||||
}
|
||||
// start and end in the past? use $end
|
||||
if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) {
|
||||
$result = true;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class FrontpageController extends Controller
|
||||
* @param PiggyBankRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function piggyBanks(PiggyBankRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
|
@ -158,6 +158,7 @@ class IntroController
|
||||
* @param string $specificPage
|
||||
*
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function getSpecificSteps(string $route, string $specificPage): array
|
||||
{
|
||||
|
@ -42,6 +42,8 @@ use Illuminate\Support\Collection;
|
||||
/**
|
||||
*
|
||||
* Class ReconcileController
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class ReconcileController extends Controller
|
||||
{
|
||||
@ -84,7 +86,10 @@ class ReconcileController extends Controller
|
||||
* @return JsonResponse
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws \Throwable
|
||||
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function overview(Request $request, Account $account, Carbon $start, Carbon $end): JsonResponse
|
||||
{
|
||||
@ -140,7 +145,7 @@ class ReconcileController extends Controller
|
||||
* @return mixed
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function transactions(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
|
175
app/Http/Controllers/Json/RecurrenceController.php
Normal file
175
app/Http/Controllers/Json/RecurrenceController.php
Normal file
@ -0,0 +1,175 @@
|
||||
<?php
|
||||
/**
|
||||
* RecurrenceController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Json;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\RecurrenceRepetition;
|
||||
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class RecurrenceController
|
||||
*/
|
||||
class RecurrenceController extends Controller
|
||||
{
|
||||
/** @var RecurringRepositoryInterface */
|
||||
private $recurring;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// translations:
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->recurring = app(RecurringRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return JsonResponse
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.NPathComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function events(Request $request): JsonResponse
|
||||
{
|
||||
$return = [];
|
||||
$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');
|
||||
$repetitionType = explode(',', $request->get('type'))[0];
|
||||
$repetitions = (int)$request->get('reps');
|
||||
$repetitionMoment = '';
|
||||
$start->startOfDay();
|
||||
|
||||
// if $firstDate is beyond $end, simply return an empty array.
|
||||
if ($firstDate->gt($end)) {
|
||||
return response()->json([]);
|
||||
}
|
||||
// if $firstDate is beyond start, use that one:
|
||||
$actualStart = clone $firstDate;
|
||||
|
||||
if ($repetitionType === 'weekly' || $repetitionType === 'monthly') {
|
||||
$repetitionMoment = explode(',', $request->get('type'))[1] ?? '1';
|
||||
}
|
||||
if ($repetitionType === 'ndom') {
|
||||
$repetitionMoment = str_ireplace('ndom,', '', $request->get('type'));
|
||||
}
|
||||
if ($repetitionType === 'yearly') {
|
||||
$repetitionMoment = explode(',', $request->get('type'))[1] ?? '2018-01-01';
|
||||
}
|
||||
$repetition = new RecurrenceRepetition;
|
||||
$repetition->repetition_type = $repetitionType;
|
||||
$repetition->repetition_moment = $repetitionMoment;
|
||||
$repetition->repetition_skip = (int)$request->get('skip');
|
||||
$repetition->weekend = (int)$request->get('weekend');
|
||||
$actualEnd = clone $end;
|
||||
|
||||
switch ($endsAt) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Cannot generate events for type that ends at "%s".', $endsAt));
|
||||
case 'forever':
|
||||
// simply generate up until $end. No change from default behavior.
|
||||
$occurrences = $this->recurring->getOccurrencesInRange($repetition, $actualStart, $actualEnd);
|
||||
break;
|
||||
case 'until_date':
|
||||
$actualEnd = $endDate ?? clone $end;
|
||||
$occurrences = $this->recurring->getOccurrencesInRange($repetition, $actualStart, $actualEnd);
|
||||
break;
|
||||
case 'times':
|
||||
$occurrences = $this->recurring->getXOccurrences($repetition, $actualStart, $repetitions);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/** @var Carbon $current */
|
||||
foreach ($occurrences as $current) {
|
||||
if ($current->gte($start)) {
|
||||
$event = [
|
||||
'id' => $repetitionType . $firstDate->format('Ymd'),
|
||||
'title' => 'X',
|
||||
'allDay' => true,
|
||||
'start' => $current->format('Y-m-d'),
|
||||
'end' => $current->format('Y-m-d'),
|
||||
'editable' => false,
|
||||
'rendering' => 'background',
|
||||
];
|
||||
$return[] = $event;
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function suggest(Request $request): JsonResponse
|
||||
{
|
||||
$today = new Carbon;
|
||||
$date = Carbon::createFromFormat('Y-m-d', $request->get('date'));
|
||||
$preSelected = (string)$request->get('pre_select');
|
||||
$result = [];
|
||||
if ($date > $today || 'true' === (string)$request->get('past')) {
|
||||
$weekly = sprintf('weekly,%s', $date->dayOfWeekIso);
|
||||
$monthly = sprintf('monthly,%s', $date->day);
|
||||
$dayOfWeek = 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(trans('config.month_and_day_no_year'));
|
||||
$result = [
|
||||
'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]),
|
||||
'selected' => 0 === strpos($preSelected, 'monthly')],
|
||||
$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]), 'selected' => 0 === strpos($preSelected, 'yearly')],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
return response()->json($result);
|
||||
}
|
||||
|
||||
}
|
@ -34,7 +34,7 @@ class JsonController extends Controller
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function action(Request $request): JsonResponse
|
||||
{
|
||||
@ -53,7 +53,7 @@ class JsonController extends Controller
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function trigger(Request $request): JsonResponse
|
||||
{
|
||||
|
@ -97,31 +97,17 @@ class NewUserController extends Controller
|
||||
$currency = $currencyRepository->findByCodeNull('EUR');
|
||||
}
|
||||
|
||||
// create normal asset account:
|
||||
$this->createAssetAccount($request, $currency);
|
||||
|
||||
// create savings account
|
||||
$this->createSavingsAccount($request, $currency, $language);
|
||||
|
||||
// create cash wallet account
|
||||
$this->createCashWalletAccount($currency, $language);
|
||||
$this->createAssetAccount($request, $currency); // create normal asset account
|
||||
$this->createSavingsAccount($request, $currency, $language); // create savings account
|
||||
$this->createCashWalletAccount($currency, $language); // create cash wallet account
|
||||
|
||||
// store currency preference:
|
||||
app('preferences')->set('currencyPreference', $currency->code);
|
||||
app('preferences')->mark();
|
||||
|
||||
// set default optional fields:
|
||||
$visibleFields = [
|
||||
'interest_date' => true,
|
||||
'book_date' => false,
|
||||
'process_date' => false,
|
||||
'due_date' => false,
|
||||
'payment_date' => false,
|
||||
'invoice_date' => false,
|
||||
'internal_reference' => false,
|
||||
'notes' => true,
|
||||
'attachments' => true,
|
||||
];
|
||||
$visibleFields = ['interest_date' => true, 'book_date' => false, 'process_date' => false, 'due_date' => false, 'payment_date' => false,
|
||||
'invoice_date' => false, 'internal_reference' => false, 'notes' => true, 'attachments' => true,];
|
||||
app('preferences')->set('transaction_journal_optional_fields', $visibleFields);
|
||||
|
||||
session()->flash('success', (string)trans('firefly.stored_new_accounts_new_user'));
|
||||
|
@ -40,6 +40,9 @@ use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
|
||||
/**
|
||||
* Class PiggyBankController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class PiggyBankController extends Controller
|
||||
{
|
||||
@ -174,6 +177,8 @@ class PiggyBankController extends Controller
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function edit(PiggyBank $piggyBank)
|
||||
{
|
||||
@ -212,6 +217,8 @@ class PiggyBankController extends Controller
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
|
@ -23,7 +23,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Http\Controllers\Popup;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collection\BalanceLine;
|
||||
use FireflyIII\Helpers\Report\PopupReportInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
@ -35,9 +34,13 @@ use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Route;
|
||||
use InvalidArgumentException;
|
||||
use Log;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class ReportController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class ReportController extends Controller
|
||||
{
|
||||
@ -79,9 +82,7 @@ class ReportController extends Controller
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws \Throwable
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function general(Request $request): JsonResponse
|
||||
{
|
||||
@ -93,7 +94,8 @@ class ReportController extends Controller
|
||||
|
||||
switch ($attributes['location']) {
|
||||
default:
|
||||
throw new FireflyException('Firefly cannot handle "' . e($attributes['location']) . '" ');
|
||||
$html = sprintf('Firefly III cannot handle "%s"-popups.', $attributes['location']);
|
||||
break;
|
||||
case 'budget-spent-amount':
|
||||
$html = $this->budgetSpentAmount($attributes);
|
||||
break;
|
||||
@ -119,8 +121,7 @@ class ReportController extends Controller
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws \Throwable
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function balanceAmount(array $attributes): string
|
||||
{
|
||||
@ -141,51 +142,60 @@ class ReportController extends Controller
|
||||
break;
|
||||
case BalanceLine::ROLE_TAGROLE === $role:
|
||||
// row with tag info.
|
||||
throw new FireflyException('Firefly cannot handle this type of info-button (BalanceLine::TagRole)');
|
||||
return 'Firefly cannot handle this type of info-button (BalanceLine::TagRole)';
|
||||
}
|
||||
try {
|
||||
$view = view('popup.report.balance-amount', compact('journals', 'budget', 'account'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render: %s', $e->getMessage()));
|
||||
$view = 'Firefly III could not render the view. Please see the log files.';
|
||||
}
|
||||
$view = view('popup.report.balance-amount', compact('journals', 'budget', 'account'))->render();
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all expenses inside the given budget for the given accounts.
|
||||
*
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
private function budgetSpentAmount(array $attributes): string
|
||||
{
|
||||
$budget = $this->budgetRepository->findNull((int)$attributes['budgetId']);
|
||||
if (null === $budget) {
|
||||
throw new FireflyException('This is an unknown budget. Apologies.');
|
||||
return 'This is an unknown budget. Apologies.';
|
||||
}
|
||||
$journals = $this->popupHelper->byBudget($budget, $attributes);
|
||||
$view = view('popup.report.budget-spent-amount', compact('journals', 'budget'))->render();
|
||||
try {
|
||||
$view = view('popup.report.budget-spent-amount', compact('journals', 'budget'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render: %s', $e->getMessage()));
|
||||
$view = 'Firefly III could not render the view. Please see the log files.';
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all expenses in category in range.
|
||||
*
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
private function categoryEntry(array $attributes): string
|
||||
{
|
||||
$category = $this->categoryRepository->findNull((int)$attributes['categoryId']);
|
||||
|
||||
if (null === $category) {
|
||||
throw new FireflyException('This is an unknown category. Apologies.');
|
||||
return 'This is an unknown category. Apologies.';
|
||||
}
|
||||
|
||||
$journals = $this->popupHelper->byCategory($category, $attributes);
|
||||
$view = view('popup.report.category-entry', compact('journals', 'category'))->render();
|
||||
try {
|
||||
$view = view('popup.report.category-entry', compact('journals', 'category'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render: %s', $e->getMessage()));
|
||||
$view = 'Firefly III could not render the view. Please see the log files.';
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
@ -196,18 +206,22 @@ class ReportController extends Controller
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
private function expenseEntry(array $attributes): string
|
||||
{
|
||||
$account = $this->accountRepository->findNull((int)$attributes['accountId']);
|
||||
|
||||
if (null === $account) {
|
||||
throw new FireflyException('This is an unknown account. Apologies.');
|
||||
return 'This is an unknown account. Apologies.';
|
||||
}
|
||||
|
||||
$journals = $this->popupHelper->byExpenses($account, $attributes);
|
||||
$view = view('popup.report.expense-entry', compact('journals', 'account'))->render();
|
||||
try {
|
||||
$view = view('popup.report.expense-entry', compact('journals', 'account'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render: %s', $e->getMessage()));
|
||||
$view = 'Firefly III could not render the view. Please see the log files.';
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
@ -218,18 +232,22 @@ class ReportController extends Controller
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
private function incomeEntry(array $attributes): string
|
||||
{
|
||||
$account = $this->accountRepository->findNull((int)$attributes['accountId']);
|
||||
|
||||
if (null === $account) {
|
||||
throw new FireflyException('This is an unknown category. Apologies.');
|
||||
return 'This is an unknown category. Apologies.';
|
||||
}
|
||||
|
||||
$journals = $this->popupHelper->byIncome($account, $attributes);
|
||||
$view = view('popup.report.income-entry', compact('journals', 'account'))->render();
|
||||
try {
|
||||
$view = view('popup.report.income-entry', compact('journals', 'account'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render: %s', $e->getMessage()));
|
||||
$view = 'Firefly III could not render the view. Please see the log files.';
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
@ -238,8 +256,6 @@ class ReportController extends Controller
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function parseAttributes(array $attributes): array
|
||||
{
|
||||
@ -248,13 +264,19 @@ class ReportController extends Controller
|
||||
try {
|
||||
$attributes['startDate'] = Carbon::createFromFormat('Ymd', $attributes['startDate']);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
throw new FireflyException(sprintf('Could not parse start date "%s": %s', $attributes['startDate'], $e->getMessage()));
|
||||
Log::debug('Not important error message: %s', $e->getMessage());
|
||||
$date = new Carbon;
|
||||
$date->startOfMonth();
|
||||
$attributes['startDate'] = $date;
|
||||
}
|
||||
|
||||
try {
|
||||
$attributes['endDate'] = Carbon::createFromFormat('Ymd', $attributes['endDate']);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
throw new FireflyException(sprintf('Could not parse end date "%s": %s', $attributes['endDate'], $e->getMessage()));
|
||||
Log::debug('Not important error message: %s', $e->getMessage());
|
||||
$date = new Carbon;
|
||||
$date->startOfMonth();
|
||||
$attributes['endDate'] = $date;
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
|
@ -86,6 +86,9 @@ class PreferencesController extends Controller
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function postIndex(Request $request)
|
||||
{
|
||||
|
@ -49,6 +49,8 @@ use phpseclib\Crypt\RSA;
|
||||
* Class ProfileController.
|
||||
*
|
||||
* @method Guard guard()
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
|
||||
*/
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
@ -185,10 +187,10 @@ class ProfileController extends Controller
|
||||
if ($repository->hasRole($user, 'demo')) {
|
||||
return redirect(route('profile.index'));
|
||||
}
|
||||
$hasTwoFactorAuthSecret = (null !== app('preferences')->get('twoFactorAuthSecret'));
|
||||
$hasSecret = (null !== app('preferences')->get('twoFactorAuthSecret'));
|
||||
|
||||
// if we don't have a valid secret yet, redirect to the code page to get one.
|
||||
if (!$hasTwoFactorAuthSecret) {
|
||||
if (!$hasSecret) {
|
||||
return redirect(route('profile.code'));
|
||||
}
|
||||
|
||||
@ -308,6 +310,8 @@ class ProfileController extends Controller
|
||||
* @param TokenFormRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
public function postCode(TokenFormRequest $request)
|
||||
{
|
||||
@ -316,7 +320,6 @@ class ProfileController extends Controller
|
||||
|
||||
session()->flash('success', (string)trans('firefly.saved_preferences'));
|
||||
app('preferences')->mark();
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
}
|
||||
|
||||
@ -366,6 +369,8 @@ class ProfileController extends Controller
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function undoEmailChange(UserRepositoryInterface $repository, string $token, string $hash)
|
||||
{
|
||||
@ -382,8 +387,7 @@ class ProfileController extends Controller
|
||||
throw new FireflyException('Invalid token.');
|
||||
}
|
||||
|
||||
// found user.
|
||||
// which email address to return to?
|
||||
// found user.which email address to return to?
|
||||
$set = app('preferences')->beginsWith($user, 'previous_email_');
|
||||
/** @var string $match */
|
||||
$match = null;
|
||||
|
@ -69,6 +69,7 @@ class CreateController extends Controller
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
@ -83,14 +84,11 @@ class CreateController extends Controller
|
||||
$this->rememberPreviousUri('recurring.create.uri');
|
||||
}
|
||||
$request->session()->forget('recurring.create.fromStore');
|
||||
|
||||
// when will it end?
|
||||
$repetitionEnds = [
|
||||
'forever' => (string)trans('firefly.repeat_forever'),
|
||||
'until_date' => (string)trans('firefly.repeat_until_date'),
|
||||
'times' => (string)trans('firefly.repeat_times'),
|
||||
];
|
||||
// what to do in the weekend?
|
||||
$weekendResponses = [
|
||||
RecurrenceRepetition::WEEKEND_DO_NOTHING => (string)trans('firefly.do_nothing'),
|
||||
RecurrenceRepetition::WEEKEND_SKIP_CREATION => (string)trans('firefly.skip_transaction'),
|
||||
@ -98,8 +96,8 @@ class CreateController extends Controller
|
||||
RecurrenceRepetition::WEEKEND_TO_MONDAY => (string)trans('firefly.jump_to_monday'),
|
||||
];
|
||||
|
||||
// flash some data:
|
||||
$hasOldInput = null !== $request->old('_token');
|
||||
|
||||
$hasOldInput = null !== $request->old('_token'); // flash some data
|
||||
$preFilled = [
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'transaction_type' => $hasOldInput ? $request->old('transaction_type') : 'withdrawal',
|
||||
|
@ -68,31 +68,29 @@ class EditController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* todo move to repository
|
||||
* todo handle old repetition type as well.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function edit(Request $request, Recurrence $recurrence)
|
||||
{
|
||||
|
||||
|
||||
// use transformer:
|
||||
$transformer = new RecurrenceTransformer(new ParameterBag);
|
||||
$array = $transformer->transform($recurrence);
|
||||
$budgets = app('expandedform')->makeSelectListWithEmpty($this->budgets->getActiveBudgets());
|
||||
|
||||
// get recurrence type:
|
||||
// todo move to repository
|
||||
// todo handle old repetition type as well.
|
||||
|
||||
|
||||
/** @var RecurrenceRepetition $repetition */
|
||||
$repetition = $recurrence->recurrenceRepetitions()->first();
|
||||
$currentRepetitionType = $repetition->repetition_type;
|
||||
$currentRepType = $repetition->repetition_type;
|
||||
if ('' !== $repetition->repetition_moment) {
|
||||
$currentRepetitionType .= ',' . $repetition->repetition_moment;
|
||||
$currentRepType .= ',' . $repetition->repetition_moment;
|
||||
}
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
@ -101,9 +99,7 @@ class EditController extends Controller
|
||||
}
|
||||
$request->session()->forget('recurrences.edit.fromUpdate');
|
||||
|
||||
// assume repeats forever:
|
||||
$repetitionEnd = 'forever';
|
||||
// types of repetitions:
|
||||
$repetitionEnd = 'forever';
|
||||
$repetitionEnds = [
|
||||
'forever' => (string)trans('firefly.repeat_forever'),
|
||||
'until_date' => (string)trans('firefly.repeat_until_date'),
|
||||
@ -116,7 +112,6 @@ class EditController extends Controller
|
||||
$repetitionEnd = 'times';
|
||||
}
|
||||
|
||||
// what to do in the weekend?
|
||||
$weekendResponses = [
|
||||
RecurrenceRepetition::WEEKEND_DO_NOTHING => (string)trans('firefly.do_nothing'),
|
||||
RecurrenceRepetition::WEEKEND_SKIP_CREATION => (string)trans('firefly.skip_transaction'),
|
||||
@ -124,10 +119,8 @@ class EditController extends Controller
|
||||
RecurrenceRepetition::WEEKEND_TO_MONDAY => (string)trans('firefly.jump_to_monday'),
|
||||
];
|
||||
|
||||
// code to handle active-checkboxes
|
||||
$hasOldInput = null !== $request->old('_token');
|
||||
// $hasOldInput = false;
|
||||
$preFilled = [
|
||||
$preFilled = [
|
||||
'transaction_type' => strtolower($recurrence->transactionType->type),
|
||||
'active' => $hasOldInput ? (bool)$request->old('active') : $recurrence->active,
|
||||
'apply_rules' => $hasOldInput ? (bool)$request->old('apply_rules') : $recurrence->apply_rules,
|
||||
@ -135,7 +128,7 @@ class EditController extends Controller
|
||||
|
||||
return view(
|
||||
'recurring.edit',
|
||||
compact('recurrence', 'array', 'weekendResponses', 'budgets', 'preFilled', 'currentRepetitionType', 'repetitionEnd', 'repetitionEnds')
|
||||
compact('recurrence', 'array', 'weekendResponses', 'budgets', 'preFilled', 'currentRepType', 'repetitionEnd', 'repetitionEnds')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -28,10 +28,8 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\RecurrenceRepetition;
|
||||
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
|
||||
use FireflyIII\Transformers\RecurrenceTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
|
||||
@ -64,98 +62,14 @@ class IndexController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* TODO: split collection into pages
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function events(Request $request): JsonResponse
|
||||
{
|
||||
$return = [];
|
||||
$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');
|
||||
$repetitionType = explode(',', $request->get('type'))[0];
|
||||
$repetitions = (int)$request->get('reps');
|
||||
$repetitionMoment = '';
|
||||
$start->startOfDay();
|
||||
|
||||
// if $firstDate is beyond $end, simply return an empty array.
|
||||
if ($firstDate->gt($end)) {
|
||||
return response()->json([]);
|
||||
}
|
||||
// if $firstDate is beyond start, use that one:
|
||||
$actualStart = clone $firstDate;
|
||||
|
||||
switch ($repetitionType) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Cannot handle repetition type "%s"', $repetitionType));
|
||||
case 'daily':
|
||||
break;
|
||||
case 'weekly':
|
||||
case 'monthly':
|
||||
$repetitionMoment = explode(',', $request->get('type'))[1] ?? '1';
|
||||
break;
|
||||
case 'ndom':
|
||||
$repetitionMoment = str_ireplace('ndom,', '', $request->get('type'));
|
||||
break;
|
||||
case 'yearly':
|
||||
$repetitionMoment = explode(',', $request->get('type'))[1] ?? '2018-01-01';
|
||||
break;
|
||||
}
|
||||
$repetition = new RecurrenceRepetition;
|
||||
$repetition->repetition_type = $repetitionType;
|
||||
$repetition->repetition_moment = $repetitionMoment;
|
||||
$repetition->repetition_skip = (int)$request->get('skip');
|
||||
$repetition->weekend = (int)$request->get('weekend');
|
||||
|
||||
$actualEnd = clone $end;
|
||||
switch ($endsAt) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Cannot generate events for type that ends at "%s".', $endsAt));
|
||||
case 'forever':
|
||||
// simply generate up until $end. No change from default behavior.
|
||||
$occurrences = $this->recurring->getOccurrencesInRange($repetition, $actualStart, $actualEnd);
|
||||
break;
|
||||
case 'until_date':
|
||||
$actualEnd = $endDate ?? clone $end;
|
||||
$occurrences = $this->recurring->getOccurrencesInRange($repetition, $actualStart, $actualEnd);
|
||||
break;
|
||||
case 'times':
|
||||
$occurrences = $this->recurring->getXOccurrences($repetition, $actualStart, $repetitions);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/** @var Carbon $current */
|
||||
foreach ($occurrences as $current) {
|
||||
if ($current->gte($start)) {
|
||||
$event = [
|
||||
'id' => $repetitionType . $firstDate->format('Ymd'),
|
||||
'title' => 'X',
|
||||
'allDay' => true,
|
||||
'start' => $current->format('Y-m-d'),
|
||||
'end' => $current->format('Y-m-d'),
|
||||
'editable' => false,
|
||||
'rendering' => 'background',
|
||||
];
|
||||
$return[] = $event;
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
@ -163,7 +77,6 @@ class IndexController extends Controller
|
||||
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
|
||||
$collection = $this->recurring->get();
|
||||
|
||||
// TODO: split collection into pages
|
||||
|
||||
$transformer = new RecurrenceTransformer(new ParameterBag);
|
||||
$recurring = [];
|
||||
@ -206,38 +119,4 @@ class IndexController extends Controller
|
||||
return view('recurring.show', compact('recurrence', 'subTitle', 'array', 'transactions'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function suggest(Request $request): JsonResponse
|
||||
{
|
||||
$today = new Carbon;
|
||||
$date = Carbon::createFromFormat('Y-m-d', $request->get('date'));
|
||||
$preSelected = (string)$request->get('pre_select');
|
||||
$result = [];
|
||||
if ($date > $today || 'true' === (string)$request->get('past')) {
|
||||
$weekly = sprintf('weekly,%s', $date->dayOfWeekIso);
|
||||
$monthly = sprintf('monthly,%s', $date->day);
|
||||
$dayOfWeek = 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(trans('config.month_and_day_no_year'));
|
||||
$result = [
|
||||
'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]),
|
||||
'selected' => 0 === strpos($preSelected, 'monthly')],
|
||||
$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]), 'selected' => 0 === strpos($preSelected, 'yearly')],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
return response()->json($result);
|
||||
}
|
||||
|
||||
}
|
@ -41,7 +41,7 @@ class AccountController extends Controller
|
||||
*
|
||||
* @return mixed|string
|
||||
*
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function general(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ class BalanceController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed|string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function general(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
|
@ -41,7 +41,7 @@ class BudgetController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed|string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function general(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
@ -70,7 +70,7 @@ class BudgetController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed|string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function period(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
|
@ -28,6 +28,8 @@ use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class CategoryController.
|
||||
@ -41,7 +43,6 @@ class CategoryController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed|string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function expenses(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
@ -60,7 +61,12 @@ class CategoryController extends Controller
|
||||
$data[0] = $repository->periodExpensesNoCategory($accounts, $start, $end);
|
||||
$report = $this->filterReport($data);
|
||||
$periods = app('navigation')->listOfPeriods($start, $end);
|
||||
$result = view('reports.partials.category-period', compact('report', 'periods'))->render();
|
||||
try {
|
||||
$result = view('reports.partials.category-period', compact('report', 'periods'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
|
||||
$result = 'An error prevented Firefly III from rendering. Apologies.';
|
||||
}
|
||||
|
||||
$cache->store($result);
|
||||
|
||||
@ -75,7 +81,6 @@ class CategoryController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function income(Collection $accounts, Carbon $start, Carbon $end): string
|
||||
{
|
||||
@ -94,8 +99,12 @@ class CategoryController extends Controller
|
||||
$data[0] = $repository->periodIncomeNoCategory($accounts, $start, $end);
|
||||
$report = $this->filterReport($data);
|
||||
$periods = app('navigation')->listOfPeriods($start, $end);
|
||||
$result = view('reports.partials.category-period', compact('report', 'periods'))->render();
|
||||
|
||||
try {
|
||||
$result = view('reports.partials.category-period', compact('report', 'periods'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
|
||||
$result = 'An error prevented Firefly III from rendering. Apologies.';
|
||||
}
|
||||
$cache->store($result);
|
||||
|
||||
return $result;
|
||||
@ -109,8 +118,7 @@ class CategoryController extends Controller
|
||||
*
|
||||
* @return mixed|string
|
||||
*
|
||||
* @throws \Throwable
|
||||
* @internal param ReportHelperInterface $helper
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function operations(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
@ -136,17 +144,18 @@ class CategoryController extends Controller
|
||||
$report[$category->id] = ['name' => $category->name, 'spent' => $spent, 'earned' => $earned, 'id' => $category->id];
|
||||
}
|
||||
}
|
||||
// sort the result
|
||||
// Obtain a list of columns
|
||||
$sum = [];
|
||||
foreach ($report as $categoryId => $row) {
|
||||
$sum[$categoryId] = (float)$row['spent'];
|
||||
}
|
||||
|
||||
array_multisort($sum, SORT_ASC, $report);
|
||||
|
||||
$result = view('reports.partials.categories', compact('report'))->render();
|
||||
$cache->store($result);
|
||||
try {
|
||||
$result = view('reports.partials.categories', compact('report'))->render();
|
||||
$cache->store($result);
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
|
||||
$result = 'An error prevented Firefly III from rendering. Apologies.';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Report;
|
||||
@ -33,9 +32,13 @@ use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class ExpenseController
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
|
||||
*/
|
||||
class ExpenseController extends Controller
|
||||
{
|
||||
@ -60,6 +63,7 @@ class ExpenseController extends Controller
|
||||
}
|
||||
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* Generates the overview per budget.
|
||||
*
|
||||
@ -69,7 +73,7 @@ class ExpenseController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function budget(Collection $accounts, Collection $expense, Carbon $start, Carbon $end): string
|
||||
{
|
||||
@ -85,7 +89,7 @@ class ExpenseController extends Controller
|
||||
}
|
||||
$combined = $this->combineAccounts($expense);
|
||||
$all = new Collection;
|
||||
foreach ($combined as $name => $combi) {
|
||||
foreach ($combined as $combi) {
|
||||
$all = $all->merge($combi);
|
||||
}
|
||||
// now find spent / earned:
|
||||
@ -100,13 +104,19 @@ class ExpenseController extends Controller
|
||||
}
|
||||
$together[$categoryId]['grand_total'] = bcadd($spentInfo['grand_total'], $together[$categoryId]['grand_total']);
|
||||
}
|
||||
$result = view('reports.partials.exp-budgets', compact('together'))->render();
|
||||
try {
|
||||
$result = view('reports.partials.exp-budgets', compact('together'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
|
||||
$result = 'An error prevented Firefly III from rendering. Apologies.';
|
||||
}
|
||||
$cache->store($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* Generates the overview per category (spent and earned).
|
||||
*
|
||||
@ -116,7 +126,8 @@ class ExpenseController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function category(Collection $accounts, Collection $expense, Carbon $start, Carbon $end): string
|
||||
{
|
||||
@ -132,7 +143,7 @@ class ExpenseController extends Controller
|
||||
}
|
||||
$combined = $this->combineAccounts($expense);
|
||||
$all = new Collection;
|
||||
foreach ($combined as $name => $combi) {
|
||||
foreach ($combined as $combi) {
|
||||
$all = $all->merge($combi);
|
||||
}
|
||||
// now find spent / earned:
|
||||
@ -156,14 +167,18 @@ class ExpenseController extends Controller
|
||||
}
|
||||
$together[$categoryId]['grand_total'] = bcadd($earnedInfo['grand_total'], $together[$categoryId]['grand_total']);
|
||||
}
|
||||
|
||||
$result = view('reports.partials.exp-categories', compact('together'))->render();
|
||||
try {
|
||||
$result = view('reports.partials.exp-categories', compact('together'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
|
||||
$result = 'An error prevented Firefly III from rendering. Apologies.';
|
||||
}
|
||||
$cache->store($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* Overview of spending
|
||||
*
|
||||
@ -173,7 +188,6 @@ class ExpenseController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array|mixed|string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function spent(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
|
||||
{
|
||||
@ -203,14 +217,19 @@ class ExpenseController extends Controller
|
||||
'earned' => $earned,
|
||||
];
|
||||
}
|
||||
$result = view('reports.partials.exp-not-grouped', compact('result'))->render();
|
||||
try {
|
||||
$result = view('reports.partials.exp-not-grouped', compact('result'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
|
||||
$result = 'An error prevented Firefly III from rendering. Apologies.';
|
||||
}
|
||||
$cache->store($result);
|
||||
|
||||
return $result;
|
||||
// for period, get spent and earned for each account (by name)
|
||||
}
|
||||
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $expense
|
||||
@ -218,7 +237,6 @@ class ExpenseController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function topExpense(Collection $accounts, Collection $expense, Carbon $start, Carbon $end): string
|
||||
{
|
||||
@ -234,7 +252,7 @@ class ExpenseController extends Controller
|
||||
}
|
||||
$combined = $this->combineAccounts($expense);
|
||||
$all = new Collection;
|
||||
foreach ($combined as $name => $combi) {
|
||||
foreach ($combined as $combi) {
|
||||
$all = $all->merge($combi);
|
||||
}
|
||||
// get all expenses in period:
|
||||
@ -248,12 +266,17 @@ class ExpenseController extends Controller
|
||||
return (float)$transaction->transaction_amount;
|
||||
}
|
||||
);
|
||||
$result = view('reports.partials.top-transactions', compact('sorted'))->render();
|
||||
try {
|
||||
$result = view('reports.partials.top-transactions', compact('sorted'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
|
||||
$result = 'An error prevented Firefly III from rendering. Apologies.';
|
||||
}
|
||||
$cache->store($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $expense
|
||||
@ -261,7 +284,6 @@ class ExpenseController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed|string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function topIncome(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
|
||||
{
|
||||
@ -277,7 +299,7 @@ class ExpenseController extends Controller
|
||||
}
|
||||
$combined = $this->combineAccounts($expense);
|
||||
$all = new Collection;
|
||||
foreach ($combined as $name => $combi) {
|
||||
foreach ($combined as $combi) {
|
||||
$all = $all->merge($combi);
|
||||
}
|
||||
// get all expenses in period:
|
||||
@ -291,7 +313,12 @@ class ExpenseController extends Controller
|
||||
return (float)$transaction->transaction_amount;
|
||||
}
|
||||
);
|
||||
$result = view('reports.partials.top-transactions', compact('sorted'))->render();
|
||||
try {
|
||||
$result = view('reports.partials.top-transactions', compact('sorted'))->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
|
||||
$result = 'An error prevented Firefly III from rendering. Apologies.';
|
||||
}
|
||||
$cache->store($result);
|
||||
|
||||
return $result;
|
||||
@ -320,6 +347,7 @@ class ExpenseController extends Controller
|
||||
return $combined;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* @param Collection $assets
|
||||
* @param Collection $opposing
|
||||
@ -327,6 +355,9 @@ class ExpenseController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
protected function earnedByCategory(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
|
||||
{
|
||||
@ -381,6 +412,7 @@ class ExpenseController extends Controller
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* @param Collection $assets
|
||||
* @param Collection $opposing
|
||||
@ -423,6 +455,7 @@ class ExpenseController extends Controller
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* @param Collection $assets
|
||||
* @param Collection $opposing
|
||||
@ -430,6 +463,8 @@ class ExpenseController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
protected function spentByBudget(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
|
||||
{
|
||||
@ -484,6 +519,7 @@ class ExpenseController extends Controller
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* @param Collection $assets
|
||||
* @param Collection $opposing
|
||||
@ -491,6 +527,9 @@ class ExpenseController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
protected function spentByCategory(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
|
||||
{
|
||||
@ -545,6 +584,7 @@ class ExpenseController extends Controller
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* @param Collection $assets
|
||||
* @param Collection $opposing
|
||||
|
@ -61,7 +61,7 @@ class OperationsController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed|string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function expenses(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
@ -88,7 +88,7 @@ class OperationsController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function income(Collection $accounts, Carbon $start, Carbon $end): string
|
||||
{
|
||||
@ -116,7 +116,7 @@ class OperationsController extends Controller
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed|string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function operations(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
|
@ -19,7 +19,6 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @noinspection CallableParameterUseCaseInTypeContextInspection */
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
@ -40,6 +39,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class ReportController.
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class ReportController extends Controller
|
||||
{
|
||||
@ -68,7 +68,7 @@ class ReportController extends Controller
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $expense
|
||||
@ -133,6 +133,7 @@ class ReportController extends Controller
|
||||
return $generator->generate();
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $budgets
|
||||
@ -168,6 +169,7 @@ class ReportController extends Controller
|
||||
return $generator->generate();
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $categories
|
||||
@ -259,8 +261,7 @@ class ReportController extends Controller
|
||||
* @param string $reportType
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Throwable
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function options(string $reportType)
|
||||
{
|
||||
@ -291,6 +292,10 @@ class ReportController extends Controller
|
||||
* @return RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.NPathComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function postIndex(ReportFormRequest $request)
|
||||
{
|
||||
@ -358,6 +363,7 @@ class ReportController extends Controller
|
||||
return redirect($uri);
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $tags
|
||||
@ -395,7 +401,6 @@ class ReportController extends Controller
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
private function accountReportOptions(): string
|
||||
{
|
||||
@ -416,7 +421,6 @@ class ReportController extends Controller
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
private function budgetReportOptions(): string
|
||||
{
|
||||
@ -429,7 +433,6 @@ class ReportController extends Controller
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
private function categoryReportOptions(): string
|
||||
{
|
||||
@ -442,7 +445,6 @@ class ReportController extends Controller
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
private function noReportOptions(): string
|
||||
{
|
||||
@ -451,7 +453,6 @@ class ReportController extends Controller
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
*/
|
||||
private function tagReportOptions(): string
|
||||
{
|
||||
|
250
app/Http/Controllers/Rule/CreateController.php
Normal file
250
app/Http/Controllers/Rule/CreateController.php
Normal file
@ -0,0 +1,250 @@
|
||||
<?php
|
||||
/**
|
||||
* CreateController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Rule;
|
||||
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\RuleFormRequest;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Controllers\RuleManagement;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class CreateController
|
||||
*/
|
||||
class CreateController extends Controller
|
||||
{
|
||||
use RuleManagement;
|
||||
/** @var BillRepositoryInterface */
|
||||
private $billRepos;
|
||||
/** @var RuleGroupRepositoryInterface */
|
||||
private $ruleRepos;
|
||||
|
||||
/**
|
||||
* RuleController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string)trans('firefly.rules'));
|
||||
app('view')->share('mainTitleIcon', 'fa-random');
|
||||
|
||||
$this->billRepos = app(BillRepositoryInterface::class);
|
||||
$this->ruleRepos = app(RuleRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new rule. It will be stored under the given $ruleGroup.
|
||||
*
|
||||
* TODO remove bill from this method, move to separate routine.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function create(Request $request, RuleGroup $ruleGroup)
|
||||
{
|
||||
$this->createDefaultRuleGroup();
|
||||
$this->createDefaultRule();
|
||||
$bill = null;
|
||||
$billId = (int)$request->get('fromBill');
|
||||
$preFilled = [
|
||||
'strict' => true,
|
||||
];
|
||||
$oldTriggers = [];
|
||||
$oldActions = [];
|
||||
$returnToBill = false;
|
||||
|
||||
if ('true' === $request->get('return')) {
|
||||
$returnToBill = true;
|
||||
}
|
||||
|
||||
// has bill?
|
||||
if ($billId > 0) {
|
||||
$bill = $this->billRepos->find($billId);
|
||||
}
|
||||
|
||||
// has old input?
|
||||
if ($request->old()) {
|
||||
$oldTriggers = $this->getPreviousTriggers($request);
|
||||
$oldActions = $this->getPreviousActions($request);
|
||||
}
|
||||
// has existing bill refered to in URI?
|
||||
if (null !== $bill && !$request->old()) {
|
||||
|
||||
// create some sensible defaults:
|
||||
$preFilled['title'] = (string)trans('firefly.new_rule_for_bill_title', ['name' => $bill->name]);
|
||||
$preFilled['description'] = (string)trans('firefly.new_rule_for_bill_description', ['name' => $bill->name]);
|
||||
|
||||
|
||||
// get triggers and actions for bill:
|
||||
$oldTriggers = $this->getTriggersForBill($bill);
|
||||
$oldActions = $this->getActionsForBill($bill);
|
||||
}
|
||||
|
||||
$triggerCount = \count($oldTriggers);
|
||||
$actionCount = \count($oldActions);
|
||||
$subTitleIcon = 'fa-clone';
|
||||
$subTitle = (string)trans('firefly.make_new_rule', ['title' => $ruleGroup->title]);
|
||||
|
||||
$request->session()->flash('preFilled', $preFilled);
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (true !== session('rules.create.fromStore')) {
|
||||
$this->rememberPreviousUri('rules.create.uri');
|
||||
}
|
||||
session()->forget('rules.create.fromStore');
|
||||
|
||||
return view(
|
||||
'rules.rule.create',
|
||||
compact(
|
||||
'subTitleIcon', 'oldTriggers', 'returnToBill', 'preFilled', 'bill', 'oldActions', 'triggerCount', 'actionCount', 'ruleGroup',
|
||||
'subTitle'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleFormRequest $request
|
||||
*
|
||||
* @return RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function store(RuleFormRequest $request)
|
||||
{
|
||||
$data = $request->getRuleData();
|
||||
$rule = $this->ruleRepos->store($data);
|
||||
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
|
||||
}
|
||||
|
||||
// redirect to new bill creation.
|
||||
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')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
session()->put('rules.create.fromStore', true);
|
||||
$redirect = redirect(route('rules.create', [$data['rule_group_id']]))->withInput();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getActionsForBill(Bill $bill): array
|
||||
{
|
||||
$result = '';
|
||||
try {
|
||||
$result = view(
|
||||
'rules.partials.action',
|
||||
[
|
||||
'oldAction' => 'link_to_bill',
|
||||
'oldValue' => $bill->name,
|
||||
'oldChecked' => false,
|
||||
'count' => 1,
|
||||
]
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Throwable was thrown in getActionsForBill(): %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
$result = 'Could not render view. See log files.';
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return [$result];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create fake triggers to match the bill's properties
|
||||
*
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getTriggersForBill(Bill $bill): array
|
||||
{
|
||||
$result = [];
|
||||
$triggers = ['currency_is', 'amount_more', 'amount_less', 'description_contains'];
|
||||
$values = [
|
||||
$bill->transactionCurrency()->first()->name,
|
||||
round($bill->amount_min, 12),
|
||||
round($bill->amount_max, 12),
|
||||
$bill->name,
|
||||
];
|
||||
foreach ($triggers as $index => $trigger) {
|
||||
try {
|
||||
$string = view(
|
||||
'rules.partials.trigger',
|
||||
[
|
||||
'oldTrigger' => $trigger,
|
||||
'oldValue' => $values[$index],
|
||||
'oldChecked' => false,
|
||||
'count' => $index + 1,
|
||||
]
|
||||
)->render();
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Throwable was thrown in getTriggersForBill(): %s', $e->getMessage()));
|
||||
Log::debug($e->getTraceAsString());
|
||||
$string = '';
|
||||
}
|
||||
if ('' !== $string) {
|
||||
$result[] = $string;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
94
app/Http/Controllers/Rule/DeleteController.php
Normal file
94
app/Http/Controllers/Rule/DeleteController.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* DeleteController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Rule;
|
||||
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
||||
/**
|
||||
* Class DeleteController
|
||||
*/
|
||||
class DeleteController extends Controller
|
||||
{
|
||||
/** @var RuleRepositoryInterface */
|
||||
private $ruleRepos;
|
||||
|
||||
/**
|
||||
* RuleController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string)trans('firefly.rules'));
|
||||
app('view')->share('mainTitleIcon', 'fa-random');
|
||||
|
||||
$this->ruleRepos = app(RuleRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a given rule.
|
||||
*
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function delete(Rule $rule)
|
||||
{
|
||||
$subTitle = (string)trans('firefly.delete_rule', ['title' => $rule->title]);
|
||||
|
||||
// put previous url in session
|
||||
$this->rememberPreviousUri('rules.delete.uri');
|
||||
|
||||
return view('rules.rule.delete', compact('rule', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually destroy the given rule.
|
||||
*
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function destroy(Rule $rule): RedirectResponse
|
||||
{
|
||||
$title = $rule->title;
|
||||
$this->ruleRepos->destroy($rule);
|
||||
|
||||
session()->flash('success', (string)trans('firefly.deleted_rule', ['title' => $title]));
|
||||
app('preferences')->mark();
|
||||
|
||||
return redirect($this->getPreviousUri('rules.delete.uri'));
|
||||
}
|
||||
|
||||
}
|
219
app/Http/Controllers/Rule/EditController.php
Normal file
219
app/Http/Controllers/Rule/EditController.php
Normal file
@ -0,0 +1,219 @@
|
||||
<?php
|
||||
/**
|
||||
* EditController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Rule;
|
||||
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\RuleFormRequest;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Controllers\RuleManagement;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class EditController
|
||||
*/
|
||||
class EditController extends Controller
|
||||
{
|
||||
use RuleManagement;
|
||||
|
||||
/** @var RuleRepositoryInterface */
|
||||
private $ruleRepos;
|
||||
|
||||
/**
|
||||
* RuleController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string)trans('firefly.rules'));
|
||||
app('view')->share('mainTitleIcon', 'fa-random');
|
||||
|
||||
$this->ruleRepos = app(RuleRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function edit(Request $request, Rule $rule)
|
||||
{
|
||||
$triggerCount = 0;
|
||||
$actionCount = 0;
|
||||
$oldActions = [];
|
||||
$oldTriggers = [];
|
||||
// has old input?
|
||||
if (\count($request->old()) > 0) {
|
||||
$oldTriggers = $this->getPreviousTriggers($request);
|
||||
$triggerCount = \count($oldTriggers);
|
||||
$oldActions = $this->getPreviousActions($request);
|
||||
$actionCount = \count($oldActions);
|
||||
}
|
||||
|
||||
// overrule old input when it has no rule data:
|
||||
if (0 === $triggerCount && 0 === $actionCount) {
|
||||
$oldTriggers = $this->getCurrentTriggers($rule);
|
||||
$triggerCount = \count($oldTriggers);
|
||||
$oldActions = $this->getCurrentActions($rule);
|
||||
$actionCount = \count($oldActions);
|
||||
}
|
||||
|
||||
$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,
|
||||
|
||||
];
|
||||
|
||||
// get rule trigger for update / store-journal:
|
||||
$primaryTrigger = $this->ruleRepos->getPrimaryTrigger($rule);
|
||||
$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')) {
|
||||
$this->rememberPreviousUri('rules.edit.uri');
|
||||
}
|
||||
session()->forget('rules.edit.fromUpdate');
|
||||
|
||||
$request->session()->flash('preFilled', $preFilled);
|
||||
|
||||
return view('rules.rule.edit', compact('rule', 'subTitle', 'primaryTrigger', 'oldTriggers', 'oldActions', 'triggerCount', 'actionCount'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleFormRequest $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse|\Illuminate\Routing\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 Rule $rule
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
private function getCurrentActions(Rule $rule): array
|
||||
{
|
||||
$index = 0;
|
||||
$actions = [];
|
||||
|
||||
/** @var RuleAction $entry */
|
||||
foreach ($rule->ruleActions as $entry) {
|
||||
$count = ($index + 1);
|
||||
try {
|
||||
$actions[] = view(
|
||||
'rules.partials.action',
|
||||
[
|
||||
'oldAction' => $entry->action_type,
|
||||
'oldValue' => $entry->action_value,
|
||||
'oldChecked' => $entry->stop_processing,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Throwable was thrown in getCurrentActions(): %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
++$index;
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
private function getCurrentTriggers(Rule $rule): array
|
||||
{
|
||||
$index = 0;
|
||||
$triggers = [];
|
||||
|
||||
/** @var RuleTrigger $entry */
|
||||
foreach ($rule->ruleTriggers as $entry) {
|
||||
if ('user_action' !== $entry->trigger_type) {
|
||||
$count = ($index + 1);
|
||||
try {
|
||||
$triggers[] = view(
|
||||
'rules.partials.trigger',
|
||||
[
|
||||
'oldTrigger' => $entry->trigger_type,
|
||||
'oldValue' => $entry->trigger_value,
|
||||
'oldChecked' => $entry->stop_processing,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Throwable was thrown in getCurrentTriggers(): %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
++$index;
|
||||
}
|
||||
}
|
||||
|
||||
return $triggers;
|
||||
}
|
||||
}
|
136
app/Http/Controllers/Rule/IndexController.php
Normal file
136
app/Http/Controllers/Rule/IndexController.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* RuleController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Rule;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Controllers\RuleManagement;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class IndexController
|
||||
*/
|
||||
class IndexController extends Controller
|
||||
{
|
||||
use RuleManagement;
|
||||
/** @var RuleGroupRepositoryInterface */
|
||||
private $ruleGroupRepos;
|
||||
/** @var RuleRepositoryInterface */
|
||||
private $ruleRepos;
|
||||
|
||||
/**
|
||||
* RuleController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string)trans('firefly.rules'));
|
||||
app('view')->share('mainTitleIcon', 'fa-random');
|
||||
$this->ruleGroupRepos = app(RuleGroupRepositoryInterface::class);
|
||||
$this->ruleRepos = app(RuleRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function down(Rule $rule)
|
||||
{
|
||||
$this->ruleRepos->moveDown($rule);
|
||||
|
||||
return redirect(route('rules.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->createDefaultRuleGroup();
|
||||
$this->createDefaultRule();
|
||||
$ruleGroups = $this->ruleGroupRepos->getRuleGroupsWithRules($user);
|
||||
|
||||
return view('rules.index', compact('ruleGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function reorderRuleActions(Request $request, Rule $rule): JsonResponse
|
||||
{
|
||||
$ids = $request->get('actions');
|
||||
if (\is_array($ids)) {
|
||||
$this->ruleRepos->reorderRuleActions($rule, $ids);
|
||||
}
|
||||
|
||||
return response()->json('true');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function reorderRuleTriggers(Request $request, Rule $rule): JsonResponse
|
||||
{
|
||||
$ids = $request->get('triggers');
|
||||
if (\is_array($ids)) {
|
||||
$this->ruleRepos->reorderRuleTriggers($rule, $ids);
|
||||
}
|
||||
|
||||
return response()->json('true');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*/
|
||||
public function up(Rule $rule)
|
||||
{
|
||||
$this->ruleRepos->moveUp($rule);
|
||||
|
||||
return redirect(route('rules.index'));
|
||||
}
|
||||
|
||||
}
|
283
app/Http/Controllers/Rule/SelectController.php
Normal file
283
app/Http/Controllers/Rule/SelectController.php
Normal file
@ -0,0 +1,283 @@
|
||||
<?php
|
||||
/**
|
||||
* SelectController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Rule;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\SelectTransactionsRequest;
|
||||
use FireflyIII\Http\Requests\TestRuleFormRequest;
|
||||
use FireflyIII\Jobs\ExecuteRuleOnExistingTransactions;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Controllers\RuleManagement;
|
||||
use FireflyIII\TransactionRules\TransactionMatcher;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class SelectController
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class SelectController extends Controller
|
||||
{
|
||||
use RuleManagement;
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepos;
|
||||
|
||||
/**
|
||||
* RuleController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string)trans('firefly.rules'));
|
||||
app('view')->share('mainTitleIcon', 'fa-random');
|
||||
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the given rule on a set of existing transactions.
|
||||
*
|
||||
* @param SelectTransactionsRequest $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function execute(SelectTransactionsRequest $request, Rule $rule): RedirectResponse
|
||||
{
|
||||
// Get parameters specified by the user
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$accounts = $this->accountRepos->getAccountsById($request->get('accounts'));
|
||||
$startDate = new Carbon($request->get('start_date'));
|
||||
$endDate = new Carbon($request->get('end_date'));
|
||||
|
||||
// Create a job to do the work asynchronously
|
||||
$job = new ExecuteRuleOnExistingTransactions($rule);
|
||||
|
||||
// Apply parameters to the job
|
||||
$job->setUser($user);
|
||||
$job->setAccounts($accounts);
|
||||
$job->setStartDate($startDate);
|
||||
$job->setEndDate($endDate);
|
||||
|
||||
// Dispatch a new job to execute it in a queue
|
||||
$this->dispatch($job);
|
||||
|
||||
// Tell the user that the job is queued
|
||||
session()->flash('success', (string)trans('firefly.applied_rule_selection', ['title' => $rule->title]));
|
||||
|
||||
return redirect()->route('rules.index');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function selectTransactions(Rule $rule)
|
||||
{
|
||||
// does the user have shared accounts?
|
||||
$first = session('first')->format('Y-m-d');
|
||||
$today = Carbon::create()->format('Y-m-d');
|
||||
$subTitle = (string)trans('firefly.apply_rule_selection', ['title' => $rule->title]);
|
||||
|
||||
return view('rules.rule.select-transactions', compact('first', 'today', 'rule', 'subTitle'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method allows the user to test a certain set of rule triggers. The rule triggers are passed along
|
||||
* using the URL parameters (GET), and are usually put there using a Javascript thing.
|
||||
*
|
||||
* This method will parse and validate those rules and create a "TransactionMatcher" which will attempt
|
||||
* to find transaction journals matching the users input. A maximum range of transactions to try (range) and
|
||||
* a maximum number of transactions to return (limit) are set as well.
|
||||
*
|
||||
* @param TestRuleFormRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function testTriggers(TestRuleFormRequest $request): JsonResponse
|
||||
{
|
||||
// build trigger array from response
|
||||
$triggers = $this->getValidTriggerList($request);
|
||||
|
||||
if (0 === \count($triggers)) {
|
||||
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$limit = (int)config('firefly.test-triggers.limit');
|
||||
$range = (int)config('firefly.test-triggers.range');
|
||||
$matchingTransactions = new Collection;
|
||||
/** @var TransactionMatcher $matcher */
|
||||
$matcher = app(TransactionMatcher::class);
|
||||
$matcher->setLimit($limit);
|
||||
$matcher->setRange($range);
|
||||
$matcher->setTriggers($triggers);
|
||||
try {
|
||||
$matchingTransactions = $matcher->findTransactionsByTriggers();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (FireflyException $exception) {
|
||||
Log::error(sprintf('Could not grab transactions in testTriggers(): %s', $exception->getMessage()));
|
||||
Log::error($exception->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
|
||||
// Warn the user if only a subset of transactions is returned
|
||||
$warning = '';
|
||||
if ($matchingTransactions->count() === $limit) {
|
||||
$warning = (string)trans('firefly.warning_transaction_subset', ['max_num_transactions' => $limit]); // @codeCoverageIgnore
|
||||
}
|
||||
if (0 === $matchingTransactions->count()) {
|
||||
$warning = (string)trans('firefly.warning_no_matching_transactions', ['num_transactions' => $range]); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// Return json response
|
||||
$view = 'ERROR, see logs.';
|
||||
try {
|
||||
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $exception) {
|
||||
Log::error(sprintf('Could not render view in testTriggers(): %s', $exception->getMessage()));
|
||||
Log::error($exception->getTraceAsString());
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return response()->json(['html' => $view, 'warning' => $warning]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows the user to test a certain set of rule triggers. The rule triggers are grabbed from
|
||||
* the rule itself.
|
||||
*
|
||||
* This method will parse and validate those rules and create a "TransactionMatcher" which will attempt
|
||||
* to find transaction journals matching the users input. A maximum range of transactions to try (range) and
|
||||
* a maximum number of transactions to return (limit) are set as well.
|
||||
*
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return JsonResponse
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function testTriggersByRule(Rule $rule): JsonResponse
|
||||
{
|
||||
$triggers = $rule->ruleTriggers;
|
||||
|
||||
if (0 === \count($triggers)) {
|
||||
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$limit = (int)config('firefly.test-triggers.limit');
|
||||
$range = (int)config('firefly.test-triggers.range');
|
||||
$matchingTransactions = new Collection;
|
||||
|
||||
/** @var TransactionMatcher $matcher */
|
||||
$matcher = app(TransactionMatcher::class);
|
||||
$matcher->setLimit($limit);
|
||||
$matcher->setRange($range);
|
||||
$matcher->setRule($rule);
|
||||
try {
|
||||
$matchingTransactions = $matcher->findTransactionsByRule();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (FireflyException $exception) {
|
||||
Log::error(sprintf('Could not grab transactions in testTriggersByRule(): %s', $exception->getMessage()));
|
||||
Log::error($exception->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// Warn the user if only a subset of transactions is returned
|
||||
$warning = '';
|
||||
if ($matchingTransactions->count() === $limit) {
|
||||
$warning = (string)trans('firefly.warning_transaction_subset', ['max_num_transactions' => $limit]); // @codeCoverageIgnore
|
||||
}
|
||||
if (0 === $matchingTransactions->count()) {
|
||||
$warning = (string)trans('firefly.warning_no_matching_transactions', ['num_transactions' => $range]); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// Return json response
|
||||
$view = 'ERROR, see logs.';
|
||||
try {
|
||||
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $exception) {
|
||||
Log::error(sprintf('Could not render view in testTriggersByRule(): %s', $exception->getMessage()));
|
||||
Log::error($exception->getTraceAsString());
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return response()->json(['html' => $view, 'warning' => $warning]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param TestRuleFormRequest $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getValidTriggerList(TestRuleFormRequest $request): array
|
||||
{
|
||||
$triggers = [];
|
||||
$data = [
|
||||
'rule-triggers' => $request->get('rule-trigger'),
|
||||
'rule-trigger-values' => $request->get('rule-trigger-value'),
|
||||
'rule-trigger-stop' => $request->get('rule-trigger-stop'),
|
||||
];
|
||||
if (\is_array($data['rule-triggers'])) {
|
||||
foreach ($data['rule-triggers'] as $index => $triggerType) {
|
||||
$data['rule-trigger-stop'][$index] = (int)($data['rule-trigger-stop'][$index] ?? 0.0);
|
||||
$triggers[] = [
|
||||
'type' => $triggerType,
|
||||
'value' => $data['rule-trigger-values'][$index],
|
||||
'stopProcessing' => 1 === (int)$data['rule-trigger-stop'][$index],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $triggers;
|
||||
}
|
||||
}
|
@ -1,875 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* RuleController.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Requests\RuleFormRequest;
|
||||
use FireflyIII\Http\Requests\SelectTransactionsRequest;
|
||||
use FireflyIII\Http\Requests\TestRuleFormRequest;
|
||||
use FireflyIII\Jobs\ExecuteRuleOnExistingTransactions;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
|
||||
use FireflyIII\TransactionRules\TransactionMatcher;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class RuleController.
|
||||
*/
|
||||
class RuleController extends Controller
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepos;
|
||||
/** @var BillRepositoryInterface */
|
||||
private $billRepos;
|
||||
/** @var RuleGroupRepositoryInterface */
|
||||
private $ruleGroupRepos;
|
||||
/** @var RuleRepositoryInterface */
|
||||
private $ruleRepos;
|
||||
|
||||
/**
|
||||
* RuleController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string)trans('firefly.rules'));
|
||||
app('view')->share('mainTitleIcon', 'fa-random');
|
||||
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
$this->billRepos = app(BillRepositoryInterface::class);
|
||||
$this->ruleGroupRepos = app(RuleGroupRepositoryInterface::class);
|
||||
$this->ruleRepos = app(RuleRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new rule. It will be stored under the given $ruleGroup.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function create(Request $request, RuleGroup $ruleGroup)
|
||||
{
|
||||
$this->createDefaultRuleGroup();
|
||||
$this->createDefaultRule();
|
||||
$bill = null;
|
||||
$billId = (int)$request->get('fromBill');
|
||||
$preFilled = [
|
||||
'strict' => true,
|
||||
];
|
||||
$oldTriggers = [];
|
||||
$oldActions = [];
|
||||
$returnToBill = false;
|
||||
|
||||
if ('true' === $request->get('return')) {
|
||||
$returnToBill = true;
|
||||
}
|
||||
|
||||
// has bill?
|
||||
if ($billId > 0) {
|
||||
$bill = $this->billRepos->find($billId);
|
||||
}
|
||||
|
||||
// has old input?
|
||||
if ($request->old()) {
|
||||
$oldTriggers = $this->getPreviousTriggers($request);
|
||||
$oldActions = $this->getPreviousActions($request);
|
||||
}
|
||||
// has existing bill refered to in URI?
|
||||
if (null !== $bill && !$request->old()) {
|
||||
|
||||
// create some sensible defaults:
|
||||
$preFilled['title'] = (string)trans('firefly.new_rule_for_bill_title', ['name' => $bill->name]);
|
||||
$preFilled['description'] = (string)trans('firefly.new_rule_for_bill_description', ['name' => $bill->name]);
|
||||
|
||||
|
||||
// get triggers and actions for bill:
|
||||
$oldTriggers = $this->getTriggersForBill($bill);
|
||||
$oldActions = $this->getActionsForBill($bill);
|
||||
}
|
||||
|
||||
$triggerCount = \count($oldTriggers);
|
||||
$actionCount = \count($oldActions);
|
||||
$subTitleIcon = 'fa-clone';
|
||||
$subTitle = (string)trans('firefly.make_new_rule', ['title' => $ruleGroup->title]);
|
||||
|
||||
$request->session()->flash('preFilled', $preFilled);
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (true !== session('rules.create.fromStore')) {
|
||||
$this->rememberPreviousUri('rules.create.uri');
|
||||
}
|
||||
session()->forget('rules.create.fromStore');
|
||||
|
||||
return view(
|
||||
'rules.rule.create',
|
||||
compact(
|
||||
'subTitleIcon', 'oldTriggers', 'returnToBill', 'preFilled', 'bill', 'oldActions', 'triggerCount', 'actionCount', 'ruleGroup',
|
||||
'subTitle'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a given rule.
|
||||
*
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function delete(Rule $rule)
|
||||
{
|
||||
$subTitle = (string)trans('firefly.delete_rule', ['title' => $rule->title]);
|
||||
|
||||
// put previous url in session
|
||||
$this->rememberPreviousUri('rules.delete.uri');
|
||||
|
||||
return view('rules.rule.delete', compact('rule', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually destroy the given rule.
|
||||
*
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function destroy(Rule $rule): RedirectResponse
|
||||
{
|
||||
$title = $rule->title;
|
||||
$this->ruleRepos->destroy($rule);
|
||||
|
||||
session()->flash('success', (string)trans('firefly.deleted_rule', ['title' => $title]));
|
||||
app('preferences')->mark();
|
||||
|
||||
return redirect($this->getPreviousUri('rules.delete.uri'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function down(Rule $rule)
|
||||
{
|
||||
$this->ruleRepos->moveDown($rule);
|
||||
|
||||
return redirect(route('rules.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function edit(Request $request, Rule $rule)
|
||||
{
|
||||
$triggerCount = 0;
|
||||
$actionCount = 0;
|
||||
$oldActions = [];
|
||||
$oldTriggers = [];
|
||||
// has old input?
|
||||
if (\count($request->old()) > 0) {
|
||||
$oldTriggers = $this->getPreviousTriggers($request);
|
||||
$triggerCount = \count($oldTriggers);
|
||||
$oldActions = $this->getPreviousActions($request);
|
||||
$actionCount = \count($oldActions);
|
||||
}
|
||||
|
||||
// overrule old input when it as no rule data:
|
||||
if (0 === $triggerCount && 0 === $actionCount) {
|
||||
$oldTriggers = $this->getCurrentTriggers($rule);
|
||||
$triggerCount = \count($oldTriggers);
|
||||
$oldActions = $this->getCurrentActions($rule);
|
||||
$actionCount = \count($oldActions);
|
||||
}
|
||||
|
||||
$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,
|
||||
|
||||
];
|
||||
|
||||
// get rule trigger for update / store-journal:
|
||||
$primaryTrigger = $this->ruleRepos->getPrimaryTrigger($rule);
|
||||
$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')) {
|
||||
$this->rememberPreviousUri('rules.edit.uri');
|
||||
}
|
||||
session()->forget('rules.edit.fromUpdate');
|
||||
|
||||
$request->session()->flash('preFilled', $preFilled);
|
||||
|
||||
return view('rules.rule.edit', compact('rule', 'subTitle', 'primaryTrigger', 'oldTriggers', 'oldActions', 'triggerCount', 'actionCount'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the given rule on a set of existing transactions.
|
||||
*
|
||||
* @param SelectTransactionsRequest $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*
|
||||
* @internal param RuleGroup $ruleGroup
|
||||
*/
|
||||
public function execute(SelectTransactionsRequest $request, Rule $rule): RedirectResponse
|
||||
{
|
||||
// Get parameters specified by the user
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$accounts = $this->accountRepos->getAccountsById($request->get('accounts'));
|
||||
$startDate = new Carbon($request->get('start_date'));
|
||||
$endDate = new Carbon($request->get('end_date'));
|
||||
|
||||
// Create a job to do the work asynchronously
|
||||
$job = new ExecuteRuleOnExistingTransactions($rule);
|
||||
|
||||
// Apply parameters to the job
|
||||
$job->setUser($user);
|
||||
$job->setAccounts($accounts);
|
||||
$job->setStartDate($startDate);
|
||||
$job->setEndDate($endDate);
|
||||
|
||||
// Dispatch a new job to execute it in a queue
|
||||
$this->dispatch($job);
|
||||
|
||||
// Tell the user that the job is queued
|
||||
session()->flash('success', (string)trans('firefly.applied_rule_selection', ['title' => $rule->title]));
|
||||
|
||||
return redirect()->route('rules.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->createDefaultRuleGroup();
|
||||
$this->createDefaultRule();
|
||||
$ruleGroups = $this->ruleGroupRepos->getRuleGroupsWithRules($user);
|
||||
|
||||
return view('rules.index', compact('ruleGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function reorderRuleActions(Request $request, Rule $rule): JsonResponse
|
||||
{
|
||||
$ids = $request->get('actions');
|
||||
if (\is_array($ids)) {
|
||||
$this->ruleRepos->reorderRuleActions($rule, $ids);
|
||||
}
|
||||
|
||||
return response()->json('true');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function reorderRuleTriggers(Request $request, Rule $rule): JsonResponse
|
||||
{
|
||||
$ids = $request->get('triggers');
|
||||
if (\is_array($ids)) {
|
||||
$this->ruleRepos->reorderRuleTriggers($rule, $ids);
|
||||
}
|
||||
|
||||
return response()->json('true');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function selectTransactions(Rule $rule)
|
||||
{
|
||||
// does the user have shared accounts?
|
||||
$first = session('first')->format('Y-m-d');
|
||||
$today = Carbon::create()->format('Y-m-d');
|
||||
$subTitle = (string)trans('firefly.apply_rule_selection', ['title' => $rule->title]);
|
||||
|
||||
return view('rules.rule.select-transactions', compact('first', 'today', 'rule', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleFormRequest $request
|
||||
*
|
||||
* @return RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function store(RuleFormRequest $request)
|
||||
{
|
||||
$data = $request->getRuleData();
|
||||
$rule = $this->ruleRepos->store($data);
|
||||
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
|
||||
}
|
||||
|
||||
// redirect to new bill creation.
|
||||
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')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
session()->put('rules.create.fromStore', true);
|
||||
$redirect = redirect(route('rules.create', [$data['rule_group_id']]))->withInput();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows the user to test a certain set of rule triggers. The rule triggers are passed along
|
||||
* using the URL parameters (GET), and are usually put there using a Javascript thing.
|
||||
*
|
||||
* This method will parse and validate those rules and create a "TransactionMatcher" which will attempt
|
||||
* to find transaction journals matching the users input. A maximum range of transactions to try (range) and
|
||||
* a maximum number of transactions to return (limit) are set as well.
|
||||
*
|
||||
* @param TestRuleFormRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function testTriggers(TestRuleFormRequest $request): JsonResponse
|
||||
{
|
||||
// build trigger array from response
|
||||
$triggers = $this->getValidTriggerList($request);
|
||||
|
||||
if (0 === \count($triggers)) {
|
||||
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$limit = (int)config('firefly.test-triggers.limit');
|
||||
$range = (int)config('firefly.test-triggers.range');
|
||||
$matchingTransactions = new Collection;
|
||||
/** @var TransactionMatcher $matcher */
|
||||
$matcher = app(TransactionMatcher::class);
|
||||
$matcher->setLimit($limit);
|
||||
$matcher->setRange($range);
|
||||
$matcher->setTriggers($triggers);
|
||||
try {
|
||||
$matchingTransactions = $matcher->findTransactionsByTriggers();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (FireflyException $exception) {
|
||||
Log::error(sprintf('Could not grab transactions in testTriggers(): %s', $exception->getMessage()));
|
||||
Log::error($exception->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
|
||||
// Warn the user if only a subset of transactions is returned
|
||||
$warning = '';
|
||||
if ($matchingTransactions->count() === $limit) {
|
||||
$warning = (string)trans('firefly.warning_transaction_subset', ['max_num_transactions' => $limit]); // @codeCoverageIgnore
|
||||
}
|
||||
if (0 === $matchingTransactions->count()) {
|
||||
$warning = (string)trans('firefly.warning_no_matching_transactions', ['num_transactions' => $range]); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// Return json response
|
||||
$view = 'ERROR, see logs.';
|
||||
try {
|
||||
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $exception) {
|
||||
Log::error(sprintf('Could not render view in testTriggers(): %s', $exception->getMessage()));
|
||||
Log::error($exception->getTraceAsString());
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return response()->json(['html' => $view, 'warning' => $warning]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows the user to test a certain set of rule triggers. The rule triggers are grabbed from
|
||||
* the rule itself.
|
||||
*
|
||||
* This method will parse and validate those rules and create a "TransactionMatcher" which will attempt
|
||||
* to find transaction journals matching the users input. A maximum range of transactions to try (range) and
|
||||
* a maximum number of transactions to return (limit) are set as well.
|
||||
*
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function testTriggersByRule(Rule $rule): JsonResponse
|
||||
{
|
||||
$triggers = $rule->ruleTriggers;
|
||||
|
||||
if (0 === \count($triggers)) {
|
||||
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$limit = (int)config('firefly.test-triggers.limit');
|
||||
$range = (int)config('firefly.test-triggers.range');
|
||||
$matchingTransactions = new Collection;
|
||||
|
||||
/** @var TransactionMatcher $matcher */
|
||||
$matcher = app(TransactionMatcher::class);
|
||||
$matcher->setLimit($limit);
|
||||
$matcher->setRange($range);
|
||||
$matcher->setRule($rule);
|
||||
try {
|
||||
$matchingTransactions = $matcher->findTransactionsByRule();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (FireflyException $exception) {
|
||||
Log::error(sprintf('Could not grab transactions in testTriggersByRule(): %s', $exception->getMessage()));
|
||||
Log::error($exception->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// Warn the user if only a subset of transactions is returned
|
||||
$warning = '';
|
||||
if ($matchingTransactions->count() === $limit) {
|
||||
$warning = (string)trans('firefly.warning_transaction_subset', ['max_num_transactions' => $limit]); // @codeCoverageIgnore
|
||||
}
|
||||
if (0 === $matchingTransactions->count()) {
|
||||
$warning = (string)trans('firefly.warning_no_matching_transactions', ['num_transactions' => $range]); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// Return json response
|
||||
$view = 'ERROR, see logs.';
|
||||
try {
|
||||
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $exception) {
|
||||
Log::error(sprintf('Could not render view in testTriggersByRule(): %s', $exception->getMessage()));
|
||||
Log::error($exception->getTraceAsString());
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return response()->json(['html' => $view, 'warning' => $warning]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function up(Rule $rule)
|
||||
{
|
||||
$this->ruleRepos->moveUp($rule);
|
||||
|
||||
return redirect(route('rules.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleFormRequest $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse|\Illuminate\Routing\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;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function createDefaultRule(): void
|
||||
{
|
||||
if (0 === $this->ruleRepos->count()) {
|
||||
$data = [
|
||||
'rule_group_id' => $this->ruleRepos->getFirstRuleGroup()->id,
|
||||
'stop-processing' => 0,
|
||||
'title' => (string)trans('firefly.default_rule_name'),
|
||||
'description' => (string)trans('firefly.default_rule_description'),
|
||||
'trigger' => 'store-journal',
|
||||
'strict' => true,
|
||||
'rule-triggers' => [
|
||||
[
|
||||
'name' => 'description_is',
|
||||
'value' => (string)trans('firefly.default_rule_trigger_description'),
|
||||
'stop-processing' => false,
|
||||
|
||||
],
|
||||
[
|
||||
'name' => 'from_account_is',
|
||||
'value' => (string)trans('firefly.default_rule_trigger_from_account'),
|
||||
'stop-processing' => false,
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
'rule-actions' => [
|
||||
[
|
||||
'name' => 'prepend_description',
|
||||
'value' => (string)trans('firefly.default_rule_action_prepend'),
|
||||
'stop-processing' => false,
|
||||
],
|
||||
[
|
||||
'name' => 'set_category',
|
||||
'value' => (string)trans('firefly.default_rule_action_set_category'),
|
||||
'stop-processing' => false,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->ruleRepos->store($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function createDefaultRuleGroup(): void
|
||||
{
|
||||
if (0 === $this->ruleGroupRepos->count()) {
|
||||
$data = [
|
||||
'title' => (string)trans('firefly.default_rule_group_name'),
|
||||
'description' => (string)trans('firefly.default_rule_group_description'),
|
||||
];
|
||||
|
||||
$this->ruleGroupRepos->store($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getActionsForBill(Bill $bill): array
|
||||
{
|
||||
$actions = [];
|
||||
try {
|
||||
$actions[] = view(
|
||||
'rules.partials.action',
|
||||
[
|
||||
'oldAction' => 'link_to_bill',
|
||||
'oldValue' => $bill->name,
|
||||
'oldChecked' => false,
|
||||
'count' => 1,
|
||||
]
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::error(sprintf('Throwable was thrown in getActionsForBill(): %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
|
||||
*/
|
||||
private function getCurrentActions(Rule $rule): array
|
||||
{
|
||||
$index = 0;
|
||||
$actions = [];
|
||||
|
||||
/** @var RuleAction $entry */
|
||||
foreach ($rule->ruleActions as $entry) {
|
||||
$count = ($index + 1);
|
||||
try {
|
||||
$actions[] = view(
|
||||
'rules.partials.action',
|
||||
[
|
||||
'oldAction' => $entry->action_type,
|
||||
'oldValue' => $entry->action_value,
|
||||
'oldChecked' => $entry->stop_processing,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Throwable was thrown in getCurrentActions(): %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
++$index;
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
private function getCurrentTriggers(Rule $rule): array
|
||||
{
|
||||
$index = 0;
|
||||
$triggers = [];
|
||||
|
||||
/** @var RuleTrigger $entry */
|
||||
foreach ($rule->ruleTriggers as $entry) {
|
||||
if ('user_action' !== $entry->trigger_type) {
|
||||
$count = ($index + 1);
|
||||
try {
|
||||
$triggers[] = view(
|
||||
'rules.partials.trigger',
|
||||
[
|
||||
'oldTrigger' => $entry->trigger_type,
|
||||
'oldValue' => $entry->trigger_value,
|
||||
'oldChecked' => $entry->stop_processing,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Throwable was thrown in getCurrentTriggers(): %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
++$index;
|
||||
}
|
||||
}
|
||||
|
||||
return $triggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
private function getPreviousActions(Request $request): array
|
||||
{
|
||||
$newIndex = 0;
|
||||
$actions = [];
|
||||
/** @var array $oldActions */
|
||||
$oldActions = \is_array($request->old('rule-action')) ? $request->old('rule-action') : [];
|
||||
foreach ($oldActions as $index => $entry) {
|
||||
$count = ($newIndex + 1);
|
||||
$checked = isset($request->old('rule-action-stop')[$index]) ? true : false;
|
||||
try {
|
||||
$actions[] = view(
|
||||
'rules.partials.action',
|
||||
[
|
||||
'oldAction' => $entry,
|
||||
'oldValue' => $request->old('rule-action-value')[$index],
|
||||
'oldChecked' => $checked,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Throwable was thrown in getPreviousActions(): %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
++$newIndex;
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
|
||||
*/
|
||||
private function getPreviousTriggers(Request $request): array
|
||||
{
|
||||
$newIndex = 0;
|
||||
$triggers = [];
|
||||
/** @var array $oldTriggers */
|
||||
$oldTriggers = \is_array($request->old('rule-trigger')) ? $request->old('rule-trigger') : [];
|
||||
foreach ($oldTriggers as $index => $entry) {
|
||||
$count = ($newIndex + 1);
|
||||
$oldChecked = isset($request->old('rule-trigger-stop')[$index]) ? true : false;
|
||||
try {
|
||||
$triggers[] = view(
|
||||
'rules.partials.trigger',
|
||||
[
|
||||
'oldTrigger' => $entry,
|
||||
'oldValue' => $request->old('rule-trigger-value')[$index],
|
||||
'oldChecked' => $oldChecked,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
++$newIndex;
|
||||
}
|
||||
|
||||
return $triggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create fake triggers to match the bill's properties
|
||||
*
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getTriggersForBill(Bill $bill): array
|
||||
{
|
||||
$triggers = [];
|
||||
/** @noinspection BadExceptionsProcessingInspection */
|
||||
try {
|
||||
$triggers[] = view(
|
||||
'rules.partials.trigger',
|
||||
[
|
||||
'oldTrigger' => 'currency_is',
|
||||
'oldValue' => $bill->transactionCurrency()->first()->name,
|
||||
'oldChecked' => false,
|
||||
'count' => 1,
|
||||
]
|
||||
)->render();
|
||||
|
||||
$triggers[] = view(
|
||||
'rules.partials.trigger',
|
||||
[
|
||||
'oldTrigger' => 'amount_more',
|
||||
'oldValue' => round($bill->amount_min, 12),
|
||||
'oldChecked' => false,
|
||||
'count' => 2,
|
||||
]
|
||||
)->render();
|
||||
|
||||
$triggers[] = view(
|
||||
'rules.partials.trigger',
|
||||
[
|
||||
'oldTrigger' => 'amount_less',
|
||||
'oldValue' => round($bill->amount_max, 12),
|
||||
'oldChecked' => false,
|
||||
'count' => 3,
|
||||
]
|
||||
)->render();
|
||||
|
||||
$triggers[] = view(
|
||||
'rules.partials.trigger',
|
||||
[
|
||||
'oldTrigger' => 'description_contains',
|
||||
'oldValue' => $bill->name, 12,
|
||||
'oldChecked' => false,
|
||||
'count' => 4,
|
||||
]
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Throwable was thrown in getTriggersForBill(): %s', $e->getMessage()));
|
||||
Log::debug($e->getTraceAsString());
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return $triggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TestRuleFormRequest $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getValidTriggerList(TestRuleFormRequest $request): array
|
||||
{
|
||||
$triggers = [];
|
||||
$data = [
|
||||
'rule-triggers' => $request->get('rule-trigger'),
|
||||
'rule-trigger-values' => $request->get('rule-trigger-value'),
|
||||
'rule-trigger-stop' => $request->get('rule-trigger-stop'),
|
||||
];
|
||||
if (\is_array($data['rule-triggers'])) {
|
||||
foreach ($data['rule-triggers'] as $index => $triggerType) {
|
||||
$data['rule-trigger-stop'][$index] = (int)($data['rule-trigger-stop'][$index] ?? 0.0);
|
||||
$triggers[] = [
|
||||
'type' => $triggerType,
|
||||
'value' => $data['rule-trigger-values'][$index],
|
||||
'stopProcessing' => 1 === (int)$data['rule-trigger-stop'][$index],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $triggers;
|
||||
}
|
||||
}
|
@ -35,6 +35,8 @@ use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class RuleGroupController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
|
||||
*/
|
||||
class RuleGroupController extends Controller
|
||||
{
|
||||
@ -231,6 +233,8 @@ class RuleGroupController extends Controller
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*/
|
||||
public function up(RuleGroupRepositoryInterface $repository, RuleGroup $ruleGroup)
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ class SearchController extends Controller
|
||||
* @param SearchInterface $searcher
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function search(Request $request, SearchInterface $searcher): JsonResponse
|
||||
{
|
||||
|
@ -166,7 +166,12 @@ class TagController extends Controller
|
||||
* @param Tag $tag
|
||||
* @param string|null $moment
|
||||
*
|
||||
* TODO will be cleaned up and separated
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function show(Request $request, Tag $tag, string $moment = null)
|
||||
{
|
||||
@ -286,6 +291,8 @@ class TagController extends Controller
|
||||
* @param Tag $tag
|
||||
*
|
||||
* @return Collection
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
private function getPeriodOverview(Tag $tag): Collection
|
||||
{
|
||||
|
@ -87,6 +87,8 @@ class BulkController extends Controller
|
||||
* @param BulkEditJournalRequest $request
|
||||
*
|
||||
* @return mixed
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function update(BulkEditJournalRequest $request)
|
||||
{
|
||||
|
@ -82,16 +82,14 @@ class ConvertController extends Controller
|
||||
$subTitle = (string)trans('firefly.convert_to_' . $destinationType->type, ['description' => $journal->description]);
|
||||
$subTitleIcon = 'fa-exchange';
|
||||
|
||||
// cannot convert to its own type.
|
||||
if ($sourceType->type === $destinationType->type) {
|
||||
if ($sourceType->type === $destinationType->type) { // cannot convert to its own type.
|
||||
Log::debug('This is already a transaction of the expected type..');
|
||||
session()->flash('info', (string)trans('firefly.convert_is_already_type_' . $destinationType->type));
|
||||
|
||||
return redirect(route('transactions.show', [$journal->id]));
|
||||
}
|
||||
|
||||
// cannot convert split.
|
||||
if ($journal->transactions()->count() > 2) {
|
||||
if ($journal->transactions()->count() > 2) { // cannot convert split.
|
||||
Log::info('This journal has more than two transactions.');
|
||||
session()->flash('error', (string)trans('firefly.cannot_convert_split_journal'));
|
||||
|
||||
@ -119,7 +117,8 @@ class ConvertController extends Controller
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws FireflyException
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function postIndex(Request $request, TransactionType $destinationType, TransactionJournal $journal)
|
||||
{
|
||||
@ -172,6 +171,9 @@ class ConvertController extends Controller
|
||||
* @return Account
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function getDestinationAccount(TransactionJournal $journal, TransactionType $destinationType, array $data): Account
|
||||
{
|
||||
@ -228,6 +230,9 @@ class ConvertController extends Controller
|
||||
* @return Account
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function getSourceAccount(TransactionJournal $journal, TransactionType $destinationType, array $data): Account
|
||||
{
|
||||
|
@ -101,13 +101,7 @@ class LinkController extends Controller
|
||||
|
||||
Log::debug('We are here (store)');
|
||||
$linkInfo = $request->getLinkInfo();
|
||||
if (0 === $linkInfo['transaction_journal_id']) {
|
||||
session()->flash('error', (string)trans('firefly.invalid_link_selection'));
|
||||
|
||||
return redirect(route('transactions.show', [$journal->id]));
|
||||
}
|
||||
$other = $this->journalRepository->findNull($linkInfo['transaction_journal_id']);
|
||||
|
||||
$other = $this->journalRepository->findNull($linkInfo['transaction_journal_id']);
|
||||
if (null === $other) {
|
||||
session()->flash('error', (string)trans('firefly.invalid_link_selection'));
|
||||
|
||||
|
@ -42,6 +42,8 @@ use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
|
||||
/**
|
||||
* Class MassController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class MassController extends Controller
|
||||
{
|
||||
@ -85,29 +87,24 @@ class MassController extends Controller
|
||||
* @param MassDeleteJournalRequest $request
|
||||
*
|
||||
* @return mixed
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function destroy(MassDeleteJournalRequest $request)
|
||||
{
|
||||
$ids = $request->get('confirm_mass_delete');
|
||||
$set = new Collection;
|
||||
$ids = $request->get('confirm_mass_delete');
|
||||
$count = 0;
|
||||
if (\is_array($ids)) {
|
||||
/** @var string $journalId */
|
||||
foreach ($ids as $journalId) {
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $this->repository->findNull((int)$journalId);
|
||||
if (null !== $journal && (int)$journalId === $journal->id) {
|
||||
$set->push($journal);
|
||||
$this->repository->destroy($journal);
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($journal);
|
||||
$count = 0;
|
||||
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($set as $journal) {
|
||||
$this->repository->destroy($journal);
|
||||
++$count;
|
||||
}
|
||||
|
||||
app('preferences')->mark();
|
||||
session()->flash('success', (string)trans('firefly.mass_deleted_transactions_success', ['amount' => $count]));
|
||||
@ -127,20 +124,16 @@ class MassController extends Controller
|
||||
$user = auth()->user();
|
||||
$subTitle = (string)trans('firefly.mass_edit_journals');
|
||||
|
||||
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$accounts = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
|
||||
// get budgets
|
||||
/** @var BudgetRepositoryInterface $budgetRepository */
|
||||
$budgetRepository = app(BudgetRepositoryInterface::class);
|
||||
$budgets = $budgetRepository->getBudgets();
|
||||
|
||||
// put previous url in session
|
||||
$this->rememberPreviousUri('transactions.mass-edit.uri');
|
||||
|
||||
// use the collector to get them.
|
||||
$transformer = new TransactionTransformer(new ParameterBag);
|
||||
/** @var JournalCollectorInterface $collector */
|
||||
$collector = app(JournalCollectorInterface::class);
|
||||
@ -148,12 +141,7 @@ class MassController extends Controller
|
||||
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
|
||||
$collector->setJournals($journals);
|
||||
$collector->addFilter(TransactionViewFilter::class);
|
||||
$collection = $collector->getJournals();
|
||||
|
||||
// add some filters:
|
||||
|
||||
|
||||
// transform to array
|
||||
$collection = $collector->getJournals();
|
||||
$transactions = $collection->map(
|
||||
function (Transaction $transaction) use ($transformer) {
|
||||
$transformed = $transformer->transform($transaction);
|
||||
@ -173,6 +161,8 @@ class MassController extends Controller
|
||||
* @param JournalRepositoryInterface $repository
|
||||
*
|
||||
* @return mixed
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function update(MassEditJournalRequest $request, JournalRepositoryInterface $repository)
|
||||
{
|
||||
|
@ -41,6 +41,8 @@ use View;
|
||||
|
||||
/**
|
||||
* Class SingleController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class SingleController extends Controller
|
||||
{
|
||||
@ -82,6 +84,8 @@ class SingleController extends Controller
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function cloneTransaction(TransactionJournal $journal)
|
||||
{
|
||||
@ -137,6 +141,8 @@ class SingleController extends Controller
|
||||
* @param string|null $what
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function create(Request $request, string $what = null)
|
||||
{
|
||||
@ -203,8 +209,6 @@ class SingleController extends Controller
|
||||
* @param TransactionJournal $transactionJournal
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @internal param JournalRepositoryInterface $repository
|
||||
*/
|
||||
public function destroy(TransactionJournal $transactionJournal): RedirectResponse
|
||||
{
|
||||
@ -229,6 +233,9 @@ class SingleController extends Controller
|
||||
* @param JournalRepositoryInterface $repository
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function edit(TransactionJournal $journal, JournalRepositoryInterface $repository)
|
||||
{
|
||||
@ -319,6 +326,10 @@ class SingleController extends Controller
|
||||
*
|
||||
* @return RedirectResponse
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
*
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function store(JournalFormRequest $request, JournalRepositoryInterface $repository): RedirectResponse
|
||||
{
|
||||
@ -377,6 +388,9 @@ class SingleController extends Controller
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function update(JournalFormRequest $request, JournalRepositoryInterface $repository, TransactionJournal $journal)
|
||||
{
|
||||
|
@ -42,6 +42,7 @@ use View;
|
||||
|
||||
/**
|
||||
* Class SplitController.
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class SplitController extends Controller
|
||||
{
|
||||
@ -122,6 +123,9 @@ class SplitController extends Controller
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function update(SplitJournalFormRequest $request, TransactionJournal $journal)
|
||||
{
|
||||
@ -216,6 +220,8 @@ class SplitController extends Controller
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function getTransactionDataFromJournal(TransactionJournal $journal): array
|
||||
{
|
||||
@ -253,6 +259,9 @@ class SplitController extends Controller
|
||||
* @param $old
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function updateWithPrevious($array, $old): array
|
||||
{
|
||||
|
@ -45,6 +45,8 @@ use View;
|
||||
|
||||
/**
|
||||
* Class TransactionController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class TransactionController extends Controller
|
||||
{
|
||||
@ -174,6 +176,7 @@ class TransactionController extends Controller
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function reorder(Request $request): JsonResponse
|
||||
{
|
||||
@ -241,6 +244,9 @@ class TransactionController extends Controller
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return Collection
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function getPeriodOverview(string $what, Carbon $date): Collection
|
||||
{
|
||||
@ -277,7 +283,6 @@ class TransactionController extends Controller
|
||||
'name' => $dateName,
|
||||
'sums' => $sums,
|
||||
'sum' => $sum,
|
||||
|
||||
'start' => $currentDate['start']->format('Y-m-d'),
|
||||
'end' => $currentDate['end']->format('Y-m-d'),
|
||||
]
|
||||
|
@ -41,7 +41,7 @@ class StartFireflySession extends StartSession
|
||||
{
|
||||
$uri = $request->fullUrl();
|
||||
$strpos = strpos($uri, 'jscript');
|
||||
if (false === $strpos && 'GET' === $request->method() && $request->route() && !$request->ajax()) {
|
||||
if (false === $strpos && 'GET' === $request->method() && !$request->ajax()) {
|
||||
$session->setPreviousUrl($uri);
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ class TrustProxies extends Middleware
|
||||
*
|
||||
* @var array|string
|
||||
*/
|
||||
protected $proxies;
|
||||
protected $proxies = [];
|
||||
|
||||
/**
|
||||
* TrustProxies constructor.
|
||||
@ -49,17 +49,8 @@ class TrustProxies extends Middleware
|
||||
*/
|
||||
public function __construct(Repository $config)
|
||||
{
|
||||
$trustedProxies = env('TRUSTED_PROXIES', null);
|
||||
if (false !== $trustedProxies && null !== $trustedProxies && \strlen($trustedProxies) > 0) {
|
||||
if ('*' === $trustedProxies || '**' === $trustedProxies) {
|
||||
$this->proxies = $trustedProxies;
|
||||
|
||||
}
|
||||
if ('*' !== $trustedProxies && '**' !== $trustedProxies) {
|
||||
$this->proxies = explode(',', $trustedProxies);
|
||||
}
|
||||
}
|
||||
|
||||
$trustedProxies = (string)env('TRUSTED_PROXIES', null);
|
||||
$this->proxies = explode(',', $trustedProxies);
|
||||
parent::__construct($config);
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ class JournalFormRequest extends Request
|
||||
* Returns and validates the data required to store a new journal. Can handle both single transaction journals and split journals.
|
||||
*
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function getJournalData(): array
|
||||
{
|
||||
@ -240,61 +242,79 @@ class JournalFormRequest extends Request
|
||||
$type = $data['what'] ?? 'invalid';
|
||||
Log::debug(sprintf('Type is %s', $type));
|
||||
if ('withdrawal' === $type) {
|
||||
|
||||
$selectedCurrency = (int)($data['amount_currency_id_amount'] ?? 0);
|
||||
$accountCurrency = (int)($data['source_account_currency'] ?? 0);
|
||||
Log::debug(sprintf('Selected currency is %d, account currency is %d', $selectedCurrency, $accountCurrency));
|
||||
$nativeAmount = (string)($data['native_amount'] ?? '');
|
||||
if ($selectedCurrency !== $accountCurrency && '' === $nativeAmount
|
||||
&& 0 !== $selectedCurrency
|
||||
&& 0 !== $accountCurrency
|
||||
) {
|
||||
Log::debug('ADD validation error on native_amount');
|
||||
$validator->errors()->add('native_amount', (string)trans('validation.numeric_native'));
|
||||
|
||||
return;
|
||||
}
|
||||
$this->validateWithdrawal($validator);
|
||||
}
|
||||
|
||||
// same thing for deposits:
|
||||
if ('deposit' === $type) {
|
||||
$selectedCurrency = (int)($data['amount_currency_id_amount'] ?? 0);
|
||||
$accountCurrency = (int)($data['destination_account_currency'] ?? 0);
|
||||
$nativeAmount = (string)($data['native_amount'] ?? '');
|
||||
if ($selectedCurrency !== $accountCurrency && '' === $nativeAmount
|
||||
&& 0 !== $selectedCurrency
|
||||
&& 0 !== $accountCurrency
|
||||
) {
|
||||
$validator->errors()->add('native_amount', (string)trans('validation.numeric_native'));
|
||||
|
||||
return;
|
||||
}
|
||||
$this->validateDeposit($validator);
|
||||
}
|
||||
|
||||
// and for transfers
|
||||
if ('transfer' === $type) {
|
||||
$this->validateTransfer($validator);
|
||||
}
|
||||
}
|
||||
|
||||
$sourceCurrency = (int)($data['source_account_currency'] ?? 0);
|
||||
$destinationCurrency = (int)($data['destination_account_currency'] ?? 0);
|
||||
$sourceAmount = (string)($data['source_amount'] ?? '');
|
||||
$destinationAmount = (string)($data['destination_amount'] ?? '');
|
||||
/**
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function validateDeposit(Validator $validator): void
|
||||
{
|
||||
$selectedCurrency = (int)($data['amount_currency_id_amount'] ?? 0);
|
||||
$accountCurrency = (int)($data['destination_account_currency'] ?? 0);
|
||||
$nativeAmount = (string)($data['native_amount'] ?? '');
|
||||
if ($selectedCurrency !== $accountCurrency && '' === $nativeAmount && 0 !== $selectedCurrency && 0 !== $accountCurrency) {
|
||||
$validator->errors()->add('native_amount', (string)trans('validation.numeric_native'));
|
||||
|
||||
Log::debug(sprintf('Source currency is %d, destination currency is %d', $sourceCurrency, $destinationCurrency));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ($sourceCurrency !== $destinationCurrency && '' === $sourceAmount
|
||||
&& 0 !== $sourceCurrency
|
||||
&& 0 !== $destinationCurrency
|
||||
) {
|
||||
$validator->errors()->add('source_amount', (string)trans('validation.numeric_source'));
|
||||
}
|
||||
/**
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function validateTransfer(Validator $validator): void
|
||||
{
|
||||
$sourceCurrency = (int)($data['source_account_currency'] ?? 0);
|
||||
$destinationCurrency = (int)($data['destination_account_currency'] ?? 0);
|
||||
$sourceAmount = (string)($data['source_amount'] ?? '');
|
||||
$destinationAmount = (string)($data['destination_amount'] ?? '');
|
||||
|
||||
if ($sourceCurrency !== $destinationCurrency && '' === $destinationAmount
|
||||
&& 0 !== $sourceCurrency
|
||||
&& 0 !== $destinationCurrency
|
||||
) {
|
||||
$validator->errors()->add('destination_amount', (string)trans('validation.numeric_destination'));
|
||||
$validator->errors()->add('destination_amount', (string)trans('validation.numeric', ['attribute' => 'destination_amount']));
|
||||
}
|
||||
Log::debug(sprintf('Source currency is %d, destination currency is %d', $sourceCurrency, $destinationCurrency));
|
||||
|
||||
if ($sourceCurrency !== $destinationCurrency && '' === $sourceAmount && 0 !== $sourceCurrency && 0 !== $destinationCurrency) {
|
||||
$validator->errors()->add('source_amount', (string)trans('validation.numeric_source'));
|
||||
}
|
||||
|
||||
if ($sourceCurrency !== $destinationCurrency && '' === $destinationAmount && 0 !== $sourceCurrency && 0 !== $destinationCurrency) {
|
||||
$validator->errors()->add('destination_amount', (string)trans('validation.numeric_destination'));
|
||||
$validator->errors()->add('destination_amount', (string)trans('validation.numeric', ['attribute' => 'destination_amount']));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Validator $validator
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function validateWithdrawal(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$selectedCurrency = (int)($data['amount_currency_id_amount'] ?? 0);
|
||||
$accountCurrency = (int)($data['source_account_currency'] ?? 0);
|
||||
Log::debug(sprintf('Selected currency is %d, account currency is %d', $selectedCurrency, $accountCurrency));
|
||||
$nativeAmount = (string)($data['native_amount'] ?? '');
|
||||
if ($selectedCurrency !== $accountCurrency && '' === $nativeAmount
|
||||
&& 0 !== $selectedCurrency
|
||||
&& 0 !== $accountCurrency
|
||||
) {
|
||||
Log::debug('ADD validation error on native_amount');
|
||||
$validator->errors()->add('native_amount', (string)trans('validation.numeric_native'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -48,6 +48,9 @@ class RecurrenceFormRequest extends Request
|
||||
/**
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
@ -132,6 +135,10 @@ class RecurrenceFormRequest extends Request
|
||||
/**
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.NPathComplexity)
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
@ -222,6 +229,8 @@ class RecurrenceFormRequest extends Request
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function parseRepetitionData(): array
|
||||
{
|
||||
|
@ -27,6 +27,8 @@ use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
/**
|
||||
* Class Request.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.NumberOfChildren)
|
||||
*/
|
||||
class Request extends FormRequest
|
||||
{
|
||||
@ -71,6 +73,8 @@ class Request extends FormRequest
|
||||
* @param string $field
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function string(string $field): string
|
||||
{
|
||||
|
@ -40,6 +40,9 @@ class RuleFormRequest extends Request
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function getRuleData(): array
|
||||
{
|
||||
|
@ -40,6 +40,9 @@ class SplitJournalFormRequest extends Request
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
@ -147,6 +150,8 @@ class SplitJournalFormRequest extends Request
|
||||
|
||||
/**
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
protected function sameAccounts(Validator $validator): void
|
||||
{
|
||||
|
@ -36,7 +36,6 @@ use Illuminate\Support\Collection;
|
||||
/**
|
||||
* Interface RecurringRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\Recurring
|
||||
*/
|
||||
interface RecurringRepositoryInterface
|
||||
{
|
||||
|
@ -41,7 +41,6 @@ use Log;
|
||||
/**
|
||||
* Trait RecurringTransactionTrait
|
||||
*
|
||||
* @package FireflyIII\Services\Internal\Support
|
||||
*/
|
||||
trait RecurringTransactionTrait
|
||||
{
|
||||
|
@ -30,7 +30,6 @@ use Log;
|
||||
/**
|
||||
* Trait TransactionTypeTrait
|
||||
*
|
||||
* @package FireflyIII\Services\Internal\Support
|
||||
*/
|
||||
trait TransactionTypeTrait
|
||||
{
|
||||
|
@ -23,8 +23,12 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Support\Binder;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Routing\Route;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ImportProvider.
|
||||
@ -40,10 +44,63 @@ class ImportProvider implements BinderInterface
|
||||
*/
|
||||
public static function routeBinder(string $value, Route $route): string
|
||||
{
|
||||
$providers = array_keys((array)config('import.enabled'));
|
||||
$providers = array_keys(self::getProviders());
|
||||
if (\in_array($value, $providers, true)) {
|
||||
return $value;
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getProviders(): array
|
||||
{
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
// get and filter all import routines:
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
/** @var array $config */
|
||||
$providerNames = array_keys(config('import.enabled'));
|
||||
$providers = [];
|
||||
$isDemoUser = $repository->hasRole($user, 'demo');
|
||||
$isDebug = (bool)config('app.debug');
|
||||
foreach ($providerNames as $providerName) {
|
||||
//Log::debug(sprintf('Now with provider %s', $providerName));
|
||||
// only consider enabled providers
|
||||
$enabled = (bool)config(sprintf('import.enabled.%s', $providerName));
|
||||
$allowedForDemo = (bool)config(sprintf('import.allowed_for_demo.%s', $providerName));
|
||||
$allowedForUser = (bool)config(sprintf('import.allowed_for_user.%s', $providerName));
|
||||
if (false === $enabled) {
|
||||
//Log::debug('Provider is not enabled. NEXT!');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (true === $isDemoUser && false === $allowedForDemo) {
|
||||
//Log::debug('User is demo and this provider is not allowed for demo user. NEXT!');
|
||||
continue;
|
||||
}
|
||||
if (false === $isDemoUser && false === $allowedForUser && false === $isDebug) {
|
||||
//Log::debug('User is not demo and this provider is not allowed for such users. NEXT!');
|
||||
continue; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$providers[$providerName] = [
|
||||
'has_prereq' => (bool)config('import.has_prereq.' . $providerName),
|
||||
];
|
||||
$class = (string)config(sprintf('import.prerequisites.%s', $providerName));
|
||||
$result = false;
|
||||
if ('' !== $class && class_exists($class)) {
|
||||
//Log::debug('Will not check prerequisites.');
|
||||
/** @var PrerequisitesInterface $object */
|
||||
$object = app($class);
|
||||
$object->setUser($user);
|
||||
$result = $object->isComplete();
|
||||
}
|
||||
$providers[$providerName]['prereq_complete'] = $result;
|
||||
}
|
||||
Log::debug(sprintf('Enabled providers: %s', json_encode(array_keys($providers))));
|
||||
|
||||
return $providers;
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ class ExpandedForm
|
||||
* @param null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function activeAssetAccountList(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -93,7 +93,7 @@ class ExpandedForm
|
||||
*
|
||||
* @return string
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function amount(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -106,7 +106,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function amountNoCurrency(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -145,7 +145,7 @@ class ExpandedForm
|
||||
* @param null $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function assetAccountCheckList(string $name, $options = null): string
|
||||
{
|
||||
@ -183,7 +183,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function assetAccountList(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -225,7 +225,7 @@ class ExpandedForm
|
||||
*
|
||||
* @return string
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function balance(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -239,7 +239,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function checkbox(string $name, $value = 1, $checked = null, $options = []): string
|
||||
{
|
||||
@ -268,7 +268,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function currencyList(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -293,7 +293,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function currencyListEmpty(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -320,7 +320,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function date(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -339,7 +339,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function file(string $name, array $options = []): string
|
||||
{
|
||||
@ -357,7 +357,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function integer(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -377,7 +377,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function location(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -450,7 +450,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function multiRadio(string $name, array $list = [], $selected = null, array $options = []): string
|
||||
{
|
||||
@ -472,7 +472,7 @@ class ExpandedForm
|
||||
*
|
||||
* @return string
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function nonSelectableAmount(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -501,7 +501,7 @@ class ExpandedForm
|
||||
*
|
||||
* @return string
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function nonSelectableBalance(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -530,7 +530,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function number(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -551,7 +551,7 @@ class ExpandedForm
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function optionsList(string $type, string $name): string
|
||||
{
|
||||
@ -565,7 +565,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function password(string $name, array $options = null): string
|
||||
{
|
||||
@ -584,7 +584,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function piggyBankList(string $name, $value = null, array $options = null): string
|
||||
{
|
||||
@ -610,7 +610,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function ruleGroupList(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -664,7 +664,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function select(string $name, array $list = [], $selected = null, array $options = []): string
|
||||
{
|
||||
@ -684,7 +684,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function staticText(string $name, $value, array $options = []): string
|
||||
{
|
||||
@ -702,7 +702,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function tags(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -722,7 +722,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function text(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -741,7 +741,7 @@ class ExpandedForm
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
public function textarea(string $name, $value = null, array $options = []): string
|
||||
{
|
||||
@ -843,7 +843,7 @@ class ExpandedForm
|
||||
* @return string
|
||||
*
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
* @throws \Throwable
|
||||
|
||||
*/
|
||||
private function currencyField(string $name, string $view, $value = null, array $options = []): string
|
||||
{
|
||||
|
@ -29,7 +29,6 @@ use Log;
|
||||
/**
|
||||
* Trait DateCalculation
|
||||
*
|
||||
* @package FireflyIII\Support\Http\Controllers
|
||||
*/
|
||||
trait DateCalculation
|
||||
{
|
||||
|
177
app/Support/Http/Controllers/RuleManagement.php
Normal file
177
app/Support/Http/Controllers/RuleManagement.php
Normal file
@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/**
|
||||
* RuleManagement.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Http\Controllers;
|
||||
|
||||
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Trait RuleManagement
|
||||
*
|
||||
* @package FireflyIII\Support\Http\Controllers
|
||||
*/
|
||||
trait RuleManagement
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function createDefaultRule(): void
|
||||
{
|
||||
/** @var RuleRepositoryInterface $ruleRepository */
|
||||
$ruleRepository = app(RuleRepositoryInterface::class);
|
||||
if (0 === $ruleRepository->count()) {
|
||||
$data = [
|
||||
'rule_group_id' => $ruleRepository->getFirstRuleGroup()->id,
|
||||
'stop-processing' => 0,
|
||||
'title' => (string)trans('firefly.default_rule_name'),
|
||||
'description' => (string)trans('firefly.default_rule_description'),
|
||||
'trigger' => 'store-journal',
|
||||
'strict' => true,
|
||||
'rule-triggers' => [
|
||||
[
|
||||
'name' => 'description_is',
|
||||
'value' => (string)trans('firefly.default_rule_trigger_description'),
|
||||
'stop-processing' => false,
|
||||
|
||||
],
|
||||
[
|
||||
'name' => 'from_account_is',
|
||||
'value' => (string)trans('firefly.default_rule_trigger_from_account'),
|
||||
'stop-processing' => false,
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
'rule-actions' => [
|
||||
[
|
||||
'name' => 'prepend_description',
|
||||
'value' => (string)trans('firefly.default_rule_action_prepend'),
|
||||
'stop-processing' => false,
|
||||
],
|
||||
[
|
||||
'name' => 'set_category',
|
||||
'value' => (string)trans('firefly.default_rule_action_set_category'),
|
||||
'stop-processing' => false,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$ruleRepository->store($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
protected function getPreviousActions(Request $request): array
|
||||
{
|
||||
$newIndex = 0;
|
||||
$actions = [];
|
||||
/** @var array $oldActions */
|
||||
$oldActions = \is_array($request->old('rule-action')) ? $request->old('rule-action') : [];
|
||||
foreach ($oldActions as $index => $entry) {
|
||||
$count = ($newIndex + 1);
|
||||
$checked = isset($request->old('rule-action-stop')[$index]) ? true : false;
|
||||
try {
|
||||
$actions[] = view(
|
||||
'rules.partials.action',
|
||||
[
|
||||
'oldAction' => $entry,
|
||||
'oldValue' => $request->old('rule-action-value')[$index],
|
||||
'oldChecked' => $checked,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Throwable was thrown in getPreviousActions(): %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
++$newIndex;
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getPreviousTriggers(Request $request): array
|
||||
{
|
||||
$newIndex = 0;
|
||||
$triggers = [];
|
||||
/** @var array $oldTriggers */
|
||||
$oldTriggers = \is_array($request->old('rule-trigger')) ? $request->old('rule-trigger') : [];
|
||||
foreach ($oldTriggers as $index => $entry) {
|
||||
$count = ($newIndex + 1);
|
||||
$oldChecked = isset($request->old('rule-trigger-stop')[$index]) ? true : false;
|
||||
try {
|
||||
$triggers[] = view(
|
||||
'rules.partials.trigger',
|
||||
[
|
||||
'oldTrigger' => $entry,
|
||||
'oldValue' => $request->old('rule-trigger-value')[$index],
|
||||
'oldChecked' => $oldChecked,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $e) {
|
||||
Log::debug(sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
++$newIndex;
|
||||
}
|
||||
|
||||
return $triggers;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function createDefaultRuleGroup(): void
|
||||
{
|
||||
/** @var RuleGroupRepositoryInterface $repository */
|
||||
$repository = app(RuleGroupRepositoryInterface::class);
|
||||
if (0 === $repository->count()) {
|
||||
$data = [
|
||||
'title' => (string)trans('firefly.default_rule_group_name'),
|
||||
'description' => (string)trans('firefly.default_rule_group_description'),
|
||||
];
|
||||
|
||||
$repository->store($data);
|
||||
}
|
||||
}
|
||||
}
|
@ -32,7 +32,6 @@ use Log;
|
||||
/**
|
||||
* Trait GetSpectreTokenTrait
|
||||
*
|
||||
* @package FireflyIII\Support\Import\Information
|
||||
*/
|
||||
trait GetSpectreTokenTrait
|
||||
{
|
||||
|
@ -33,7 +33,6 @@ use InvalidArgumentException;
|
||||
*
|
||||
* Contains advanced validation rules used in validation of new and existing recurrences.
|
||||
*
|
||||
* @package FireflyIII\Validation
|
||||
*/
|
||||
trait RecurrenceValidation
|
||||
{
|
||||
|
@ -33,8 +33,6 @@ use Log;
|
||||
|
||||
/**
|
||||
* Trait TransactionValidation
|
||||
*
|
||||
* @package FireflyIII\Validation
|
||||
*/
|
||||
trait TransactionValidation
|
||||
{
|
||||
|
13
composer.lock
generated
13
composer.lock
generated
@ -5126,12 +5126,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Roave/SecurityAdvisories.git",
|
||||
"reference": "731d60f7fc78a8816dae7049df255cd55e30c313"
|
||||
"reference": "053766d789f6393e5bc0896635d35abf8d2d362e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/731d60f7fc78a8816dae7049df255cd55e30c313",
|
||||
"reference": "731d60f7fc78a8816dae7049df255cd55e30c313",
|
||||
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/053766d789f6393e5bc0896635d35abf8d2d362e",
|
||||
"reference": "053766d789f6393e5bc0896635d35abf8d2d362e",
|
||||
"shasum": ""
|
||||
},
|
||||
"conflict": {
|
||||
@ -5180,7 +5180,7 @@
|
||||
"kreait/firebase-php": ">=3.2,<3.8.1",
|
||||
"laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15",
|
||||
"laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
|
||||
"magento/magento1ce": ">=1.5.0.1,<1.9.3.2",
|
||||
"magento/magento1ce": "<1.9.3.9",
|
||||
"magento/magento1ee": ">=1.9,<1.14.3.2",
|
||||
"magento/product-community-edition": ">=2,<2.2.5",
|
||||
"monolog/monolog": ">=1.8,<1.12",
|
||||
@ -5238,7 +5238,8 @@
|
||||
"thelia/thelia": ">=2.1,<2.1.2|>=2.1.0-beta1,<2.1.3",
|
||||
"titon/framework": ">=0,<9.9.99",
|
||||
"twig/twig": "<1.20",
|
||||
"typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.22|>=8,<8.7.5",
|
||||
"typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.30|>=8,<8.7.17|>=9,<9.3.2",
|
||||
"typo3/cms-core": ">=8,<8.7.17|>=9,<9.3.2",
|
||||
"typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.10|>=3.1,<3.1.7|>=3.2,<3.2.7|>=3.3,<3.3.5",
|
||||
"typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4",
|
||||
"willdurand/js-translation-bundle": "<2.1.1",
|
||||
@ -5287,7 +5288,7 @@
|
||||
}
|
||||
],
|
||||
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
|
||||
"time": "2018-07-09T14:09:25+00:00"
|
||||
"time": "2018-07-18T13:51:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/code-unit-reverse-lookup",
|
||||
|
Loading…
Reference in New Issue
Block a user