Small cleanup in CSV processor

This commit is contained in:
James Cole 2017-08-12 16:12:30 +02:00
parent 0375f77b73
commit accbff3ccb
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
2 changed files with 61 additions and 33 deletions

View File

@ -58,7 +58,7 @@ class CsvProcessor implements FileProcessorInterface
} }
/** /**
* Does the actual job: * Does the actual job.
* *
* @return bool * @return bool
*/ */
@ -66,34 +66,45 @@ class CsvProcessor implements FileProcessorInterface
{ {
Log::debug('Now in CsvProcessor run(). Job is now running...'); Log::debug('Now in CsvProcessor run(). Job is now running...');
$entries = $this->getImportArray(); $entries = new Collection($this->getImportArray());
$index = 0;
Log::notice('Building importable objects from CSV file.'); Log::notice('Building importable objects from CSV file.');
foreach ($entries as $index => $row) { Log::debug(sprintf('Number of entries: %d', $entries->count()));
// verify if not exists already: $notImported = $entries->filter(
if ($this->rowAlreadyImported($row)) { function (array $row, int $index) {
$message = sprintf('Row #%d has already been imported.', $index); if ($this->rowAlreadyImported($row)) {
$this->job->addError($index, $message); $message = sprintf('Row #%d has already been imported.', $index);
$this->job->addStepsDone(5); // all steps. $this->job->addError($index, $message);
Log::info($message); $this->job->addStepsDone(5); // all steps.
continue; Log::info($message);
return null;
}
return $row;
} }
$this->objects->push($this->importRow($index, $row)); );
$this->job->addStepsDone(1); Log::debug(sprintf('Number of entries left: %d', $notImported->count()));
}
// if job has no step count, set it now:
$extended = $this->job->extended_status;
if ($extended['steps'] === 0) {
$extended['steps'] = $index * 5;
$this->job->extended_status = $extended;
$this->job->save();
}
// set (new) number of steps:
$status = $this->job->extended_status;
$status['steps'] = $notImported->count() * 5;
$this->job->extended_status = $status;
$this->job->save();
Log::debug(sprintf('Number of steps: %d', $notImported->count() * 5));
$notImported->each(
function (array $row, int $index) {
$journal = $this->importRow($index, $row);
$this->objects->push($journal);
$this->job->addStepsDone(1);
}
);
return true; return true;
} }
/** /**
* Set import job for this processor.
*
* @param ImportJob $job * @param ImportJob $job
* *
* @return FileProcessorInterface * @return FileProcessorInterface
@ -116,7 +127,6 @@ class CsvProcessor implements FileProcessorInterface
*/ */
private function annotateValue(int $index, string $value) private function annotateValue(int $index, string $value)
{ {
$value = trim($value);
$config = $this->job->configuration; $config = $this->job->configuration;
$role = $config['column-roles'][$index] ?? '_ignore'; $role = $config['column-roles'][$index] ?? '_ignore';
$mapped = $config['column-mapping-config'][$index][$value] ?? null; $mapped = $config['column-mapping-config'][$index][$value] ?? null;
@ -188,6 +198,26 @@ class CsvProcessor implements FileProcessorInterface
} }
} }
/**
* Hash an array and return the result.
*
* @param array $array
*
* @return string
* @throws FireflyException
*/
private function getRowHash(array $array): string
{
$json = json_encode($array);
$jsonError = json_last_error();
if ($json === false) {
throw new FireflyException(sprintf('Error while encoding JSON for CSV row: %s', $this->getJsonError($jsonError)));
}
$hash = hash('sha256', $json);
return $hash;
}
/** /**
* Take a row, build import journal by annotating each value and storing it in the import journal. * Take a row, build import journal by annotating each value and storing it in the import journal.
* *
@ -200,18 +230,17 @@ class CsvProcessor implements FileProcessorInterface
private function importRow(int $index, array $row): ImportJournal private function importRow(int $index, array $row): ImportJournal
{ {
Log::debug(sprintf('Now at row %d', $index)); Log::debug(sprintf('Now at row %d', $index));
$row = $this->specifics($row); $row = $this->specifics($row);
$json = json_encode($row); $hash = $this->getRowHash($row);
$jsonError = json_last_error();
if ($json === false) {
throw new FireflyException(sprintf('Error while encoding JSON: %s', $this->getJsonError($jsonError)));
}
$journal = new ImportJournal; $journal = new ImportJournal;
$journal->setUser($this->job->user); $journal->setUser($this->job->user);
$journal->setHash(hash('sha256', $json)); $journal->setHash($hash);
/**
* @var int $rowIndex
* @var string $value
*/
foreach ($row as $rowIndex => $value) { foreach ($row as $rowIndex => $value) {
$value = trim($value); $value = trim($value);
if (strlen($value) > 0) { if (strlen($value) > 0) {
@ -234,8 +263,7 @@ class CsvProcessor implements FileProcessorInterface
*/ */
private function rowAlreadyImported(array $array): bool private function rowAlreadyImported(array $array): bool
{ {
$string = json_encode($array); $hash = $this->getRowHash($array);
$hash = hash('sha256', json_encode($string));
$json = json_encode($hash); $json = json_encode($hash);
$entry = TransactionJournalMeta::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id') $entry = TransactionJournalMeta::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
->where('data', $json) ->where('data', $json)

View File

@ -397,7 +397,7 @@ class ImportStorage
$foreignCurrencyId = $this->getForeignCurrencyId($importJournal, $currency); $foreignCurrencyId = $this->getForeignCurrencyId($importJournal, $currency);
$date = $importJournal->getDate($this->dateFormat); $date = $importJournal->getDate($this->dateFormat);
$transactionType = $this->getTransactionType($amount); $transactionType = $this->getTransactionType($amount);
$opposing = $this->getOpposingAccount($importJournal->opposing, $amount); $opposing = $this->getOpposingAccount($importJournal->opposing, $asset->id, $amount);
// if opposing is an asset account, it's a transfer: // if opposing is an asset account, it's a transfer:
if ($opposing->accountType->type === AccountType::ASSET) { if ($opposing->accountType->type === AccountType::ASSET) {