Merge pull request #1770 from bnw/develop

Added a first version of an import via FinTS
This commit is contained in:
James Cole 2018-10-05 17:34:41 +02:00 committed by GitHub
commit 7ac439fd0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 854 additions and 1 deletions

View File

@ -0,0 +1,137 @@
<?php
/**
* FinTSJobConfiguration.php
* Copyright (c) 2017 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\Import\JobConfiguration;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\ImportJob;
use FireflyIII\Support\Import\JobConfiguration\FinTS\ChooseAccountHandler;
use FireflyIII\Support\Import\JobConfiguration\FinTS\FinTSConfigurationInterface;
use FireflyIII\Support\Import\JobConfiguration\FinTS\NewFinTSJobHandler;
use Illuminate\Support\MessageBag;
abstract class FinTSConfigurationSteps
{
const NEW = 'new';
const CHOOSE_ACCOUNT = 'choose_account';
const GO_FOR_IMPORT = 'go-for-import';
}
class FinTSJobConfiguration implements JobConfigurationInterface
{
/** @var ImportJob */
private $importJob;
/**
* Returns true when the initial configuration for this job is complete.
*
* @return bool
*/
public function configurationComplete(): bool
{
return $this->importJob->stage == FinTSConfigurationSteps::GO_FOR_IMPORT;
}
/**
* Store any data from the $data array into the job. Anything in the message bag will be flashed
* as an error to the user, regardless of its content.
*
* @param array $data
*
* @return MessageBag
* @throws FireflyException
*/
public function configureJob(array $data): MessageBag
{
return $this->getConfigurationObject()->configureJob($data);
}
/**
* Return the data required for the next step in the job configuration.
*
* @return array
* @throws FireflyException
*/
public function getNextData(): array
{
return $this->getConfigurationObject()->getNextData();
}
/**
* Returns the view of the next step in the job configuration.
*
* @return string
* @throws FireflyException
*/
public function getNextView(): string
{
switch ($this->importJob->stage) {
case FinTSConfigurationSteps::NEW:
case FinTSConfigurationSteps::CHOOSE_ACCOUNT:
return 'import.fints.' . $this->importJob->stage;
break;
default:
// @codeCoverageIgnoreStart
throw new FireflyException(
sprintf('FinTSJobConfiguration::getNextView() cannot handle stage "%s"', $this->importJob->stage)
);
// @codeCoverageIgnoreEnd
}
}
/**
* @param ImportJob $importJob
*/
public function setImportJob(ImportJob $importJob): void
{
$this->importJob = $importJob;
}
/**
* Get the configuration handler for this specific stage.
*
* @return FinTSConfigurationInterface
* @throws FireflyException
*/
private function getConfigurationObject(): FinTSConfigurationInterface
{
$class = 'DoNotExist';
switch ($this->importJob->stage) {
case FinTSConfigurationSteps::NEW:
$class = NewFinTSJobHandler::class;
break;
case FinTSConfigurationSteps::CHOOSE_ACCOUNT:
$class = ChooseAccountHandler::class;
break;
}
if (!class_exists($class)) {
throw new FireflyException(sprintf('Class %s does not exist in getConfigurationClass().', $class)); // @codeCoverageIgnore
}
$configurator = app($class);
$configurator->setImportJob($this->importJob);
return $configurator;
}
}

View File

@ -0,0 +1,84 @@
<?php
/**
* FinTSRoutine.php
* Copyright (c) 2017 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\Import\Routine;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Import\JobConfiguration\FinTSConfigurationSteps;
use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Support\Import\Routine\FinTS\StageImportDataHandler;
use Illuminate\Support\Facades\Log;
class FinTSRoutine implements RoutineInterface
{
/** @var ImportJob */
private $importJob;
/** @var ImportJobRepositoryInterface */
private $repository;
/**
* At the end of each run(), the import routine must set the job to the expected status.
*
* The final status of the routine must be "provider_finished".
*
* @throws FireflyException
*/
public function run(): void
{
Log::debug(sprintf('Now in FinTSRoutine::run() with status "%s" and stage "%s".', $this->importJob->status, $this->importJob->stage));
$valid = ['ready_to_run']; // should be only ready_to_run
if (\in_array($this->importJob->status, $valid, true)) {
switch ($this->importJob->stage) {
default:
throw new FireflyException(sprintf('FinTSRoutine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore
case FinTSConfigurationSteps::GO_FOR_IMPORT:
$this->repository->setStatus($this->importJob, 'running');
/** @var StageImportDataHandler $handler */
$handler = app(StageImportDataHandler::class);
$handler->setImportJob($this->importJob);
$handler->run();
$transactions = $handler->getTransactions();
$this->repository->setTransactions($this->importJob, $transactions);
$this->repository->setStatus($this->importJob, 'provider_finished');
$this->repository->setStage($this->importJob, 'final');
return;
}
}
}
/**
* @param ImportJob $importJob
*
* @return void
*/
public function setImportJob(ImportJob $importJob): void
{
$this->importJob = $importJob;
$this->repository = app(ImportJobRepositoryInterface::class);
$this->repository->setUser($importJob->user);
}
}

View File

@ -0,0 +1,94 @@
<?php
namespace FireflyIII\Support\FinTS;
use Fhp\Model\SEPAAccount;
use FireflyIII\Exceptions\FireflyException;
use Illuminate\Support\Facades\Crypt;
class FinTS
{
/** @var \Fhp\FinTs */
private $finTS;
/**
* @param array $config
* @throws FireflyException
*/
public function __construct(array $config)
{
if (
!isset($config['fints_url']) or
!isset($config['fints_port']) or
!isset($config['fints_bank_code']) or
!isset($config['fints_username']) or
!isset($config['fints_password']))
throw new FireflyException(
"Constructed FinTS with incomplete config."
);
$this->finTS = new \Fhp\FinTs(
$config['fints_url'],
$config['fints_port'],
$config['fints_bank_code'],
$config['fints_username'],
Crypt::decrypt($config['fints_password'])
);
}
public function checkConnection()
{
try {
$this->finTS->getSEPAAccounts();
return true;
} catch (\Exception $exception) {
return $exception->getMessage();
}
}
/**
* @return SEPAAccount[]
* @throws FireflyException
*/
public function getAccounts()
{
try {
return $this->finTS->getSEPAAccounts();
} catch (\Exception $exception) {
throw new FireflyException($exception->getMessage());
}
}
/**
* @param string $accountNumber
* @return SEPAAccount
* @throws FireflyException
*/
public function getAccount(string $accountNumber)
{
$accounts = $this->getAccounts();
$filteredAccounts = array_filter($accounts, function (SEPAAccount $account) use ($accountNumber) {
return $account->getAccountNumber() == $accountNumber;
});
if (count($filteredAccounts) != 1) {
throw new FireflyException("Cannot find account with number " . $accountNumber);
}
return reset($filteredAccounts);
}
/**
* @param SEPAAccount $account
* @param \DateTime $from
* @param \DateTIme $to
* @return \Fhp\Model\StatementOfAccount\StatementOfAccount|null
* @throws FireflyException
*/
public function getStatementOfAccount(SEPAAccount $account, \DateTime $from, \DateTIme $to)
{
try {
return $this->finTS->getStatementOfAccount($account, $from, $to);
} catch (\Exception $exception) {
throw new FireflyException($exception->getMessage());
}
}
}

View File

@ -0,0 +1,120 @@
<?php
/**
* ChooseAccountHandler.php
* Copyright (c) 2017 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\FinTS;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Import\JobConfiguration\FinTSConfigurationSteps;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Support\FinTS\FinTS;
use Illuminate\Support\MessageBag;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
class ChooseAccountHandler implements FinTSConfigurationInterface
{
/** @var ImportJob */
private $importJob;
/** @var ImportJobRepositoryInterface */
private $repository;
/** @var AccountRepositoryInterface */
private $accountRepository;
/**
* Store data associated with current stage.
*
* @param array $data
*
* @return MessageBag
*/
public function configureJob(array $data): MessageBag
{
$config = $this->importJob->configuration;
$config['fints_account'] = (string)($data['fints_account'] ?? '');
$config['local_account'] = (string)($data['local_account'] ?? '');
$config['from_date'] = (string)($data['from_date'] ?? '');
$config['to_date'] = (string)($data['to_date'] ?? '');
$this->repository->setConfiguration($this->importJob, $config);
try {
$finTS = app(FinTS::class, ['config' => $this->importJob->configuration]);
$finTS->getAccount($config['fints_account']);
} catch (FireflyException $e) {
return new MessageBag([$e->getMessage()]);
}
$this->repository->setStage($this->importJob, FinTSConfigurationSteps::GO_FOR_IMPORT);
return new MessageBag();
}
/**
* Get the data necessary to show the configuration screen.
*
* @return array
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function getNextData(): array
{
$finTS = app(FinTS::class, ['config' => $this->importJob->configuration]);
$finTSAccounts = $finTS->getAccounts();
$finTSAccountsData = [];
foreach ($finTSAccounts as $account) {
$finTSAccountsData[$account->getAccountNumber()] = $account->getIban();
}
$localAccounts = [];
foreach ($this->accountRepository->getAccountsByType([AccountType::ASSET]) as $localAccount) {
$display_name = $localAccount->name;
if ($localAccount->iban) {
$display_name .= " - $localAccount->iban";
}
$localAccounts[$localAccount->id] = $display_name;
}
$data = [
'fints_accounts' => $finTSAccountsData,
'fints_account' => $this->importJob->configuration['fints_account'] ?? null,
'local_accounts' => $localAccounts,
'local_account' => $this->importJob->configuration['local_account'] ?? null,
'from_date' => $this->importJob->configuration['from_date'] ?? (new Carbon('now - 1 month'))->format('Y-m-d'),
'to_date' => $this->importJob->configuration['to_date'] ?? (new Carbon('now'))->format('Y-m-d')
];
return $data;
}
/**
* @param ImportJob $importJob
*/
public function setImportJob(ImportJob $importJob): void
{
$this->importJob = $importJob;
$this->repository = app(ImportJobRepositoryInterface::class);
$this->accountRepository = app(AccountRepositoryInterface::class);
$this->repository->setUser($importJob->user);
}
}

View File

@ -0,0 +1,50 @@
<?php
/**
* FinTSConfigurationInterface.php
* Copyright (c) 2017 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\FinTS;
use FireflyIII\Models\ImportJob;
use Illuminate\Support\MessageBag;
interface FinTSConfigurationInterface
{
/**
* Store data associated with current stage.
*
* @param array $data
*
* @return MessageBag
*/
public function configureJob(array $data): MessageBag;
/**
* Get the data necessary to show the configuration screen.
*
* @return array
*/
public function getNextData(): array;
/**
* @param ImportJob $importJob
*/
public function setImportJob(ImportJob $importJob): void;
}

View File

@ -0,0 +1,105 @@
<?php
/**
* NewFinTSJobHandler.php
* Copyright (c) 2017 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\FinTS;
use FireflyIII\Import\JobConfiguration\FinTSConfigurationSteps;
use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Support\FinTS\FinTS;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\MessageBag;
class NewFinTSJobHandler implements FinTSConfigurationInterface
{
/** @var ImportJob */
private $importJob;
/** @var ImportJobRepositoryInterface */
private $repository;
/**
* Store data associated with current stage.
*
* @param array $data
*
* @return MessageBag
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function configureJob(array $data): MessageBag
{
$config = [];
$config['fints_url'] = trim($data['fints_url'] ?? '');
$config['fints_port'] = (int)($data['fints_port'] ?? '');
$config['fints_bank_code'] = (string)($data['fints_bank_code'] ?? '');
$config['fints_username'] = (string)($data['fints_username'] ?? '');
$config['fints_password'] = (string)(Crypt::encrypt($data['fints_password']) ?? '');
$this->repository->setConfiguration($this->importJob, $config);
$incomplete = false;
foreach ($config as $value) {
$incomplete = $value === '' or $incomplete;
}
if ($incomplete) {
return new MessageBag([trans('import.incomplete_fints_form')]);
}
$finTS = app(FinTS::class, ['config' => $this->importJob->configuration]);
if (($checkConnection = $finTS->checkConnection()) !== true) {
return new MessageBag([trans('import.fints_connection_failed', ['originalError' => $checkConnection])]);
}
$this->repository->setStage($this->importJob, FinTSConfigurationSteps::CHOOSE_ACCOUNT);
return new MessageBag();
}
/**
* Get the data necessary to show the configuration screen.
*
* @return array
*/
public function getNextData(): array
{
$config = $this->importJob->configuration;
return [
'fints_url' => $config['fints_url'] ?? '',
'fints_port' => $config['fints_port'] ?? '443',
'fints_bank_code' => $config['fints_bank_code'] ?? '',
'fints_username' => $config['fints_username'] ?? ''
];
}
/**
* @param ImportJob $importJob
*/
public function setImportJob(ImportJob $importJob): void
{
$this->importJob = $importJob;
$this->repository = app(ImportJobRepositoryInterface::class);
$this->repository->setUser($importJob->user);
}
}

View File

@ -0,0 +1,152 @@
<?php
namespace FireflyIII\Support\Import\Routine\FinTS;
use Fhp\Model\StatementOfAccount\Transaction as FinTSTransaction;
use Fhp\Model\StatementOfAccount\Transaction;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\ImportJob;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Support\FinTS\FinTS;
use FireflyIII\Models\Account as LocalAccount;
use FireflyIII\Support\Import\Routine\File\OpposingAccountMapper;
use Illuminate\Support\Facades\Log;
class StageImportDataHandler
{
/** @var AccountRepositoryInterface */
private $accountRepository;
/** @var ImportJob */
private $importJob;
/** @var ImportJobRepositoryInterface */
private $repository;
/** @var array */
private $transactions;
/** @var OpposingAccountMapper */
private $mapper;
/**
* @param ImportJob $importJob
*
* @return void
*/
public function setImportJob(ImportJob $importJob): void
{
$this->transactions = [];
$this->importJob = $importJob;
$this->repository = app(ImportJobRepositoryInterface::class);
$this->accountRepository = app(AccountRepositoryInterface::class);
$this->mapper = app(OpposingAccountMapper::class);
$this->mapper->setUser($importJob->user);
$this->repository->setUser($importJob->user);
$this->accountRepository->setUser($importJob->user);
}
/**
* @throws FireflyException
*/
public function run()
{
Log::debug('Now in StageImportDataHandler::run()');
$localAccount = $this->accountRepository->findNull($this->importJob->configuration['local_account']);
if ($localAccount === null) {
throw new FireflyException('Cannot find Firefly account with id ' . $this->importJob->configuration['local_account']);
}
$finTS = app(FinTS::class, ['config' => $this->importJob->configuration]);
$fintTSAccount = $finTS->getAccount($this->importJob->configuration['fints_account']);
$statementOfAccount = $finTS->getStatementOfAccount($fintTSAccount, new \DateTime($this->importJob->configuration['from_date']), new \DateTime($this->importJob->configuration['to_date']));
$collection = [];
foreach ($statementOfAccount->getStatements() as $statement) {
foreach ($statement->getTransactions() as $transaction) {
$collection[] = $this->convertTransaction($transaction, $localAccount);
}
}
$this->transactions = $collection;
}
private function convertTransaction(FinTSTransaction $transaction, LocalAccount $source): array
{
Log::debug(sprintf('Start converting transaction %s', $transaction->getDescription1()));
$amount = (string) $transaction->getAmount();
$debitOrCredit = $transaction->getCreditDebit();
Log::debug(sprintf('Amount is %s', $amount));
if ($debitOrCredit == Transaction::CD_CREDIT) {
$type = TransactionType::DEPOSIT;
} else {
$type = TransactionType::WITHDRAWAL;
$amount = bcmul($amount, '-1');
}
$destination = $this->mapper->map(
null,
$amount,
['iban' => $transaction->getAccountNumber(), 'name' => $transaction->getName()]
);
if ($debitOrCredit == Transaction::CD_CREDIT) {
[$source, $destination] = [$destination, $source];
}
if ($source->accountType->type === AccountType::ASSET && $destination->accountType->type === AccountType::ASSET) {
$type = TransactionType::TRANSFER;
Log::debug('Both are assets, will make transfer.');
}
$storeData = [
'user' => $this->importJob->user_id,
'type' => $type,
'date' => $transaction->getValutaDate()->format('Y-m-d'),
'description' => $transaction->getDescription1(),
'piggy_bank_id' => null,
'piggy_bank_name' => null,
'bill_id' => null,
'bill_name' => null,
'tags' => [],
'internal_reference' => null,
'external_id' => null,
'notes' => null,
'bunq_payment_id' => null,
'original-source' => sprintf('fints-v%s', config('firefly.version')),
'transactions' => [
// single transaction:
[
'description' => null,
'amount' => $amount,
'currency_id' => null,
'currency_code' => 'EUR',
'foreign_amount' => null,
'foreign_currency_id' => null,
'foreign_currency_code' => null,
'budget_id' => null,
'budget_name' => null,
'category_id' => null,
'category_name' => null,
'source_id' => $source->id,
'source_name' => null,
'destination_id' => $destination->id,
'destination_name' => null,
'reconciled' => false,
'identifier' => 0,
],
],
];
return $storeData;
}
/**
* @return array
*/
public function getTransactions(): array
{
return $this->transactions;
}
}

View File

@ -64,6 +64,7 @@
"league/commonmark": "0.*",
"league/csv": "9.*",
"league/fractal": "^0.17.0",
"mschindler83/fints-hbci-php": "^1.0",
"pragmarx/google2fa": "3.*",
"pragmarx/google2fa-laravel": "0.*",
"rcrowe/twigbridge": "0.9.*",

View File

@ -25,6 +25,7 @@ declare(strict_types=1);
use FireflyIII\Import\JobConfiguration\BunqJobConfiguration;
use FireflyIII\Import\JobConfiguration\FakeJobConfiguration;
use FireflyIII\Import\JobConfiguration\FileJobConfiguration;
use FireflyIII\Import\JobConfiguration\FinTSJobConfiguration;
use FireflyIII\Import\JobConfiguration\SpectreJobConfiguration;
use FireflyIII\Import\JobConfiguration\YnabJobConfiguration;
use FireflyIII\Import\Prerequisites\BunqPrerequisites;
@ -34,6 +35,7 @@ use FireflyIII\Import\Prerequisites\YnabPrerequisites;
use FireflyIII\Import\Routine\BunqRoutine;
use FireflyIII\Import\Routine\FakeRoutine;
use FireflyIII\Import\Routine\FileRoutine;
use FireflyIII\Import\Routine\FinTSRoutine;
use FireflyIII\Import\Routine\SpectreRoutine;
use FireflyIII\Import\Routine\YnabRoutine;
use FireflyIII\Support\Import\Routine\File\CSVProcessor;
@ -49,6 +51,7 @@ return [
'plaid' => false,
'quovo' => false,
'yodlee' => false,
'fints' => true,
'bad' => false, // always disabled
],
// demo user can use these import providers (when enabled):
@ -61,6 +64,7 @@ return [
'plaid' => false,
'quovo' => false,
'yodlee' => false,
'fints' => false,
],
// a normal user user can use these import providers (when enabled):
'allowed_for_user' => [
@ -72,6 +76,7 @@ return [
'plaid' => true,
'quovo' => true,
'yodlee' => true,
'fints' => true,
],
// some providers have pre-requisites.
'has_prereq' => [
@ -83,6 +88,7 @@ return [
'plaid' => true,
'quovo' => true,
'yodlee' => true,
'fints' => false,
],
// if so, there must be a class to handle them.
'prerequisites' => [
@ -94,6 +100,7 @@ return [
'plaid' => false,
'quovo' => false,
'yodlee' => false,
'fints' => false,
],
// some providers may need extra configuration per job
'has_job_config' => [
@ -105,6 +112,7 @@ return [
'plaid' => false,
'quovo' => false,
'yodlee' => false,
'fints' => true,
],
// if so, this is the class that handles it.
'configuration' => [
@ -116,6 +124,7 @@ return [
'plaid' => false,
'quovo' => false,
'yodlee' => false,
'fints' => FinTSJobConfiguration::class,
],
// this is the routine that runs the actual import.
'routine' => [
@ -127,6 +136,7 @@ return [
'plaid' => false,
'quovo' => false,
'yodlee' => false,
'fints' => FinTSRoutine::class,
],
'options' => [

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -222,6 +222,16 @@ return [
'public_key' => 'Public key',
'country_code' => 'Country code',
'provider_code' => 'Bank or data-provider',
'fints_url' => 'FinTS API URL',
'fints_port' => 'Port',
'fints_bank_code' => 'Bank code',
'fints_username' => 'Username',
'fints_password' => 'PIN / Password',
'fints_account' => 'FinTS account',
'local_account' => 'Firefly III account',
'from_date' => 'Date from',
'to_date' => 'Date to',
'due_date' => 'Due date',
'payment_date' => 'Payment date',

View File

@ -199,7 +199,14 @@ return [
'spectre_extra_key_units' => 'Units',
'spectre_extra_key_unit_price' => 'Unit price',
'spectre_extra_key_transactions_count' => 'Transaction count',
//job configuration for finTS
'fints_connection_failed' => 'An error occurred while trying to connecting to your bank. Please mak sure that all the data you entered is correct. Original error message: :originalError',
'button_fints' => 'FinTS',
'job_config_fints_url_help' => 'E.g. https://banking-dkb.s-fints-pt-dkb.de/fints30',
'job_config_fints_username_help' => 'For many banks this is your account number.',
'job_config_fints_port_help' => 'The default port is 443.',
'job_config_fints_account_help' => 'Choose the bank account for which you want to import transactions.',
'job_config_local_account_help' => 'Choose the Firefly III account corresponding to your bank account chosen above.',
// specifics:
'specific_ing_name' => 'ING NL',
'specific_ing_descr' => 'Create better descriptions in ING exports',

View File

@ -0,0 +1,44 @@
{% extends "./layout/default" %}
{% block breadcrumbs %}
{{ Breadcrumbs.render }}
{% endblock %}
{% block content %}
<form method="POST" action="{{ route('import.job.configuration.post', [importJob.key]) }}" accept-charset="UTF-8"
class="form-horizontal">
<input name="_token" type="hidden" value="{{ csrf_token() }}">
<div class="row">
<div class="col-lg-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ trans('import.job_config_input') }}</h3>
</div>
<div class="box-body">
{{ ExpandedForm.select('fints_account', data.fints_accounts, data.fints_account, {helpText: trans('import.job_config_fints_account_help'), required: true}) }}
</div>
<div class="box-body">
{{ ExpandedForm.select('local_account', data.local_accounts, data.local_account, {helpText: trans('import.job_config_local_account_help'), required: true}) }}
</div>
<div class="box-body">
{{ ExpandedForm.date('from_date', data.from_date, {required: true}) }}
</div>
<div class="box-body">
{{ ExpandedForm.date('to_date', data.to_date, {required: true}) }}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="box">
<div class="box-body">
<button type="submit" class="btn btn-success pull-right">
{{ ('submit')|_ }} <i class="fa fa-arrow-right"></i>
</button>
</div>
</div>
</div>
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,39 @@
{% extends "./layout/default" %}
{% block breadcrumbs %}
{{ Breadcrumbs.render }}
{% endblock %}
{% block content %}
<form method="POST" action="{{ route('import.job.configuration.post', [importJob.key]) }}" accept-charset="UTF-8"
class="form-horizontal">
<input name="_token" type="hidden" value="{{ csrf_token() }}">
<div class="row">
<div class="col-lg-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ trans('import.job_config_input') }}</h3>
</div>
<div class="box-body">
{{ ExpandedForm.text('fints_url', data.fints_url, {helpText: trans('import.job_config_fints_url_help'), required: true}) }}
{{ ExpandedForm.text('fints_port', data.fints_port, {helpText: trans('import.job_config_fints_port_help'), required: true}) }}
{{ ExpandedForm.text('fints_bank_code', data.fints_bank_code, {required: true}) }}
{{ ExpandedForm.text('fints_username', data.fints_username, {helpText: trans('import.job_config_fints_username_help'), required: true}) }}
{{ ExpandedForm.password('fints_password', {required: true}) }}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="box">
<div class="box-body">
<button type="submit" class="btn btn-success pull-right">
{{ ('submit')|_ }} <i class="fa fa-arrow-right"></i>
</button>
</div>
</div>
</div>
</div>
</form>
{% endblock %}