mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2024-12-25 08:21:08 -06:00
Import routine is prepped for multi-source import (such as banks).
This commit is contained in:
parent
194fe178c0
commit
3e513e92b1
28
app/Http/Controllers/Import/BankController.php
Normal file
28
app/Http/Controllers/Import/BankController.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* BankController.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Import;
|
||||
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
|
||||
class BankController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $bank
|
||||
*/
|
||||
public function prerequisites(string $bank)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
308
app/Http/Controllers/Import/FileController.php
Normal file
308
app/Http/Controllers/Import/FileController.php
Normal file
@ -0,0 +1,308 @@
|
||||
<?php
|
||||
/**
|
||||
* FileController.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Import;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\ImportUploadRequest;
|
||||
use FireflyIII\Import\Configurator\ConfiguratorInterface;
|
||||
use FireflyIII\Import\Routine\ImportRoutine;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response as LaravelResponse;
|
||||
use Log;
|
||||
use Response;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
|
||||
/**
|
||||
* Class FileController.
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers\Import
|
||||
*/
|
||||
class FileController extends Controller
|
||||
{
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
public $repository;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
View::share('mainTitleIcon', 'fa-archive');
|
||||
View::share('title', trans('firefly.import_index_title'));
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is step 1. Upload a file.
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$subTitle = trans('firefly.import_index_sub_title');
|
||||
$subTitleIcon = 'fa-home';
|
||||
$importFileTypes = [];
|
||||
$defaultImportType = config('firefly.default_import_format');
|
||||
|
||||
foreach (array_keys(config('firefly.import_formats')) as $type) {
|
||||
$importFileTypes[$type] = trans('firefly.import_file_type_' . $type);
|
||||
}
|
||||
|
||||
return view('import.file.index', compact('subTitle', 'subTitleIcon', 'importFileTypes', 'defaultImportType'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is step 3. This repeats until the job is configured.
|
||||
*
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return View
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function configure(ImportJob $job)
|
||||
{
|
||||
// create configuration class:
|
||||
$configurator = $this->makeConfigurator($job);
|
||||
|
||||
// is the job already configured?
|
||||
if ($configurator->isJobConfigured()) {
|
||||
$this->repository->updateStatus($job, 'configured');
|
||||
|
||||
return redirect(route('import.file.status', [$job->key]));
|
||||
}
|
||||
$view = $configurator->getNextView();
|
||||
$data = $configurator->getNextData();
|
||||
$subTitle = trans('firefly.import_config_bread_crumb');
|
||||
$subTitleIcon = 'fa-wrench';
|
||||
|
||||
return view($view, compact('data', 'job', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a JSON file of the job's configuration and send it to the user.
|
||||
*
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return LaravelResponse
|
||||
*/
|
||||
public function download(ImportJob $job)
|
||||
{
|
||||
Log::debug('Now in download()', ['job' => $job->key]);
|
||||
$config = $job->configuration;
|
||||
|
||||
// This is CSV import specific:
|
||||
$config['column-roles-complete'] = false;
|
||||
$config['column-mapping-complete'] = false;
|
||||
$config['initial-config-complete'] = false;
|
||||
$config['delimiter'] = $config['delimiter'] === "\t" ? 'tab' : $config['delimiter'];
|
||||
|
||||
$result = json_encode($config, JSON_PRETTY_PRINT);
|
||||
$name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\'));
|
||||
|
||||
/** @var LaravelResponse $response */
|
||||
$response = response($result, 200);
|
||||
$response->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));
|
||||
|
||||
return $response;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is step 2. It creates an Import Job. Stores the import.
|
||||
*
|
||||
* @param ImportUploadRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function initialize(ImportUploadRequest $request)
|
||||
{
|
||||
Log::debug('Now in initialize()');
|
||||
|
||||
// create import job:
|
||||
$type = $request->get('import_file_type');
|
||||
$job = $this->repository->create($type);
|
||||
Log::debug('Created new job', ['key' => $job->key, 'id' => $job->id]);
|
||||
|
||||
// process file:
|
||||
$this->repository->processFile($job, $request->files->get('import_file'));
|
||||
|
||||
// process config, if present:
|
||||
if ($request->files->has('configuration_file')) {
|
||||
$this->repository->processConfiguration($job, $request->files->get('configuration_file'));
|
||||
}
|
||||
|
||||
$this->repository->updateStatus($job, 'initialized');
|
||||
|
||||
return redirect(route('import.file.configure', [$job->key]));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Show status of import job in JSON.
|
||||
*
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function json(ImportJob $job)
|
||||
{
|
||||
$result = [
|
||||
'started' => false,
|
||||
'finished' => false,
|
||||
'running' => false,
|
||||
'errors' => array_values($job->extended_status['errors']),
|
||||
'percentage' => 0,
|
||||
'show_percentage' => false,
|
||||
'steps' => $job->extended_status['steps'],
|
||||
'done' => $job->extended_status['done'],
|
||||
'statusText' => trans('firefly.import_status_job_' . $job->status),
|
||||
'status' => $job->status,
|
||||
'finishedText' => '',
|
||||
];
|
||||
|
||||
if ($job->extended_status['steps'] !== 0) {
|
||||
$result['percentage'] = round(($job->extended_status['done'] / $job->extended_status['steps']) * 100, 0);
|
||||
$result['show_percentage'] = true;
|
||||
}
|
||||
|
||||
if ($job->status === 'finished') {
|
||||
$tagId = $job->extended_status['tag'];
|
||||
/** @var TagRepositoryInterface $repository */
|
||||
$repository = app(TagRepositoryInterface::class);
|
||||
$tag = $repository->find($tagId);
|
||||
$result['finished'] = true;
|
||||
$result['finishedText'] = trans('firefly.import_status_finished_job', ['link' => route('tags.show', [$tag->id, 'all']), 'tag' => $tag->tag]);
|
||||
}
|
||||
|
||||
if ($job->status === 'running') {
|
||||
$result['started'] = true;
|
||||
$result['running'] = true;
|
||||
}
|
||||
|
||||
return Response::json($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 4. Save the configuration.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function postConfigure(Request $request, ImportJob $job)
|
||||
{
|
||||
Log::debug('Now in postConfigure()', ['job' => $job->key]);
|
||||
$configurator = $this->makeConfigurator($job);
|
||||
|
||||
// is the job already configured?
|
||||
if ($configurator->isJobConfigured()) {
|
||||
return redirect(route('import.file.status', [$job->key]));
|
||||
}
|
||||
$data = $request->all();
|
||||
$configurator->configureJob($data);
|
||||
|
||||
// get possible warning from configurator:
|
||||
$warning = $configurator->getWarningMessage();
|
||||
|
||||
if (strlen($warning) > 0) {
|
||||
Session::flash('warning', $warning);
|
||||
}
|
||||
|
||||
// return to configure
|
||||
return redirect(route('import.file.configure', [$job->key]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function start(ImportJob $job)
|
||||
{
|
||||
/** @var ImportRoutine $routine */
|
||||
$routine = app(ImportRoutine::class);
|
||||
$routine->setJob($job);
|
||||
$result = $routine->run();
|
||||
if ($result) {
|
||||
return Response::json(['run' => 'ok']);
|
||||
}
|
||||
|
||||
throw new FireflyException('Job did not complete succesfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View
|
||||
*/
|
||||
public function status(ImportJob $job)
|
||||
{
|
||||
$statuses = ['configured', 'running', 'finished'];
|
||||
if (!in_array($job->status, $statuses)) {
|
||||
return redirect(route('import.file.configure', [$job->key]));
|
||||
}
|
||||
$subTitle = trans('firefly.import_status_sub_title');
|
||||
$subTitleIcon = 'fa-star';
|
||||
|
||||
return view('import.file.status', compact('job', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return ConfiguratorInterface
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function makeConfigurator(ImportJob $job): ConfiguratorInterface
|
||||
{
|
||||
$type = $job->file_type;
|
||||
$key = sprintf('firefly.import_configurators.%s', $type);
|
||||
$className = config($key);
|
||||
if (is_null($className)) {
|
||||
throw new FireflyException('Cannot find configurator class for this job.'); // @codeCoverageIgnore
|
||||
}
|
||||
/** @var ConfiguratorInterface $configurator */
|
||||
$configurator = app($className);
|
||||
$configurator->setJob($job);
|
||||
|
||||
|
||||
return $configurator;
|
||||
}
|
||||
}
|
@ -12,18 +12,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Requests\ImportUploadRequest;
|
||||
use FireflyIII\Import\Configurator\ConfiguratorInterface;
|
||||
use FireflyIII\Import\Routine\ImportRoutine;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response as LaravelResponse;
|
||||
use Log;
|
||||
use Response;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
/**
|
||||
@ -54,72 +43,9 @@ class ImportController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is step 3. This repeats until the job is configured.
|
||||
*
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return View
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function configure(ImportJob $job)
|
||||
{
|
||||
// create configuration class:
|
||||
$configurator = $this->makeConfigurator($job);
|
||||
|
||||
// is the job already configured?
|
||||
if ($configurator->isJobConfigured()) {
|
||||
$this->repository->updateStatus($job, 'configured');
|
||||
|
||||
return redirect(route('import.status', [$job->key]));
|
||||
}
|
||||
$view = $configurator->getNextView();
|
||||
$data = $configurator->getNextData();
|
||||
$subTitle = trans('firefly.import_config_bread_crumb');
|
||||
$subTitleIcon = 'fa-wrench';
|
||||
|
||||
return view($view, compact('data', 'job', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a JSON file of the job's configuration and send it to the user.
|
||||
*
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return LaravelResponse
|
||||
*/
|
||||
public function download(ImportJob $job)
|
||||
{
|
||||
Log::debug('Now in download()', ['job' => $job->key]);
|
||||
$config = $job->configuration;
|
||||
|
||||
// This is CSV import specific:
|
||||
$config['column-roles-complete'] = false;
|
||||
$config['column-mapping-complete'] = false;
|
||||
$config['initial-config-complete'] = false;
|
||||
$config['delimiter'] = $config['delimiter'] === "\t" ? 'tab' : $config['delimiter'];
|
||||
|
||||
$result = json_encode($config, JSON_PRETTY_PRINT);
|
||||
$name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\'));
|
||||
|
||||
/** @var LaravelResponse $response */
|
||||
$response = response($result, 200);
|
||||
$response->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));
|
||||
|
||||
return $response;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is step 1. Upload a file.
|
||||
* General import index
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
@ -137,167 +63,4 @@ class ImportController extends Controller
|
||||
return view('import.index', compact('subTitle', 'subTitleIcon', 'importFileTypes', 'defaultImportType'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is step 2. It creates an Import Job. Stores the import.
|
||||
*
|
||||
* @param ImportUploadRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function initialize(ImportUploadRequest $request)
|
||||
{
|
||||
Log::debug('Now in initialize()');
|
||||
|
||||
// create import job:
|
||||
$type = $request->get('import_file_type');
|
||||
$job = $this->repository->create($type);
|
||||
Log::debug('Created new job', ['key' => $job->key, 'id' => $job->id]);
|
||||
|
||||
// process file:
|
||||
$this->repository->processFile($job, $request->files->get('import_file'));
|
||||
|
||||
// process config, if present:
|
||||
if ($request->files->has('configuration_file')) {
|
||||
$this->repository->processConfiguration($job, $request->files->get('configuration_file'));
|
||||
}
|
||||
|
||||
$this->repository->updateStatus($job, 'initialized');
|
||||
|
||||
return redirect(route('import.configure', [$job->key]));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Show status of import job in JSON.
|
||||
*
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function json(ImportJob $job)
|
||||
{
|
||||
$result = [
|
||||
'started' => false,
|
||||
'finished' => false,
|
||||
'running' => false,
|
||||
'errors' => array_values($job->extended_status['errors']),
|
||||
'percentage' => 0,
|
||||
'show_percentage' => false,
|
||||
'steps' => $job->extended_status['steps'],
|
||||
'done' => $job->extended_status['done'],
|
||||
'statusText' => trans('firefly.import_status_job_' . $job->status),
|
||||
'status' => $job->status,
|
||||
'finishedText' => '',
|
||||
];
|
||||
|
||||
if ($job->extended_status['steps'] !== 0) {
|
||||
$result['percentage'] = round(($job->extended_status['done'] / $job->extended_status['steps']) * 100, 0);
|
||||
$result['show_percentage'] = true;
|
||||
}
|
||||
|
||||
if ($job->status === 'finished') {
|
||||
$tagId = $job->extended_status['tag'];
|
||||
/** @var TagRepositoryInterface $repository */
|
||||
$repository = app(TagRepositoryInterface::class);
|
||||
$tag = $repository->find($tagId);
|
||||
$result['finished'] = true;
|
||||
$result['finishedText'] = trans('firefly.import_status_finished_job', ['link' => route('tags.show', [$tag->id, 'all']), 'tag' => $tag->tag]);
|
||||
}
|
||||
|
||||
if ($job->status === 'running') {
|
||||
$result['started'] = true;
|
||||
$result['running'] = true;
|
||||
}
|
||||
|
||||
return Response::json($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 4. Save the configuration.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function postConfigure(Request $request, ImportJob $job)
|
||||
{
|
||||
Log::debug('Now in postConfigure()', ['job' => $job->key]);
|
||||
$configurator = $this->makeConfigurator($job);
|
||||
|
||||
// is the job already configured?
|
||||
if ($configurator->isJobConfigured()) {
|
||||
return redirect(route('import.status', [$job->key]));
|
||||
}
|
||||
$data = $request->all();
|
||||
$configurator->configureJob($data);
|
||||
|
||||
// get possible warning from configurator:
|
||||
$warning = $configurator->getWarningMessage();
|
||||
|
||||
if (strlen($warning) > 0) {
|
||||
Session::flash('warning', $warning);
|
||||
}
|
||||
|
||||
// return to configure
|
||||
return redirect(route('import.configure', [$job->key]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function start(ImportJob $job)
|
||||
{
|
||||
/** @var ImportRoutine $routine */
|
||||
$routine = app(ImportRoutine::class);
|
||||
$routine->setJob($job);
|
||||
$result = $routine->run();
|
||||
if ($result) {
|
||||
return Response::json(['run' => 'ok']);
|
||||
}
|
||||
|
||||
throw new FireflyException('Job did not complete succesfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View
|
||||
*/
|
||||
public function status(ImportJob $job)
|
||||
{
|
||||
$statuses = ['configured', 'running', 'finished'];
|
||||
if (!in_array($job->status, $statuses)) {
|
||||
return redirect(route('import.configure', [$job->key]));
|
||||
}
|
||||
$subTitle = trans('firefly.import_status_sub_title');
|
||||
$subTitleIcon = 'fa-star';
|
||||
|
||||
return view('import.status', compact('job', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return ConfiguratorInterface
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function makeConfigurator(ImportJob $job): ConfiguratorInterface
|
||||
{
|
||||
$type = $job->file_type;
|
||||
$key = sprintf('firefly.import_configurators.%s', $type);
|
||||
$className = config($key);
|
||||
if (is_null($className)) {
|
||||
throw new FireflyException('Cannot find configurator class for this job.'); // @codeCoverageIgnore
|
||||
}
|
||||
/** @var ConfiguratorInterface $configurator */
|
||||
$configurator = app($className);
|
||||
$configurator->setJob($job);
|
||||
|
||||
|
||||
return $configurator;
|
||||
}
|
||||
}
|
||||
|
@ -471,16 +471,26 @@ Breadcrumbs::register(
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* FILE IMPORT
|
||||
*/
|
||||
Breadcrumbs::register(
|
||||
'import.configure', function (BreadCrumbGenerator $breadcrumbs, ImportJob $job) {
|
||||
'import.file.index', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('import.index');
|
||||
$breadcrumbs->push(trans('firefly.import_config_sub_title', ['key' => $job->key]), route('import.configure', [$job->key]));
|
||||
$breadcrumbs->push(trans('firefly.import_file'), route('import.file.index'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'import.file.configure', function (BreadCrumbGenerator $breadcrumbs, ImportJob $job) {
|
||||
$breadcrumbs->parent('import.file.index');
|
||||
$breadcrumbs->push(trans('firefly.import_config_sub_title', ['key' => $job->key]), route('import.file.configure', [$job->key]));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'import.status', function (BreadCrumbGenerator $breadcrumbs, ImportJob $job) {
|
||||
$breadcrumbs->parent('import.index');
|
||||
$breadcrumbs->push(trans('firefly.import_status_bread_crumb', ['key' => $job->key]), route('import.status', [$job->key]));
|
||||
'import.file.status', function (BreadCrumbGenerator $breadcrumbs, ImportJob $job) {
|
||||
$breadcrumbs->parent('import.file.index');
|
||||
$breadcrumbs->push(trans('firefly.import_status_bread_crumb', ['key' => $job->key]), route('import.file.status', [$job->key]));
|
||||
}
|
||||
);
|
||||
|
||||
|
BIN
public/images/logos/bunq.png
Normal file
BIN
public/images/logos/bunq.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
@ -966,7 +966,8 @@ return [
|
||||
// import index page:
|
||||
'import_index_title' => 'Import data into Firefly III',
|
||||
'import_index_sub_title' => 'Index',
|
||||
'import_index_intro' => 'Welcome to Firefly\'s import routine. These pages can help you import data from your bank into Firefly III. Please check out the help pages in the top right corner.',
|
||||
'import_general_index_intro' => 'Welcome to Firefly\'s import routine. There are a few ways of importing data into Firefly III, displayed here as buttons.',
|
||||
'import_index_intro' => 'This routine will help you import files from your bank into Firefly III. Please check out the help pages in the top right corner.',
|
||||
'import_index_file' => 'Select your file',
|
||||
'import_index_config' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you. For some banks, other users have kindly provided their <a href="https://github.com/firefly-iii/import-configurations/wiki">configuration file</a>.',
|
||||
'import_index_type' => 'Select the type of file you will upload',
|
||||
|
@ -22,7 +22,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="form-horizontal" action="{{ route('import.process-configuration', job.key) }}" method="post" enctype="multipart/form-data">
|
||||
<form class="form-horizontal" action="{{ route('import.file.process-configuration', job.key) }}" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
|
||||
|
||||
<div class="row">
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<form action="{{ route('import.process-configuration', job.key) }}" method="post">
|
||||
<form action="{{ route('import.file.process-configuration', job.key) }}" method="post">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
|
||||
|
||||
{% for field in data %}
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<form action="{{ route('import.process-configuration', job.key) }}" method="post">
|
||||
<form action="{{ route('import.file.process-configuration', job.key) }}" method="post">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
|
||||
<input type="hidden" name="settings" value="roles"/>
|
||||
|
||||
|
38
resources/views/import/file/finished.twig
Normal file
38
resources/views/import/file/finished.twig
Normal file
@ -0,0 +1,38 @@
|
||||
{% extends "./layout/default" %}
|
||||
|
||||
{% 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_finished'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>
|
||||
{{ 'import_finished_intro'|_ }}
|
||||
</p>
|
||||
{% if tagId > 0 %}
|
||||
<p>
|
||||
{{ trans('firefly.import_finished_text_with_link', {tag: tagId})|raw }}
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
{{ 'import_finished_text_without_link'|_ }}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<p>
|
||||
{{ 'import_share_configuration'|_ }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
||||
{% block styles %}
|
||||
{% endblock %}
|
53
resources/views/import/file/index.twig
Normal file
53
resources/views/import/file/index.twig
Normal file
@ -0,0 +1,53 @@
|
||||
{% extends "./layout/default" %}
|
||||
|
||||
{% 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_index_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<p>
|
||||
{{ 'import_index_intro'|_ }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<form method="POST" action="{{ route('import.file.initialize') }}" accept-charset="UTF-8" class="form-horizontal" id="initialize"
|
||||
enctype="multipart/form-data">
|
||||
|
||||
<input name="_token" type="hidden" value="{{ csrf_token() }}">
|
||||
|
||||
<div class="col-lg-8 col-md-8 col-sm-12 col-xs-12">
|
||||
|
||||
{{ ExpandedForm.file('import_file', {helpText: 'import_index_file'|_}) }}
|
||||
{{ ExpandedForm.file('configuration_file', {helpText: 'import_index_config'|_|raw}) }}
|
||||
{{ ExpandedForm.select('import_file_type', importFileTypes, defaultImportType, {'helpText' : 'import_index_type'|_}) }}
|
||||
|
||||
<div class="form-group" id="import_file_holder">
|
||||
<label for="ffInput_submit" class="col-sm-4 control-label"> </label>
|
||||
<div class="col-sm-8">
|
||||
<button type="submit" class="btn pull-right btn-success">
|
||||
{{ ('import_index_start')|_ }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
||||
{% block styles %}
|
||||
{% endblock %}
|
157
resources/views/import/file/status.twig
Normal file
157
resources/views/import/file/status.twig
Normal file
@ -0,0 +1,157 @@
|
||||
{% extends "./layout/default" %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ Breadcrumbs.renderIfExists }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{# Initial display. Will refresh (and disappear almost immediately. #}
|
||||
|
||||
<div class="row status_initial statusbox">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_status_wait_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>
|
||||
{{ 'import_status_wait_text'|_ }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Fatal error display. Will be shown (duh) when something goes horribly wrong. #}
|
||||
<div class="row fatal_error" style="display:none;">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-danger">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_status_fatal_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>
|
||||
{{ 'import_status_fatal_text'|_ }}
|
||||
</p>
|
||||
<p class="text-danger fatal_error_txt">
|
||||
|
||||
</p>
|
||||
<p>
|
||||
{{ 'import_status_fatal_more'|_ }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Box for when the job is ready to start #}
|
||||
<div class="row status_configured statusbox" style="display:none;">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_status_ready_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>
|
||||
{{ 'import_status_ready_text'|_ }}
|
||||
</p>
|
||||
<p>
|
||||
<code>php artisan firefly:start-import {{ job.key }}</code>
|
||||
</p>
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<a href="{{ route('import.file.download', [job.key]) }}" class="btn btn-default"><i
|
||||
class="fa fa-fw fa-download"></i> {{ 'import_status_ready_config'|_ }}</a>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<button class="btn btn-success start-job"><i class="fa fa-fw fa-gears"></i> {{ 'import_status_ready_start'|_ }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p class="text-info">
|
||||
{{ 'import_status_ready_share'|_ }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Box for when the job is running! #}
|
||||
<div class="row status_running statusbox" style="display: none;">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title" id="import-status-title">{{ 'import_status_running_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div id="import-status-holder">
|
||||
<div class="progress" id="import-status-holder">
|
||||
<div id="import-status-bar" class="progress-bar progress-bar-info active progress-bar-striped" role="progressbar"
|
||||
aria-valuenow="100" aria-valuemin="0"
|
||||
aria-valuemax="100" style="width: 100%;min-width:40px;">
|
||||
</div>
|
||||
</div>
|
||||
<p id="import-status-txt">{{ 'import_status_running_placeholder'|_ }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# displays the finished status of the import #}
|
||||
<div class="row status_finished statusbox" style="display:none;">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_status_finished_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p id="import-status-intro">
|
||||
{{ 'import_status_finished_text'|_ }}
|
||||
</p>
|
||||
<p id="import-status-more-info"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# box to show error information. #}
|
||||
<div class="row info_errors" style="display:none;">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-danger">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_status_errors_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p id="import-status-error-intro">
|
||||
</p>
|
||||
<div id="import-status-error-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script type="text/javascript">
|
||||
|
||||
// some useful translations.
|
||||
var langImportSingleError = '{{ 'import_status_errors_single'|_|escape }}';
|
||||
var langImportMultiError = '{{ 'import_status_errors_multi'|_|escape }}';
|
||||
|
||||
//var langImportFatalError = '{{ 'import_error_fatal'|_|escape }}';
|
||||
//var langImportTimeOutError = '{{ 'import_error_timeout'|_|escape }}';
|
||||
//var langImportFinished = '{{ 'import_finished_all'|_|escape }}';
|
||||
|
||||
|
||||
var jobKey = '{{ job.key }}';
|
||||
var jobImportUrl = '{{ route('import.file.json', [job.key]) }}';
|
||||
var jobStartUrl = '{{ route('import.file.start', [job.key]) }}';
|
||||
var token = '{{ csrf_token() }}';
|
||||
</script>
|
||||
<script type="text/javascript" src="js/ff/import/status.js"></script>
|
||||
{% endblock %}
|
||||
{% block styles %}
|
||||
{% endblock %}
|
@ -14,33 +14,28 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<p>
|
||||
{{ 'import_index_intro'|_ }}
|
||||
{{ 'import_general_index_intro'|_ }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<form method="POST" action="{{ route('import.initialize') }}" accept-charset="UTF-8" class="form-horizontal" id="initialize"
|
||||
enctype="multipart/form-data">
|
||||
|
||||
<input name="_token" type="hidden" value="{{ csrf_token() }}">
|
||||
|
||||
<div class="col-lg-8 col-md-8 col-sm-12 col-xs-12">
|
||||
|
||||
{{ ExpandedForm.file('import_file', {helpText: 'import_index_file'|_}) }}
|
||||
{{ ExpandedForm.file('configuration_file', {helpText: 'import_index_config'|_|raw}) }}
|
||||
{{ ExpandedForm.select('import_file_type', importFileTypes, defaultImportType, {'helpText' : 'import_index_type'|_}) }}
|
||||
|
||||
<div class="form-group" id="import_file_holder">
|
||||
<label for="ffInput_submit" class="col-sm-4 control-label"> </label>
|
||||
<div class="col-sm-8">
|
||||
<button type="submit" class="btn pull-right btn-success">
|
||||
{{ ('import_index_start')|_ }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="col-lg-8">
|
||||
<p>
|
||||
{# file import #}
|
||||
<a href="{{ route('import.file.index') }}" class="btn btn-app">
|
||||
<i class="fa fa-file-text-o"></i>
|
||||
Import a (CSV) file
|
||||
</a>
|
||||
{# bunq import #}
|
||||
{#
|
||||
<a href="{{ route('import.bank.prerequisites', ['bunq']) }}" class="btn btn-app">
|
||||
<img src="images/logos/bunq.png" alt="bunq"/><br />
|
||||
Import from bunq
|
||||
</a>
|
||||
#}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -153,48 +153,6 @@
|
||||
<a href="{{ route('reports.report.audit',[accountList, start.format('Ymd'),'currentMonthEnd']) }}">{{ 'report_all_time_quick'|_ }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{#<h4>{{ ('quick_link_category_report')|_ }}</h4>#}
|
||||
|
||||
|
||||
{#
|
||||
|
||||
{% for type in ['default','audit'] %}
|
||||
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route('reports.report.'~type,
|
||||
[
|
||||
'currentYearStart',
|
||||
'currentYearEnd',
|
||||
accountList
|
||||
]) }}">{{ 'report_this_year_quick'|_ }}</a>
|
||||
</li>
|
||||
{% if customFiscalYear == 1 %}
|
||||
<li>
|
||||
<a href="{{ route('reports.report.'~type,
|
||||
['default',
|
||||
'currentFiscalYearStart',
|
||||
'currentFiscalYearEnd',
|
||||
accountList
|
||||
]) }}">{{ 'report_this_fiscal_year_quick'|_ }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a href="{{ route('reports.report.'~type,
|
||||
[
|
||||
start.format('Ymd'),
|
||||
'currentMonthEnd',
|
||||
accountList
|
||||
]) }}">{{ 'report_all_time_quick'|_ }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
#}
|
||||
|
||||
<p>
|
||||
<em>{{ 'reports_can_bookmark'|_ }}</em>
|
||||
</p>
|
||||
|
@ -384,23 +384,22 @@ Route::group(
|
||||
['middleware' => 'user-full-auth', 'prefix' => 'import', 'as' => 'import.'], function () {
|
||||
|
||||
Route::get('', ['uses' => 'ImportController@index', 'as' => 'index']);
|
||||
Route::post('initialize', ['uses' => 'ImportController@initialize', 'as' => 'initialize']);
|
||||
|
||||
Route::get('configure/{importJob}', ['uses' => 'ImportController@configure', 'as' => 'configure']);
|
||||
Route::post('configure/{importJob}', ['uses' => 'ImportController@postConfigure', 'as' => 'process-configuration']);
|
||||
|
||||
Route::get('download/{importJob}', ['uses' => 'ImportController@download', 'as' => 'download']);
|
||||
Route::get('status/{importJob}', ['uses' => 'ImportController@status', 'as' => 'status']);
|
||||
Route::get('json/{importJob}', ['uses' => 'ImportController@json', 'as' => 'json']);
|
||||
Route::post('start/{importJob}', ['uses' => 'ImportController@start', 'as' => 'start']);
|
||||
|
||||
|
||||
//Route::get('settings/{importJob}', ['uses' => 'ImportController@settings', 'as' => 'settings']);
|
||||
//Route::get('complete/{importJob}', ['uses' => 'ImportController@complete', 'as' => 'complete']);
|
||||
//Route::get('finished/{importJob}', ['uses' => 'ImportController@finished', 'as' => 'finished']);
|
||||
//Route::post('settings/{importJob}', ['uses' => 'ImportController@postSettings', 'as' => 'post-settings']);
|
||||
// file import
|
||||
Route::get('file', ['uses' => 'Import\FileController@index', 'as' => 'file.index']);
|
||||
Route::post('file/initialize', ['uses' => 'Import\FileController@initialize', 'as' => 'file.initialize']);
|
||||
|
||||
Route::get('file/configure/{importJob}', ['uses' => 'Import\FileController@configure', 'as' => 'file.configure']);
|
||||
Route::post('file/configure/{importJob}', ['uses' => 'Import\FileController@postConfigure', 'as' => 'file.process-configuration']);
|
||||
|
||||
Route::get('file/download/{importJob}', ['uses' => 'Import\FileController@download', 'as' => 'file.download']);
|
||||
Route::get('file/status/{importJob}', ['uses' => 'Import\FileController@status', 'as' => 'file.status']);
|
||||
Route::get('file/json/{importJob}', ['uses' => 'Import\FileController@json', 'as' => 'file.json']);
|
||||
Route::post('file/start/{importJob}', ['uses' => 'Import\FileController@start', 'as' => 'file.start']);
|
||||
|
||||
// banks:
|
||||
Route::get('bank/{bank}/prerequisites', ['uses' => 'Import\BankController@prerequisites', 'as' => 'bank.prerequisites']);
|
||||
}
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user