First code for file import.

This commit is contained in:
James Cole
2018-05-03 22:20:06 +02:00
parent 480d65fc1f
commit ca14496e4e
9 changed files with 244 additions and 20 deletions

View File

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

View File

@@ -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
@@ -95,13 +97,16 @@ class FakeJobConfiguration implements JobConfiguratorInterface
// 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;
@@ -129,6 +134,10 @@ class FakeJobConfiguration implements JobConfiguratorInterface
$artist = $config['artist'] ?? '';
$song = $config['song'] ?? '';
$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';
}

View File

@@ -0,0 +1,157 @@
<?php
namespace FireflyIII\Import\JobConfiguration;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Support\Import\Configuration\ConfigurationInterface;
use FireflyIII\Support\Import\Configuration\File\Initial;
use FireflyIII\Support\Import\Configuration\File\Map;
use FireflyIII\Support\Import\Configuration\File\Roles;
use FireflyIII\Support\Import\Configuration\File\UploadConfig;
use Illuminate\Support\MessageBag;
use Log;
/**
* Class FileJobConfiguration
*
* @package FireflyIII\Import\JobConfiguration
*/
class FileJobConfiguration implements JobConfigurationInterface
{
/** @var ImportJob */
private $job;
/** @var ImportJobRepositoryInterface */
private $repository;
/**
* ConfiguratorInterface constructor.
*/
public function __construct()
{
$this->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;
}
}

View File

@@ -1,6 +1,6 @@
<?php
/**
* JobConfiguratorInterface.php
* JobConfigurationInterface.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
@@ -26,9 +26,9 @@ use FireflyIII\Models\ImportJob;
use Illuminate\Support\MessageBag;
/**
* Interface JobConfiguratorInterface.
* Interface JobConfigurationInterface.
*/
interface JobConfiguratorInterface
interface JobConfigurationInterface
{
/**
* ConfiguratorInterface constructor.

View File

@@ -6,6 +6,7 @@ use FireflyIII\Import\Configuration\FileConfigurator;
use FireflyIII\Import\Configuration\SpectreConfigurator;
use FireflyIII\Import\FileProcessor\CsvProcessor;
use FireflyIII\Import\JobConfiguration\FakeJobConfiguration;
use FireflyIII\Import\JobConfiguration\FileJobConfiguration;
use FireflyIII\Import\Prerequisites\BunqPrerequisites;
use FireflyIII\Import\Prerequisites\FakePrerequisites;
use FireflyIII\Import\Prerequisites\FilePrerequisites;
@@ -47,8 +48,8 @@ return [
'yodlee' => 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,

View File

@@ -61,7 +61,7 @@ function reportOnJobStatus(data) {
break;
case "running":
case "storing_data":
showProgressBox(data.ttatus);
showProgressBox(data.status);
checkOnJob();
break;

View File

@@ -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 <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
'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 <a href="https://github.com/firefly-iii/import-configurations/wiki">configuration file</a>',
'file_upload_type_help' => 'Select the type of file you will upload',
'file_upload_submit' => 'Upload files',

View File

@@ -0,0 +1,56 @@
{% extends "./layout/default" %}
{% block breadcrumbs %}
{{ Breadcrumbs.render }}
{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">Rules</h3>
</div>
<div class="box-body">
<p>
Should apply rules?
</p>
</div>
</div>
</div>
</div>
<form method="POST" action="{{ route('import.job.configuration.post', importJob.key) }}" accept-charset="UTF-8" class="form-horizontal" enctype="multipart/form-data">
<input name="_token" type="hidden" value="{{ csrf_token() }}">
<div class="row">
<div class="col-lg-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">Fields be here.</h3>
</div>
<div class="box-body">
<select name="apply-rules">
<option value="1">yes</option>
<option value="0">no</option>
</select>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="box">
<div class="box-body">
<button type="submit" class="btn btn-success pull-right">
Submit it!
</button>
</div>
</div>
</div>
</div>
</form>
{% endblock %}
{% block scripts %}
{% endblock %}
{% block styles %}
{% endblock %}

View File

@@ -20,7 +20,7 @@
</div>
</div>
<form method="POST" action="{{ route('import.configure.post', job.key) }}" accept-charset="UTF-8" class="form-horizontal" enctype="multipart/form-data">
<form method="POST" action="{{ route('import.job.configuration.post', [importJob.key]) }}" accept-charset="UTF-8" class="form-horizontal" enctype="multipart/form-data">
<input name="_token" type="hidden" value="{{ csrf_token() }}">
<input type="hidden" name="settings" value="upload"/>