diff --git a/app/Generator/Chart/Bill/ChartJsBillChartGenerator.php b/app/Generator/Chart/Bill/ChartJsBillChartGenerator.php index 4afa0c6ea7..c7ba8172d5 100644 --- a/app/Generator/Chart/Bill/ChartJsBillChartGenerator.php +++ b/app/Generator/Chart/Bill/ChartJsBillChartGenerator.php @@ -1,10 +1,4 @@ mapped[$this->index][$this->value])) { - $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); - } else { - // find or create new account: - $accountType = AccountType::where('type', 'Asset account')->first(); - $account = Account::firstOrCreateEncrypted( - [ - 'name' => $this->value, - //'iban' => $this->value, - 'user_id' => Auth::user()->id, - 'account_type_id' => $accountType->id, - 'active' => true, - ] - ); - if ($account->getErrors()->count() > 0) { - Log::error('Create or find asset account: ' . json_encode($account->getErrors()->all())); - } - } - - return $account; - } -} \ No newline at end of file diff --git a/app/Helpers/Csv/Converter/AccountId.php b/app/Helpers/Csv/Converter/AccountId.php new file mode 100644 index 0000000000..ef555174a6 --- /dev/null +++ b/app/Helpers/Csv/Converter/AccountId.php @@ -0,0 +1,29 @@ +mapped[$this->index][$this->value])) { + $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); + } else { + $account = Auth::user()->accounts()->find($this->value); + } + + return $account; + } +} \ No newline at end of file diff --git a/app/Helpers/Csv/Converter/Amount.php b/app/Helpers/Csv/Converter/Amount.php index de2e9d5b08..38acf974b5 100644 --- a/app/Helpers/Csv/Converter/Amount.php +++ b/app/Helpers/Csv/Converter/Amount.php @@ -1,10 +1,4 @@ mapped[$this->index][$this->value])) { + $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); + + return $account; + } + // find or create new account: + $accountType = AccountType::where('type', 'Asset account')->first(); + $set = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get(); + /** @var Account $entry */ + foreach ($set as $entry) { + if ($entry->iban == $this->value) { + return $entry; + } + } + + // create it if doesnt exist. + $account = Account::firstOrCreateEncrypted( + [ + 'name' => $this->value, + 'iban' => $this->value, + 'user_id' => Auth::user()->id, + 'account_type_id' => $accountType->id, + 'active' => 1, + ] + ); + + return $account; + } +} \ No newline at end of file diff --git a/app/Helpers/Csv/Converter/AssetAccountName.php b/app/Helpers/Csv/Converter/AssetAccountName.php new file mode 100644 index 0000000000..cf1ff1a666 --- /dev/null +++ b/app/Helpers/Csv/Converter/AssetAccountName.php @@ -0,0 +1,50 @@ +mapped[$this->index][$this->value])) { + $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); + + return $account; + } + // find or create new account: + $accountType = AccountType::where('type', 'Asset account')->first(); + $set = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get(); + /** @var Account $entry */ + foreach ($set as $entry) { + if ($entry->name == $this->value) { + return $entry; + } + } + + // create it if doesnt exist. + $account = Account::firstOrCreateEncrypted( + [ + 'name' => $this->value, + 'iban' => '', + 'user_id' => Auth::user()->id, + 'account_type_id' => $accountType->id, + 'active' => 1, + ] + ); + + return $account; + } +} \ No newline at end of file diff --git a/app/Helpers/Csv/Converter/BillId.php b/app/Helpers/Csv/Converter/BillId.php new file mode 100644 index 0000000000..975ce66771 --- /dev/null +++ b/app/Helpers/Csv/Converter/BillId.php @@ -0,0 +1,30 @@ +mapped[$this->index][$this->value])) { + $bill = Auth::user()->bills()->find($this->mapped[$this->index][$this->value]); + } else { + $bill = Auth::user()->bills()->find($this->value); + } + + return $bill; + } +} \ No newline at end of file diff --git a/app/Helpers/Csv/Converter/BillName.php b/app/Helpers/Csv/Converter/BillName.php new file mode 100644 index 0000000000..4e15b1bdbd --- /dev/null +++ b/app/Helpers/Csv/Converter/BillName.php @@ -0,0 +1,38 @@ +mapped[$this->index][$this->value])) { + $bill = Auth::user()->bills()->find($this->mapped[$this->index][$this->value]); + } else { + + $bills = Auth::user()->bills()->get(); + /** @var Bill $bill */ + foreach ($bills as $bill) { + if ($bill->name == $this->value) { + return $bill; + } + } + } + + return $bill; + } +} \ No newline at end of file diff --git a/app/Helpers/Csv/Converter/ConverterInterface.php b/app/Helpers/Csv/Converter/ConverterInterface.php index 1e9eb275e3..aad4e3999a 100644 --- a/app/Helpers/Csv/Converter/ConverterInterface.php +++ b/app/Helpers/Csv/Converter/ConverterInterface.php @@ -1,10 +1,4 @@ errors; + } + + /** + * @return int + */ + public function getImported() + { + return $this->imported; + } + + /** + * @return int + */ + public function getRows() + { + return $this->rows; + } + + /** + * @throws FireflyException */ public function run() { @@ -46,15 +76,18 @@ class Importer $this->roles = $this->data->getRoles(); $this->mapped = $this->data->getMapped(); foreach ($this->data->getReader() as $index => $row) { - Log::debug('Now at row ' . $index); - $result = $this->importRow($row); - if (!($result === true)) { - Log::error('Caught error at row #' . $index . ': ' . $result); - $this->errors[$index] = $result; + if (($this->data->getHasHeaders() && $index > 1) || !$this->data->getHasHeaders()) { + $this->rows++; + Log::debug('Now at row ' . $index); + $result = $this->importRow($row); + if (!($result === true)) { + Log::error('Caught error at row #' . $index . ': ' . $result); + $this->errors[$index] = $result; + } else { + $this->imported++; + } } } - - return count($this->errors); } /** @@ -80,8 +113,12 @@ class Importer if (is_null($field)) { throw new FireflyException('No place to store value of type "' . $role . '".'); } - /** @var ConverterInterface $converter */ - $converter = App::make('FireflyIII\Helpers\Csv\Converter\\' . $class); + try { + /** @var ConverterInterface $converter */ + $converter = App::make('FireflyIII\Helpers\Csv\Converter\\' . $class); + } catch (ReflectionException $e) { + throw new FireflyException('Cannot continue with column of type "' . $role . '" because class "' . $class . '" cannot be found.'); + } $converter->setData($data); // the complete array so far. $converter->setField($field); $converter->setIndex($index); @@ -122,6 +159,8 @@ class Importer 'amount-modifier' => 1, 'ignored' => null, 'date-rent' => null, + 'bill' => null, + 'bill-id' => null, ]; } @@ -147,19 +186,27 @@ class Importer $accountType = AccountType::where('type', 'Revenue account')->first(); } - if(strlen($data['description']) == 0) { + if (strlen($data['description']) == 0) { $data['description'] = trans('firefly.csv_empty_description'); } + // fix currency + if (is_null($data['currency'])) { + $currencyPreference = Preferences::get('currencyPreference', 'EUR'); + $data['currency'] = TransactionCurrency::whereCode($currencyPreference->data)->first(); + } + if (!is_null($data['bill'])) { + $data['bill-id'] = $data['bill']->id; + } // do bank specific fixes: $specifix = new Specifix(); $specifix->setData($data); $specifix->setRow($row); - $specifix->fix($data, $row); + //$specifix->fix($data, $row); // TODO // get data back: - $data = $specifix->getData(); + //$data = $specifix->getData(); // TODO $data['opposing-account-object'] = Account::firstOrCreateEncrypted( [ @@ -215,11 +262,11 @@ class Importer [ 'user_id' => Auth::user()->id, 'transaction_type_id' => $transactionType->id, - 'bill_id' => null, 'transaction_currency_id' => $data['currency']->id, 'description' => $data['description'], 'completed' => 0, 'date' => $date, + 'bill_id' => $data['bill-id'], ] ); $errors = $journal->getErrors()->merge($errors); @@ -261,14 +308,5 @@ class Importer $this->data = $data; } - /** - * @param $value - * - * @return Carbon - */ - protected function parseDate($value) - { - return Carbon::createFromFormat($this->data->getDateFormat(), $value); - } } \ No newline at end of file diff --git a/app/Helpers/Csv/Mapper/AssetAccount.php b/app/Helpers/Csv/Mapper/AssetAccount.php index d8fe71cc2d..44982539b5 100644 --- a/app/Helpers/Csv/Mapper/AssetAccount.php +++ b/app/Helpers/Csv/Mapper/AssetAccount.php @@ -1,10 +1,4 @@ data->getReader()->fetchOne(); $count = count($firstRow); $headers = []; - $example = $this->data->getReader()->fetchOne(); + $example = $this->data->getReader()->fetchOne(1); $availableRoles = []; $roles = $this->data->getRoles(); $map = $this->data->getMap(); @@ -166,6 +161,9 @@ class CsvController extends Controller if ($role['mappable'] === true && !isset($role['mapper'])) { $unsupported[] = trans('firefly.csv_unsupported_map', ['columnRole' => $role['name']]); } + if (!isset($role['field'])) { + $unsupported[] = trans('firefly.csv_cannot_store_value', ['columnRole' => $role['name']]); + } } sort($unsupported); @@ -309,8 +307,13 @@ class CsvController extends Controller } Log::debug('Done importing!'); - echo 'display result'; - exit; + $rows = $importer->getRows(); + $errors = $importer->getErrors(); + $imported = $importer->getImported(); + + Preferences::mark(); + + return view('csv.process', compact('rows', 'errors', 'imported')); } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 987967585c..d57649bd24 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -40,6 +40,9 @@ class HomeController extends Controller */ public function flush() { + + Preferences::mark(); + // get all tags. // update all counts: $tags = Tag::get(); @@ -54,6 +57,7 @@ class HomeController extends Controller } + Session::clear(); return Redirect::route('index'); diff --git a/app/Models/Account.php b/app/Models/Account.php index 9b77363657..42bf226a20 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -76,7 +76,7 @@ class Account extends Model // everything but the name: $query = Account::orderBy('id'); foreach ($fields as $name => $value) { - if ($name != 'name') { + if ($name != 'name' && $name != 'iban') { $query->where($name, $value); } } @@ -87,6 +87,11 @@ class Account extends Model return $account; } } + // account must have a name. If not set, use IBAN. + if (!isset($fields['name'])) { + $fields['name'] = $fields['iban']; + } + // create it! $account = Account::create($fields); diff --git a/config/csv.php b/config/csv.php index e141c2f438..f5ebdad7fa 100644 --- a/config/csv.php +++ b/config/csv.php @@ -8,12 +8,16 @@ return [ 'field' => 'ignored', ], 'bill-id' => [ - 'name' => 'Bill ID (matching Firefly)', - 'mappable' => true, + 'name' => 'Bill ID (matching Firefly)', + 'mappable' => false, + 'field' => 'bill', + 'converter' => 'BillId' ], 'bill-name' => [ - 'name' => 'Bill name', - 'mappable' => true, + 'name' => 'Bill name', + 'mappable' => true, + 'converter' => 'BillName', + 'field' => 'bill', ], 'currency-id' => [ 'name' => 'Currency ID (matching Firefly)', @@ -83,32 +87,38 @@ return [ 'mappable' => true, ], 'account-id' => [ - 'name' => 'Asset account ID (matching Firefly)', - 'mappable' => true, + 'name' => 'Asset account ID (matching Firefly)', + 'mappable' => true, + 'mapper' => 'AssetAccount', + 'field' => 'asset-account', + 'converter' => 'AccountId' ], 'account-name' => [ - 'name' => 'Asset account name', - 'mappable' => true, + 'name' => 'Asset account name', + 'mappable' => true, + 'mapper' => 'AssetAccount', + 'field' => 'asset-account', + 'converter' => 'AssetAccountName' ], 'account-iban' => [ 'name' => 'Asset account IBAN', 'mappable' => true, - 'converter' => 'AccountIban', + 'converter' => 'AssetAccountIban', 'field' => 'asset-account', 'mapper' => 'AssetAccount' ], 'opposing-id' => [ - 'name' => 'Expense or revenue account ID (matching Firefly)', + 'name' => 'Opposing account account ID (matching Firefly)', 'mappable' => true, ], 'opposing-name' => [ - 'name' => 'Expense or revenue account name', + 'name' => 'Opposing account name', 'mappable' => true, 'converter' => 'OpposingName', 'field' => 'opposing-account' ], 'opposing-iban' => [ - 'name' => 'Expense or revenue account IBAN', + 'name' => 'Opposing account IBAN', 'mappable' => true, ], 'amount' => [ diff --git a/resources/lang/en/firefly.php b/resources/lang/en/firefly.php index 1374379ef4..85a663d095 100644 --- a/resources/lang/en/firefly.php +++ b/resources/lang/en/firefly.php @@ -62,6 +62,14 @@ return [ 'csv_index_unsupported_warning' => 'The CSV importer is yet incapable of doing the following:', 'csv_unsupported_map' => 'The importer cannot map the column ":columnRole" to existing values in the database.', 'csv_unsupported_value' => 'The importer does not know how to handle values in columns marked as ":columnRole".', + 'csv_cannot_store_value' => 'The importer has not reserved space for columns marked ":columnRole" and will be incapable of processing them.', + 'csv_process_title' => 'CVS import finished', + 'csv_process_text' => 'The CVS importer has finished and has imported :rows rows', + 'csv_row' => 'Row', + 'csv_import_with_errors' => 'There was one error.|There were :errors errors.', + 'csv_error_see_logs' => 'Check the log files to see details.', + 'csv_start_over' => 'Import again', + 'csv_to_index' => 'Back home', // 'csv_index_text' => 'Here be explanation.', // 'csv_upload_form' => 'Upload form', // 'upload_csv_file' => 'Upload CSV file', diff --git a/resources/twig/csv/download-config.twig b/resources/twig/csv/download-config.twig index 302670614d..c1f8a7eb88 100644 --- a/resources/twig/csv/download-config.twig +++ b/resources/twig/csv/download-config.twig @@ -40,7 +40,7 @@
+ + {{ trans('firefly.csv_process_text',{rows: rows}) }} +
+ + {% if errors|length > 0 %} +{{ Lang.choice('firefly.csv_import_with_errors',errors|length,{errors: errors|length}) }}
++ {{ trans('firefly.csv_error_see_logs') }} +
+ {% endif %} + +