diff --git a/app/Import/Converter/Amount.php b/app/Import/Converter/Amount.php index 802664269a..cd25a8d51f 100644 --- a/app/Import/Converter/Amount.php +++ b/app/Import/Converter/Amount.php @@ -82,20 +82,20 @@ class Amount implements ConverterInterface // if decimal is dot, replace all comma's and spaces with nothing. then parse as float (round to 4 pos) if ('.' === $decimal) { - $search = [',', ' ']; - $value = str_replace($search, '', $value); + $search = [',', ' ']; + $value = str_replace($search, '', $value); Log::debug(sprintf('Converted amount from "%s" to "%s".', $original, $value)); } if (',' === $decimal) { - $search = ['.', ' ']; - $value = str_replace($search, '', $value); - $value = str_replace(',', '.', $value); + $search = ['.', ' ']; + $value = str_replace($search, '', $value); + $value = str_replace(',', '.', $value); Log::debug(sprintf('Converted amount from "%s" to "%s".', $original, $value)); } if (null === $decimal) { // replace all: - $search = ['.', ' ', ',']; - $value = str_replace($search, '', $value); + $search = ['.', ' ', ',']; + $value = str_replace($search, '', $value); Log::debug(sprintf('No decimal character found. Converted amount from "%s" to "%s".', $original, $value)); } diff --git a/app/Import/Object/ImportJournal.php b/app/Import/Object/ImportJournal.php index 34fd59eded..740e60e0cf 100644 --- a/app/Import/Object/ImportJournal.php +++ b/app/Import/Object/ImportJournal.php @@ -48,6 +48,8 @@ class ImportJournal public $currency; /** @var string */ public $description = ''; + /** @var ImportCurrency */ + public $foreignCurrency; /** @var string */ public $hash; /** @var array */ @@ -71,6 +73,8 @@ class ImportJournal /** @var string */ private $externalId = ''; /** @var array */ + private $foreignAmount; + /** @var array */ private $modifiers = []; /** @var User */ private $user; @@ -80,12 +84,13 @@ class ImportJournal */ public function __construct() { - $this->asset = new ImportAccount; - $this->opposing = new ImportAccount; - $this->bill = new ImportBill; - $this->category = new ImportCategory; - $this->budget = new ImportBudget; - $this->currency = new ImportCurrency; + $this->asset = new ImportAccount; + $this->opposing = new ImportAccount; + $this->bill = new ImportBill; + $this->category = new ImportCategory; + $this->budget = new ImportBudget; + $this->currency = new ImportCurrency; + $this->foreignCurrency = new ImportCurrency; } /** @@ -190,6 +195,12 @@ class ImportJournal case 'amount': $this->amount = $array; break; + case 'amount_foreign': + $this->foreignAmount = $array; + break; + case 'foreign-currency-code': + $this->foreignCurrency->setId($array); + break; case 'amount_debit': $this->amountDebit = $array; break; diff --git a/app/Import/Routine/SpectreRoutine.php b/app/Import/Routine/SpectreRoutine.php index cc6d8dd74d..e68bef568b 100644 --- a/app/Import/Routine/SpectreRoutine.php +++ b/app/Import/Routine/SpectreRoutine.php @@ -412,8 +412,27 @@ class SpectreRoutine implements RoutineInterface $notes = ''; $notes .= strval(trans('import.imported_from_account', ['account' => $account->getName()])) . ' ' . "\n"; // double space for newline in Markdown. + foreach ($extra as $key => $value) { switch ($key) { + case 'account_number': + $importJournal->setValue(['role' => 'account-number', 'value' => $value]); + break; + case 'original_category': + case 'original_subcategory': + case 'customer_category_code': + case 'customer_category_name': + $tags[] = $value; + break; + case 'payee': + $importJournal->setValue(['role' => 'opposing-name', 'value' => $value]); + break; + case 'original_amount': + $importJournal->setValue(['role' => 'amount_foreign', 'value' => $value]); + break; + case 'original_currency_code': + $importJournal->setValue(['role' => 'foreign-currency-code', 'value' => $value]); + break; default: $notes .= $key . ': ' . $value . ' '; // for newline in Markdown. } @@ -494,7 +513,8 @@ class SpectreRoutine implements RoutineInterface */ private function runStageHaveMapping() { - $accounts = $this->getConfig()['accounts'] ?? []; + $config = $this->getConfig(); + $accounts = $config['accounts'] ?? []; $all = []; $count = 0; /** @var array $accountArray */ @@ -503,7 +523,7 @@ class SpectreRoutine implements RoutineInterface $importId = intval($config['accounts-mapped'][$account->getid()] ?? 0); $doImport = $importId !== 0 ? true : false; if (!$doImport) { - Log::debug('Will NOT import from Spectre account #%d ("%s")', $account->getId(), $account->getName()); + Log::debug(sprintf('Will NOT import from Spectre account #%d ("%s")', $account->getId(), $account->getName())); continue; } // grab all transactions diff --git a/app/Import/Storage/ImportStorage.php b/app/Import/Storage/ImportStorage.php index 576499d685..1be3c5d9d8 100644 --- a/app/Import/Storage/ImportStorage.php +++ b/app/Import/Storage/ImportStorage.php @@ -98,13 +98,13 @@ class ImportStorage $this->repository->setUser($job->user); $config = $this->repository->getConfiguration($job); - $currency = app('amount')->getDefaultCurrencyByUser($this->job->user); + $currency = app('amount')->getDefaultCurrencyByUser($job->user); $this->defaultCurrencyId = $currency->id; + $this->job = $job; $this->transfers = $this->getTransfers(); $this->applyRules = $config['apply-rules'] ?? false; $this->matchBills = $config['match-bills'] ?? false; - if (true === $this->applyRules) { Log::debug('applyRules seems to be true, get the rules.'); $this->rules = $this->getRules(); @@ -119,8 +119,6 @@ class ImportStorage Log::debug(sprintf('Value of match bills is %s', var_export($this->matchBills, true))); - $this->job = $job; - } /** diff --git a/app/Repositories/ImportJob/ImportJobRepository.php b/app/Repositories/ImportJob/ImportJobRepository.php index b768d23a0e..6573344311 100644 --- a/app/Repositories/ImportJob/ImportJobRepository.php +++ b/app/Repositories/ImportJob/ImportJobRepository.php @@ -69,7 +69,7 @@ class ImportJobRepository implements ImportJobRepositoryInterface $status['done'] += $steps; Log::debug(sprintf('Add %d to steps done for job "%s" making steps done %d', $steps, $job->key, $status['done'])); - return $this->setExtendedStatus($status); + return $this->setExtendedStatus($job, $status); } /** diff --git a/app/Support/Import/Configuration/File/Roles.php b/app/Support/Import/Configuration/File/Roles.php index 884e6bcdbd..e779582df2 100644 --- a/app/Support/Import/Configuration/File/Roles.php +++ b/app/Support/Import/Configuration/File/Roles.php @@ -143,14 +143,13 @@ class Roles implements ConfigurationInterface $this->saveConfig($config); $this->ignoreUnmappableColumns(); - $this->setRolesComplete(); - - $config = $this->getConfig(); - $config['stage'] = 'map'; - $this->saveConfig($config); - - $this->isMappingNecessary(); - + $res = $this->isRolesComplete(); + if ($res === true) { + $config = $this->getConfig(); + $config['stage'] = 'map'; + $this->saveConfig($config); + $this->isMappingNecessary(); + } return true; } @@ -225,6 +224,56 @@ class Roles implements ConfigurationInterface return true; } + /** + * @return bool + */ + private function isRolesComplete(): bool + { + $config = $this->getConfig(); + $count = $config['column-count']; + $assigned = 0; + + // check if data actually contains amount column (foreign amount does not count) + $hasAmount = false; + $hasForeignAmount = false; + $hasForeignCode = false; + for ($i = 0; $i < $count; ++$i) { + $role = $config['column-roles'][$i] ?? '_ignore'; + if ('_ignore' !== $role) { + ++$assigned; + } + if (in_array($role, ['amount', 'amount_credit', 'amount_debit'])) { + $hasAmount = true; + } + if ($role === 'foreign-currency-code') { + $hasForeignCode = true; + } + if ($role === 'amount_foreign') { + $hasForeignAmount = true; + } + } + if ($assigned > 0 && $hasAmount && ($hasForeignCode === false && $hasForeignAmount === false)) { + $this->warning = ''; + $this->saveConfig($config); + + return true; + } + // warn if has foreign amount but no currency code: + if ($hasForeignAmount && !$hasForeignCode) { + $this->warning = strval(trans('import.foreign_amount_warning')); + + return false; + } + + if (0 === $assigned || !$hasAmount) { + $this->warning = strval(trans('import.roles_warning')); + + return false; + } + + return false; + } + /** * make unique example data. */ @@ -284,36 +333,6 @@ class Roles implements ConfigurationInterface $this->repository->setConfiguration($this->job, $array); } - /** - * @return bool - */ - private function setRolesComplete(): bool - { - $config = $this->getConfig(); - $count = $config['column-count']; - $assigned = 0; - $hasAmount = false; - for ($i = 0; $i < $count; ++$i) { - $role = $config['column-roles'][$i] ?? '_ignore'; - if ('_ignore' !== $role) { - ++$assigned; - } - if (in_array($role, ['amount', 'amount_credit', 'amount_debit'])) { - $hasAmount = true; - } - } - if ($assigned > 0 && $hasAmount) { - $config['column-roles-complete'] = true; - $this->warning = ''; - } - if (0 === $assigned || !$hasAmount) { - $this->warning = strval(trans('import.roles_warning')); - } - $this->saveConfig($config); - - return true; - } - /** * @return bool */