diff --git a/app/Http/Controllers/Import/IndexController.php b/app/Http/Controllers/Import/IndexController.php
index ba3c8913f4..9dd0691f07 100644
--- a/app/Http/Controllers/Import/IndexController.php
+++ b/app/Http/Controllers/Import/IndexController.php
@@ -26,11 +26,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
-use FireflyIII\Import\Routine\RoutineInterface;
-use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
-use Illuminate\Http\Request;
-use Preferences;
use View;
@@ -74,6 +70,24 @@ class IndexController extends Controller
{
$importJob = $this->repository->create($importProvider);
+ // if job provider has no prerequisites:
+ if (!(bool)config(sprintf('import.has_prereq.%s', $importProvider))) {
+
+
+ // if job provider also has no configuration:
+ if (!(bool)config(sprintf('import.has_config.%s', $importProvider))) {
+ $this->repository->updateStatus($importJob, 'ready_to_run');
+
+ return redirect(route('import.job.status.index', [$importJob->key]));
+ }
+
+ // update job to say "has_prereq".
+ $this->repository->setStatus($importJob, 'has_prereq');
+
+ // redirect to job configuration.
+ return redirect(route('import.job.configuration.index', [$importJob->key]));
+ }
+
// if need to set prerequisites, do that first.
$class = (string)config(sprintf('import.prerequisites.%s', $importProvider));
if (!class_exists($class)) {
@@ -87,6 +101,7 @@ class IndexController extends Controller
// redirect to global prerequisites
return redirect(route('import.prerequisites.index', [$importProvider, $importJob->key]));
}
+
// update job to say "has_prereq".
$this->repository->setStatus($importJob, 'has_prereq');
@@ -158,7 +173,7 @@ class IndexController extends Controller
if ($class !== '' && class_exists($class)) {
/** @var PrerequisitesInterface $object */
$object = app($class);
- $object->setuser(auth()->user());
+ $object->setUser(auth()->user());
$result = $object->isComplete();
}
$providers[$name]['prereq_complete'] = $result;
@@ -169,72 +184,72 @@ class IndexController extends Controller
return view('import.index', compact('subTitle', 'subTitleIcon', 'providers'));
}
-//
-// /**
-// * @param Request $request
-// * @param string $bank
-// *
-// * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
-// */
-// public function reset(Request $request, string $bank)
-// {
-// if ($bank === 'bunq') {
-// // remove bunq related preferences.
-// Preferences::delete('bunq_api_key');
-// Preferences::delete('bunq_server_public_key');
-// Preferences::delete('bunq_private_key');
-// Preferences::delete('bunq_public_key');
-// Preferences::delete('bunq_installation_token');
-// Preferences::delete('bunq_installation_id');
-// Preferences::delete('bunq_device_server_id');
-// Preferences::delete('external_ip');
-//
-// }
-//
-// if ($bank === 'spectre') {
-// // remove spectre related preferences:
-// Preferences::delete('spectre_client_id');
-// Preferences::delete('spectre_app_secret');
-// Preferences::delete('spectre_service_secret');
-// Preferences::delete('spectre_app_id');
-// Preferences::delete('spectre_secret');
-// Preferences::delete('spectre_private_key');
-// Preferences::delete('spectre_public_key');
-// Preferences::delete('spectre_customer');
-// }
-//
-// Preferences::mark();
-// $request->session()->flash('info', (string)trans('firefly.settings_reset_for_' . $bank));
-//
-// return redirect(route('import.index'));
-//
-// }
+ //
+ // /**
+ // * @param Request $request
+ // * @param string $bank
+ // *
+ // * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+ // */
+ // public function reset(Request $request, string $bank)
+ // {
+ // if ($bank === 'bunq') {
+ // // remove bunq related preferences.
+ // Preferences::delete('bunq_api_key');
+ // Preferences::delete('bunq_server_public_key');
+ // Preferences::delete('bunq_private_key');
+ // Preferences::delete('bunq_public_key');
+ // Preferences::delete('bunq_installation_token');
+ // Preferences::delete('bunq_installation_id');
+ // Preferences::delete('bunq_device_server_id');
+ // Preferences::delete('external_ip');
+ //
+ // }
+ //
+ // if ($bank === 'spectre') {
+ // // remove spectre related preferences:
+ // Preferences::delete('spectre_client_id');
+ // Preferences::delete('spectre_app_secret');
+ // Preferences::delete('spectre_service_secret');
+ // Preferences::delete('spectre_app_id');
+ // Preferences::delete('spectre_secret');
+ // Preferences::delete('spectre_private_key');
+ // Preferences::delete('spectre_public_key');
+ // Preferences::delete('spectre_customer');
+ // }
+ //
+ // Preferences::mark();
+ // $request->session()->flash('info', (string)trans('firefly.settings_reset_for_' . $bank));
+ //
+ // return redirect(route('import.index'));
+ //
+ // }
-// /**
-// * @param ImportJob $job
-// *
-// * @return \Illuminate\Http\JsonResponse
-// *
-// * @throws FireflyException
-// */
-// public function start(ImportJob $job)
-// {
-// $type = $job->file_type;
-// $key = sprintf('import.routine.%s', $type);
-// $className = config($key);
-// if (null === $className || !class_exists($className)) {
-// throw new FireflyException(sprintf('Cannot find import routine class for job of type "%s".', $type)); // @codeCoverageIgnore
-// }
-//
-// /** @var RoutineInterface $routine */
-// $routine = app($className);
-// $routine->setJob($job);
-// $result = $routine->run();
-//
-// if ($result) {
-// return response()->json(['run' => 'ok']);
-// }
-//
-// throw new FireflyException('Job did not complete successfully. Please review the log files.');
-// }
+ // /**
+ // * @param ImportJob $job
+ // *
+ // * @return \Illuminate\Http\JsonResponse
+ // *
+ // * @throws FireflyException
+ // */
+ // public function start(ImportJob $job)
+ // {
+ // $type = $job->file_type;
+ // $key = sprintf('import.routine.%s', $type);
+ // $className = config($key);
+ // if (null === $className || !class_exists($className)) {
+ // throw new FireflyException(sprintf('Cannot find import routine class for job of type "%s".', $type)); // @codeCoverageIgnore
+ // }
+ //
+ // /** @var RoutineInterface $routine */
+ // $routine = app($className);
+ // $routine->setJob($job);
+ // $result = $routine->run();
+ //
+ // if ($result) {
+ // return response()->json(['run' => 'ok']);
+ // }
+ //
+ // throw new FireflyException('Job did not complete successfully. Please review the log files.');
+ // }
}
diff --git a/app/Http/Controllers/Import/JobConfigurationController.php b/app/Http/Controllers/Import/JobConfigurationController.php
index aaa1626ec1..7261da9bc1 100644
--- a/app/Http/Controllers/Import/JobConfigurationController.php
+++ b/app/Http/Controllers/Import/JobConfigurationController.php
@@ -69,6 +69,15 @@ class JobConfigurationController extends Controller
*/
public function index(ImportJob $job)
{
+ // if provider has no config, just push it through
+ $importProvider = $job->provider;
+ if (!(bool)config(sprintf('import.has_config.%s', $importProvider))) {
+ $this->repository->updateStatus($job, 'ready_to_run');
+
+ return redirect(route('import.job.status.index', [$job->key]));
+ }
+
+
// create configuration class:
$configurator = $this->makeConfigurator($job);
@@ -76,7 +85,7 @@ class JobConfigurationController extends Controller
if ($configurator->configurationComplete()) {
$this->repository->updateStatus($job, 'ready_to_run');
- return redirect(route('import.job.landing', [$job->key]));
+ return redirect(route('import.job.status.index', [$job->key]));
}
$this->repository->updateStatus($job, 'configuring');
@@ -108,7 +117,7 @@ class JobConfigurationController extends Controller
if ($configurator->configurationComplete()) {
$this->repository->updateStatus($job, 'ready_to_run');
- return redirect(route('import.job.landing', [$job->key]));
+ return redirect(route('import.job.status.index', [$job->key]));
}
$data = $request->all();
diff --git a/app/Http/Controllers/Import/JobStatusController.php b/app/Http/Controllers/Import/JobStatusController.php
new file mode 100644
index 0000000000..ece8a4cdea
--- /dev/null
+++ b/app/Http/Controllers/Import/JobStatusController.php
@@ -0,0 +1,196 @@
+.
+ */
+declare(strict_types=1);
+
+namespace FireflyIII\Http\Controllers\Import;
+
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Http\Controllers\Controller;
+use FireflyIII\Http\Middleware\IsDemoUser;
+use FireflyIII\Import\Routine\RoutineInterface;
+use FireflyIII\Models\ImportJob;
+use Illuminate\Http\JsonResponse;
+use Log;
+
+/**
+ * Class JobStatusController
+ */
+class JobStatusController extends Controller
+{
+ /**
+ *
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->middleware(
+ function ($request, $next) {
+ app('view')->share('mainTitleIcon', 'fa-archive');
+ app('view')->share('title', trans('firefly.import_index_title'));
+
+ return $next($request);
+ }
+ );
+ $this->middleware(IsDemoUser::class);
+ }
+
+ /**
+ * @param ImportJob $importJob
+ *
+ * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+ */
+ public function index(ImportJob $importJob)
+ {
+ // jump away depending on job status:
+ if ($importJob->status === 'has_prereq') {
+ // TODO back to configuration.
+ }
+
+ if ($importJob->status === 'errored') {
+ // TODO to error screen
+ }
+
+ if ($importJob->status === 'finished') {
+ // TODO to finished screen.
+ }
+
+ return view('import.status', compact('importJob'));
+ }
+
+ /**
+ * @param ImportJob $job
+ *
+ * @return JsonResponse
+ */
+ public function json(ImportJob $job): JsonResponse
+ {
+ $json = [
+ 'status' => $job->status,
+ ];
+
+ return response()->json($json);
+ }
+
+ /**
+ * @param ImportJob $job
+ *
+ * @return JsonResponse
+ * @throws FireflyException
+ */
+ public function start(ImportJob $job): JsonResponse
+ {
+ $importProvider = $job->provider;
+ $key = sprintf('import.routine.%s', $importProvider);
+ $className = config($key);
+ if (null === $className || !class_exists($className)) {
+ return response()->json(['status' => 'NOK', 'message' => sprintf('Cannot find import routine class for job of type "%s".', $importProvider)]);
+ }
+
+ /** @var RoutineInterface $routine */
+ $routine = app($className);
+ $routine->setJob($job);
+ try {
+ $routine->run();
+ } catch (FireflyException $e) {
+ $message = 'The import routine crashed: ' . $e->getMessage();
+ Log::error($message);
+ Log::error($e->getTraceAsString());
+
+ return response()->json(['status' => 'NOK', 'message' => $message]);
+ }
+
+ // expect nothing from routine, just return OK to user.
+ return response()->json(['status' => 'OK', 'message' => 'finished']);
+ }
+
+ // /**
+ // * @param ImportJob $job
+ // *
+ // * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
+ // */
+ // public function index(ImportJob $job)
+ // {
+ // $statuses = ['configured', 'running', 'finished', 'error'];
+ // if (!\in_array($job->status, $statuses)) {
+ // return redirect(route('import.configure', [$job->key]));
+ // }
+ // $subTitle = trans('import.status_sub_title');
+ // $subTitleIcon = 'fa-star';
+ //
+ // return view('import.status', compact('job', 'subTitle', 'subTitleIcon'));
+ // }
+ //
+ // /**
+ // * Show status of import job in JSON.
+ // *
+ // * @param ImportJob $job
+ // *
+ // * @return \Illuminate\Http\JsonResponse
+ // */
+ // public function json(ImportJob $job)
+ // {
+ // $result = [
+ // 'started' => false,
+ // 'finished' => false,
+ // 'running' => false,
+ // 'errors' => array_values($job->extended_status['errors']),
+ // 'percentage' => 0,
+ // 'show_percentage' => false,
+ // 'steps' => $job->extended_status['steps'],
+ // 'done' => $job->extended_status['done'],
+ // 'statusText' => trans('import.status_job_' . $job->status),
+ // 'status' => $job->status,
+ // 'finishedText' => '',
+ // ];
+ //
+ // if (0 !== $job->extended_status['steps']) {
+ // $result['percentage'] = round(($job->extended_status['done'] / $job->extended_status['steps']) * 100, 0);
+ // $result['show_percentage'] = true;
+ // }
+ // if ('finished' === $job->status) {
+ // $result['finished'] = true;
+ // $tagId = (int)$job->extended_status['tag'];
+ // if ($tagId !== 0) {
+ // /** @var TagRepositoryInterface $repository */
+ // $repository = app(TagRepositoryInterface::class);
+ // $tag = $repository->find($tagId);
+ // $count = $tag->transactionJournals()->count();
+ // $result['finishedText'] = trans(
+ // 'import.status_finished_job', ['count' => $count, 'link' => route('tags.show', [$tag->id, 'all']), 'tag' => $tag->tag]
+ // );
+ // }
+ //
+ // if ($tagId === 0) {
+ // $result['finishedText'] = trans('import.status_finished_no_tag'); // @codeCoverageIgnore
+ // }
+ // }
+ //
+ // if ('running' === $job->status) {
+ // $result['started'] = true;
+ // $result['running'] = true;
+ // }
+ // $result['percentage'] = $result['percentage'] > 100 ? 100 : $result['percentage'];
+ // Log::debug(sprintf('JOB STATUS: %d/%d', $result['done'], $result['steps']));
+ //
+ // return response()->json($result);
+ // }
+}
diff --git a/app/Http/Controllers/Import/StatusController.php b/app/Http/Controllers/Import/StatusController.php
deleted file mode 100644
index 4c95ec77a3..0000000000
--- a/app/Http/Controllers/Import/StatusController.php
+++ /dev/null
@@ -1,125 +0,0 @@
-.
- */
-declare(strict_types=1);
-
-namespace FireflyIII\Http\Controllers\Import;
-
-use FireflyIII\Http\Controllers\Controller;
-use FireflyIII\Http\Middleware\IsDemoUser;
-use FireflyIII\Models\ImportJob;
-use FireflyIII\Repositories\Tag\TagRepositoryInterface;
-use Log;
-
-/**
- * Class StatusController
- */
-class StatusController extends Controller
-{
- /**
- *
- */
- public function __construct()
- {
- parent::__construct();
-
- $this->middleware(
- function ($request, $next) {
- app('view')->share('mainTitleIcon', 'fa-archive');
- app('view')->share('title', trans('firefly.import_index_title'));
-
- return $next($request);
- }
- );
- $this->middleware(IsDemoUser::class);
- }
-
- /**
- * @param ImportJob $job
- *
- * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
- */
- public function index(ImportJob $job)
- {
- $statuses = ['configured', 'running', 'finished', 'error'];
- if (!\in_array($job->status, $statuses)) {
- return redirect(route('import.configure', [$job->key]));
- }
- $subTitle = trans('import.status_sub_title');
- $subTitleIcon = 'fa-star';
-
- return view('import.status', compact('job', 'subTitle', 'subTitleIcon'));
- }
-
- /**
- * Show status of import job in JSON.
- *
- * @param ImportJob $job
- *
- * @return \Illuminate\Http\JsonResponse
- */
- public function json(ImportJob $job)
- {
- $result = [
- 'started' => false,
- 'finished' => false,
- 'running' => false,
- 'errors' => array_values($job->extended_status['errors']),
- 'percentage' => 0,
- 'show_percentage' => false,
- 'steps' => $job->extended_status['steps'],
- 'done' => $job->extended_status['done'],
- 'statusText' => trans('import.status_job_' . $job->status),
- 'status' => $job->status,
- 'finishedText' => '',
- ];
-
- if (0 !== $job->extended_status['steps']) {
- $result['percentage'] = round(($job->extended_status['done'] / $job->extended_status['steps']) * 100, 0);
- $result['show_percentage'] = true;
- }
- if ('finished' === $job->status) {
- $result['finished'] = true;
- $tagId = (int)$job->extended_status['tag'];
- if ($tagId !== 0) {
- /** @var TagRepositoryInterface $repository */
- $repository = app(TagRepositoryInterface::class);
- $tag = $repository->find($tagId);
- $count = $tag->transactionJournals()->count();
- $result['finishedText'] = trans(
- 'import.status_finished_job', ['count' => $count, 'link' => route('tags.show', [$tag->id, 'all']), 'tag' => $tag->tag]
- );
- }
-
- if ($tagId === 0) {
- $result['finishedText'] = trans('import.status_finished_no_tag'); // @codeCoverageIgnore
- }
- }
-
- if ('running' === $job->status) {
- $result['started'] = true;
- $result['running'] = true;
- }
- $result['percentage'] = $result['percentage'] > 100 ? 100 : $result['percentage'];
- Log::debug(sprintf('JOB STATUS: %d/%d', $result['done'], $result['steps']));
-
- return response()->json($result);
- }
-}
diff --git a/app/Import/Routine/RoutineInterface.php b/app/Import/Routine/RoutineInterface.php
index ef2d25515b..32ee378874 100644
--- a/app/Import/Routine/RoutineInterface.php
+++ b/app/Import/Routine/RoutineInterface.php
@@ -22,33 +22,19 @@ declare(strict_types=1);
namespace FireflyIII\Import\Routine;
+use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\ImportJob;
-use Illuminate\Support\Collection;
/**
* Interface RoutineInterface
*/
interface RoutineInterface
{
- /**
- * @return Collection
- */
- public function getErrors(): Collection;
-
- /**
- * @return Collection
- */
- public function getJournals(): Collection;
-
- /**
- * @return int
- */
- public function getLines(): int;
-
/**
* @return bool
+ * @throws FireflyException
*/
- public function run(): bool;
+ public function run(): void;
/**
* @param ImportJob $job
diff --git a/config/import.php b/config/import.php
index 3c87cb2461..390edfab10 100644
--- a/config/import.php
+++ b/config/import.php
@@ -46,8 +46,8 @@ return [
'yodlee' => false,
],
'has_prereq' => [
- 'fake' => true,
- 'file' => false,
+ 'fake' => false,
+ 'file' => true,
'bunq' => true,
'spectre' => true,
'plaid' => true,
@@ -64,7 +64,7 @@ return [
'yodlee' => false,
],
'has_config' => [
- 'fake' => true,
+ 'fake' => false,
'file' => true,
'bunq' => true,
'spectre' => true,
diff --git a/public/js/ff/import/status_v2.js b/public/js/ff/import/status_v2.js
new file mode 100644
index 0000000000..b1a2d00a8f
--- /dev/null
+++ b/public/js/ff/import/status_v2.js
@@ -0,0 +1,388 @@
+/*
+ * status_v2.js
+ * 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