mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
New code for YNAB import.
This commit is contained in:
parent
7ad09da4e9
commit
dfd9cf0874
@ -132,11 +132,12 @@ class JobStatusController extends Controller
|
||||
*/
|
||||
public function start(ImportJob $importJob): JsonResponse
|
||||
{
|
||||
Log::debug('Now in JobStatusController::start');
|
||||
// catch impossible status:
|
||||
$allowed = ['ready_to_run', 'need_job_config'];
|
||||
|
||||
if (null !== $importJob && !\in_array($importJob->status, $allowed, true)) {
|
||||
Log::error('Job is not ready.');
|
||||
Log::error(sprintf('Job is not ready. Status should be in array, but is %s', $importJob->status), $allowed);
|
||||
$this->repository->setStatus($importJob, 'error');
|
||||
|
||||
return response()->json(
|
||||
@ -157,7 +158,11 @@ class JobStatusController extends Controller
|
||||
/** @var RoutineInterface $routine */
|
||||
$routine = app($className);
|
||||
$routine->setImportJob($importJob);
|
||||
|
||||
Log::debug(sprintf('Created class of type %s', $className));
|
||||
|
||||
try {
|
||||
Log::debug(sprintf('Try to call %s:run()', $className));
|
||||
$routine->run();
|
||||
} catch (FireflyException|Exception $e) {
|
||||
$message = 'The import routine crashed: ' . $e->getMessage();
|
||||
@ -189,7 +194,7 @@ class JobStatusController extends Controller
|
||||
// catch impossible status:
|
||||
$allowed = ['provider_finished', 'storing_data'];
|
||||
if (null !== $importJob && !\in_array($importJob->status, $allowed, true)) {
|
||||
Log::error('Job is not ready.');
|
||||
Log::error(sprintf('Job is not ready. Status should be in array, but is %s', $importJob->status), $allowed);
|
||||
|
||||
return response()->json(
|
||||
['status' => 'NOK', 'message' => sprintf('JobStatusController::start expects status "provider_finished" instead of "%s".', $importJob->status)]
|
||||
|
@ -23,8 +23,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Import\JobConfiguration;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Ynab\NewYnabJobHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Ynab\SelectBudgetsHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Ynab\YnabJobConfigurationInterface;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
@ -33,6 +37,8 @@ use Log;
|
||||
*/
|
||||
class YnabJobConfiguration implements JobConfigurationInterface
|
||||
{
|
||||
/** @var YnabJobConfigurationInterface The job handler. */
|
||||
private $handler;
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
@ -45,16 +51,7 @@ class YnabJobConfiguration implements JobConfigurationInterface
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
// config is only needed when the job is in stage "new".
|
||||
if ($this->importJob->stage === 'new') {
|
||||
Log::debug('YNAB configurationComplete: stage is new, return false');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Log::debug('YNAB configurationComplete: stage is not new, return true');
|
||||
|
||||
return true;
|
||||
return $this->handler->configurationComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,10 +64,7 @@ class YnabJobConfiguration implements JobConfigurationInterface
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
Log::debug('YNAB configureJob: nothing to do.');
|
||||
|
||||
// there is never anything to store from this job.
|
||||
return new MessageBag;
|
||||
return $this->handler->configureJob($data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,24 +74,7 @@ class YnabJobConfiguration implements JobConfigurationInterface
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
$data = [];
|
||||
// here we update the job so it can redirect properly to YNAB
|
||||
if ($this->importJob->stage === 'new') {
|
||||
|
||||
// update stage to make sure we catch the token.
|
||||
$this->repository->setStage($this->importJob, 'catch-auth-code');
|
||||
$clientId = (string)config('import.options.ynab.client_id');
|
||||
$callBackUri = route('import.callback.ynab');
|
||||
$uri = sprintf(
|
||||
'https://app.youneedabudget.com/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code&state=%s', $clientId, $callBackUri,
|
||||
$this->importJob->key
|
||||
);
|
||||
$data['token-url'] = $uri;
|
||||
Log::debug(sprintf('YNAB getNextData: URI to redirect to is %s', $uri));
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
||||
return $this->handler->getNextData();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,19 +84,53 @@ class YnabJobConfiguration implements JobConfigurationInterface
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
Log::debug('Return YNAB redirect view.');
|
||||
return 'import.ynab.redirect';
|
||||
return $this->handler->getNextView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->handler = $this->getHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get correct handler.
|
||||
*
|
||||
* @return YnabJobConfigurationInterface
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function getHandler(): YnabJobConfigurationInterface
|
||||
{
|
||||
Log::debug(sprintf('Now in YnabJobConfiguration::getHandler() with stage "%s"', $this->importJob->stage));
|
||||
$handler = null;
|
||||
switch ($this->importJob->stage) {
|
||||
case 'new':
|
||||
/** @var NewYnabJobHandler $handler */
|
||||
$handler = app(NewYnabJobHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
case 'select_budgets':
|
||||
/** @var SelectBudgetsHandler $handler */
|
||||
$handler = app(SelectBudgetsHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
default:
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException(sprintf('Firefly III cannot create a YNAB configuration handler for stage "%s"', $this->importJob->stage));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $handler;
|
||||
}
|
||||
}
|
@ -26,7 +26,9 @@ namespace FireflyIII\Import\Routine;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\Routine\Ynab\GetAccountsHandler;
|
||||
use FireflyIII\Support\Import\Routine\Ynab\StageGetAccessHandler;
|
||||
use FireflyIII\Support\Import\Routine\Ynab\StageGetBudgetsHandler;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
@ -61,12 +63,69 @@ class YnabRoutine implements RoutineInterface
|
||||
$handler = app(StageGetAccessHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
$this->repository->setStage($this->importJob, 'get_transactions');
|
||||
|
||||
// back to correct stage:
|
||||
$this->repository->setStatus($this->importJob, 'ready_to_run');
|
||||
$this->repository->setStage($this->importJob, 'get_budgets');
|
||||
|
||||
return;
|
||||
}
|
||||
if ('get_budgets' === $this->importJob->stage) {
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
/** @var StageGetBudgetsHandler $handler */
|
||||
$handler = app(StageGetBudgetsHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
|
||||
// count budgets in job, to determine next step.
|
||||
$configuration = $this->repository->getConfiguration($this->importJob);
|
||||
$budgets = $configuration['budgets'] ?? [];
|
||||
|
||||
// if more than 1 budget, select budget first.
|
||||
if (\count($budgets) > 0) { // TODO should be 1
|
||||
$this->repository->setStage($this->importJob, 'select_budgets');
|
||||
$this->repository->setStatus($this->importJob, 'need_job_config');
|
||||
return;
|
||||
}
|
||||
|
||||
if (\count($budgets) === 1) {
|
||||
$this->repository->setStage($this->importJob, 'match_accounts');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
if('get_accounts' === $this->importJob->stage) {
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
|
||||
/** @var GetAccountsHandler $handler */
|
||||
$handler = app(GetAccountsHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
|
||||
$this->repository->setStage($this->importJob, 'select_accounts');
|
||||
$this->repository->setStatus($this->importJob, 'need_job_config');
|
||||
|
||||
}
|
||||
|
||||
// if ('match_accounts' === $this->importJob->stage) {
|
||||
// // $this->repository->setStatus($this->importJob, 'running');
|
||||
// /** @var StageGetBudgetsHandler $handler */
|
||||
// $handler = app(StageGetBudgetsHandler::class);
|
||||
// $handler->setImportJob($this->importJob);
|
||||
// $handler->run();
|
||||
// $this->repository->setStage($this->importJob, 'get_transactions');
|
||||
// }
|
||||
//
|
||||
// if ('get_transactions' === $this->importJob->stage) {
|
||||
// // $this->repository->setStatus($this->importJob, 'running');
|
||||
// /** @var StageGetBudgetsHandler $handler */
|
||||
// $handler = app(StageGetBudgetsHandler::class);
|
||||
// $handler->setImportJob($this->importJob);
|
||||
// $handler->run();
|
||||
// $this->repository->setStage($this->importJob, 'get_transactions');
|
||||
// }
|
||||
throw new FireflyException(sprintf('YNAB import routine cannot handle stage "%s"', $this->importJob->stage));
|
||||
}
|
||||
throw new FireflyException(sprintf('YNAB import routine cannot handle status "%s"', $this->importJob->status));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,7 +184,6 @@ class ImportJobRepository implements ImportJobRepositoryInterface
|
||||
$newConfig = array_merge($currentConfig, $configuration);
|
||||
$job->configuration = $newConfig;
|
||||
$job->save();
|
||||
|
||||
//Log::debug(sprintf('Set config of job "%s" to: ', $job->key), $newConfig);
|
||||
|
||||
return $job;
|
||||
|
53
app/Services/Ynab/Request/GetAccountsRequest.php
Normal file
53
app/Services/Ynab/Request/GetAccountsRequest.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* GetAccountsRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Services\Ynab\Request;
|
||||
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class GetAccountsRequest
|
||||
*/
|
||||
class GetAccountsRequest extends YnabRequest
|
||||
{
|
||||
/** @var array */
|
||||
public $accounts;
|
||||
/** @var string */
|
||||
public $budgetId;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function call(): void
|
||||
{
|
||||
Log::debug('Now in GetAccountsRequest::call()');
|
||||
$uri = $this->api . sprintf('/budgets/%s/accounts', $this->budgetId);
|
||||
|
||||
Log::debug(sprintf('URI is %s', $uri));
|
||||
|
||||
$result = $this->authenticatedGetRequest($uri, []);
|
||||
|
||||
// expect data in [data][accounts]
|
||||
$this->accounts = $result['data']['accounts'] ?? [];
|
||||
}
|
||||
}
|
66
app/Services/Ynab/Request/GetBudgetsRequest.php
Normal file
66
app/Services/Ynab/Request/GetBudgetsRequest.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* GetBudgetsRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Services\Ynab\Request;
|
||||
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class GetBudgetsRequest
|
||||
*/
|
||||
class GetBudgetsRequest extends YnabRequest
|
||||
{
|
||||
/** @var array */
|
||||
public $budgets;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->budgets = [];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function call(): void
|
||||
{
|
||||
Log::debug('Now in GetBudgetsRequest::call()');
|
||||
$uri = $this->api . '/budgets';
|
||||
|
||||
Log::debug(sprintf('URI is %s', $uri));
|
||||
|
||||
$result = $this->authenticatedGetRequest($uri, []);
|
||||
|
||||
// expect data in [data][budgets]
|
||||
$rawBudgets = $result['data']['budgets'] ?? [];
|
||||
$freshBudgets = [];
|
||||
foreach ($rawBudgets as $rawBudget) {
|
||||
$freshBudgets[] = [
|
||||
'id' => $rawBudget['id'],
|
||||
'name' => $rawBudget['name'],
|
||||
'currency_code' => $rawBudget['currency_format']['iso_code'],
|
||||
];
|
||||
}
|
||||
$this->budgets = $freshBudgets;
|
||||
}
|
||||
}
|
100
app/Services/Ynab/Request/YnabRequest.php
Normal file
100
app/Services/Ynab/Request/YnabRequest.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* YnabRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Services\Ynab\Request;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Log;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class YnabRequest
|
||||
*/
|
||||
abstract class YnabRequest
|
||||
{
|
||||
/** @var string */
|
||||
protected $api;
|
||||
|
||||
/** @var string */
|
||||
protected $token;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->api = 'https://' . config('import.options.ynab.live') . '/' . config('import.options.ynab.version');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @param array|null $params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function authenticatedGetRequest(string $uri, array $params = null): array
|
||||
{
|
||||
Log::debug(sprintf('Now in YnabRequest::authenticatedGetRequest(%s)', $uri), $params);
|
||||
$client = new Client;
|
||||
$params = $params ?? [];
|
||||
$options = [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $this->token,
|
||||
],
|
||||
];
|
||||
if (\count($params) > 0) {
|
||||
$uri = $uri . '?' . http_build_query($params);
|
||||
}
|
||||
Log::debug(sprintf('Going to call YNAB on URI: %s', $uri), $options);
|
||||
try {
|
||||
$res = $client->request('get', $uri, $options);
|
||||
} catch (GuzzleException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
$content = trim($res->getBody()->getContents());
|
||||
} catch (RuntimeException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
return json_decode($content, true) ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
abstract public function call(): void;
|
||||
|
||||
/**
|
||||
* @param string $token
|
||||
*/
|
||||
public function setAccessToken(string $token): void
|
||||
{
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
}
|
252
app/Support/Import/JobConfiguration/Ynab/NewYnabJobHandler.php
Normal file
252
app/Support/Import/JobConfiguration/Ynab/NewYnabJobHandler.php
Normal file
@ -0,0 +1,252 @@
|
||||
<?php
|
||||
/**
|
||||
* NewYnabJobHandler.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Ynab;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class NewYnabJobHandler
|
||||
*/
|
||||
class NewYnabJobHandler implements YnabJobConfigurationInterface
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Return true when this stage is complete.
|
||||
*
|
||||
* @return bool
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
if (!$this->hasRefreshToken()) {
|
||||
Log::debug('YNAB NewYnabJobHandler configurationComplete: stage is new, no refresh token, return false');
|
||||
|
||||
return false;
|
||||
}
|
||||
if ($this->hasRefreshToken() && $this->hasClientId() && $this->hasClientSecret()) {
|
||||
Log::debug('YNAB NewYnabJobHandler configurationComplete: stage is new, has a refresh token, return true');
|
||||
// need to grab access token using refresh token
|
||||
$this->getAccessToken();
|
||||
$this->repository->setStatus($this->importJob, 'ready_to_run');
|
||||
$this->repository->setStage($this->importJob, 'get_budgets');
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::error('YNAB NewYnabJobHandler configurationComplete: something broke, return true');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the job configuration. There is never anything to store for this stage.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
Log::debug('YNAB NewYnabJobHandler configureJob: nothing to do.');
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for config view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
$data = [];
|
||||
// here we update the job so it can redirect properly to YNAB
|
||||
if (!$this->hasRefreshToken() && $this->hasClientSecret() && $this->hasClientId()) {
|
||||
// update stage to make sure we catch the token.
|
||||
$this->repository->setStage($this->importJob, 'catch-auth-code');
|
||||
$clientId = app('preferences')->get('ynab_client_id')->data;
|
||||
$callBackUri = route('import.callback.ynab');
|
||||
$uri = sprintf(
|
||||
'https://app.youneedabudget.com/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code&state=%s', $clientId, $callBackUri,
|
||||
$this->importJob->key
|
||||
);
|
||||
$data['token-url'] = $uri;
|
||||
Log::debug(sprintf('YNAB getNextData: URI to redirect to is %s', $uri));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
Log::debug('Return YNAB redirect view.');
|
||||
|
||||
return 'import.ynab.redirect';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getAccessToken(): void
|
||||
{
|
||||
$clientId = app('preferences')->get('ynab_client_id')->data;
|
||||
$clientSecret = app('preferences')->get('ynab_client_secret')->data;
|
||||
$refreshToken = app('preferences')->get('ynab_refresh_token')->data;
|
||||
$uri = sprintf(
|
||||
'https://app.youneedabudget.com/oauth/token?client_id=%s&client_secret=%s&grant_type=refresh_token&refresh_token=%s', $clientId, $clientSecret,
|
||||
$refreshToken
|
||||
);
|
||||
|
||||
$client = new Client();
|
||||
try {
|
||||
$res = $client->request('post', $uri, []);
|
||||
} catch (GuzzleException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
throw new FireflyException($e->getMessage());
|
||||
}
|
||||
$statusCode = $res->getStatusCode();
|
||||
try {
|
||||
$content = trim($res->getBody()->getContents());
|
||||
} catch (RuntimeException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
throw new FireflyException($e->getMessage());
|
||||
}
|
||||
$json = json_decode($content, true) ?? [];
|
||||
Log::debug(sprintf('Status code from YNAB is %d', $statusCode));
|
||||
Log::debug(sprintf('Body of result is %s', $content), $json);
|
||||
|
||||
// store refresh token (if present?) as preference
|
||||
// store token in job:
|
||||
$configuration = $this->repository->getConfiguration($this->importJob);
|
||||
$configuration['access_token'] = $json['access_token'];
|
||||
$configuration['access_token_expires'] = (int)$json['created_at'] + (int)$json['expires_in'];
|
||||
$this->repository->setConfiguration($this->importJob, $configuration);
|
||||
|
||||
// also store new refresh token:
|
||||
$refreshToken = (string)($json['refresh_token'] ?? '');
|
||||
if ('' !== $refreshToken) {
|
||||
app('preferences')->set('ynab_refresh_token', $refreshToken);
|
||||
}
|
||||
|
||||
|
||||
Log::debug('end of NewYnabJobHandler::getAccessToken()');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have the client ID.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasClientId(): bool
|
||||
{
|
||||
$clientId = app('preferences')->getForUser($this->importJob->user, 'ynab_client_id', null);
|
||||
if (null === $clientId) {
|
||||
Log::debug('user has no YNAB client ID');
|
||||
|
||||
return false;
|
||||
}
|
||||
if ('' === (string)$clientId->data) {
|
||||
Log::debug('user has no YNAB client ID (empty)');
|
||||
|
||||
return false;
|
||||
}
|
||||
Log::debug('user has a YNAB client ID');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have the client secret
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasClientSecret(): bool
|
||||
{
|
||||
$clientSecret = app('preferences')->getForUser($this->importJob->user, 'ynab_client_secret', null);
|
||||
if (null === $clientSecret) {
|
||||
Log::debug('user has no YNAB client secret');
|
||||
|
||||
return false;
|
||||
}
|
||||
if ('' === (string)$clientSecret->data) {
|
||||
Log::debug('user has no YNAB client secret (empty)');
|
||||
|
||||
return false;
|
||||
}
|
||||
Log::debug('user has a YNAB client secret');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function hasRefreshToken(): bool
|
||||
{
|
||||
$preference = app('preferences')->get('ynab_refresh_token');
|
||||
if (null === $preference) {
|
||||
Log::debug('user has no YNAB refresh token.');
|
||||
|
||||
return false;
|
||||
}
|
||||
if ('' === (string)$preference->data) {
|
||||
Log::debug('user has no YNAB refresh token (empty).');
|
||||
|
||||
return false;
|
||||
}
|
||||
Log::debug(sprintf('user has YNAB refresh token: %s', $preference->data));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* SelectBudgetsHandler.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Ynab;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class SelectBudgetsHandler
|
||||
*/
|
||||
class SelectBudgetsHandler implements YnabJobConfigurationInterface
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Return true when this stage is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
Log::debug('Now in SelectBudgetsHandler::configComplete');
|
||||
$configuration = $this->repository->getConfiguration($this->importJob);
|
||||
$selectedBudget = $configuration['selected_budget'] ?? '';
|
||||
if ($selectedBudget !== '') {
|
||||
Log::debug(sprintf('Selected budget is %s, config is complete. Return true.', $selectedBudget));
|
||||
$this->repository->setStage($this->importJob, 'get_accounts');
|
||||
return true;
|
||||
}
|
||||
Log::debug('User has not selected a budget yet, config is not yet complete.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the job configuration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
Log::debug('Now in SelectBudgetsHandler::configureJob');
|
||||
$configuration = $this->repository->getConfiguration($this->importJob);
|
||||
$configuration['selected_budget'] = $data['budget_id'];
|
||||
|
||||
Log::debug(sprintf('Set selected budget to %s', $data['budget_id']));
|
||||
Log::debug('Mark job as ready for next stage.');
|
||||
|
||||
|
||||
$this->repository->setConfiguration($this->importJob, $configuration);
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for config view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
Log::debug('Now in SelectBudgetsHandler::getNextData');
|
||||
$configuration = $this->repository->getConfiguration($this->importJob);
|
||||
$budgets = $configuration['budgets'] ?? [];
|
||||
$return = [];
|
||||
foreach ($budgets as $budget) {
|
||||
$return[$budget['id']] = $budget['name'] . ' (' . $budget['currency_code'] . ')';
|
||||
}
|
||||
|
||||
return [
|
||||
'budgets' => $return,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
Log::debug('Now in SelectBudgetsHandler::getNextView');
|
||||
|
||||
return 'import.ynab.select-budgets';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* YnabJobConfigurationInterface.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Ynab;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* Interface YnabJobConfigurationInterface
|
||||
*
|
||||
* @package FireflyIII\Support\Import\JobConfiguration\Ynab
|
||||
*/
|
||||
interface YnabJobConfigurationInterface
|
||||
{
|
||||
/**
|
||||
* Return true when this stage is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool;
|
||||
|
||||
|
||||
/**
|
||||
* Store the job configuration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag;
|
||||
|
||||
/**
|
||||
* Get data for config view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array;
|
||||
|
||||
/**
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string;
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void;
|
||||
}
|
80
app/Support/Import/Routine/Ynab/GetAccountsHandler.php
Normal file
80
app/Support/Import/Routine/Ynab/GetAccountsHandler.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* GetAccountsHandler.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Ynab;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Services\Ynab\Request\GetAccountsRequest;
|
||||
|
||||
/**
|
||||
* Class GetAccountsHandler
|
||||
*/
|
||||
class GetAccountsHandler
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Get list of accounts for the selected budget.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$selectedBudget = $config['selected_budget'] ?? '';
|
||||
if ('' === $selectedBudget) {
|
||||
$firstBudget = $config['budgets'][0] ?? false;
|
||||
if (false === $firstBudget) {
|
||||
throw new FireflyException('The configuration contains no budget. Erroring out.');
|
||||
}
|
||||
$selectedBudget = $firstBudget['id'];
|
||||
$config['selected_budget'] = $selectedBudget;
|
||||
}
|
||||
$token = $config['access_token'];
|
||||
$request = new GetAccountsRequest;
|
||||
$request->budgetId = $selectedBudget;
|
||||
$request->setAccessToken($token);
|
||||
$request->call();
|
||||
$config['accounts'] = $request->accounts;
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
if (0 === \count($config['accounts'])) {
|
||||
throw new FireflyException('This budget contains zero accounts.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Log;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class StageGetAccessHandler
|
||||
@ -66,12 +67,31 @@ class StageGetAccessHandler
|
||||
throw new FireflyException($e->getMessage());
|
||||
}
|
||||
$statusCode = $res->getStatusCode();
|
||||
$content = trim($res->getBody()->getContents());
|
||||
try {
|
||||
$content = trim($res->getBody()->getContents());
|
||||
} catch(RuntimeException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
throw new FireflyException($e->getMessage());
|
||||
}
|
||||
|
||||
$json = json_decode($content, true) ?? [];
|
||||
Log::debug(sprintf('Status code from YNAB is %d', $statusCode));
|
||||
Log::debug(sprintf('Body of result is %s', $content), $json);
|
||||
Log::error('Hard exit');
|
||||
exit;
|
||||
|
||||
// store refresh token (if present?) as preference
|
||||
// store token in job:
|
||||
$configuration = $this->repository->getConfiguration($this->importJob);
|
||||
$configuration['access_token'] = $json['access_token'];
|
||||
$configuration['access_token_expires'] = (int)$json['created_at'] + (int)$json['expires_in'];
|
||||
$this->repository->setConfiguration($this->importJob, $configuration);
|
||||
|
||||
Log::debug('end of StageGetAccessHandler::run()');
|
||||
|
||||
$refreshToken = (string)($json['refresh_token'] ?? '');
|
||||
if ('' !== $refreshToken) {
|
||||
app('preferences')->set('ynab_refresh_token', $refreshToken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
75
app/Support/Import/Routine/Ynab/StageGetBudgetsHandler.php
Normal file
75
app/Support/Import/Routine/Ynab/StageGetBudgetsHandler.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* StageGetBudgetsHandler.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Ynab;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Services\Ynab\Request\GetBudgetsRequest;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class StageGetBudgetsHandler
|
||||
*/
|
||||
class StageGetBudgetsHandler
|
||||
{
|
||||
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::debug('Now in StageGetBudgetsHandler::run()');
|
||||
// grab access token from job:
|
||||
$configuration = $this->repository->getConfiguration($this->importJob);
|
||||
$token = $configuration['access_token'];
|
||||
$request = new GetBudgetsRequest;
|
||||
$request->setAccessToken($token);
|
||||
$request->call();
|
||||
|
||||
// store budgets in users preferences.
|
||||
$configuration['budgets'] = $request->budgets;
|
||||
$this->repository->setConfiguration($this->importJob, $configuration);
|
||||
Log::debug(sprintf('Found %d budgets', \count($request->budgets)));
|
||||
if (\count($request->budgets) === 0) {
|
||||
throw new FireflyException('It seems this user has zero budgets or an error prevented Firefly III from reading them.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* StageGetTransactionsHandler.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Ynab;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class StageGetTransactionsHandler
|
||||
*/
|
||||
class StageGetTransactionsHandler
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* StageMatchAccountsHandler.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Ynab;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class StageMatchAccountsHandler
|
||||
*/
|
||||
class StageMatchAccountsHandler
|
||||
{
|
||||
|
||||
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
}
|
@ -172,7 +172,7 @@ class Preferences
|
||||
$lastActivity = implode(',', $lastActivity);
|
||||
}
|
||||
$hash = md5($lastActivity);
|
||||
Log::debug(sprintf('Value of last activity is %s, hash is %s', $lastActivity, $hash));
|
||||
//Log::debug(sprintf('Value of last activity is %s, hash is %s', $lastActivity, $hash));
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
@ -151,8 +151,9 @@ return [
|
||||
'spectre' => [
|
||||
'server' => 'www.saltedge.com',
|
||||
],
|
||||
'ynab' => [
|
||||
'client_id' => '666db19f6c5a2299bf44999a6ea802e96a5f488c3a5c8a5cbb417b59dcf18b72',
|
||||
'ynab' => [
|
||||
'live' => 'api.youneedabudget.com',
|
||||
'version' => 'v1',
|
||||
],
|
||||
'plaid' => [],
|
||||
'quovo' => [],
|
||||
|
@ -24,252 +24,259 @@ declare(strict_types=1);
|
||||
|
||||
return [
|
||||
// ALL breadcrumbs and subtitles:
|
||||
'index_breadcrumb' => 'Import data into Firefly III',
|
||||
'prerequisites_breadcrumb_fake' => 'Prerequisites for the fake import provider',
|
||||
'prerequisites_breadcrumb_spectre' => 'Prerequisites for Spectre',
|
||||
'prerequisites_breadcrumb_bunq' => 'Prerequisites for bunq',
|
||||
'prerequisites_breadcrumb_ynab' => 'Prerequisites for YNAB',
|
||||
'job_configuration_breadcrumb' => 'Configuration for ":key"',
|
||||
'job_status_breadcrumb' => 'Import status for ":key"',
|
||||
'cannot_create_for_provider' => 'Firefly III cannot create a job for the ":provider"-provider.',
|
||||
'disabled_for_demo_user' => 'disabled in demo',
|
||||
'index_breadcrumb' => 'Import data into Firefly III',
|
||||
'prerequisites_breadcrumb_fake' => 'Prerequisites for the fake import provider',
|
||||
'prerequisites_breadcrumb_spectre' => 'Prerequisites for Spectre',
|
||||
'prerequisites_breadcrumb_bunq' => 'Prerequisites for bunq',
|
||||
'prerequisites_breadcrumb_ynab' => 'Prerequisites for YNAB',
|
||||
'job_configuration_breadcrumb' => 'Configuration for ":key"',
|
||||
'job_status_breadcrumb' => 'Import status for ":key"',
|
||||
'cannot_create_for_provider' => 'Firefly III cannot create a job for the ":provider"-provider.',
|
||||
'disabled_for_demo_user' => 'disabled in demo',
|
||||
|
||||
// index page:
|
||||
'general_index_title' => 'Import a file',
|
||||
'general_index_intro' => 'Welcome to Firefly III\'s import routine. There are a few ways of importing data into Firefly III, displayed here as buttons.',
|
||||
'general_index_title' => 'Import a file',
|
||||
'general_index_intro' => 'Welcome to Firefly III\'s import routine. There are a few ways of importing data into Firefly III, displayed here as buttons.',
|
||||
// import provider strings (index):
|
||||
'button_fake' => 'Fake an import',
|
||||
'button_file' => 'Import a file',
|
||||
'button_bunq' => 'Import from bunq',
|
||||
'button_spectre' => 'Import using Spectre',
|
||||
'button_plaid' => 'Import using Plaid',
|
||||
'button_yodlee' => 'Import using Yodlee',
|
||||
'button_quovo' => 'Import using Quovo',
|
||||
'button_ynab' => 'Import from You Need A Budget',
|
||||
'button_fake' => 'Fake an import',
|
||||
'button_file' => 'Import a file',
|
||||
'button_bunq' => 'Import from bunq',
|
||||
'button_spectre' => 'Import using Spectre',
|
||||
'button_plaid' => 'Import using Plaid',
|
||||
'button_yodlee' => 'Import using Yodlee',
|
||||
'button_quovo' => 'Import using Quovo',
|
||||
'button_ynab' => 'Import from You Need A Budget',
|
||||
// global config box (index)
|
||||
'global_config_title' => 'Global import configuration',
|
||||
'global_config_text' => 'In the future, this box will feature preferences that apply to ALL import providers above.',
|
||||
'global_config_title' => 'Global import configuration',
|
||||
'global_config_text' => 'In the future, this box will feature preferences that apply to ALL import providers above.',
|
||||
// prerequisites box (index)
|
||||
'need_prereq_title' => 'Import prerequisites',
|
||||
'need_prereq_intro' => 'Some import methods need your attention before they can be used. For example, they might require special API keys or application secrets. You can configure them here. The icon indicates if these prerequisites have been met.',
|
||||
'do_prereq_fake' => 'Prerequisites for the fake provider',
|
||||
'do_prereq_file' => 'Prerequisites for file imports',
|
||||
'do_prereq_bunq' => 'Prerequisites for imports from bunq',
|
||||
'do_prereq_spectre' => 'Prerequisites for imports using Spectre',
|
||||
'do_prereq_plaid' => 'Prerequisites for imports using Plaid',
|
||||
'do_prereq_yodlee' => 'Prerequisites for imports using Yodlee',
|
||||
'do_prereq_quovo' => 'Prerequisites for imports using Quovo',
|
||||
'need_prereq_title' => 'Import prerequisites',
|
||||
'need_prereq_intro' => 'Some import methods need your attention before they can be used. For example, they might require special API keys or application secrets. You can configure them here. The icon indicates if these prerequisites have been met.',
|
||||
'do_prereq_fake' => 'Prerequisites for the fake provider',
|
||||
'do_prereq_file' => 'Prerequisites for file imports',
|
||||
'do_prereq_bunq' => 'Prerequisites for imports from bunq',
|
||||
'do_prereq_spectre' => 'Prerequisites for imports using Spectre',
|
||||
'do_prereq_plaid' => 'Prerequisites for imports using Plaid',
|
||||
'do_prereq_yodlee' => 'Prerequisites for imports using Yodlee',
|
||||
'do_prereq_quovo' => 'Prerequisites for imports using Quovo',
|
||||
'do_prereq_ynab' => 'Prerequisites for imports from YNAB',
|
||||
|
||||
// provider config box (index)
|
||||
'can_config_title' => 'Import configuration',
|
||||
'can_config_intro' => 'Some import methods can be configured to your liking. They have extra settings you can tweak.',
|
||||
'do_config_fake' => 'Configuration for the fake provider',
|
||||
'do_config_file' => 'Configuration for file imports',
|
||||
'do_config_bunq' => 'Configuration for bunq imports',
|
||||
'do_config_spectre' => 'Configuration for imports from Spectre',
|
||||
'do_config_plaid' => 'Configuration for imports from Plaid',
|
||||
'do_config_yodlee' => 'Configuration for imports from Yodlee',
|
||||
'do_config_quovo' => 'Configuration for imports from Quovo',
|
||||
'can_config_title' => 'Import configuration',
|
||||
'can_config_intro' => 'Some import methods can be configured to your liking. They have extra settings you can tweak.',
|
||||
'do_config_fake' => 'Configuration for the fake provider',
|
||||
'do_config_file' => 'Configuration for file imports',
|
||||
'do_config_bunq' => 'Configuration for bunq imports',
|
||||
'do_config_spectre' => 'Configuration for imports from Spectre',
|
||||
'do_config_plaid' => 'Configuration for imports from Plaid',
|
||||
'do_config_yodlee' => 'Configuration for imports from Yodlee',
|
||||
'do_config_quovo' => 'Configuration for imports from Quovo',
|
||||
|
||||
// prerequisites:
|
||||
'prereq_fake_title' => 'Prerequisites for an import from the fake import provider',
|
||||
'prereq_fake_text' => 'This fake provider requires a fake API key. It must be 32 characters long. You can use this one: 123456789012345678901234567890AA',
|
||||
'prereq_spectre_title' => 'Prerequisites for an import using the Spectre API',
|
||||
'prereq_spectre_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the <a href="https://www.saltedge.com/clients/profile/secrets">secrets page</a>.',
|
||||
'prereq_spectre_pub' => 'Likewise, the Spectre API needs to know the public key you see below. Without it, it will not recognize you. Please enter this public key on your <a href="https://www.saltedge.com/clients/profile/secrets">secrets page</a>.',
|
||||
'prereq_bunq_title' => 'Prerequisites for an import from bunq',
|
||||
'prereq_bunq_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.',
|
||||
'prereq_bunq_ip' => 'bunq requires your externally facing IP address. Firefly III has tried to fill this in using <a href="https://www.ipify.org/">the ipify service</a>. Make sure this IP address is correct, or the import will fail.',
|
||||
'prereq_ynab_title' => 'Prerequisites for an import from YNAB',
|
||||
'prereq_ynab_text' => 'In order to be able to download transactions from YNAB, please create a new application on your <a href="https://app.youneedabudget.com/settings/developer">Developer Settings Page</a> and enter the client ID and secret on this page.',
|
||||
'prereq_ynab_redirect' => 'To complete the configuration, enter the following URL at the <a href="https://app.youneedabudget.com/settings/developer">Developer Settings Page</a> under the "Redirect URI(s)".',
|
||||
'prereq_fake_title' => 'Prerequisites for an import from the fake import provider',
|
||||
'prereq_fake_text' => 'This fake provider requires a fake API key. It must be 32 characters long. You can use this one: 123456789012345678901234567890AA',
|
||||
'prereq_spectre_title' => 'Prerequisites for an import using the Spectre API',
|
||||
'prereq_spectre_text' => 'In order to import data using the Spectre API (v4), you must provide Firefly III with two secret values. They can be found on the <a href="https://www.saltedge.com/clients/profile/secrets">secrets page</a>.',
|
||||
'prereq_spectre_pub' => 'Likewise, the Spectre API needs to know the public key you see below. Without it, it will not recognize you. Please enter this public key on your <a href="https://www.saltedge.com/clients/profile/secrets">secrets page</a>.',
|
||||
'prereq_bunq_title' => 'Prerequisites for an import from bunq',
|
||||
'prereq_bunq_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.',
|
||||
'prereq_bunq_ip' => 'bunq requires your externally facing IP address. Firefly III has tried to fill this in using <a href="https://www.ipify.org/">the ipify service</a>. Make sure this IP address is correct, or the import will fail.',
|
||||
'prereq_ynab_title' => 'Prerequisites for an import from YNAB',
|
||||
'prereq_ynab_text' => 'In order to be able to download transactions from YNAB, please create a new application on your <a href="https://app.youneedabudget.com/settings/developer">Developer Settings Page</a> and enter the client ID and secret on this page.',
|
||||
'prereq_ynab_redirect' => 'To complete the configuration, enter the following URL at the <a href="https://app.youneedabudget.com/settings/developer">Developer Settings Page</a> under the "Redirect URI(s)".',
|
||||
// prerequisites success messages:
|
||||
'prerequisites_saved_for_fake' => 'Fake API key stored successfully!',
|
||||
'prerequisites_saved_for_spectre' => 'App ID and secret stored!',
|
||||
'prerequisites_saved_for_bunq' => 'API key and IP stored!',
|
||||
'prerequisites_saved_for_ynab' => 'YNAB client ID and secret stored!',
|
||||
'prerequisites_saved_for_fake' => 'Fake API key stored successfully!',
|
||||
'prerequisites_saved_for_spectre' => 'App ID and secret stored!',
|
||||
'prerequisites_saved_for_bunq' => 'API key and IP stored!',
|
||||
'prerequisites_saved_for_ynab' => 'YNAB client ID and secret stored!',
|
||||
|
||||
// job configuration:
|
||||
'job_config_apply_rules_title' => 'Job configuration - apply your rules?',
|
||||
'job_config_apply_rules_text' => 'Once the fake provider has run, your rules can be applied to the transactions. This adds time to the import.',
|
||||
'job_config_input' => 'Your input',
|
||||
'job_config_apply_rules_title' => 'Job configuration - apply your rules?',
|
||||
'job_config_apply_rules_text' => 'Once the fake provider has run, your rules can be applied to the transactions. This adds time to the import.',
|
||||
'job_config_input' => 'Your input',
|
||||
// job configuration for the fake provider:
|
||||
'job_config_fake_artist_title' => 'Enter album name',
|
||||
'job_config_fake_artist_text' => 'Many import routines have a few configuration steps you must go through. In the case of the fake import provider, you must answer some weird questions. In this case, enter "David Bowie" to continue.',
|
||||
'job_config_fake_song_title' => 'Enter song name',
|
||||
'job_config_fake_song_text' => 'Mention the song "Golden years" to continue with the fake import.',
|
||||
'job_config_fake_album_title' => 'Enter album name',
|
||||
'job_config_fake_album_text' => 'Some import routines require extra data halfway through the import. In the case of the fake import provider, you must answer some weird questions. Enter "Station to station" to continue.',
|
||||
'job_config_fake_artist_title' => 'Enter album name',
|
||||
'job_config_fake_artist_text' => 'Many import routines have a few configuration steps you must go through. In the case of the fake import provider, you must answer some weird questions. In this case, enter "David Bowie" to continue.',
|
||||
'job_config_fake_song_title' => 'Enter song name',
|
||||
'job_config_fake_song_text' => 'Mention the song "Golden years" to continue with the fake import.',
|
||||
'job_config_fake_album_title' => 'Enter album name',
|
||||
'job_config_fake_album_text' => 'Some import routines require extra data halfway through the import. In the case of the fake import provider, you must answer some weird questions. Enter "Station to station" to continue.',
|
||||
// job configuration form the file provider
|
||||
'job_config_file_upload_title' => 'Import setup (1/4) - Upload your file',
|
||||
'job_config_file_upload_text' => 'This routine will help you import files from your bank into Firefly III. ',
|
||||
'job_config_file_upload_help' => 'Select your file. Please make sure the file is UTF-8 encoded.',
|
||||
'job_config_file_upload_config_help' => '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>',
|
||||
'job_config_file_upload_type_help' => 'Select the type of file you will upload',
|
||||
'job_config_file_upload_submit' => 'Upload files',
|
||||
'import_file_type_csv' => 'CSV (comma separated values)',
|
||||
'file_not_utf8' => 'The file you have uploaded is not encoded as UTF-8 or ASCII. Firefly III cannot handle such files. Please use Notepad++ or Sublime to convert your file to UTF-8.',
|
||||
'job_config_uc_title' => 'Import setup (2/4) - Basic file setup',
|
||||
'job_config_uc_text' => 'To be able to import your file correctly, please validate the options below.',
|
||||
'job_config_uc_header_help' => 'Check this box if the first row of your CSV file are the column titles.',
|
||||
'job_config_uc_date_help' => 'Date time format in your file. Follow the format as <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.',
|
||||
'job_config_uc_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
|
||||
'job_config_uc_account_help' => 'If your file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the file belong to.',
|
||||
'job_config_uc_apply_rules_title' => 'Apply rules',
|
||||
'job_config_uc_apply_rules_text' => 'Applies your rules to every imported transaction. Note that this slows the import significantly.',
|
||||
'job_config_uc_specifics_title' => 'Bank-specific options',
|
||||
'job_config_uc_specifics_txt' => 'Some banks deliver badly formatted files. Firefly III can fix those automatically. If your bank delivers such files but it\'s not listed here, please open an issue on GitHub.',
|
||||
'job_config_uc_submit' => 'Continue',
|
||||
'invalid_import_account' => 'You have selected an invalid account to import into.',
|
||||
'job_config_file_upload_title' => 'Import setup (1/4) - Upload your file',
|
||||
'job_config_file_upload_text' => 'This routine will help you import files from your bank into Firefly III. ',
|
||||
'job_config_file_upload_help' => 'Select your file. Please make sure the file is UTF-8 encoded.',
|
||||
'job_config_file_upload_config_help' => '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>',
|
||||
'job_config_file_upload_type_help' => 'Select the type of file you will upload',
|
||||
'job_config_file_upload_submit' => 'Upload files',
|
||||
'import_file_type_csv' => 'CSV (comma separated values)',
|
||||
'file_not_utf8' => 'The file you have uploaded is not encoded as UTF-8 or ASCII. Firefly III cannot handle such files. Please use Notepad++ or Sublime to convert your file to UTF-8.',
|
||||
'job_config_uc_title' => 'Import setup (2/4) - Basic file setup',
|
||||
'job_config_uc_text' => 'To be able to import your file correctly, please validate the options below.',
|
||||
'job_config_uc_header_help' => 'Check this box if the first row of your CSV file are the column titles.',
|
||||
'job_config_uc_date_help' => 'Date time format in your file. Follow the format as <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.',
|
||||
'job_config_uc_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
|
||||
'job_config_uc_account_help' => 'If your file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the file belong to.',
|
||||
'job_config_uc_apply_rules_title' => 'Apply rules',
|
||||
'job_config_uc_apply_rules_text' => 'Applies your rules to every imported transaction. Note that this slows the import significantly.',
|
||||
'job_config_uc_specifics_title' => 'Bank-specific options',
|
||||
'job_config_uc_specifics_txt' => 'Some banks deliver badly formatted files. Firefly III can fix those automatically. If your bank delivers such files but it\'s not listed here, please open an issue on GitHub.',
|
||||
'job_config_uc_submit' => 'Continue',
|
||||
'invalid_import_account' => 'You have selected an invalid account to import into.',
|
||||
// job configuration for Spectre:
|
||||
'job_config_spectre_login_title' => 'Choose your login',
|
||||
'job_config_spectre_login_text' => 'Firefly III has found :count existing login(s) in your Spectre account. Which one would you like to use to import from?',
|
||||
'spectre_login_status_active' => 'Active',
|
||||
'spectre_login_status_inactive' => 'Inactive',
|
||||
'spectre_login_status_disabled' => 'Disabled',
|
||||
'spectre_login_new_login' => 'Login with another bank, or one of these banks with different credentials.',
|
||||
'job_config_spectre_accounts_title' => 'Select accounts to import from',
|
||||
'job_config_spectre_accounts_text' => 'You have selected ":name" (:country). You have :count account(s) available from this provider. Please select the Firefly III asset account(s) where the transactions from these accounts should be stored. Remember, in order to import data both the Firefly III account and the ":name"-account must have the same currency.',
|
||||
'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
|
||||
'spectre_do_not_import' => '(do not import)',
|
||||
'spectre_no_mapping' => 'It seems you have not selected any accounts to import from.',
|
||||
'imported_from_account' => 'Imported from ":account"',
|
||||
'spectre_account_with_number' => 'Account :number',
|
||||
'job_config_spectre_apply_rules' => 'Apply rules',
|
||||
'job_config_spectre_apply_rules_text' => 'By default, your rules will be applied to the transactions created during this import routine. If you do not want this to happen, deselect this checkbox.',
|
||||
'job_config_spectre_login_title' => 'Choose your login',
|
||||
'job_config_spectre_login_text' => 'Firefly III has found :count existing login(s) in your Spectre account. Which one would you like to use to import from?',
|
||||
'spectre_login_status_active' => 'Active',
|
||||
'spectre_login_status_inactive' => 'Inactive',
|
||||
'spectre_login_status_disabled' => 'Disabled',
|
||||
'spectre_login_new_login' => 'Login with another bank, or one of these banks with different credentials.',
|
||||
'job_config_spectre_accounts_title' => 'Select accounts to import from',
|
||||
'job_config_spectre_accounts_text' => 'You have selected ":name" (:country). You have :count account(s) available from this provider. Please select the Firefly III asset account(s) where the transactions from these accounts should be stored. Remember, in order to import data both the Firefly III account and the ":name"-account must have the same currency.',
|
||||
'spectre_no_supported_accounts' => 'You cannot import from this account due to a currency mismatch.',
|
||||
'spectre_do_not_import' => '(do not import)',
|
||||
'spectre_no_mapping' => 'It seems you have not selected any accounts to import from.',
|
||||
'imported_from_account' => 'Imported from ":account"',
|
||||
'spectre_account_with_number' => 'Account :number',
|
||||
'job_config_spectre_apply_rules' => 'Apply rules',
|
||||
'job_config_spectre_apply_rules_text' => 'By default, your rules will be applied to the transactions created during this import routine. If you do not want this to happen, deselect this checkbox.',
|
||||
// job configuration for bunq:
|
||||
'job_config_bunq_accounts_title' => 'bunq accounts',
|
||||
'job_config_bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.',
|
||||
'bunq_no_mapping' => 'It seems you have not selected any accounts.',
|
||||
'should_download_config' => 'You should download <a href=":route">the configuration file</a> for this job. This will make future imports way easier.',
|
||||
'share_config_file' => 'If you have imported data from a public bank, you should <a href="https://github.com/firefly-iii/import-configurations/wiki">share your configuration file</a> so it will be easy for other users to import their data. Sharing your configuration file will not expose your financial details.',
|
||||
'job_config_bunq_apply_rules' => 'Apply rules',
|
||||
'job_config_bunq_apply_rules_text' => 'By default, your rules will be applied to the transactions created during this import routine. If you do not want this to happen, deselect this checkbox.',
|
||||
'job_config_bunq_accounts_title' => 'bunq accounts',
|
||||
'job_config_bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.',
|
||||
'bunq_no_mapping' => 'It seems you have not selected any accounts.',
|
||||
'should_download_config' => 'You should download <a href=":route">the configuration file</a> for this job. This will make future imports way easier.',
|
||||
'share_config_file' => 'If you have imported data from a public bank, you should <a href="https://github.com/firefly-iii/import-configurations/wiki">share your configuration file</a> so it will be easy for other users to import their data. Sharing your configuration file will not expose your financial details.',
|
||||
'job_config_bunq_apply_rules' => 'Apply rules',
|
||||
'job_config_bunq_apply_rules_text' => 'By default, your rules will be applied to the transactions created during this import routine. If you do not want this to happen, deselect this checkbox.',
|
||||
|
||||
// job configuration for YNAB:
|
||||
'job_config_select_budgets' => 'Select your budget',
|
||||
'job_config_spectre_select_budgets_text' => 'You have :count budgets stored at YNAB. Please select the one from which Firefly III will import the transactions.',
|
||||
|
||||
// keys from "extra" array:
|
||||
'spectre_extra_key_iban' => 'IBAN',
|
||||
'spectre_extra_key_swift' => 'SWIFT',
|
||||
'spectre_extra_key_status' => 'Status',
|
||||
'spectre_extra_key_card_type' => 'Card type',
|
||||
'spectre_extra_key_account_name' => 'Account name',
|
||||
'spectre_extra_key_client_name' => 'Client name',
|
||||
'spectre_extra_key_account_number' => 'Account number',
|
||||
'spectre_extra_key_blocked_amount' => 'Blocked amount',
|
||||
'spectre_extra_key_available_amount' => 'Available amount',
|
||||
'spectre_extra_key_credit_limit' => 'Credit limit',
|
||||
'spectre_extra_key_interest_rate' => 'Interest rate',
|
||||
'spectre_extra_key_expiry_date' => 'Expiry date',
|
||||
'spectre_extra_key_open_date' => 'Open date',
|
||||
'spectre_extra_key_current_time' => 'Current time',
|
||||
'spectre_extra_key_current_date' => 'Current date',
|
||||
'spectre_extra_key_cards' => 'Cards',
|
||||
'spectre_extra_key_units' => 'Units',
|
||||
'spectre_extra_key_unit_price' => 'Unit price',
|
||||
'spectre_extra_key_transactions_count' => 'Transaction count',
|
||||
'spectre_extra_key_iban' => 'IBAN',
|
||||
'spectre_extra_key_swift' => 'SWIFT',
|
||||
'spectre_extra_key_status' => 'Status',
|
||||
'spectre_extra_key_card_type' => 'Card type',
|
||||
'spectre_extra_key_account_name' => 'Account name',
|
||||
'spectre_extra_key_client_name' => 'Client name',
|
||||
'spectre_extra_key_account_number' => 'Account number',
|
||||
'spectre_extra_key_blocked_amount' => 'Blocked amount',
|
||||
'spectre_extra_key_available_amount' => 'Available amount',
|
||||
'spectre_extra_key_credit_limit' => 'Credit limit',
|
||||
'spectre_extra_key_interest_rate' => 'Interest rate',
|
||||
'spectre_extra_key_expiry_date' => 'Expiry date',
|
||||
'spectre_extra_key_open_date' => 'Open date',
|
||||
'spectre_extra_key_current_time' => 'Current time',
|
||||
'spectre_extra_key_current_date' => 'Current date',
|
||||
'spectre_extra_key_cards' => 'Cards',
|
||||
'spectre_extra_key_units' => 'Units',
|
||||
'spectre_extra_key_unit_price' => 'Unit price',
|
||||
'spectre_extra_key_transactions_count' => 'Transaction count',
|
||||
|
||||
// specifics:
|
||||
'specific_ing_name' => 'ING NL',
|
||||
'specific_ing_descr' => 'Create better descriptions in ING exports',
|
||||
'specific_sns_name' => 'SNS / Volksbank NL',
|
||||
'specific_sns_descr' => 'Trim quotes from SNS / Volksbank export files',
|
||||
'specific_abn_name' => 'ABN AMRO NL',
|
||||
'specific_abn_descr' => 'Fixes potential problems with ABN AMRO files',
|
||||
'specific_rabo_name' => 'Rabobank NL',
|
||||
'specific_rabo_descr' => 'Fixes potential problems with Rabobank files',
|
||||
'specific_pres_name' => 'President\'s Choice Financial CA',
|
||||
'specific_pres_descr' => 'Fixes potential problems with PC files',
|
||||
'specific_ing_name' => 'ING NL',
|
||||
'specific_ing_descr' => 'Create better descriptions in ING exports',
|
||||
'specific_sns_name' => 'SNS / Volksbank NL',
|
||||
'specific_sns_descr' => 'Trim quotes from SNS / Volksbank export files',
|
||||
'specific_abn_name' => 'ABN AMRO NL',
|
||||
'specific_abn_descr' => 'Fixes potential problems with ABN AMRO files',
|
||||
'specific_rabo_name' => 'Rabobank NL',
|
||||
'specific_rabo_descr' => 'Fixes potential problems with Rabobank files',
|
||||
'specific_pres_name' => 'President\'s Choice Financial CA',
|
||||
'specific_pres_descr' => 'Fixes potential problems with PC files',
|
||||
// job configuration for file provider (stage: roles)
|
||||
'job_config_roles_title' => 'Import setup (3/4) - Define each column\'s role',
|
||||
'job_config_roles_text' => 'Each column in your CSV file contains certain data. Please indicate what kind of data the importer should expect. The option to "map" data means that you will link each entry found in the column to a value in your database. An often mapped column is the column that contains the IBAN of the opposing account. That can be easily matched to IBAN\'s present in your database already.',
|
||||
'job_config_roles_submit' => 'Continue',
|
||||
'job_config_roles_column_name' => 'Name of column',
|
||||
'job_config_roles_column_example' => 'Column example data',
|
||||
'job_config_roles_column_role' => 'Column data meaning',
|
||||
'job_config_roles_do_map_value' => 'Map these values',
|
||||
'job_config_roles_no_example' => 'No example data available',
|
||||
'job_config_roles_fa_warning' => 'If you mark a column as containing an amount in a foreign currency, you must also set the column that contains which currency it is.',
|
||||
'job_config_roles_rwarning' => 'At the very least, mark one column as the amount-column. It is advisable to also select a column for the description, date and the opposing account.',
|
||||
'job_config_roles_colum_count' => 'Column',
|
||||
'job_config_roles_title' => 'Import setup (3/4) - Define each column\'s role',
|
||||
'job_config_roles_text' => 'Each column in your CSV file contains certain data. Please indicate what kind of data the importer should expect. The option to "map" data means that you will link each entry found in the column to a value in your database. An often mapped column is the column that contains the IBAN of the opposing account. That can be easily matched to IBAN\'s present in your database already.',
|
||||
'job_config_roles_submit' => 'Continue',
|
||||
'job_config_roles_column_name' => 'Name of column',
|
||||
'job_config_roles_column_example' => 'Column example data',
|
||||
'job_config_roles_column_role' => 'Column data meaning',
|
||||
'job_config_roles_do_map_value' => 'Map these values',
|
||||
'job_config_roles_no_example' => 'No example data available',
|
||||
'job_config_roles_fa_warning' => 'If you mark a column as containing an amount in a foreign currency, you must also set the column that contains which currency it is.',
|
||||
'job_config_roles_rwarning' => 'At the very least, mark one column as the amount-column. It is advisable to also select a column for the description, date and the opposing account.',
|
||||
'job_config_roles_colum_count' => 'Column',
|
||||
// job config for the file provider (stage: mapping):
|
||||
'job_config_map_title' => 'Import setup (4/4) - Connect import data to Firefly III data',
|
||||
'job_config_map_text' => 'In the following tables, the left value shows you information found in your uploaded file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.',
|
||||
'job_config_map_nothing' => 'There is no data present in your file that you can map to existing values. Please press "Start the import" to continue.',
|
||||
'job_config_field_value' => 'Field value',
|
||||
'job_config_field_mapped' => 'Mapped to',
|
||||
'map_do_not_map' => '(do not map)',
|
||||
'job_config_map_submit' => 'Start the import',
|
||||
'job_config_map_title' => 'Import setup (4/4) - Connect import data to Firefly III data',
|
||||
'job_config_map_text' => 'In the following tables, the left value shows you information found in your uploaded file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.',
|
||||
'job_config_map_nothing' => 'There is no data present in your file that you can map to existing values. Please press "Start the import" to continue.',
|
||||
'job_config_field_value' => 'Field value',
|
||||
'job_config_field_mapped' => 'Mapped to',
|
||||
'map_do_not_map' => '(do not map)',
|
||||
'job_config_map_submit' => 'Start the import',
|
||||
|
||||
|
||||
// import status page:
|
||||
'import_with_key' => 'Import with key \':key\'',
|
||||
'status_wait_title' => 'Please hold...',
|
||||
'status_wait_text' => 'This box will disappear in a moment.',
|
||||
'status_running_title' => 'The import is running',
|
||||
'status_job_running' => 'Please wait, running the import...',
|
||||
'status_job_storing' => 'Please wait, storing data...',
|
||||
'status_job_rules' => 'Please wait, running rules...',
|
||||
'status_fatal_title' => 'Fatal error',
|
||||
'status_fatal_text' => 'The import has suffered from an error it could not recover from. Apologies!',
|
||||
'status_fatal_more' => 'This (possibly very cryptic) error message is complemented by log files, which you can find on your hard drive, or in the Docker container where you run Firefly III from.',
|
||||
'status_finished_title' => 'Import finished',
|
||||
'status_finished_text' => 'The import has finished.',
|
||||
'finished_with_errors' => 'There were some errors during the import. Please review them carefully.',
|
||||
'unknown_import_result' => 'Unknown import result',
|
||||
'result_no_transactions' => 'No transactions have been imported. Perhaps they were all duplicates is simply no transactions where present to be imported. Perhaps the log files can tell you what happened. If you import data regularly, this is normal.',
|
||||
'result_one_transaction' => 'Exactly one transaction has been imported. It is stored under tag <a href=":route" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a> where you can inspect it further.',
|
||||
'result_many_transactions' => 'Firefly III has imported :count transactions. They are stored under tag <a href=":route" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a> where you can inspect them further.',
|
||||
'import_with_key' => 'Import with key \':key\'',
|
||||
'status_wait_title' => 'Please hold...',
|
||||
'status_wait_text' => 'This box will disappear in a moment.',
|
||||
'status_running_title' => 'The import is running',
|
||||
'status_job_running' => 'Please wait, running the import...',
|
||||
'status_job_storing' => 'Please wait, storing data...',
|
||||
'status_job_rules' => 'Please wait, running rules...',
|
||||
'status_fatal_title' => 'Fatal error',
|
||||
'status_fatal_text' => 'The import has suffered from an error it could not recover from. Apologies!',
|
||||
'status_fatal_more' => 'This (possibly very cryptic) error message is complemented by log files, which you can find on your hard drive, or in the Docker container where you run Firefly III from.',
|
||||
'status_finished_title' => 'Import finished',
|
||||
'status_finished_text' => 'The import has finished.',
|
||||
'finished_with_errors' => 'There were some errors during the import. Please review them carefully.',
|
||||
'unknown_import_result' => 'Unknown import result',
|
||||
'result_no_transactions' => 'No transactions have been imported. Perhaps they were all duplicates is simply no transactions where present to be imported. Perhaps the log files can tell you what happened. If you import data regularly, this is normal.',
|
||||
'result_one_transaction' => 'Exactly one transaction has been imported. It is stored under tag <a href=":route" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a> where you can inspect it further.',
|
||||
'result_many_transactions' => 'Firefly III has imported :count transactions. They are stored under tag <a href=":route" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a> where you can inspect them further.',
|
||||
|
||||
|
||||
// general errors and warnings:
|
||||
'bad_job_status' => 'To access this page, your import job cannot have status ":status".',
|
||||
'bad_job_status' => 'To access this page, your import job cannot have status ":status".',
|
||||
|
||||
// column roles for CSV import:
|
||||
'column__ignore' => '(ignore this column)',
|
||||
'column_account-iban' => 'Asset account (IBAN)',
|
||||
'column_account-id' => 'Asset account ID (matching FF3)',
|
||||
'column_account-name' => 'Asset account (name)',
|
||||
'column_account-bic' => 'Asset account (BIC)',
|
||||
'column_amount' => 'Amount',
|
||||
'column_amount_foreign' => 'Amount (in foreign currency)',
|
||||
'column_amount_debit' => 'Amount (debit column)',
|
||||
'column_amount_credit' => 'Amount (credit column)',
|
||||
'column_amount-comma-separated' => 'Amount (comma as decimal separator)',
|
||||
'column_bill-id' => 'Bill ID (matching FF3)',
|
||||
'column_bill-name' => 'Bill name',
|
||||
'column_budget-id' => 'Budget ID (matching FF3)',
|
||||
'column_budget-name' => 'Budget name',
|
||||
'column_category-id' => 'Category ID (matching FF3)',
|
||||
'column_category-name' => 'Category name',
|
||||
'column_currency-code' => 'Currency code (ISO 4217)',
|
||||
'column_foreign-currency-code' => 'Foreign currency code (ISO 4217)',
|
||||
'column_currency-id' => 'Currency ID (matching FF3)',
|
||||
'column_currency-name' => 'Currency name (matching FF3)',
|
||||
'column_currency-symbol' => 'Currency symbol (matching FF3)',
|
||||
'column_date-interest' => 'Interest calculation date',
|
||||
'column_date-book' => 'Transaction booking date',
|
||||
'column_date-process' => 'Transaction process date',
|
||||
'column_date-transaction' => 'Date',
|
||||
'column_date-due' => 'Transaction due date',
|
||||
'column_date-payment' => 'Transaction payment date',
|
||||
'column_date-invoice' => 'Transaction invoice date',
|
||||
'column_description' => 'Description',
|
||||
'column_opposing-iban' => 'Opposing account (IBAN)',
|
||||
'column_opposing-bic' => 'Opposing account (BIC)',
|
||||
'column_opposing-id' => 'Opposing account ID (matching FF3)',
|
||||
'column_external-id' => 'External ID',
|
||||
'column_opposing-name' => 'Opposing account (name)',
|
||||
'column_rabo-debit-credit' => 'Rabobank specific debit/credit indicator',
|
||||
'column_ing-debit-credit' => 'ING specific debit/credit indicator',
|
||||
'column_sepa-ct-id' => 'SEPA end-to-end Identifier',
|
||||
'column_sepa-ct-op' => 'SEPA Opposing Account Identifier',
|
||||
'column_sepa-db' => 'SEPA Mandate Identifier',
|
||||
'column_sepa-cc' => 'SEPA Clearing Code',
|
||||
'column_sepa-ci' => 'SEPA Creditor Identifier',
|
||||
'column_sepa-ep' => 'SEPA External Purpose',
|
||||
'column_sepa-country' => 'SEPA Country Code',
|
||||
'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)',
|
||||
'column_note' => 'Note(s)',
|
||||
'column_internal-reference' => 'Internal reference',
|
||||
'column__ignore' => '(ignore this column)',
|
||||
'column_account-iban' => 'Asset account (IBAN)',
|
||||
'column_account-id' => 'Asset account ID (matching FF3)',
|
||||
'column_account-name' => 'Asset account (name)',
|
||||
'column_account-bic' => 'Asset account (BIC)',
|
||||
'column_amount' => 'Amount',
|
||||
'column_amount_foreign' => 'Amount (in foreign currency)',
|
||||
'column_amount_debit' => 'Amount (debit column)',
|
||||
'column_amount_credit' => 'Amount (credit column)',
|
||||
'column_amount-comma-separated' => 'Amount (comma as decimal separator)',
|
||||
'column_bill-id' => 'Bill ID (matching FF3)',
|
||||
'column_bill-name' => 'Bill name',
|
||||
'column_budget-id' => 'Budget ID (matching FF3)',
|
||||
'column_budget-name' => 'Budget name',
|
||||
'column_category-id' => 'Category ID (matching FF3)',
|
||||
'column_category-name' => 'Category name',
|
||||
'column_currency-code' => 'Currency code (ISO 4217)',
|
||||
'column_foreign-currency-code' => 'Foreign currency code (ISO 4217)',
|
||||
'column_currency-id' => 'Currency ID (matching FF3)',
|
||||
'column_currency-name' => 'Currency name (matching FF3)',
|
||||
'column_currency-symbol' => 'Currency symbol (matching FF3)',
|
||||
'column_date-interest' => 'Interest calculation date',
|
||||
'column_date-book' => 'Transaction booking date',
|
||||
'column_date-process' => 'Transaction process date',
|
||||
'column_date-transaction' => 'Date',
|
||||
'column_date-due' => 'Transaction due date',
|
||||
'column_date-payment' => 'Transaction payment date',
|
||||
'column_date-invoice' => 'Transaction invoice date',
|
||||
'column_description' => 'Description',
|
||||
'column_opposing-iban' => 'Opposing account (IBAN)',
|
||||
'column_opposing-bic' => 'Opposing account (BIC)',
|
||||
'column_opposing-id' => 'Opposing account ID (matching FF3)',
|
||||
'column_external-id' => 'External ID',
|
||||
'column_opposing-name' => 'Opposing account (name)',
|
||||
'column_rabo-debit-credit' => 'Rabobank specific debit/credit indicator',
|
||||
'column_ing-debit-credit' => 'ING specific debit/credit indicator',
|
||||
'column_sepa-ct-id' => 'SEPA end-to-end Identifier',
|
||||
'column_sepa-ct-op' => 'SEPA Opposing Account Identifier',
|
||||
'column_sepa-db' => 'SEPA Mandate Identifier',
|
||||
'column_sepa-cc' => 'SEPA Clearing Code',
|
||||
'column_sepa-ci' => 'SEPA Creditor Identifier',
|
||||
'column_sepa-ep' => 'SEPA External Purpose',
|
||||
'column_sepa-country' => 'SEPA Country Code',
|
||||
'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)',
|
||||
'column_note' => 'Note(s)',
|
||||
'column_internal-reference' => 'Internal reference',
|
||||
|
||||
];
|
||||
|
39
resources/views/import/ynab/select-budgets.twig
Normal file
39
resources/views/import/ynab/select-budgets.twig
Normal file
@ -0,0 +1,39 @@
|
||||
{% extends "./layout/default" %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ Breadcrumbs.render }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<form class="form-horizontal" action="{{ route('import.job.configuration.post',[importJob.key]) }}" method="post">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
|
||||
|
||||
<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">{{ trans('import.job_config_select_budgets') }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<p>
|
||||
{{ trans('import.job_config_spectre_select_budgets_text', {count: data.budgets|length}) }}
|
||||
</p>
|
||||
{{ ExpandedForm.select('budget_id', data.budgets) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn pull-right btn-success">
|
||||
{{ ('submit')|_ }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
||||
{% block styles %}
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user