mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-25 14:58:40 +00:00
Fix for #1092
This commit is contained in:
@@ -135,6 +135,7 @@ class ConfigurationController extends Controller
|
|||||||
if (null === $className || !class_exists($className)) {
|
if (null === $className || !class_exists($className)) {
|
||||||
throw new FireflyException(sprintf('Cannot find configurator class for job of type "%s".', $type)); // @codeCoverageIgnore
|
throw new FireflyException(sprintf('Cannot find configurator class for job of type "%s".', $type)); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
Log::debug(sprintf('Going to create class "%s"', $className));
|
||||||
/** @var ConfiguratorInterface $configurator */
|
/** @var ConfiguratorInterface $configurator */
|
||||||
$configurator = app($className);
|
$configurator = app($className);
|
||||||
$configurator->setJob($job);
|
$configurator->setJob($job);
|
||||||
|
@@ -43,10 +43,11 @@ class FileConfigurator implements ConfiguratorInterface
|
|||||||
private $warning = '';
|
private $warning = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConfiguratorInterface constructor.
|
* FileConfigurator constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
Log::debug('Created FileConfigurator');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,8 +141,11 @@ class FileConfigurator implements ConfiguratorInterface
|
|||||||
&& $config['column-mapping-complete']
|
&& $config['column-mapping-complete']
|
||||||
&& $config['has-file-upload']
|
&& $config['has-file-upload']
|
||||||
) {
|
) {
|
||||||
|
Log::debug('isJobConfigured returns true');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Log::debug('isJobConfigured returns false');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -152,11 +156,27 @@ class FileConfigurator implements ConfiguratorInterface
|
|||||||
public function setJob(ImportJob $job)
|
public function setJob(ImportJob $job)
|
||||||
{
|
{
|
||||||
$this->job = $job;
|
$this->job = $job;
|
||||||
if (null === $this->job->configuration || 0 === count($this->job->configuration)) {
|
// give job default config:
|
||||||
Log::debug(sprintf('Gave import job %s initial configuration.', $this->job->key));
|
$defaultConfig = [
|
||||||
$this->job->configuration = config('csv.default_config');
|
'initial-config-complete' => false,
|
||||||
$this->job->save();
|
'has-headers' => false, // assume
|
||||||
}
|
'date-format' => 'Ymd', // assume
|
||||||
|
'delimiter' => ',', // assume
|
||||||
|
'import-account' => 0, // none,
|
||||||
|
'specifics' => [], // none
|
||||||
|
'column-count' => 0, // unknown
|
||||||
|
'column-roles' => [], // unknown
|
||||||
|
'column-do-mapping' => [], // not yet set which columns must be mapped
|
||||||
|
'column-roles-complete' => false, // not yet configured roles for columns
|
||||||
|
'column-mapping-config' => [], // no mapping made yet.
|
||||||
|
'column-mapping-complete' => false, // so mapping is not complete.
|
||||||
|
'apply-rules' => true,
|
||||||
|
'match-bills' => false,
|
||||||
|
];
|
||||||
|
$config = $this->job->configuration ?? [];
|
||||||
|
$finalConfig = array_merge($defaultConfig, $config);
|
||||||
|
$this->job->configuration = $finalConfig;
|
||||||
|
$this->job->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -166,12 +186,15 @@ class FileConfigurator implements ConfiguratorInterface
|
|||||||
*/
|
*/
|
||||||
private function getConfigurationClass(): string
|
private function getConfigurationClass(): string
|
||||||
{
|
{
|
||||||
|
|
||||||
$class = false;
|
$class = false;
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case !$this->job->configuration['has-file-upload']:
|
case !$this->job->configuration['has-file-upload']:
|
||||||
$class = Upload::class;
|
$class = Upload::class;
|
||||||
break;
|
break;
|
||||||
case !$this->job->configuration['initial-config-complete']:
|
case !$this->job->configuration['initial-config-complete']:
|
||||||
|
Log::debug(sprintf('Class is %s', Initial::class));
|
||||||
|
Log::debug(sprintf('initial-config-complete is %s', var_export($this->job->configuration['initial-config-complete'], true)));
|
||||||
$class = Initial::class;
|
$class = Initial::class;
|
||||||
break;
|
break;
|
||||||
case !$this->job->configuration['column-roles-complete']:
|
case !$this->job->configuration['column-roles-complete']:
|
||||||
@@ -190,6 +213,7 @@ class FileConfigurator implements ConfiguratorInterface
|
|||||||
if (!class_exists($class)) {
|
if (!class_exists($class)) {
|
||||||
throw new FireflyException(sprintf('Class %s does not exist in getConfigurationClass().', $class));
|
throw new FireflyException(sprintf('Class %s does not exist in getConfigurationClass().', $class));
|
||||||
}
|
}
|
||||||
|
Log::debug(sprintf('Configuration class is "%s"', $class));
|
||||||
|
|
||||||
return $class;
|
return $class;
|
||||||
}
|
}
|
||||||
|
@@ -66,6 +66,7 @@ class SpectreConfigurator implements ConfiguratorInterface
|
|||||||
// update config to tell Firefly the user is redirected.
|
// update config to tell Firefly the user is redirected.
|
||||||
$config = $this->job->configuration;
|
$config = $this->job->configuration;
|
||||||
$config['is-redirected'] = true;
|
$config['is-redirected'] = true;
|
||||||
|
$config['stage'] = 'redirected';
|
||||||
$this->job->configuration = $config;
|
$this->job->configuration = $config;
|
||||||
$this->job->status = 'configured';
|
$this->job->status = 'configured';
|
||||||
$this->job->save();
|
$this->job->save();
|
||||||
@@ -117,7 +118,7 @@ class SpectreConfigurator implements ConfiguratorInterface
|
|||||||
*/
|
*/
|
||||||
public function setJob(ImportJob $job)
|
public function setJob(ImportJob $job)
|
||||||
{
|
{
|
||||||
$defaultConfig = [
|
$defaultConfig = [
|
||||||
'has-token' => false,
|
'has-token' => false,
|
||||||
'token' => '',
|
'token' => '',
|
||||||
'token-expires' => 0,
|
'token-expires' => 0,
|
||||||
@@ -125,12 +126,17 @@ class SpectreConfigurator implements ConfiguratorInterface
|
|||||||
'is-redirected' => false,
|
'is-redirected' => false,
|
||||||
'customer' => null,
|
'customer' => null,
|
||||||
'login' => null,
|
'login' => null,
|
||||||
|
'stage' => 'initial',
|
||||||
|
'accounts' => [],
|
||||||
];
|
];
|
||||||
|
$extendedStatus = $job->extended_status;
|
||||||
|
$extendedStatus['steps'] = 100;
|
||||||
|
|
||||||
$config = $job->configuration;
|
|
||||||
$finalConfig = array_merge($defaultConfig, $config);
|
$config = $job->configuration;
|
||||||
$job->configuration = $finalConfig;
|
$finalConfig = array_merge($defaultConfig, $config);
|
||||||
|
$job->configuration = $finalConfig;
|
||||||
|
$job->extended_status = $extendedStatus;
|
||||||
$job->save();
|
$job->save();
|
||||||
$this->job = $job;
|
$this->job = $job;
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,7 @@ namespace FireflyIII\Import\Routine;
|
|||||||
|
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\ImportJob;
|
use FireflyIII\Models\ImportJob;
|
||||||
|
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||||
use FireflyIII\Services\Spectre\Exception\DuplicatedCustomerException;
|
use FireflyIII\Services\Spectre\Exception\DuplicatedCustomerException;
|
||||||
use FireflyIII\Services\Spectre\Object\Customer;
|
use FireflyIII\Services\Spectre\Object\Customer;
|
||||||
use FireflyIII\Services\Spectre\Object\Login;
|
use FireflyIII\Services\Spectre\Object\Login;
|
||||||
@@ -50,6 +51,9 @@ class SpectreRoutine implements RoutineInterface
|
|||||||
/** @var ImportJob */
|
/** @var ImportJob */
|
||||||
private $job;
|
private $job;
|
||||||
|
|
||||||
|
/** @var ImportJobRepositoryInterface */
|
||||||
|
private $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ImportRoutine constructor.
|
* ImportRoutine constructor.
|
||||||
*/
|
*/
|
||||||
@@ -84,16 +88,33 @@ class SpectreRoutine implements RoutineInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A Spectre job that ends up here is either "configured" or "running", and will be set to "running"
|
||||||
|
* when it is "configured".
|
||||||
|
*
|
||||||
|
* Job has several stages, stored in extended status key 'stage'
|
||||||
|
*
|
||||||
|
* initial: just begun, nothing happened. action: get a customer and a token. Next status: has-token
|
||||||
|
* has-token: redirect user to sandstorm, make user login. set job to: user-logged-in
|
||||||
|
* user-logged-in: customer has an attempt. action: analyse/get attempt and go for next status.
|
||||||
|
* if attempt failed: job status is error, save a warning somewhere?
|
||||||
|
* if success, try to get accounts. Save in config key 'accounts'. set status: have-accounts and "configuring"
|
||||||
|
*
|
||||||
|
* If job is "configuring" and stage "have-accounts" then present the accounts and make user link them to
|
||||||
|
* own asset accounts. Store this mapping, set config to "have-account-mapping" and job status configured".
|
||||||
|
*
|
||||||
|
* have-account-mapping: start downloading transactions?
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* @throws \FireflyIII\Exceptions\FireflyException
|
* @throws \FireflyIII\Exceptions\FireflyException
|
||||||
* @throws \FireflyIII\Services\Spectre\Exception\SpectreException
|
* @throws \FireflyIII\Services\Spectre\Exception\SpectreException
|
||||||
*/
|
*/
|
||||||
public function run(): bool
|
public function run(): bool
|
||||||
{
|
{
|
||||||
if ('configured' !== $this->job->status) {
|
if ('configured' === $this->job->status) {
|
||||||
//Log::error(sprintf('Job %s is in state "%s" so it cannot be started.', $this->job->key, $this->job->status));
|
$this->repository->updateStatus($this->job,'running');
|
||||||
//return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Log::info(sprintf('Start with import job %s using Spectre.', $this->job->key));
|
Log::info(sprintf('Start with import job %s using Spectre.', $this->job->key));
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
|
|
||||||
@@ -184,6 +205,8 @@ class SpectreRoutine implements RoutineInterface
|
|||||||
public function setJob(ImportJob $job)
|
public function setJob(ImportJob $job)
|
||||||
{
|
{
|
||||||
$this->job = $job;
|
$this->job = $job;
|
||||||
|
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||||
|
$this->repository->setUser($job->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -94,8 +94,8 @@ class ImportStorage
|
|||||||
$this->defaultCurrencyId = $currency->id;
|
$this->defaultCurrencyId = $currency->id;
|
||||||
$this->transfers = $this->getTransfers();
|
$this->transfers = $this->getTransfers();
|
||||||
$config = $job->configuration;
|
$config = $job->configuration;
|
||||||
$this->applyRules = $config['apply_rules'] ?? false;
|
$this->applyRules = $config['apply-rules'] ?? false;
|
||||||
$this->matchBills = $config['match_bills'] ?? false;
|
$this->matchBills = $config['match-bills'] ?? false;
|
||||||
if (true === $this->applyRules) {
|
if (true === $this->applyRules) {
|
||||||
Log::debug('applyRules seems to be true, get the rules.');
|
Log::debug('applyRules seems to be true, get the rules.');
|
||||||
$this->rules = $this->getRules();
|
$this->rules = $this->getRules();
|
||||||
|
@@ -62,7 +62,7 @@ class ImportJobRepository implements ImportJobRepositoryInterface
|
|||||||
$importJob->file_type = $type;
|
$importJob->file_type = $type;
|
||||||
$importJob->key = Str::random(12);
|
$importJob->key = Str::random(12);
|
||||||
$importJob->status = 'new';
|
$importJob->status = 'new';
|
||||||
$importJob->configuration = config(sprintf('import.default_config.%s', $type)) ?? [];
|
$importJob->configuration = [];
|
||||||
$importJob->extended_status = [
|
$importJob->extended_status = [
|
||||||
'steps' => 0,
|
'steps' => 0,
|
||||||
'done' => 0,
|
'done' => 0,
|
||||||
|
@@ -111,23 +111,29 @@ class Initial implements ConfigurationInterface
|
|||||||
*/
|
*/
|
||||||
public function storeConfiguration(array $data): bool
|
public function storeConfiguration(array $data): bool
|
||||||
{
|
{
|
||||||
|
Log::debug('Now in Initial::storeConfiguration()');
|
||||||
|
|
||||||
|
// get config from job:
|
||||||
|
$config = $this->job->configuration;
|
||||||
|
|
||||||
|
// find import account:
|
||||||
/** @var AccountRepositoryInterface $repository */
|
/** @var AccountRepositoryInterface $repository */
|
||||||
$repository = app(AccountRepositoryInterface::class);
|
$repository = app(AccountRepositoryInterface::class);
|
||||||
$importId = $data['csv_import_account'] ?? 0;
|
$importId = intval($data['csv_import_account'] ?? 0);
|
||||||
$account = $repository->find(intval($importId));
|
$account = $repository->find($importId);
|
||||||
|
|
||||||
$hasHeaders = isset($data['has_headers']) && 1 === intval($data['has_headers']) ? true : false;
|
// set "headers":
|
||||||
$config = $this->job->configuration;
|
|
||||||
$config['initial-config-complete'] = true;
|
$config['initial-config-complete'] = true;
|
||||||
$config['has-headers'] = $hasHeaders;
|
$config['has-headers'] = intval($data['has_headers'] ?? 0) === 1;
|
||||||
$config['date-format'] = $data['date_format'];
|
$config['date-format'] = $data['date_format'];
|
||||||
$config['delimiter'] = $data['csv_delimiter'];
|
$config['delimiter'] = $data['csv_delimiter'];
|
||||||
$config['delimiter'] = 'tab' === $config['delimiter'] ? "\t" : $config['delimiter'];
|
$config['delimiter'] = 'tab' === $config['delimiter'] ? "\t" : $config['delimiter'];
|
||||||
$config['apply_rules'] = isset($data['apply_rules']) && 1 === intval($data['apply_rules']) ? true : false;
|
$config['apply-rules'] = intval($data['apply_rules'] ?? 0) === 1;
|
||||||
$config['match_bills'] = isset($data['match_bills']) && 1 === intval($data['match_bills']) ? true : false;
|
$config['match-bills'] = intval($data['match_bills'] ?? 0) === 1;
|
||||||
|
|
||||||
Log::debug('Entered import account.', ['id' => $importId]);
|
Log::debug('Entered import account.', ['id' => $importId]);
|
||||||
|
|
||||||
|
|
||||||
if (null !== $account->id) {
|
if (null !== $account->id) {
|
||||||
Log::debug('Found account.', ['id' => $account->id, 'name' => $account->name]);
|
Log::debug('Found account.', ['id' => $account->id, 'name' => $account->name]);
|
||||||
$config['import-account'] = $account->id;
|
$config['import-account'] = $account->id;
|
||||||
@@ -137,7 +143,9 @@ class Initial implements ConfigurationInterface
|
|||||||
Log::error('Could not find anything for csv_import_account.', ['id' => $importId]);
|
Log::error('Could not find anything for csv_import_account.', ['id' => $importId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$config = $this->storeSpecifics($data, $config);
|
$config = $this->storeSpecifics($data, $config);
|
||||||
|
Log::debug('Final config is ', $config);
|
||||||
|
|
||||||
$this->job->configuration = $config;
|
$this->job->configuration = $config;
|
||||||
$this->job->save();
|
$this->job->save();
|
||||||
|
|
||||||
|
@@ -320,18 +320,4 @@ return [
|
|||||||
|
|
||||||
// number of example rows:
|
// number of example rows:
|
||||||
'example_rows' => 5,
|
'example_rows' => 5,
|
||||||
'default_config' => [
|
|
||||||
'initial-config-complete' => false,
|
|
||||||
'has-headers' => false, // assume
|
|
||||||
'date-format' => 'Ymd', // assume
|
|
||||||
'delimiter' => ',', // assume
|
|
||||||
'import-account' => 0, // none,
|
|
||||||
'specifics' => [], // none
|
|
||||||
'column-count' => 0, // unknown
|
|
||||||
'column-roles' => [], // unknown
|
|
||||||
'column-do-mapping' => [], // not yet set which columns must be mapped
|
|
||||||
'column-roles-complete' => false, // not yet configured roles for columns
|
|
||||||
'column-mapping-config' => [], // no mapping made yet.
|
|
||||||
'column-mapping-complete' => false, // so mapping is not complete.
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
Reference in New Issue
Block a user