From ca14496e4e6bc98244879b1ecc32c32abfa3d95c Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 3 May 2018 22:20:06 +0200 Subject: [PATCH] First code for file import. --- .../Import/JobConfigurationController.php | 8 +- .../JobConfiguration/FakeJobConfiguration.php | 21 ++- .../JobConfiguration/FileJobConfiguration.php | 157 ++++++++++++++++++ ...face.php => JobConfigurationInterface.php} | 6 +- config/import.php | 9 +- public/js/ff/import/status_v2.js | 2 +- resources/lang/en_US/import.php | 3 +- resources/views/import/fake/apply-rules.twig | 56 +++++++ .../import/file/{initial.twig => new.twig} | 2 +- 9 files changed, 244 insertions(+), 20 deletions(-) create mode 100644 app/Import/JobConfiguration/FileJobConfiguration.php rename app/Import/JobConfiguration/{JobConfiguratorInterface.php => JobConfigurationInterface.php} (94%) create mode 100644 resources/views/import/fake/apply-rules.twig rename resources/views/import/file/{initial.twig => new.twig} (92%) diff --git a/app/Http/Controllers/Import/JobConfigurationController.php b/app/Http/Controllers/Import/JobConfigurationController.php index cb736d19ac..31bcfa954c 100644 --- a/app/Http/Controllers/Import/JobConfigurationController.php +++ b/app/Http/Controllers/Import/JobConfigurationController.php @@ -25,7 +25,7 @@ namespace FireflyIII\Http\Controllers\Import; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Middleware\IsDemoUser; -use FireflyIII\Import\JobConfiguration\JobConfiguratorInterface; +use FireflyIII\Import\JobConfiguration\JobConfigurationInterface; use FireflyIII\Models\ImportJob; use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; use Illuminate\Http\Request; @@ -151,11 +151,11 @@ class JobConfigurationController extends Controller /** * @param ImportJob $importJob * - * @return JobConfiguratorInterface + * @return JobConfigurationInterface * * @throws FireflyException */ - private function makeConfigurator(ImportJob $importJob): JobConfiguratorInterface + private function makeConfigurator(ImportJob $importJob): JobConfigurationInterface { $key = sprintf('import.configuration.%s', $importJob->provider); $className = (string)config($key); @@ -163,7 +163,7 @@ class JobConfigurationController extends Controller throw new FireflyException(sprintf('Cannot find configurator class for job with provider "%s".', $importJob->provider)); // @codeCoverageIgnore } Log::debug(sprintf('Going to create class "%s"', $className)); - /** @var JobConfiguratorInterface $configurator */ + /** @var JobConfigurationInterface $configurator */ $configurator = app($className); $configurator->setJob($importJob); diff --git a/app/Import/JobConfiguration/FakeJobConfiguration.php b/app/Import/JobConfiguration/FakeJobConfiguration.php index 509e0caf2a..f1f6582612 100644 --- a/app/Import/JobConfiguration/FakeJobConfiguration.php +++ b/app/Import/JobConfiguration/FakeJobConfiguration.php @@ -30,7 +30,7 @@ use Illuminate\Support\MessageBag; /** * Class FakeJobConfiguration */ -class FakeJobConfiguration implements JobConfiguratorInterface +class FakeJobConfiguration implements JobConfigurationInterface { /** @var ImportJob */ private $job; @@ -60,7 +60,8 @@ class FakeJobConfiguration implements JobConfiguratorInterface $config = $this->job->configuration; if ($this->job->stage === 'new') { return (isset($config['artist']) && 'david bowie' === strtolower($config['artist'])) - && (isset($config['song']) && 'golden years' === strtolower($config['song'])); + && (isset($config['song']) && 'golden years' === strtolower($config['song'])) + && isset($config['apply-rules']); } return isset($config['album']) && 'station to station' === strtolower($config['album']); @@ -80,6 +81,7 @@ class FakeJobConfiguration implements JobConfiguratorInterface $artist = strtolower($data['artist'] ?? ''); $song = strtolower($data['song'] ?? ''); $album = strtolower($data['album'] ?? ''); + $applyRules = isset($data['apply-rules']) ? (int)$data['apply-rules'] === 1 : null; $configuration = $this->job->configuration; if ($artist === 'david bowie') { // store artist @@ -91,17 +93,20 @@ class FakeJobConfiguration implements JobConfiguratorInterface $configuration['song'] = $song; } - if ($album=== 'station to station') { + if ($album === 'station to station') { // store album $configuration['album'] = $album; } + if (null !== $applyRules) { + $configuration['apply-rules'] = $applyRules; + } $this->repository->setConfiguration($this->job, $configuration); $messages = new MessageBag(); - if (\count($configuration) !== 2) { + if (\count($configuration) !== 3) { - $messages->add('some_key', 'Ignore this error'); + $messages->add('some_key', 'Ignore this error: ' . \count($configuration)); } return $messages; @@ -128,7 +133,11 @@ class FakeJobConfiguration implements JobConfiguratorInterface $config = $this->job->configuration; $artist = $config['artist'] ?? ''; $song = $config['song'] ?? ''; - $album = $config['album'] ?? ''; + $album = $config['album'] ?? ''; + $applyRules = $config['apply-rules'] ?? null; + if (null === $applyRules) { + return 'import.fake.apply-rules'; + } if (strtolower($artist) !== 'david bowie') { return 'import.fake.enter-artist'; } diff --git a/app/Import/JobConfiguration/FileJobConfiguration.php b/app/Import/JobConfiguration/FileJobConfiguration.php new file mode 100644 index 0000000000..7f486a0125 --- /dev/null +++ b/app/Import/JobConfiguration/FileJobConfiguration.php @@ -0,0 +1,157 @@ +repository = app(ImportJobRepositoryInterface::class); + } + + /** + * Store any data from the $data array into the job. Anything in the message bag will be flashed + * as an error to the user, regardless of its content. + * + * @param array $data + * + * @return MessageBag + * @throws FireflyException + */ + public function configureJob(array $data): MessageBag + { + /** @var ConfigurationInterface $object */ + $object = app($this->getConfigurationClass()); + $object->setJob($this->job); + $result = $object->storeConfiguration($data); + + return $result; + } + + /** + * Return the data required for the next step in the job configuration. + * + * @return array + * @throws FireflyException + */ + public function getNextData(): array + { + /** @var ConfigurationInterface $object */ + $object = app($this->getConfigurationClass()); + $object->setJob($this->job); + + return $object->getData(); + } + + /** + * Returns the view of the next step in the job configuration. + * + * @return string + * @throws FireflyException + */ + public function getNextView(): string + { + switch ($this->job->stage) { + case 'new': // has nothing, no file upload or anything. + return 'import.file.new'; + case 'upload-config': // has file, needs file config. + return 'import.file.upload-config'; + case 'roles': // has configured file, needs roles. + return 'import.file.roles'; + case 'map': // has roles, needs mapping. + return 'import.file.map'; + } + throw new FireflyException(sprintf('No view for stage "%s"', $this->job->stage)); + } + + /** + * Returns true when the initial configuration for this job is complete. + * + * @return bool + */ + public function configurationComplete(): bool + { + if ('ready' === $this->job->stage) { + Log::debug('isJobConfigured returns true'); + + return true; + } + Log::debug('isJobConfigured returns false'); + + return false; + } + + /** + * @param ImportJob $job + */ + public function setJob(ImportJob $job): void + { + $this->job = $job; + $this->repository->setUser($job->user); + } + + + /** + * @return string + * + * @throws FireflyException + */ + private function getConfigurationClass(): string + { + $class = false; + Log::debug(sprintf('Now in getConfigurationClass() for stage "%s"', $this->job->stage)); + + switch ($this->job->stage) { + case 'new': // has nothing, no file upload or anything. + $class = Initial::class; + break; + case 'upload-config': // has file, needs file config. + $class = UploadConfig::class; + break; + case 'roles': // has configured file, needs roles. + $class = Roles::class; + break; + case 'map': // has roles, needs mapping. + $class = Map::class; + break; + default: + break; + } + + if (false === $class || 0 === \strlen($class)) { + throw new FireflyException(sprintf('Cannot handle job stage "%s" in getConfigurationClass().', $this->job->stage)); + } + if (!class_exists($class)) { + throw new FireflyException(sprintf('Class %s does not exist in getConfigurationClass().', $class)); // @codeCoverageIgnore + } + Log::debug(sprintf('Configuration class is "%s"', $class)); + + return $class; + } +} \ No newline at end of file diff --git a/app/Import/JobConfiguration/JobConfiguratorInterface.php b/app/Import/JobConfiguration/JobConfigurationInterface.php similarity index 94% rename from app/Import/JobConfiguration/JobConfiguratorInterface.php rename to app/Import/JobConfiguration/JobConfigurationInterface.php index 7797ed7c31..70609f51d7 100644 --- a/app/Import/JobConfiguration/JobConfiguratorInterface.php +++ b/app/Import/JobConfiguration/JobConfigurationInterface.php @@ -1,6 +1,6 @@ false, ], 'has_prereq' => [ - 'fake' => false, - 'file' => true, + 'fake' => true, + 'file' => false, 'bunq' => true, 'spectre' => true, 'plaid' => true, @@ -65,7 +66,7 @@ return [ 'yodlee' => false, ], 'has_config' => [ - 'fake' => false, + 'fake' => true, 'file' => true, 'bunq' => true, 'spectre' => true, @@ -75,7 +76,7 @@ return [ ], 'configuration' => [ 'fake' => FakeJobConfiguration::class, - 'file' => FileConfigurator::class, + 'file' => FileJobConfiguration::class, 'bunq' => BunqConfigurator::class, 'spectre' => SpectreConfigurator::class, 'plaid' => false, diff --git a/public/js/ff/import/status_v2.js b/public/js/ff/import/status_v2.js index 51436101b8..c467e1f0ee 100644 --- a/public/js/ff/import/status_v2.js +++ b/public/js/ff/import/status_v2.js @@ -61,7 +61,7 @@ function reportOnJobStatus(data) { break; case "running": case "storing_data": - showProgressBox(data.ttatus); + showProgressBox(data.status); checkOnJob(); break; diff --git a/resources/lang/en_US/import.php b/resources/lang/en_US/import.php index ca2d6d0b4c..c3e85568fc 100644 --- a/resources/lang/en_US/import.php +++ b/resources/lang/en_US/import.php @@ -54,6 +54,7 @@ return [ 'status_bread_crumb' => 'Import status', 'status_sub_title' => 'Import status', 'config_sub_title' => 'Set up your import', + 'import_config_bread_crumb' => 'Import configuration', 'status_finished_job' => 'The :count transactions imported can be found in tag :tag.', 'status_finished_no_tag' => 'Firefly III has not collected any transactions from your import file.', 'import_with_key' => 'Import with key \':key\'', @@ -63,7 +64,7 @@ return [ 'file_upload_title' => 'Import setup (1/4) - Upload your file', 'file_upload_text' => 'This routine will help you import files from your bank into Firefly III. Please check out the help pages in the top right corner.', 'file_upload_fields' => 'Fields', - 'file_upload_help' => 'Select your file', + 'file_upload_help' => 'Select your file. Please make sure the file is UTF-8 encoded.', 'file_upload_config_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you. For some banks, other users have kindly provided their configuration file', 'file_upload_type_help' => 'Select the type of file you will upload', 'file_upload_submit' => 'Upload files', diff --git a/resources/views/import/fake/apply-rules.twig b/resources/views/import/fake/apply-rules.twig new file mode 100644 index 0000000000..6cf883fa41 --- /dev/null +++ b/resources/views/import/fake/apply-rules.twig @@ -0,0 +1,56 @@ +{% extends "./layout/default" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.render }} +{% endblock %} +{% block content %} +
+
+
+
+

Rules

+
+
+

+ Should apply rules? +

+
+
+ +
+
+ +
+ +
+
+
+
+

Fields be here.

+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+
+
+{% endblock %} +{% block scripts %} +{% endblock %} +{% block styles %} +{% endblock %} diff --git a/resources/views/import/file/initial.twig b/resources/views/import/file/new.twig similarity index 92% rename from resources/views/import/file/initial.twig rename to resources/views/import/file/new.twig index 8f07bfe1d1..8ca9167332 100644 --- a/resources/views/import/file/initial.twig +++ b/resources/views/import/file/new.twig @@ -20,7 +20,7 @@ -
+