mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'develop' of github.com:JC5/firefly-iii into develop
This commit is contained in:
commit
e8e7ab01d2
@ -103,7 +103,7 @@ class AccountController extends Controller
|
||||
$typeName = config('firefly.shortNamesByFullName.' . $type);
|
||||
$name = $account->name;
|
||||
$moveTo = $crud->find(intval(Input::get('move_account_before_delete')));
|
||||
|
||||
|
||||
$crud->destroy($account, $moveTo);
|
||||
|
||||
Session::flash('success', strval(trans('firefly.' . $typeName . '_deleted', ['name' => $name])));
|
||||
@ -271,6 +271,7 @@ class AccountController extends Controller
|
||||
$end = Navigation::endOfPeriod($carbon, $range);
|
||||
$subTitle = $account->name . ' (' . Navigation::periodShow($start, $range) . ')';
|
||||
$page = intval(Input::get('page'));
|
||||
$page = $page === 0 ? 1 : $page;
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$set = $repository->journalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
|
@ -13,8 +13,10 @@ namespace FireflyIII\Http\Controllers\Chart;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Crud\Account\AccountCrudInterface;
|
||||
use FireflyIII\Generator\Chart\Category\CategoryChartGeneratorInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
@ -48,12 +50,13 @@ class CategoryController extends Controller
|
||||
/**
|
||||
* Show an overview for a category for all time, per month/week/year.
|
||||
*
|
||||
* @param CRI $repository
|
||||
* @param Category $category
|
||||
* @param CRI $repository
|
||||
* @param AccountCrudInterface $crud
|
||||
* @param Category $category
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function all(CRI $repository, Category $category)
|
||||
public function all(CRI $repository, AccountCrudInterface $crud, Category $category)
|
||||
{
|
||||
$start = $repository->firstUseDate($category, new Collection);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
@ -62,6 +65,7 @@ class CategoryController extends Controller
|
||||
$end = new Carbon;
|
||||
$entries = new Collection;
|
||||
$cache = new CacheProperties;
|
||||
$accounts = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('all');
|
||||
@ -72,8 +76,8 @@ class CategoryController extends Controller
|
||||
|
||||
while ($start <= $end) {
|
||||
$currentEnd = Navigation::endOfPeriod($start, $range);
|
||||
$spent = $repository->spentInPeriod($categoryCollection, new Collection, $start, $currentEnd);
|
||||
$earned = $repository->earnedInPeriod($categoryCollection, new Collection, $start, $currentEnd);
|
||||
$spent = $repository->spentInPeriod($categoryCollection, $accounts, $start, $currentEnd);
|
||||
$earned = $repository->earnedInPeriod($categoryCollection, $accounts, $start, $currentEnd);
|
||||
$date = Navigation::periodShow($start, $range);
|
||||
$entries->push([clone $start, $date, $spent, $earned]);
|
||||
$start = Navigation::addPeriod($start, $range, 0);
|
||||
@ -250,18 +254,24 @@ class CategoryController extends Controller
|
||||
{
|
||||
$categoryCollection = new Collection([$category]);
|
||||
$cache = new CacheProperties;
|
||||
/** @var AccountCrudInterface $crud */
|
||||
$crud = app(AccountCrudInterface::class);
|
||||
$accounts = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($accounts);
|
||||
$cache->addProperty($category->id);
|
||||
$cache->addProperty('specific-period');
|
||||
|
||||
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
$entries = new Collection;
|
||||
while ($start <= $end) {
|
||||
$spent = $repository->spentInPeriod($categoryCollection, new Collection, $start, $start);
|
||||
$earned = $repository->earnedInPeriod($categoryCollection, new Collection, $start, $start);
|
||||
$spent = $repository->spentInPeriod($categoryCollection, $accounts, $start, $start);
|
||||
$earned = $repository->earnedInPeriod($categoryCollection, $accounts, $start, $start);
|
||||
$date = Navigation::periodShow($start, '1D');
|
||||
$entries->push([clone $start, $date, $spent, $earned]);
|
||||
$start->addDay();
|
||||
|
@ -10,8 +10,10 @@ use FireflyIII\Import\Importer\ImporterInterface;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
use SplFileObject;
|
||||
use Storage;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use View;
|
||||
|
||||
/**
|
||||
@ -31,6 +33,27 @@ class ImportController extends Controller
|
||||
View::share('title', trans('firefly.import_data'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the last step before the import starts.
|
||||
*
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function complete(ImportJob $job)
|
||||
{
|
||||
Log::debug('Now in complete()', ['job' => $job->key]);
|
||||
if (!$this->jobInCorrectStep($job, 'complete')) {
|
||||
return $this->redirectToCorrectStep($job);
|
||||
}
|
||||
$importer = $this->makeImporter($job);
|
||||
$subTitle = trans('firefy.import_complete');
|
||||
$subTitleIcon = 'fa-star';
|
||||
|
||||
return view('import.complete', compact('job', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is step 3.
|
||||
* This is the first step in configuring the job. It can only be executed
|
||||
@ -43,16 +66,50 @@ class ImportController extends Controller
|
||||
*/
|
||||
public function configure(ImportJob $job)
|
||||
{
|
||||
Log::debug('Now at start of configure()');
|
||||
if (!$this->jobInCorrectStep($job, 'configure')) {
|
||||
Log::debug('Job is not in correct state for configure()', ['status' => $job->status]);
|
||||
|
||||
return $this->redirectToCorrectStep($job);
|
||||
}
|
||||
|
||||
// actual code
|
||||
$importer = $this->makeImporter($job);
|
||||
$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'));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a JSON file of the job's config and send it to the user.
|
||||
*
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function download(ImportJob $job)
|
||||
{
|
||||
Log::debug('Now in download()', ['job' => $job->key]);
|
||||
$config = $job->configuration;
|
||||
$config['column-roles-complete'] = false;
|
||||
$config['column-mapping-complete'] = false;
|
||||
$result = json_encode($config, JSON_PRETTY_PRINT);
|
||||
$name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\'));
|
||||
|
||||
return response($result, 200)
|
||||
->header('Content-disposition', 'attachment; filename=' . $name)
|
||||
->header('Content-Type', 'application/json')
|
||||
->header('Content-Description', 'File Transfer')
|
||||
->header('Connection', 'Keep-Alive')
|
||||
->header('Expires', '0')
|
||||
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
|
||||
->header('Pragma', 'public')
|
||||
->header('Content-Length', strlen($result));
|
||||
|
||||
|
||||
}
|
||||
@ -64,6 +121,7 @@ class ImportController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
Log::debug('Now at index');
|
||||
$subTitle = trans('firefly.import_data_index');
|
||||
$subTitleIcon = 'fa-home';
|
||||
$importFileTypes = [];
|
||||
@ -87,9 +145,11 @@ class ImportController extends Controller
|
||||
*/
|
||||
public function postConfigure(Request $request, ImportJob $job)
|
||||
{
|
||||
Log::debug('Now in postConfigure()', ['job' => $job->key]);
|
||||
if (!$this->jobInCorrectStep($job, 'process')) {
|
||||
return $this->redirectToCorrectStep($job);
|
||||
}
|
||||
Log::debug('Continue postConfigure()', ['job' => $job->key]);
|
||||
|
||||
// actual code
|
||||
$importer = $this->makeImporter($job);
|
||||
@ -106,6 +166,29 @@ class ImportController extends Controller
|
||||
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)
|
||||
{
|
||||
Log::debug('Now in postSettings()', ['job' => $job->key]);
|
||||
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
|
||||
* fill in.
|
||||
@ -117,27 +200,32 @@ class ImportController extends Controller
|
||||
*/
|
||||
public function settings(ImportJob $job)
|
||||
{
|
||||
Log::debug('Now in settings()', ['job' => $job->key]);
|
||||
if (!$this->jobInCorrectStep($job, 'settings')) {
|
||||
Log::debug('Job should not be in settings()');
|
||||
|
||||
return $this->redirectToCorrectStep($job);
|
||||
}
|
||||
$importer = $this->makeImporter($job);
|
||||
Log::debug('Continue in settings()');
|
||||
$importer = $this->makeImporter($job);
|
||||
$subTitle = trans('firefy.settings_for_import');
|
||||
$subTitleIcon = 'fa-wrench';
|
||||
|
||||
// now show settings screen to user.
|
||||
if ($importer->requireUserSettings()) {
|
||||
Log::debug('Job requires user config.');
|
||||
$data = $importer->getDataForSettings();
|
||||
$view = $importer->getViewForSettings();
|
||||
|
||||
return view($view, compact('data', 'job'));
|
||||
return view($view, compact('data', 'job', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
Log::debug('Job does NOT require user config.');
|
||||
|
||||
$job->status = 'settings_complete';
|
||||
$job->save();
|
||||
|
||||
// if no more settings, save job and continue to process thing.
|
||||
|
||||
|
||||
echo 'now in settings (done)';
|
||||
exit;
|
||||
|
||||
// actual code
|
||||
|
||||
return redirect(route('import.complete', [$job->key]));
|
||||
|
||||
// ask the importer for the requested action.
|
||||
// for example pick columns or map data.
|
||||
@ -154,9 +242,13 @@ class ImportController extends Controller
|
||||
*/
|
||||
public function upload(ImportUploadRequest $request, ImportJobRepositoryInterface $repository)
|
||||
{
|
||||
Log::debug('Now in upload()');
|
||||
// create import job:
|
||||
$type = $request->get('import_file_type');
|
||||
$job = $repository->create($type);
|
||||
$type = $request->get('import_file_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');
|
||||
$newName = $job->key . '.upload';
|
||||
$uploaded = new SplFileObject($upload->getRealPath());
|
||||
@ -165,6 +257,30 @@ class ImportController extends Controller
|
||||
$disk = Storage::disk('upload');
|
||||
$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]));
|
||||
|
||||
}
|
||||
@ -177,14 +293,19 @@ class ImportController extends Controller
|
||||
*/
|
||||
private function jobInCorrectStep(ImportJob $job, string $method): bool
|
||||
{
|
||||
Log::debug('Now in jobInCorrectStep()', ['job' => $job->key, 'method' => $method]);
|
||||
switch ($method) {
|
||||
case 'configure':
|
||||
case 'process':
|
||||
return $job->status === 'import_status_never_started';
|
||||
break;
|
||||
case 'settings':
|
||||
case 'store-settings':
|
||||
return $job->status === 'import_configuration_saved';
|
||||
break;
|
||||
case 'complete':
|
||||
return $job->status === 'settings_complete';
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -216,13 +337,23 @@ class ImportController extends Controller
|
||||
*/
|
||||
private function redirectToCorrectStep(ImportJob $job)
|
||||
{
|
||||
Log::debug('Now in redirectToCorrectStep()', ['job' => $job->key]);
|
||||
switch ($job->status) {
|
||||
case 'import_status_never_started':
|
||||
Log::debug('Will redirect to configure()');
|
||||
|
||||
return redirect(route('import.configure', [$job->key]));
|
||||
break;
|
||||
case 'import_configuration_saved':
|
||||
Log::debug('Will redirect to settings()');
|
||||
|
||||
return redirect(route('import.settings', [$job->key]));
|
||||
break;
|
||||
case 'settings_complete':
|
||||
Log::debug('Will redirect to complete()');
|
||||
|
||||
return redirect(route('import.complete', [$job->key]));
|
||||
break;
|
||||
}
|
||||
|
||||
throw new FireflyException('Cannot redirect for job state ' . $job->status);
|
||||
|
@ -229,6 +229,8 @@ Route::group(
|
||||
Route::post('/import/configure/{importJob}', ['uses' => 'ImportController@postConfigure', 'as' => 'import.process_configuration']);
|
||||
Route::get('/import/settings/{importJob}', ['uses' => 'ImportController@settings', 'as' => 'import.settings']);
|
||||
Route::post('/import/settings/{importJob}', ['uses' => 'ImportController@postSettings', 'as' => 'import.postSettings']);
|
||||
Route::get('/import/complete/{importJob}', ['uses' => 'ImportController@complete', 'as' => 'import.complete']);
|
||||
Route::get('/import/download/{importJob}', ['uses' => 'ImportController@download', 'as' => 'import.download']);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -14,10 +14,12 @@ namespace FireflyIII\Import\Importer;
|
||||
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Crud\Account\AccountCrud;
|
||||
use FireflyIII\Import\Role\Map;
|
||||
use FireflyIII\Import\Mapper\MapperInterface;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Http\Request;
|
||||
use League\Csv\Reader;
|
||||
use Log;
|
||||
use Symfony\Component\HttpFoundation\FileBag;
|
||||
|
||||
/**
|
||||
@ -32,11 +34,38 @@ class CsvImporter implements ImporterInterface
|
||||
public $job;
|
||||
|
||||
/**
|
||||
* Create initial (empty) configuration array.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @return 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.
|
||||
Log::debug('Detected config in upload, will use that one. ', $this->job->configuration);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -83,48 +112,22 @@ class CsvImporter implements ImporterInterface
|
||||
*/
|
||||
public function getDataForSettings(): array
|
||||
{
|
||||
$config = $this->job->configuration;
|
||||
$data = [
|
||||
'columns' => [],
|
||||
'columnCount' => 0,
|
||||
];
|
||||
|
||||
if (!isset($config['columns'])) {
|
||||
|
||||
// show user column configuration.
|
||||
$content = $this->job->uploadFileContents();
|
||||
|
||||
// create CSV reader.
|
||||
$reader = Reader::createFromString($content);
|
||||
$start = $config['has_headers'] ? 1 : 0;
|
||||
$end = $start + self::EXAMPLE_ROWS; // first X rows
|
||||
while ($start < $end) {
|
||||
$row = $reader->fetchOne($start);
|
||||
foreach ($row as $index => $value) {
|
||||
$value = trim($value);
|
||||
if (strlen($value) > 0) {
|
||||
$data['columns'][$index][] = $value;
|
||||
}
|
||||
}
|
||||
$start++;
|
||||
$data['columnCount'] = count($row);
|
||||
}
|
||||
|
||||
// make unique
|
||||
foreach ($data['columns'] as $index => $values) {
|
||||
$data['columns'][$index] = array_unique($values);
|
||||
}
|
||||
// TODO preset roles from config
|
||||
$data['set_roles'] = [];
|
||||
// collect possible column roles:
|
||||
$data['available_roles'] = [];
|
||||
foreach (array_keys(config('csv.import_roles')) as $role) {
|
||||
$data['available_roles'][$role] = trans('csv.csv_column_'.$role);
|
||||
}
|
||||
if ($this->doColumnRoles()) {
|
||||
$data = $this->getDataForColumnRoles();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
if ($this->doColumnMapping()) {
|
||||
$data = $this->getDataForColumnMapping();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
echo 'no settings to do.';
|
||||
exit;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,18 +138,15 @@ class CsvImporter implements ImporterInterface
|
||||
*/
|
||||
public function getViewForSettings(): string
|
||||
{
|
||||
return 'import.csv.map';
|
||||
}
|
||||
if ($this->doColumnRoles()) {
|
||||
return 'import.csv.roles';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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';
|
||||
if ($this->doColumnMapping()) {
|
||||
return 'import.csv.map';
|
||||
}
|
||||
|
||||
echo 'no view for settings';
|
||||
exit;
|
||||
}
|
||||
|
||||
@ -158,13 +158,16 @@ class CsvImporter implements ImporterInterface
|
||||
*/
|
||||
public function requireUserSettings(): bool
|
||||
{
|
||||
// does the job have both a 'map' array and a 'columns' array.
|
||||
$config = $this->job->configuration;
|
||||
if (isset($config['map']) && isset($config['columns'])) {
|
||||
return false;
|
||||
}
|
||||
Log::debug('doColumnMapping is ' . ($this->doColumnMapping() ? 'true' : 'false'));
|
||||
Log::debug('doColumnRoles is ' . ($this->doColumnRoles() ? 'true' : 'false'));
|
||||
if ($this->doColumnMapping() || $this->doColumnRoles()) {
|
||||
Log::debug('Return true');
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
Log::debug('Return false');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,33 +177,25 @@ class CsvImporter implements ImporterInterface
|
||||
*/
|
||||
public function saveImportConfiguration(array $data, FileBag $files): bool
|
||||
{
|
||||
/*
|
||||
* TODO file upload is ignored for now.
|
||||
*/
|
||||
|
||||
/** @var AccountCrud $repository */
|
||||
$repository = app(AccountCrud::class);
|
||||
$account = $repository->find(intval($data['csv_import_account']));
|
||||
$hasHeaders = isset($data['has_headers']) && intval($data['has_headers']) === 1 ? true : false;
|
||||
$configuration = [
|
||||
'has_headers' => $hasHeaders,
|
||||
'date_format' => $data['date_format'],
|
||||
'csv_delimiter' => $data['csv_delimiter'],
|
||||
'csv_import_account' => 0,
|
||||
'specifics' => [],
|
||||
|
||||
];
|
||||
$repository = app(AccountCrud::class);
|
||||
$account = $repository->find(intval($data['csv_import_account']));
|
||||
$hasHeaders = isset($data['has_headers']) && intval($data['has_headers']) === 1 ? true : false;
|
||||
$config = $this->job->configuration;
|
||||
$config['has-headers'] = $hasHeaders;
|
||||
$config['date-format'] = $data['date_format'];
|
||||
$config['delimiter'] = $data['csv_delimiter'];
|
||||
|
||||
if (!is_null($account->id)) {
|
||||
$configuration['csv_import_account'] = $account->id;
|
||||
$config['import-account'] = $account->id;
|
||||
}
|
||||
// loop specifics.
|
||||
if (is_array($data['specifics'])) {
|
||||
if (isset($data['specifics']) && is_array($data['specifics'])) {
|
||||
foreach ($data['specifics'] as $name => $enabled) {
|
||||
$configuration['specifics'][] = $name;
|
||||
$config['specifics'][$name] = 1;
|
||||
}
|
||||
}
|
||||
$this->job->configuration = $configuration;
|
||||
$this->job->configuration = $config;
|
||||
$this->job->save();
|
||||
|
||||
return true;
|
||||
@ -215,4 +210,181 @@ class CsvImporter implements ImporterInterface
|
||||
{
|
||||
$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;
|
||||
$all = $request->all();
|
||||
if ($request->get('settings') == 'roles') {
|
||||
$count = $config['column-count'];
|
||||
|
||||
$roleSet = 0; // how many roles have been defined
|
||||
$mapSet = 0; // how many columns must be mapped
|
||||
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++;
|
||||
}
|
||||
if ($doMapping === true) {
|
||||
$mapSet++;
|
||||
}
|
||||
$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();
|
||||
}
|
||||
if ($mapSet === 0) {
|
||||
// skip setting of map:
|
||||
$config['column-mapping-complete'] = true;
|
||||
}
|
||||
}
|
||||
if ($request->get('settings') == 'map') {
|
||||
foreach ($all['mapping'] as $index => $data) {
|
||||
$config['column-mapping-config'][$index] = [];
|
||||
foreach ($data as $value => $mapId) {
|
||||
$mapId = intval($mapId);
|
||||
if ($mapId !== 0) {
|
||||
$config['column-mapping-config'][$index][$value] = intval($mapId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set thing to be completed.
|
||||
$config['column-mapping-complete'] = true;
|
||||
$this->job->configuration = $config;
|
||||
$this->job->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function doColumnMapping(): bool
|
||||
{
|
||||
return $this->job->configuration['column-mapping-complete'] === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function doColumnRoles(): bool
|
||||
{
|
||||
return $this->job->configuration['column-roles-complete'] === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getDataForColumnMapping(): array
|
||||
{
|
||||
$config = $this->job->configuration;
|
||||
$data = [];
|
||||
$indexes = [];
|
||||
|
||||
foreach ($config['column-do-mapping'] as $index => $mustBeMapped) {
|
||||
if ($mustBeMapped) {
|
||||
$column = $config['column-roles'][$index] ?? '_ignore';
|
||||
$canBeMapped = config('csv.import_roles.' . $column . '.mappable');
|
||||
if ($canBeMapped) {
|
||||
$mapperName = '\FireflyIII\Import\Mapper\\' . config('csv.import_roles.' . $column . '.mapper');
|
||||
/** @var MapperInterface $mapper */
|
||||
$mapper = new $mapperName;
|
||||
$indexes[] = $index;
|
||||
$data[$index] = [
|
||||
'name' => $column,
|
||||
'mapper' => $mapperName,
|
||||
'index' => $index,
|
||||
'options' => $mapper->getMap(),
|
||||
'values' => [],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// in order to actually map we also need all possible values from the CSV file.
|
||||
$content = $this->job->uploadFileContents();
|
||||
$reader = Reader::createFromString($content);
|
||||
$results = $reader->fetch();
|
||||
|
||||
foreach ($results as $row) {
|
||||
//do something here
|
||||
foreach ($indexes as $index) {
|
||||
$value = $row[$index];
|
||||
if (strlen($value) > 0) {
|
||||
$data[$index]['values'][] = $row[$index];
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($data as $index => $entry) {
|
||||
$data[$index]['values'] = array_unique($data[$index]['values']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getDataForColumnRoles():array
|
||||
{
|
||||
$config = $this->job->configuration;
|
||||
$data = [
|
||||
'columns' => [],
|
||||
'columnCount' => 0,
|
||||
];
|
||||
|
||||
// show user column role configuration.
|
||||
$content = $this->job->uploadFileContents();
|
||||
|
||||
// create CSV reader.
|
||||
$reader = Reader::createFromString($content);
|
||||
$start = $config['has-headers'] ? 1 : 0;
|
||||
$end = $start + self::EXAMPLE_ROWS; // first X rows
|
||||
|
||||
// collect example data in $data['columns']
|
||||
while ($start < $end) {
|
||||
$row = $reader->fetchOne($start);
|
||||
foreach ($row as $index => $value) {
|
||||
$value = trim($value);
|
||||
if (strlen($value) > 0) {
|
||||
$data['columns'][$index][] = $value;
|
||||
}
|
||||
}
|
||||
$start++;
|
||||
$data['columnCount'] = count($row);
|
||||
}
|
||||
|
||||
// make unique example data
|
||||
foreach ($data['columns'] as $index => $values) {
|
||||
$data['columns'][$index] = array_unique($values);
|
||||
}
|
||||
|
||||
$data['set_roles'] = [];
|
||||
// collect possible column roles:
|
||||
$data['available_roles'] = [];
|
||||
foreach (array_keys(config('csv.import_roles')) as $role) {
|
||||
$data['available_roles'][$role] = trans('csv.column_' . $role);
|
||||
}
|
||||
|
||||
$config['column-count'] = $data['columnCount'];
|
||||
$this->job->configuration = $config;
|
||||
$this->job->save();
|
||||
|
||||
return $data;
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ namespace FireflyIII\Import\Importer;
|
||||
|
||||
use FireflyIII\Import\Role\Map;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\FileBag;
|
||||
|
||||
/**
|
||||
@ -44,6 +45,14 @@ interface ImporterInterface
|
||||
*/
|
||||
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
|
||||
* the import job.
|
||||
@ -52,14 +61,6 @@ interface ImporterInterface
|
||||
*/
|
||||
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
|
||||
* job further.
|
||||
|
53
app/Import/Mapper/AssetAccounts.php
Normal file
53
app/Import/Mapper/AssetAccounts.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* AssetAccounts.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Import\Mapper;
|
||||
|
||||
use FireflyIII\Crud\Account\AccountCrudInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
|
||||
/**
|
||||
* Class AssetAccounts
|
||||
*
|
||||
* @package FireflyIII\Import\Mapper
|
||||
*/
|
||||
class AssetAccounts implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var AccountCrudInterface $crud */
|
||||
$crud = app(AccountCrudInterface::class);
|
||||
$set = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
$list = [];
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($set as $account) {
|
||||
$name = $account->name;
|
||||
$iban = $account->iban ?? '';
|
||||
if (strlen($iban) > 0) {
|
||||
$name .= ' (' . $account->iban . ')';
|
||||
}
|
||||
$list[$account->id] = $name;
|
||||
}
|
||||
|
||||
asort($list);
|
||||
|
||||
$list = [0 => trans('csv.do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
|
||||
}
|
||||
}
|
46
app/Import/Mapper/Bills.php
Normal file
46
app/Import/Mapper/Bills.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Bills.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Import\Mapper;
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class Bills
|
||||
*
|
||||
* @package FireflyIII\Import\Mapper
|
||||
*/
|
||||
class Bills implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var BillRepositoryInterface $repository */
|
||||
$repository = app(BillRepositoryInterface::class);
|
||||
$result = $repository->getBills();
|
||||
$list = [];
|
||||
|
||||
/** @var Bill $bill */
|
||||
foreach ($result as $bill) {
|
||||
$list[$bill->id] = $bill->name . ' [' . $bill->match . ']';
|
||||
}
|
||||
asort($list);
|
||||
|
||||
$list = [0 => trans('csv.do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
|
||||
}
|
||||
}
|
47
app/Import/Mapper/Budgets.php
Normal file
47
app/Import/Mapper/Budgets.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Budgets.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Import\Mapper;
|
||||
|
||||
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class Budgets
|
||||
*
|
||||
* @package FireflyIII\Import\Mapper
|
||||
*/
|
||||
class Budgets implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var BudgetRepositoryInterface $repository */
|
||||
$repository = app(BudgetRepositoryInterface::class);
|
||||
$result = $repository->getBudgets();
|
||||
$list = [];
|
||||
|
||||
/** @var Budget $budget */
|
||||
foreach ($result as $budget) {
|
||||
$list[$budget->id] = $budget->name;
|
||||
}
|
||||
asort($list);
|
||||
|
||||
$list = [0 => trans('csv.do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
|
||||
}
|
||||
}
|
47
app/Import/Mapper/Categories.php
Normal file
47
app/Import/Mapper/Categories.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Categories.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Import\Mapper;
|
||||
|
||||
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class Categories
|
||||
*
|
||||
* @package FireflyIII\Import\Mapper
|
||||
*/
|
||||
class Categories implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var CategoryRepositoryInterface $repository */
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
$result = $repository->getCategories();
|
||||
$list = [];
|
||||
|
||||
/** @var Category $category */
|
||||
foreach ($result as $category) {
|
||||
$list[$category->id] = $category->name;
|
||||
}
|
||||
asort($list);
|
||||
|
||||
$list = [0 => trans('csv.do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
|
||||
}
|
||||
}
|
26
app/Import/Mapper/MapperInterface.php
Normal file
26
app/Import/Mapper/MapperInterface.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* MapperInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Import\Mapper;
|
||||
|
||||
/**
|
||||
* Interface MapperInterface
|
||||
*
|
||||
* @package FireflyIII\Import\Mapper
|
||||
*/
|
||||
interface MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array;
|
||||
}
|
57
app/Import/Mapper/OpposingAccounts.php
Normal file
57
app/Import/Mapper/OpposingAccounts.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* OpposingAccounts.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Import\Mapper;
|
||||
|
||||
use FireflyIII\Crud\Account\AccountCrudInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
|
||||
/**
|
||||
* Class OpposingAccounts
|
||||
*
|
||||
* @package FireflyIII\Import\Mapper
|
||||
*/
|
||||
class OpposingAccounts implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var AccountCrudInterface $crud */
|
||||
$crud = app(AccountCrudInterface::class);
|
||||
$set = $crud->getAccountsByType(
|
||||
[
|
||||
AccountType::DEFAULT, AccountType::ASSET,
|
||||
AccountType::EXPENSE, AccountType::BENEFICIARY,
|
||||
AccountType::REVENUE
|
||||
]);
|
||||
$list = [];
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($set as $account) {
|
||||
$name = $account->name;
|
||||
$iban = $account->iban ?? '';
|
||||
if (strlen($iban) > 0) {
|
||||
$name .= ' (' . $account->iban . ')';
|
||||
}
|
||||
$list[$account->id] = $name;
|
||||
}
|
||||
|
||||
asort($list);
|
||||
|
||||
$list = [0 => trans('csv.do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
46
app/Import/Mapper/Tags.php
Normal file
46
app/Import/Mapper/Tags.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Tags.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Import\Mapper;
|
||||
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class Tags
|
||||
*
|
||||
* @package FireflyIII\Import\Mapper
|
||||
*/
|
||||
class Tags implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var TagRepositoryInterface $repository */
|
||||
$repository = app(TagRepositoryInterface::class);
|
||||
$result = $repository->get();
|
||||
$list = [];
|
||||
|
||||
/** @var Tag $tag */
|
||||
foreach ($result as $tag) {
|
||||
$list[$tag->id] = $tag->tag;
|
||||
}
|
||||
asort($list);
|
||||
|
||||
$list = [0 => trans('csv.do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
|
||||
}
|
||||
}
|
42
app/Import/Mapper/TransactionCurrencies.php
Normal file
42
app/Import/Mapper/TransactionCurrencies.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* TransactionCurrencies.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Import\Mapper;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency as TC;
|
||||
|
||||
/**
|
||||
* Class TransactionCurrencies
|
||||
*
|
||||
* @package FireflyIII\Import\Mapper
|
||||
*/
|
||||
class TransactionCurrencies implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
$currencies = TC::get();
|
||||
$list = [];
|
||||
foreach ($currencies as $currency) {
|
||||
$list[$currency->id] = $currency->name . ' (' . $currency->code . ')';
|
||||
}
|
||||
|
||||
asort($list);
|
||||
|
||||
$list = [0 => trans('csv.do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
|
||||
}
|
||||
}
|
@ -13,6 +13,8 @@ namespace FireflyIII\Models;
|
||||
|
||||
use Auth;
|
||||
use Crypt;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
@ -183,10 +185,14 @@ class Account extends Model
|
||||
*/
|
||||
public function getIbanAttribute($value): string
|
||||
{
|
||||
if (is_null($value)) {
|
||||
if (is_null($value) || strlen(strval($value)) === 0) {
|
||||
return '';
|
||||
}
|
||||
$result = Crypt::decrypt($value);
|
||||
try {
|
||||
$result = Crypt::decrypt($value);
|
||||
} catch (DecryptException $e) {
|
||||
throw new FireflyException('Cannot decrypt value "' . $value . '" for account #' . $this->id);
|
||||
}
|
||||
if (is_null($result)) {
|
||||
return '';
|
||||
}
|
||||
|
@ -15,47 +15,48 @@ return [
|
||||
/*
|
||||
* Configuration for possible column roles.
|
||||
*/
|
||||
'import_roles' => [
|
||||
'import_roles' => [
|
||||
'_ignore' => [
|
||||
'mappable' => false,
|
||||
'converter' => 'Ignore',
|
||||
'field' => 'ignored',
|
||||
'converter' => 'Ignore',
|
||||
|
||||
],
|
||||
'bill-id' => [
|
||||
'mappable' => false,
|
||||
'field' => 'bill',
|
||||
'converter' => 'BillId',
|
||||
'mapper' => 'Bill',
|
||||
'mapper' => 'Bills',
|
||||
],
|
||||
'bill-name' => [
|
||||
'mappable' => true,
|
||||
'converter' => 'BillName',
|
||||
'field' => 'bill',
|
||||
'mapper' => 'Bill',
|
||||
'converter' => 'BillName',
|
||||
'mapper' => 'Bills',
|
||||
],
|
||||
'currency-id' => [
|
||||
'mappable' => true,
|
||||
'converter' => 'CurrencyId',
|
||||
'field' => 'currency',
|
||||
'mapper' => 'TransactionCurrency'
|
||||
'converter' => 'CurrencyId',
|
||||
'mapper' => 'TransactionCurrencies',
|
||||
],
|
||||
'currency-name' => [
|
||||
'mappable' => true,
|
||||
'converter' => 'CurrencyName',
|
||||
'field' => 'currency',
|
||||
'mapper' => 'TransactionCurrency'
|
||||
'mapper' => 'TransactionCurrencies',
|
||||
],
|
||||
'currency-code' => [
|
||||
'mappable' => true,
|
||||
'converter' => 'CurrencyCode',
|
||||
'field' => 'currency',
|
||||
'mapper' => 'TransactionCurrency'
|
||||
'mapper' => 'TransactionCurrencies',
|
||||
],
|
||||
'currency-symbol' => [
|
||||
'mappable' => true,
|
||||
'converter' => 'CurrencySymbol',
|
||||
'field' => 'currency',
|
||||
'mapper' => 'TransactionCurrency'
|
||||
'mapper' => 'TransactionCurrencies',
|
||||
],
|
||||
'description' => [
|
||||
'mappable' => false,
|
||||
@ -76,20 +77,20 @@ return [
|
||||
'mappable' => true,
|
||||
'converter' => 'BudgetId',
|
||||
'field' => 'budget',
|
||||
'mapper' => 'Budget',
|
||||
'mapper' => 'Budgets',
|
||||
],
|
||||
'budget-name' => [
|
||||
'mappable' => true,
|
||||
'converter' => 'BudgetName',
|
||||
'field' => 'budget',
|
||||
'mapper' => 'Budget',
|
||||
'mapper' => 'Budgets',
|
||||
],
|
||||
'rabo-debet-credit' => [
|
||||
'mappable' => false,
|
||||
'converter' => 'RabobankDebetCredit',
|
||||
'field' => 'amount-modifier',
|
||||
],
|
||||
'ing-debet-credit' => [
|
||||
'ing-debet-credit' => [
|
||||
'mappable' => false,
|
||||
'converter' => 'INGDebetCredit',
|
||||
'field' => 'amount-modifier',
|
||||
@ -98,84 +99,80 @@ return [
|
||||
'mappable' => true,
|
||||
'converter' => 'CategoryId',
|
||||
'field' => 'category',
|
||||
'mapper' => 'Category',
|
||||
'mapper' => 'Categories',
|
||||
],
|
||||
'category-name' => [
|
||||
'mappable' => true,
|
||||
'converter' => 'CategoryName',
|
||||
'field' => 'category',
|
||||
'mapper' => 'Category',
|
||||
'mapper' => 'Categories',
|
||||
],
|
||||
'tags-comma' => [
|
||||
'mappable' => true,
|
||||
'field' => 'tags',
|
||||
'converter' => 'TagsComma',
|
||||
'mapper' => 'Tag',
|
||||
'mapper' => 'Tags',
|
||||
],
|
||||
'tags-space' => [
|
||||
'mappable' => true,
|
||||
'field' => 'tags',
|
||||
'converter' => 'TagsSpace',
|
||||
'mapper' => 'Tag',
|
||||
'mapper' => 'Tags',
|
||||
],
|
||||
'account-id' => [
|
||||
'mappable' => true,
|
||||
'mapper' => 'AssetAccount',
|
||||
'field' => 'asset-account-id',
|
||||
'converter' => 'AccountId'
|
||||
'converter' => 'AssetAccountId',
|
||||
'mapper' => 'AssetAccounts',
|
||||
],
|
||||
'account-name' => [
|
||||
'mappable' => true,
|
||||
'mapper' => 'AssetAccount',
|
||||
'field' => 'asset-account-name',
|
||||
'converter' => 'AssetAccountName'
|
||||
'converter' => 'AssetAccountName',
|
||||
'mapper' => 'AssetAccounts',
|
||||
],
|
||||
'account-iban' => [
|
||||
'mappable' => true,
|
||||
'converter' => 'AssetAccountIban',
|
||||
'field' => 'asset-account-iban',
|
||||
'mapper' => 'AssetAccount'
|
||||
'converter' => 'AssetAccountIban',
|
||||
'mapper' => 'AssetAccounts',
|
||||
|
||||
],
|
||||
'account-number' => [
|
||||
'account-number' => [
|
||||
'mappable' => true,
|
||||
'converter' => 'AssetAccountNumber',
|
||||
'field' => 'asset-account-number',
|
||||
'mapper' => 'AssetAccount'
|
||||
'converter' => 'AssetAccountNumber',
|
||||
'mapper' => 'AssetAccounts',
|
||||
],
|
||||
'opposing-id' => [
|
||||
'mappable' => true,
|
||||
'field' => 'opposing-account-id',
|
||||
'converter' => 'OpposingAccountId',
|
||||
'mapper' => 'AnyAccount',
|
||||
'mapper' => 'OpposingAccounts',
|
||||
],
|
||||
'opposing-name' => [
|
||||
'mappable' => true,
|
||||
'field' => 'opposing-account-name',
|
||||
'converter' => 'OpposingAccountName',
|
||||
'mapper' => 'AnyAccount',
|
||||
'mapper' => 'OpposingAccounts',
|
||||
],
|
||||
'opposing-iban' => [
|
||||
'mappable' => true,
|
||||
'field' => 'opposing-account-iban',
|
||||
'converter' => 'OpposingAccountIban',
|
||||
'mapper' => 'AnyAccount',
|
||||
'mapper' => 'OpposingAccounts',
|
||||
],
|
||||
'opposing-number' => [
|
||||
'opposing-number' => [
|
||||
'mappable' => true,
|
||||
'field' => 'opposing-account-number',
|
||||
'converter' => 'OpposingAccountNumber',
|
||||
'mapper' => 'AnyAccount',
|
||||
'mapper' => 'OpposingAccounts',
|
||||
],
|
||||
'amount' => [
|
||||
'mappable' => false,
|
||||
'converter' => 'Amount',
|
||||
'field' => 'amount',
|
||||
],
|
||||
'amount-comma-separated' => [
|
||||
'mappable' => false,
|
||||
'converter' => 'AmountComma',
|
||||
'field' => 'amount',
|
||||
],
|
||||
'sepa-ct-id' => [
|
||||
'mappable' => false,
|
||||
'converter' => 'Description',
|
||||
@ -194,12 +191,6 @@ return [
|
||||
],
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
@ -10,35 +10,59 @@
|
||||
declare(strict_types = 1);
|
||||
|
||||
return [
|
||||
'csv_column__ignore' => '(ignore this column)',
|
||||
'csv_column_account-iban' => 'Asset account (IBAN)',
|
||||
'csv_column_account-id' => 'Asset account ID (matching Firefly)',
|
||||
'csv_column_account-name' => 'Asset account (name)',
|
||||
'csv_column_amount' => 'Amount',
|
||||
'csv_column_amount-comma-separated' => 'Amount (comma as decimal separator)',
|
||||
'csv_column_bill-id' => 'Bill ID (matching Firefly)',
|
||||
'csv_column_bill-name' => 'Bill name',
|
||||
'csv_column_budget-id' => 'Budget ID (matching Firefly)',
|
||||
'csv_column_budget-name' => 'Budget name',
|
||||
'csv_column_category-id' => 'Category ID (matching Firefly)',
|
||||
'csv_column_category-name' => 'Category name',
|
||||
'csv_column_currency-code' => 'Currency code (ISO 4217)',
|
||||
'csv_column_currency-id' => 'Currency ID (matching Firefly)',
|
||||
'csv_column_currency-name' => 'Currency name (matching Firefly)',
|
||||
'csv_column_currency-symbol' => 'Currency symbol (matching Firefly)',
|
||||
'csv_column_date-rent' => 'Rent calculation date',
|
||||
'csv_column_date-transaction' => 'Date',
|
||||
'csv_column_description' => 'Description',
|
||||
'csv_column_opposing-iban' => 'Opposing account (IBAN)',
|
||||
'csv_column_opposing-id' => 'Opposing account ID (matching Firefly)',
|
||||
'csv_column_opposing-name' => 'Opposing account (name)',
|
||||
'csv_column_rabo-debet-credit' => 'Rabobank specific debet/credit indicator',
|
||||
'csv_column_ing-debet-credit' => 'ING specific debet/credit indicator',
|
||||
'csv_column_sepa-ct-id' => 'SEPA Credit Transfer end-to-end ID',
|
||||
'csv_column_sepa-ct-op' => 'SEPA Credit Transfer opposing account',
|
||||
'csv_column_sepa-db' => 'SEPA Direct Debet',
|
||||
'csv_column_tags-comma' => 'Tags (comma separated)',
|
||||
'csv_column_tags-space' => 'Tags (space separated)',
|
||||
'csv_column_account-number' => 'Asset account (account number)',
|
||||
'csv_column_opposing-number' => 'Opposing account (account number)',
|
||||
|
||||
'import_configure_title' => 'Configure your import',
|
||||
'import_configure_intro' => 'There are some options for your CSV import.',
|
||||
'import_configure_form' => 'Form',
|
||||
'header_help' => 'Check this if the first row of your CSV file are the column titles',
|
||||
'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.',
|
||||
'delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
|
||||
'config_file_help' => 'Select your CSV import configuration here. If you do not know what this is, ignore it. It will be explained later.',
|
||||
'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.',
|
||||
'upload_not_writeable' => 'The grey box contains a file path. It should be writeable. Please make sure it is.',
|
||||
|
||||
// roles
|
||||
'column_roles_title' => 'Define column roles',
|
||||
'column_roles_text' => 'Each column contains some data. What data?',
|
||||
'column_roles_table' => 'Table',
|
||||
'column_name' => 'Name of column',
|
||||
'column_example' => 'Column example data',
|
||||
'column_role' => 'Column data meaning',
|
||||
'do_map_value' => 'Map these values',
|
||||
'column' => 'Column',
|
||||
'no_example_data' => 'No example data available',
|
||||
'store_column_roles' => 'Continue import',
|
||||
'do_not_map' => '(do not map)',
|
||||
|
||||
'column__ignore' => '(ignore this column)',
|
||||
'column_account-iban' => 'Asset account (IBAN)',
|
||||
'column_account-id' => 'Asset account ID (matching Firefly)',
|
||||
'column_account-name' => 'Asset account (name)',
|
||||
'column_amount' => 'Amount',
|
||||
'column_amount-comma-separated' => 'Amount (comma as decimal separator)',
|
||||
'column_bill-id' => 'Bill ID (matching Firefly)',
|
||||
'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)',
|
||||
];
|
@ -749,18 +749,12 @@ return [
|
||||
'split_this_transfer' => 'Split this transfer',
|
||||
|
||||
// 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_help' => 'Select the type of file you will upload',
|
||||
'import_start' => 'Start the import',
|
||||
'import_csv_configure_title' => 'Configure your import',
|
||||
'import_csv_configure_intro' => 'There are some options for your CSV import.',
|
||||
'import_csv_configure_form' => 'Form',
|
||||
'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.',
|
||||
|
||||
|
||||
'configure_import' => 'Further configure your import',
|
||||
'import_finish_configuration' => 'Finish configuration',
|
||||
'settings_for_import' => 'Settings',
|
||||
];
|
||||
|
@ -133,6 +133,7 @@ return [
|
||||
|
||||
// import
|
||||
'import_file' => 'Import file',
|
||||
'configuration_file' => 'Configuration file',
|
||||
'import_file_type' => 'Import file type',
|
||||
'csv_comma' => 'A comma (,)',
|
||||
'csv_semicolon' => 'A semicolon (;)',
|
||||
@ -142,5 +143,4 @@ return [
|
||||
'csv_config' => 'CSV import configuration',
|
||||
|
||||
|
||||
|
||||
];
|
||||
|
33
resources/views/import/complete.twig
Normal file
33
resources/views/import/complete.twig
Normal file
@ -0,0 +1,33 @@
|
||||
{% extends "./layout/default.twig" %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ Breadcrumbs.renderIfExists }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_complete'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>
|
||||
{{ 'import_complete_text'|_ }}
|
||||
</p>
|
||||
<div class="row">
|
||||
<div class="col-lg-2">
|
||||
<a href="{{ route('import.download', [job.key]) }}" class="btn btn-default"><i class="fa fa-fw fa-download"></i> {{ 'import_download_config' }}</a>
|
||||
</div>
|
||||
<div class="col-lg-2">
|
||||
<a href="#" class="btn btn-default"><i class="fa fa-fw fa-gears"></i> {{ 'import_start_import' }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
||||
{% block styles %}
|
||||
{% endblock %}
|
@ -10,11 +10,11 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="box">
|
||||
<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 class="box-body">
|
||||
<p>
|
||||
{{ 'import_csv_configure_intro'|_ }}
|
||||
{{ trans('csv.import_configure_intro') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -29,17 +29,14 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="box">
|
||||
<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 class="box-body">
|
||||
|
||||
{{ ExpandedForm.checkbox('has_headers',1,null,{helpText: 'csv_header_help'|_}) }}
|
||||
{{ ExpandedForm.text('date_format','Ymd',{helpText: trans('firefly.csv_date_help', {dateExample: phpdate('Ymd')}) }) }}
|
||||
{{ ExpandedForm.select('csv_delimiter', data.delimiters, 0, {helpText: 'csv_delimiter_help'|_} ) }}
|
||||
|
||||
{{ ExpandedForm.file('csv_config',{helpText: 'csv_csv_config_file_help'|_}) }}
|
||||
|
||||
{{ ExpandedForm.select('csv_import_account', data.accounts, 0, {helpText: 'csv_import_account_help'|_} ) }}
|
||||
{{ ExpandedForm.checkbox('has_headers',1,job.configuration['has-headers'],{helpText: trans('csv.header_help')}) }}
|
||||
{{ ExpandedForm.text('date_format',job.configuration['date-format'],{helpText: trans('csv.date_help', {dateExample: phpdate('Ymd')}) }) }}
|
||||
{{ 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')} ) }}
|
||||
|
||||
{% for type, specific in data.specifics %}
|
||||
<div class="form-group">
|
||||
@ -49,7 +46,8 @@
|
||||
|
||||
<div class="col-sm-8">
|
||||
<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 }}
|
||||
</label>
|
||||
</div>
|
||||
@ -66,7 +64,7 @@
|
||||
<div class="col-sm-8">
|
||||
<pre>{{ data.upload_path }}</pre>
|
||||
<p class="text-danger">
|
||||
{{ 'csv_upload_not_writeable'|_ }}
|
||||
{{ trans('csv.upload_not_writeable') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -82,7 +80,7 @@
|
||||
<div class="box">
|
||||
<div class="box-body">
|
||||
<button type="submit" class="pull-right btn btn-success">
|
||||
{{ 'csv_upload_button'|_ }}
|
||||
{{ 'import_finish_configuration'|_ }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,14 +6,17 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'csv_column_roles_title'|_ }}</h3>
|
||||
<h3 class="box-title">{{ trans('csv.map_title') }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>{{ 'csv_column_roles_text'|_ }}</p>
|
||||
<p>
|
||||
{{ trans('csv.map_text') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -21,67 +24,98 @@
|
||||
</div>
|
||||
<form action="{{ route('import.postSettings', job.key) }}" method="post">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
|
||||
<input type="hidden" name="settings" value="map"/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'csv_column_roles_table'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:20%;">{{ 'csv_column_name'|_ }}</th>
|
||||
<th style="width:40%;">{{ 'csv_column_example'|_ }}</th>
|
||||
<th style="width:30%;">{{ 'csv_column_role'|_ }}</th>
|
||||
<th style="width:10%;">{{ 'csv_do_map_value'|_ }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for i in 0..data.columnCount %}
|
||||
{% for field in data %}
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ field.name }}</h3>
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Column #{{ loop.index }}</td>
|
||||
<td>
|
||||
{% if data.columns[i]|length == 0 %}
|
||||
<em>No example data available</em>
|
||||
{% else %}
|
||||
{% for example in data.columns[i] %}
|
||||
<code>{{ example }}</code><br />
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<td>
|
||||
{{ Form.select(('role['~index~']'), data.available_roles,data.set_roles[index],{class: 'form-control'}) }}
|
||||
</td>
|
||||
<td>
|
||||
{# Form.checkbox(('map['~index~']'),1,map[index]) #}
|
||||
</td>
|
||||
|
||||
<th style="width:50%;">{{ trans('csv.field_value') }}</th>
|
||||
<th>{{ trans('csv.field_mapped_to') }}</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for option in field.values %}
|
||||
<tr>
|
||||
<td>
|
||||
<code>{{ option }}</code>
|
||||
</td>
|
||||
<td>
|
||||
{{ Form.select('mapping['~field.index~']['~option~']',
|
||||
field.options,
|
||||
job.configuration['column-mapping-config'][field.index][option], {class: 'form-control'}) }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{#
|
||||
|
||||
{% for index,columnName in map %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ Config.get('csv.roles.'~columnName~'.name') }}</h3>
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:50%;">{{ 'csv_field_value'|_ }}</th>
|
||||
<th>{{ 'csv_field_mapped_to'|_ }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for value in values[index] %}
|
||||
<tr>
|
||||
<td><code>{{ value }}</code></td>
|
||||
<td>
|
||||
{{ Form.select('mapping['~index~']['~value~']',options[index], mapped[index][value], {class: 'form-control'}) }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
#}
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="box">
|
||||
<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">
|
||||
{{ 'csv_continue'|_ }} <i class="fa fa-arrow-right"></i>
|
||||
{{ trans('csv.store_column_mapping') }} <i class="fa fa-arrow-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
|
95
resources/views/import/csv/roles.twig
Normal file
95
resources/views/import/csv/roles.twig
Normal file
@ -0,0 +1,95 @@
|
||||
{% extends "./layout/default.twig" %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ trans('csv.column_roles_title') }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>{{ trans('csv.column_roles_text') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<form action="{{ route('import.postSettings', job.key) }}" method="post">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
|
||||
<input type="hidden" name="settings" value="roles"/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ trans('csv.column_roles_table') }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:20%;">{{ trans('csv.column_name') }}</th>
|
||||
<th style="width:40%;">{{ trans('csv.column_example') }}</th>
|
||||
<th style="width:30%;">{{ trans('csv.column_role') }}</th>
|
||||
<th style="width:10%;">{{ trans('csv.do_map_value') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for i in 0..(data.columnCount-1) %}
|
||||
|
||||
<tr>
|
||||
<td>{{ trans('csv.column') }} #{{ loop.index }}</td>
|
||||
<td>
|
||||
{% if data.columns[i]|length == 0 %}
|
||||
<em>{{ trans('csv.no_example_data') }}</em>
|
||||
{% else %}
|
||||
{% for example in data.columns[i] %}
|
||||
<code>{{ example }}</code><br />
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<td>
|
||||
{{ Form.select(('role['~loop.index0~']'),
|
||||
data.available_roles,
|
||||
job.configuration['column-roles'][loop.index0],
|
||||
{class: 'form-control'}) }}
|
||||
</td>
|
||||
<td>
|
||||
{{ Form.checkbox(('map['~loop.index0~']'),1,
|
||||
job.configuration['column-do-mapping'][loop.index0]
|
||||
|
||||
) }}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="box">
|
||||
<div class="box-body">
|
||||
<button type="submit" class="btn btn-success pull-right">
|
||||
{{ trans('csv.store_column_roles') }} <i class="fa fa-arrow-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{% endblock %}
|
@ -6,7 +6,6 @@
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<!-- ACCOUNTS -->
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import'|_ }}</h3>
|
||||
@ -26,6 +25,7 @@
|
||||
|
||||
<div class="col-lg-6 col-md-8 col-sm-12 col-xs-12">
|
||||
{{ 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'|_}) }}
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
||||
{% for data in transactions %}
|
||||
<div class="box">
|
||||
<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 -->
|
||||
<div class="box-tools pull-right">
|
||||
|
Loading…
Reference in New Issue
Block a user