From efe9933721a6c0fdb3d6574659962c65724aee11 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 11 Aug 2016 08:00:02 +0200 Subject: [PATCH] Import storage routine is creating the first transaction journals. Signed-off-by: James Cole --- .gitignore | 1 + app/Console/Commands/Import.php | 10 +- app/Import/ImportStorage.php | 158 ++++++++++++++++++++++++++++ app/Import/ImportValidator.php | 16 +-- app/Import/Importer/CsvImporter.php | 1 + app/Import/Setup/CsvSetup.php | 10 +- 6 files changed, 181 insertions(+), 15 deletions(-) create mode 100644 app/Import/ImportStorage.php diff --git a/.gitignore b/.gitignore index 76b63316ba..3285ef1ed2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ _development .env.local result.html +test-import.sh diff --git a/app/Console/Commands/Import.php b/app/Console/Commands/Import.php index 483eb179d9..bd02d71384 100644 --- a/app/Console/Commands/Import.php +++ b/app/Console/Commands/Import.php @@ -13,6 +13,7 @@ namespace FireflyIII\Console\Commands; use FireflyIII\Crud\Account\AccountCrud; use FireflyIII\Import\Importer\ImporterInterface; +use FireflyIII\Import\ImportStorage; use FireflyIII\Import\ImportValidator; use FireflyIII\Import\Logging\CommandHandler; use FireflyIII\Models\ImportJob; @@ -92,7 +93,14 @@ class Import extends Command $validator->setDefaultImportAccount($repository->find($job->configuration['import-account'])); } - $validator->clean(); + $cleaned = $validator->clean(); + + // then import collection: + $storage = new ImportStorage($collection); + $storage->setUser($job->user); + + // and run store routine: + $storage->store(); $this->line('Something something import: ' . $jobKey); diff --git a/app/Import/ImportStorage.php b/app/Import/ImportStorage.php new file mode 100644 index 0000000000..178c6bdb25 --- /dev/null +++ b/app/Import/ImportStorage.php @@ -0,0 +1,158 @@ +entries = $entries; + + } + + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + + /** + * + */ + public function store() + { + foreach ($this->entries as $entry) { + $this->storeSingle($entry); + } + + } + + /** + * @param float $amount + * + * @return string + */ + private function makePositive(float $amount): string + { + $amount = strval($amount); + if (bccomp($amount, '0', 4) === -1) { // left is larger than right + $amount = bcmul($amount, '-1'); + } + + return $amount; + } + + /** + * @param ImportEntry $entry + */ + private function storeSingle(ImportEntry $entry) + { + Log::debug('Going to store entry!'); + $billId = is_null($entry->fields['bill']) ? null : $entry->fields['bill']->id; + $journalData = [ + 'user_id' => $entry->user->id, + 'transaction_type_id' => $entry->fields['transaction-type']->id, + 'bill_id' => $billId, + 'transaction_currency_id' => $entry->fields['currency']->id, + 'description' => $entry->fields['description'], + 'date' => $entry->fields['date-transaction'], + 'interest_date' => $entry->fields['date-interest'], + 'book_date' => $entry->fields['date-book'], + 'process_date' => $entry->fields['date-process'], + 'completed' => 0, + ]; + /** @var TransactionJournal $journal */ + $journal = TransactionJournal::create($journalData); + $amount = $this->makePositive($entry->fields['amount']); + + Log::debug('Created journal', ['id' => $journal->id]); + + // then create transactions. Single ones, unfortunately. + switch ($entry->fields['transaction-type']->type) { + default: + throw new FireflyException('ImportStorage cannot handle ' . $entry->fields['transaction-type']->type); + case TransactionType::WITHDRAWAL: + $source = $entry->fields['asset-account']; + $destination = $entry->fields['opposing-account']; + // make amount positive, if it is not. + break; + case TransactionType::DEPOSIT: + $source = $entry->fields['opposing-account']; + $destination = $entry->fields['asset-account']; + break; + case TransactionType::TRANSFER: + // depends on amount: + if ($entry->fields['amount'] < 0) { + $source = $entry->fields['asset-account']; + $destination = $entry->fields['opposing-account']; + break; + } + $destination = $entry->fields['asset-account']; + $source = $entry->fields['opposing-account']; + break; + } + + // create new transactions. This is something that needs a rewrite for multiple/split transactions. + $sourceData = [ + 'account_id' => $source->id, + 'transaction_journal_id' => $journal->id, + 'description' => $journalData['description'], + 'amount' => bcmul($amount, '-1'), + ]; + + $destinationData = [ + 'account_id' => $destination->id, + 'transaction_journal_id' => $journal->id, + 'description' => $journalData['description'], + 'amount' => $amount, + ]; + + $one = Transaction::create($sourceData); + $two = Transaction::create($destinationData); + Log::debug('Created transactions', ['source' => $one->id,'destination' => $two->id]); + + $journal->completed = 1; + $journal->save(); + + // now attach budget and so on. + + + + } +} \ No newline at end of file diff --git a/app/Import/ImportValidator.php b/app/Import/ImportValidator.php index 761f421b13..e53a503bac 100644 --- a/app/Import/ImportValidator.php +++ b/app/Import/ImportValidator.php @@ -48,7 +48,7 @@ class ImportValidator /** * Clean collection by filling in all the blanks. */ - public function clean() + public function clean(): Collection { /** @var ImportEntry $entry */ foreach ($this->entries as $entry) { @@ -67,13 +67,7 @@ class ImportValidator $this->setTransactionType($entry); $this->setTransactionCurrency($entry); } - - - /** @var ImportEntry $entry */ - foreach ($this->entries as $entry) { - Log::debug('Description: ' . $entry->fields['description']); - } - + return $this->entries; } /** @@ -328,13 +322,13 @@ class ImportValidator $type = $entry->fields['opposing-account']->accountType->type; switch ($type) { case AccountType::EXPENSE: - $entry->fields['transaction-type'] = TransactionType::WITHDRAWAL; + $entry->fields['transaction-type'] = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); break; case AccountType::REVENUE: - $entry->fields['transaction-type'] = TransactionType::DEPOSIT; + $entry->fields['transaction-type'] = TransactionType::whereType(TransactionType::DEPOSIT)->first(); break; case AccountType::ASSET: - $entry->fields['transaction-type'] = TransactionType::TRANSFER; + $entry->fields['transaction-type'] = TransactionType::whereType(TransactionType::TRANSFER)->first(); break; } } diff --git a/app/Import/Importer/CsvImporter.php b/app/Import/Importer/CsvImporter.php index 9f74eab0ec..8abaab2024 100644 --- a/app/Import/Importer/CsvImporter.php +++ b/app/Import/Importer/CsvImporter.php @@ -42,6 +42,7 @@ class CsvImporter implements ImporterInterface // create CSV reader. $reader = Reader::createFromString($content); + $reader->setDelimiter($config['delimiter']); $start = $config['has-headers'] ? 1 : 0; $results = $reader->fetch(); $collection = new Collection; diff --git a/app/Import/Setup/CsvSetup.php b/app/Import/Setup/CsvSetup.php index 53d445037f..5dc009b90e 100644 --- a/app/Import/Setup/CsvSetup.php +++ b/app/Import/Setup/CsvSetup.php @@ -191,7 +191,8 @@ class CsvSetup implements SetupInterface { /** @var AccountCrud $repository */ $repository = app(AccountCrud::class, [auth()->user()]); - $account = $repository->find(intval($data['csv_import_account'])); + $importId = $data['csv_import_account'] ?? 0; + $account = $repository->find(intval($importId)); $hasHeaders = isset($data['has_headers']) && intval($data['has_headers']) === 1 ? true : false; $config = $this->job->configuration; @@ -199,14 +200,14 @@ class CsvSetup implements SetupInterface $config['date-format'] = $data['date_format']; $config['delimiter'] = $data['csv_delimiter']; - Log::debug('Entered import account.', ['id' => $data['csv_import_account']]); + Log::debug('Entered import account.', ['id' => $importId]); if (!is_null($account->id)) { Log::debug('Found account.', ['id' => $account->id, 'name' => $account->name]); $config['import-account'] = $account->id; } else { - Log::error('Could not find anything for csv_import_account.', ['id' => $data['csv_import_account']]); + Log::error('Could not find anything for csv_import_account.', ['id' => $importId]); } // loop specifics. if (isset($data['specifics']) && is_array($data['specifics'])) { @@ -353,7 +354,9 @@ class CsvSetup implements SetupInterface // in order to actually map we also need all possible values from the CSV file. $content = $this->job->uploadFileContents(); + /** @var Reader $reader */ $reader = Reader::createFromString($content); + $reader->setDelimiter($config['delimiter']); $results = $reader->fetch(); foreach ($results as $rowIndex => $row) { @@ -405,6 +408,7 @@ class CsvSetup implements SetupInterface // create CSV reader. $reader = Reader::createFromString($content); + $reader->setDelimiter($config['delimiter']); $start = $config['has-headers'] ? 1 : 0; $end = $start + self::EXAMPLE_ROWS; // first X rows