New code for import routine.

This commit is contained in:
James Cole
2016-07-02 17:33:57 +02:00
parent cbe3fb73a8
commit a56a5fc228
11 changed files with 264 additions and 129 deletions

View File

@@ -10,8 +10,10 @@ use FireflyIII\Import\Importer\ImporterInterface;
use FireflyIII\Models\ImportJob; use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Log;
use SplFileObject; use SplFileObject;
use Storage; use Storage;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use View; use View;
/** /**
@@ -50,9 +52,11 @@ class ImportController extends Controller
// actual code // actual code
$importer = $this->makeImporter($job); $importer = $this->makeImporter($job);
$importer->configure(); $importer->configure();
$data = $importer->getConfigurationData(); $data = $importer->getConfigurationData();
$subTitle = trans('firefly.configure_import');
$subTitleIcon = 'fa-wrench';
return view('import.' . $job->file_type . '.configure', compact('data', 'job')); return view('import.' . $job->file_type . '.configure', compact('data', 'job', 'subTitle', 'subTitleIcon'));
} }
@@ -106,6 +110,28 @@ class ImportController extends Controller
return redirect(route('import.settings', $job->key)); return redirect(route('import.settings', $job->key));
} }
/**
* This step 6. Depending on the importer, this will process the
* settings given and store them.
*
* @param Request $request
* @param ImportJob $job
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @throws FireflyException
*/
public function postSettings(Request $request, ImportJob $job)
{
if (!$this->jobInCorrectStep($job, 'store-settings')) {
return $this->redirectToCorrectStep($job);
}
$importer = $this->makeImporter($job);
$importer->storeSettings($request);
// return redirect to settings (for more settings perhaps)
return redirect(route('import.settings', [$job->key]));
}
/** /**
* Step 5. Depending on the importer, this will show the user settings to * Step 5. Depending on the importer, this will show the user settings to
* fill in. * fill in.
@@ -120,14 +146,16 @@ class ImportController extends Controller
if (!$this->jobInCorrectStep($job, 'settings')) { if (!$this->jobInCorrectStep($job, 'settings')) {
return $this->redirectToCorrectStep($job); return $this->redirectToCorrectStep($job);
} }
$importer = $this->makeImporter($job); $importer = $this->makeImporter($job);
$subTitle = trans('firefy.settings_for_import');
$subTitleIcon = 'fa-wrench';
// now show settings screen to user. // now show settings screen to user.
if ($importer->requireUserSettings()) { if ($importer->requireUserSettings()) {
$data = $importer->getDataForSettings(); $data = $importer->getDataForSettings();
$view = $importer->getViewForSettings(); $view = $importer->getViewForSettings();
return view($view, compact('data', 'job')); return view($view, compact('data', 'job', 'subTitle', 'subTitleIcon'));
} }
// if no more settings, save job and continue to process thing. // if no more settings, save job and continue to process thing.
@@ -155,8 +183,11 @@ class ImportController extends Controller
public function upload(ImportUploadRequest $request, ImportJobRepositoryInterface $repository) public function upload(ImportUploadRequest $request, ImportJobRepositoryInterface $repository)
{ {
// create import job: // create import job:
$type = $request->get('import_file_type'); $type = $request->get('import_file_type');
$job = $repository->create($type); $job = $repository->create($type);
Log::debug('Created new job', ['key' => $job->key, 'id' => $job->id]);
/** @var UploadedFile $upload */
$upload = $request->files->get('import_file'); $upload = $request->files->get('import_file');
$newName = $job->key . '.upload'; $newName = $job->key . '.upload';
$uploaded = new SplFileObject($upload->getRealPath()); $uploaded = new SplFileObject($upload->getRealPath());
@@ -165,6 +196,30 @@ class ImportController extends Controller
$disk = Storage::disk('upload'); $disk = Storage::disk('upload');
$disk->put($newName, $contentEncrypted); $disk->put($newName, $contentEncrypted);
Log::debug('Uploaded file', ['name' => $upload->getClientOriginalName(), 'size' => $upload->getSize(), 'mime' => $upload->getClientMimeType()]);
// store configuration file's content into the job's configuration
// thing.
// otherwise, leave it empty.
if ($request->files->has('configuration_file')) {
/** @var UploadedFile $configFile */
$configFile = $request->files->get('configuration_file');
Log::debug(
'Uploaded configuration file',
['name' => $configFile->getClientOriginalName(), 'size' => $configFile->getSize(), 'mime' => $configFile->getClientMimeType()]
);
$configFileObject = new SplFileObject($configFile->getRealPath());
$configRaw = $configFileObject->fread($configFileObject->getSize());
$configuration = json_decode($configRaw, true);
if (!is_null($configuration) && is_array($configuration)) {
Log::debug('Found configuration', $configuration);
$job->configuration = $configuration;
$job->save();
}
}
return redirect(route('import.configure', [$job->key])); return redirect(route('import.configure', [$job->key]));
} }
@@ -183,6 +238,7 @@ class ImportController extends Controller
return $job->status === 'import_status_never_started'; return $job->status === 'import_status_never_started';
break; break;
case 'settings': case 'settings':
case 'store-settings':
return $job->status === 'import_configuration_saved'; return $job->status === 'import_configuration_saved';
break; break;
} }

View File

@@ -14,10 +14,11 @@ namespace FireflyIII\Import\Importer;
use ExpandedForm; use ExpandedForm;
use FireflyIII\Crud\Account\AccountCrud; use FireflyIII\Crud\Account\AccountCrud;
use FireflyIII\Import\Role\Map;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Models\ImportJob; use FireflyIII\Models\ImportJob;
use Illuminate\Http\Request;
use League\Csv\Reader; use League\Csv\Reader;
use Log;
use Symfony\Component\HttpFoundation\FileBag; use Symfony\Component\HttpFoundation\FileBag;
/** /**
@@ -32,11 +33,38 @@ class CsvImporter implements ImporterInterface
public $job; public $job;
/** /**
* Create initial (empty) configuration array.
*
*
*
* @return bool * @return bool
*/ */
public function configure(): bool public function configure(): bool
{ {
if (is_null($this->job->configuration) || (is_array($this->job->configuration) && count($this->job->configuration) === 0)) {
Log::debug('No config detected, will create empty one.');
$config = [
'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.
];
$this->job->configuration = $config;
$this->job->save();
return true;
}
// need to do nothing, for now. // need to do nothing, for now.
Log::debug('Detected config in upload, will use that one. ', $this->job->configuration);
return true; return true;
} }
@@ -89,15 +117,17 @@ class CsvImporter implements ImporterInterface
'columnCount' => 0, 'columnCount' => 0,
]; ];
if (!isset($config['columns'])) { if ($this->doColumnRoles()) {
// show user column configuration. // show user column role configuration.
$content = $this->job->uploadFileContents(); $content = $this->job->uploadFileContents();
// create CSV reader. // create CSV reader.
$reader = Reader::createFromString($content); $reader = Reader::createFromString($content);
$start = $config['has_headers'] ? 1 : 0; $start = $config['has-headers'] ? 1 : 0;
$end = $start + self::EXAMPLE_ROWS; // first X rows $end = $start + self::EXAMPLE_ROWS; // first X rows
// collect example data in $data['columns']
while ($start < $end) { while ($start < $end) {
$row = $reader->fetchOne($start); $row = $reader->fetchOne($start);
foreach ($row as $index => $value) { foreach ($row as $index => $value) {
@@ -110,21 +140,29 @@ class CsvImporter implements ImporterInterface
$data['columnCount'] = count($row); $data['columnCount'] = count($row);
} }
// make unique // make unique example data
foreach ($data['columns'] as $index => $values) { foreach ($data['columns'] as $index => $values) {
$data['columns'][$index] = array_unique($values); $data['columns'][$index] = array_unique($values);
} }
// TODO preset roles from config
$data['set_roles'] = []; $data['set_roles'] = [];
// collect possible column roles: // collect possible column roles:
$data['available_roles'] = []; $data['available_roles'] = [];
foreach (array_keys(config('csv.import_roles')) as $role) { foreach (array_keys(config('csv.import_roles')) as $role) {
$data['available_roles'][$role] = trans('csv.csv_column_'.$role); $data['available_roles'][$role] = trans('csv.column_' . $role);
} }
$config['column-count'] = $data['columnCount'];
$this->job->configuration = $config;
$this->job->save();
return $data; return $data;
} }
echo 'no settings to do.';
exit;
} }
/** /**
@@ -135,18 +173,10 @@ class CsvImporter implements ImporterInterface
*/ */
public function getViewForSettings(): string public function getViewForSettings(): string
{ {
return 'import.csv.map'; if ($this->doColumnRoles()) {
} return 'import.csv.roles';
}
/** echo 'no view for settings';
* Returns a Map thing used to allow the user to
* define roles for each entry.
*
* @return Map
*/
public function prepareRoles(): Map
{
return 'do not work';
exit; exit;
} }
@@ -174,33 +204,25 @@ class CsvImporter implements ImporterInterface
*/ */
public function saveImportConfiguration(array $data, FileBag $files): bool public function saveImportConfiguration(array $data, FileBag $files): bool
{ {
/*
* TODO file upload is ignored for now.
*/
/** @var AccountCrud $repository */ /** @var AccountCrud $repository */
$repository = app(AccountCrud::class); $repository = app(AccountCrud::class);
$account = $repository->find(intval($data['csv_import_account'])); $account = $repository->find(intval($data['csv_import_account']));
$hasHeaders = isset($data['has_headers']) && intval($data['has_headers']) === 1 ? true : false; $hasHeaders = isset($data['has_headers']) && intval($data['has_headers']) === 1 ? true : false;
$configuration = [ $config = $this->job->configuration;
'has_headers' => $hasHeaders, $config['has-headers'] = $hasHeaders;
'date_format' => $data['date_format'], $config['date-format'] = $data['date_format'];
'csv_delimiter' => $data['csv_delimiter'], $config['delimiter'] = $data['csv_delimiter'];
'csv_import_account' => 0,
'specifics' => [],
];
if (!is_null($account->id)) { if (!is_null($account->id)) {
$configuration['csv_import_account'] = $account->id; $config['import-account'] = $account->id;
} }
// loop specifics. // loop specifics.
if (is_array($data['specifics'])) { if (isset($data['specifics']) && is_array($data['specifics'])) {
foreach ($data['specifics'] as $name => $enabled) { foreach ($data['specifics'] as $name => $enabled) {
$configuration['specifics'][] = $name; $config['specifics'][$name] = 1;
} }
} }
$this->job->configuration = $configuration; $this->job->configuration = $config;
$this->job->save(); $this->job->save();
return true; return true;
@@ -215,4 +237,43 @@ class CsvImporter implements ImporterInterface
{ {
$this->job = $job; $this->job = $job;
} }
/**
* Store the settings filled in by the user, if applicable.
*
* @param Request $request
*
*/
public function storeSettings(Request $request)
{
$config = $this->job->configuration;
$count = $config['column-count'];
$all = $request->all();
$roleSet = 0;
for ($i = 0; $i < $count; $i++) {
$selectedRole = $all['role'][$i] ?? '_ignore';
$doMapping = isset($all['map'][$i]) && $all['map'][$i] == '1' ? true : false;
if ($selectedRole == '_ignore' && $doMapping === true) {
$doMapping = false; // cannot map ignored columns.
}
if ($selectedRole != '_ignore') {
$roleSet++;
}
$config['column-roles'][$i] = $selectedRole;
$config['column-do-mapping'][$i] = $doMapping;
}
if ($roleSet > 0) {
$config['column-roles-complete'] = true;
$this->job->configuration = $config;
$this->job->save();
}
}
/**
* @return bool
*/
private function doColumnRoles(): bool
{
return $this->job->configuration['column-roles-complete'] === false;
}
} }

View File

@@ -13,6 +13,7 @@ namespace FireflyIII\Import\Importer;
use FireflyIII\Import\Role\Map; use FireflyIII\Import\Role\Map;
use FireflyIII\Models\ImportJob; use FireflyIII\Models\ImportJob;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\FileBag; use Symfony\Component\HttpFoundation\FileBag;
/** /**
@@ -44,6 +45,14 @@ interface ImporterInterface
*/ */
public function getDataForSettings(): array; public function getDataForSettings(): array;
/**
* Store the settings filled in by the user, if applicable.
*
* @param Request $request
*
*/
public function storeSettings(Request $request);
/** /**
* This method returns the name of the view that will be shown to the user to further configure * This method returns the name of the view that will be shown to the user to further configure
* the import job. * the import job.
@@ -52,14 +61,6 @@ interface ImporterInterface
*/ */
public function getViewForSettings(): string; public function getViewForSettings(): string;
/**
* Returns a Map thing used to allow the user to
* define roles for each entry.
*
* @return Map
*/
public function prepareRoles(): Map;
/** /**
* This method returns whether or not the user must configure this import * This method returns whether or not the user must configure this import
* job further. * job further.

View File

@@ -171,11 +171,11 @@ return [
'converter' => 'Amount', 'converter' => 'Amount',
'field' => 'amount', 'field' => 'amount',
], ],
'amount-comma-separated' => [ // 'amount-comma-separated' => [
'mappable' => false, // 'mappable' => false,
'converter' => 'AmountComma', // 'converter' => 'AmountComma',
'field' => 'amount', // 'field' => 'amount',
], // ],
'sepa-ct-id' => [ 'sepa-ct-id' => [
'mappable' => false, 'mappable' => false,
'converter' => 'Description', 'converter' => 'Description',

View File

@@ -10,35 +10,58 @@
declare(strict_types = 1); declare(strict_types = 1);
return [ return [
'csv_column__ignore' => '(ignore this column)',
'csv_column_account-iban' => 'Asset account (IBAN)', 'import_configure_title' => 'Configure your import',
'csv_column_account-id' => 'Asset account ID (matching Firefly)', 'import_configure_intro' => 'There are some options for your CSV import.',
'csv_column_account-name' => 'Asset account (name)', 'import_configure_form' => 'Form',
'csv_column_amount' => 'Amount', 'header_help' => 'Check this if the first row of your CSV file are the column titles',
'csv_column_amount-comma-separated' => 'Amount (comma as decimal separator)', 'date_help' => 'Date time format in your CSV. Follow the format like <a href="https://secure.php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters">this page</a> indicates. The default value will parse dates that look like this: :dateExample.',
'csv_column_bill-id' => 'Bill ID (matching Firefly)', 'delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
'csv_column_bill-name' => 'Bill name', 'config_file_help' => 'Select your CSV import configuration here. If you do not know what this is, ignore it. It will be explained later.',
'csv_column_budget-id' => 'Budget ID (matching Firefly)', 'import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the CSV belong to.',
'csv_column_budget-name' => 'Budget name', 'upload_not_writeable' => 'The grey box contains a file path. It should be writeable. Please make sure it is.',
'csv_column_category-id' => 'Category ID (matching Firefly)',
'csv_column_category-name' => 'Category name', // roles
'csv_column_currency-code' => 'Currency code (ISO 4217)', 'column_roles_title' => 'Define column roles',
'csv_column_currency-id' => 'Currency ID (matching Firefly)', 'column_roles_text' => 'Each column contains some data. What data?',
'csv_column_currency-name' => 'Currency name (matching Firefly)', 'column_roles_table' => 'Table',
'csv_column_currency-symbol' => 'Currency symbol (matching Firefly)', 'column_name' => 'Name of column',
'csv_column_date-rent' => 'Rent calculation date', 'column_example' => 'Column example data',
'csv_column_date-transaction' => 'Date', 'column_role' => 'Column data meaning',
'csv_column_description' => 'Description', 'do_map_value' => 'Map these values',
'csv_column_opposing-iban' => 'Opposing account (IBAN)', 'column' => 'Column',
'csv_column_opposing-id' => 'Opposing account ID (matching Firefly)', 'no_example_data' => 'No example data available',
'csv_column_opposing-name' => 'Opposing account (name)', 'store_column_roles' => 'Continue import',
'csv_column_rabo-debet-credit' => 'Rabobank specific debet/credit indicator',
'csv_column_ing-debet-credit' => 'ING specific debet/credit indicator', 'column__ignore' => '(ignore this column)',
'csv_column_sepa-ct-id' => 'SEPA Credit Transfer end-to-end ID', 'column_account-iban' => 'Asset account (IBAN)',
'csv_column_sepa-ct-op' => 'SEPA Credit Transfer opposing account', 'column_account-id' => 'Asset account ID (matching Firefly)',
'csv_column_sepa-db' => 'SEPA Direct Debet', 'column_account-name' => 'Asset account (name)',
'csv_column_tags-comma' => 'Tags (comma separated)', 'column_amount' => 'Amount',
'csv_column_tags-space' => 'Tags (space separated)', 'column_amount-comma-separated' => 'Amount (comma as decimal separator)',
'csv_column_account-number' => 'Asset account (account number)', 'column_bill-id' => 'Bill ID (matching Firefly)',
'csv_column_opposing-number' => 'Opposing account (account number)', 'column_bill-name' => 'Bill name',
'column_budget-id' => 'Budget ID (matching Firefly)',
'column_budget-name' => 'Budget name',
'column_category-id' => 'Category ID (matching Firefly)',
'column_category-name' => 'Category name',
'column_currency-code' => 'Currency code (ISO 4217)',
'column_currency-id' => 'Currency ID (matching Firefly)',
'column_currency-name' => 'Currency name (matching Firefly)',
'column_currency-symbol' => 'Currency symbol (matching Firefly)',
'column_date-rent' => 'Rent calculation date',
'column_date-transaction' => 'Date',
'column_description' => 'Description',
'column_opposing-iban' => 'Opposing account (IBAN)',
'column_opposing-id' => 'Opposing account ID (matching Firefly)',
'column_opposing-name' => 'Opposing account (name)',
'column_rabo-debet-credit' => 'Rabobank specific debet/credit indicator',
'column_ing-debet-credit' => 'ING specific debet/credit indicator',
'column_sepa-ct-id' => 'SEPA Credit Transfer end-to-end ID',
'column_sepa-ct-op' => 'SEPA Credit Transfer opposing account',
'column_sepa-db' => 'SEPA Direct Debet',
'column_tags-comma' => 'Tags (comma separated)',
'column_tags-space' => 'Tags (space separated)',
'column_account-number' => 'Asset account (account number)',
'column_opposing-number' => 'Opposing account (account number)',
]; ];

View File

@@ -749,18 +749,12 @@ return [
'split_this_transfer' => 'Split this transfer', 'split_this_transfer' => 'Split this transfer',
// import // import
'configuration_file_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you.',
'import_data_index' => 'Index',
'import_file_type_csv' => 'CSV (comma separated values)', 'import_file_type_csv' => 'CSV (comma separated values)',
'import_file_type_help' => 'Select the type of file you will upload', 'import_file_type_help' => 'Select the type of file you will upload',
'import_start' => 'Start the import', 'import_start' => 'Start the import',
'import_csv_configure_title' => 'Configure your import', 'configure_import' => 'Further configure your import',
'import_csv_configure_intro' => 'There are some options for your CSV import.', 'import_finish_configuration' => 'Finish configuration',
'import_csv_configure_form' => 'Form', 'settings_for_import' => 'Settings',
'csv_header_help' => 'Check this if the first row of your CSV file are the column titles',
'csv_date_help' => 'Date time format in your CSV. Follow the format like <a href="https://secure.php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters">this page</a> indicates. The default value will parse dates that look like this: :dateExample.',
'csv_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
'csv_csv_config_file_help' => 'Select your CSV import configuration here. If you do not know what this is, ignore it. It will be explained later.',
'csv_import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the CSV belong to.',
'csv_upload_not_writeable' => 'The grey box contains a file path. It should be writeable. Please make sure it is.',
]; ];

View File

@@ -133,6 +133,7 @@ return [
// import // import
'import_file' => 'Import file', 'import_file' => 'Import file',
'configuration_file' => 'Configuration file',
'import_file_type' => 'Import file type', 'import_file_type' => 'Import file type',
'csv_comma' => 'A comma (,)', 'csv_comma' => 'A comma (,)',
'csv_semicolon' => 'A semicolon (;)', 'csv_semicolon' => 'A semicolon (;)',
@@ -142,5 +143,4 @@ return [
'csv_config' => 'CSV import configuration', 'csv_config' => 'CSV import configuration',
]; ];

View File

@@ -10,11 +10,11 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">{{ 'import_csv_configure_title'|_ }}</h3> <h3 class="box-title">{{ trans('csv.import_configure_title') }}</h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<p> <p>
{{ 'import_csv_configure_intro'|_ }} {{ trans('csv.import_configure_intro') }}
</p> </p>
</div> </div>
</div> </div>
@@ -29,17 +29,14 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">{{ 'import_csv_configure_form'|_ }}</h3> <h3 class="box-title">{{ trans('csv.import_configure_form') }}</h3>
</div> </div>
<div class="box-body"> <div class="box-body">
{{ ExpandedForm.checkbox('has_headers',1,null,{helpText: 'csv_header_help'|_}) }} {{ ExpandedForm.checkbox('has_headers',1,job.configuration['has-headers'],{helpText: trans('csv.header_help')}) }}
{{ ExpandedForm.text('date_format','Ymd',{helpText: trans('firefly.csv_date_help', {dateExample: phpdate('Ymd')}) }) }} {{ ExpandedForm.text('date_format',job.configuration['date-format'],{helpText: trans('csv.date_help', {dateExample: phpdate('Ymd')}) }) }}
{{ ExpandedForm.select('csv_delimiter', data.delimiters, 0, {helpText: 'csv_delimiter_help'|_} ) }} {{ ExpandedForm.select('csv_delimiter', data.delimiters, job.configuration['delimiter'], {helpText: trans('csv.delimiter_help') } ) }}
{{ ExpandedForm.select('csv_import_account', data.accounts, 0, {helpText: trans('csv.import_account_help')} ) }}
{{ ExpandedForm.file('csv_config',{helpText: 'csv_csv_config_file_help'|_}) }}
{{ ExpandedForm.select('csv_import_account', data.accounts, 0, {helpText: 'csv_import_account_help'|_} ) }}
{% for type, specific in data.specifics %} {% for type, specific in data.specifics %}
<div class="form-group"> <div class="form-group">
@@ -49,7 +46,8 @@
<div class="col-sm-8"> <div class="col-sm-8">
<div class="radio"><label> <div class="radio"><label>
{{ Form.checkbox('specifics['~type~']', '1', Input.old('specifics')[type] == '1', {'id': type ~ '_label'}) }} {{ Form.checkbox('specifics['~type~']', '1',
job.configuration.specifics[type] == '1', {'id': type ~ '_label'}) }}
{{ specific.description }} {{ specific.description }}
</label> </label>
</div> </div>
@@ -66,7 +64,7 @@
<div class="col-sm-8"> <div class="col-sm-8">
<pre>{{ data.upload_path }}</pre> <pre>{{ data.upload_path }}</pre>
<p class="text-danger"> <p class="text-danger">
{{ 'csv_upload_not_writeable'|_ }} {{ trans('csv.upload_not_writeable') }}
</p> </p>
</div> </div>
</div> </div>
@@ -82,7 +80,7 @@
<div class="box"> <div class="box">
<div class="box-body"> <div class="box-body">
<button type="submit" class="pull-right btn btn-success"> <button type="submit" class="pull-right btn btn-success">
{{ 'csv_upload_button'|_ }} {{ 'import_finish_configuration'|_ }}
</button> </button>
</div> </div>
</div> </div>

View File

@@ -10,10 +10,10 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">{{ 'csv_column_roles_title'|_ }}</h3> <h3 class="box-title">{{ trans('csv.column_roles_title') }}</h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<p>{{ 'csv_column_roles_text'|_ }}</p> <p>{{ trans('csv.column_roles_text') }}</p>
</div> </div>
</div> </div>
@@ -21,30 +21,32 @@
</div> </div>
<form action="{{ route('import.postSettings', job.key) }}" method="post"> <form action="{{ route('import.postSettings', job.key) }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/> <input type="hidden" name="_token" value="{{ csrf_token() }}"/>
<input type="hidden" name="settings" value="roles"/>
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">{{ 'csv_column_roles_table'|_ }}</h3> <h3 class="box-title">{{ trans('csv.column_roles_table') }}</h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th style="width:20%;">{{ 'csv_column_name'|_ }}</th> <th style="width:20%;">{{ trans('csv.column_name') }}</th>
<th style="width:40%;">{{ 'csv_column_example'|_ }}</th> <th style="width:40%;">{{ trans('csv.column_example') }}</th>
<th style="width:30%;">{{ 'csv_column_role'|_ }}</th> <th style="width:30%;">{{ trans('csv.column_role') }}</th>
<th style="width:10%;">{{ 'csv_do_map_value'|_ }}</th> <th style="width:10%;">{{ trans('csv.do_map_value') }}</th>
</tr> </tr>
</thead> </thead>
{% for i in 0..data.columnCount %} {% for i in 0..(data.columnCount-1) %}
<tr> <tr>
<td>Column #{{ loop.index }}</td> <td>{{ trans('csv.column') }} #{{ loop.index }}</td>
<td> <td>
{% if data.columns[i]|length == 0 %} {% if data.columns[i]|length == 0 %}
<em>No example data available</em> <em>{{ trans('csv.no_example_data') }}</em>
{% else %} {% else %}
{% for example in data.columns[i] %} {% for example in data.columns[i] %}
<code>{{ example }}</code><br /> <code>{{ example }}</code><br />
@@ -52,10 +54,10 @@
{% endif %} {% endif %}
<td> <td>
{{ Form.select(('role['~index~']'), data.available_roles,data.set_roles[index],{class: 'form-control'}) }} {{ Form.select(('role['~loop.index0~']'), data.available_roles,data.set_roles[index],{class: 'form-control'}) }}
</td> </td>
<td> <td>
{# Form.checkbox(('map['~index~']'),1,map[index]) #} {{ Form.checkbox(('map['~loop.index0~']'),1,map[index]) }}
</td> </td>
</tr> </tr>
@@ -74,9 +76,8 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box"> <div class="box">
<div class="box-body"> <div class="box-body">
<a href="{{ route('import.index') }}" class="btn btn-danger"><i class="fa fa-arrow-left"></i> {{ 'csv_go_back'|_ }}</a>
<button type="submit" class="btn btn-success pull-right"> <button type="submit" class="btn btn-success pull-right">
{{ 'csv_continue'|_ }} <i class="fa fa-arrow-right"></i> {{ trans('csv.store_column_roles') }} <i class="fa fa-arrow-right"></i>
</button> </button>
</div> </div>
</div> </div>

View File

@@ -26,6 +26,7 @@
<div class="col-lg-6 col-md-8 col-sm-12 col-xs-12"> <div class="col-lg-6 col-md-8 col-sm-12 col-xs-12">
{{ ExpandedForm.file('import_file', {helpText: 'import_file_help'|_}) }} {{ ExpandedForm.file('import_file', {helpText: 'import_file_help'|_}) }}
{{ ExpandedForm.file('configuration_file', {helpText: 'configuration_file_help'|_}) }}
{{ ExpandedForm.select('import_file_type', importFileTypes, defaultImportType, {'helpText' : 'import_file_type_help'|_}) }} {{ ExpandedForm.select('import_file_type', importFileTypes, defaultImportType, {'helpText' : 'import_file_type_help'|_}) }}

View File

@@ -59,7 +59,7 @@
{% for data in transactions %} {% for data in transactions %}
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">{{ data[1].name }}</h3> <h3 class="box-title"><a href="{{ route('accounts.show', data[1].id) }}">{{ data[1].name }}</a></h3>
<!-- ACTIONS MENU --> <!-- ACTIONS MENU -->
<div class="box-tools pull-right"> <div class="box-tools pull-right">