Improving bunq import.

This commit is contained in:
James Cole 2017-08-27 08:54:58 +02:00
parent 1ecf3d04d9
commit 1319cb2e4e
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
16 changed files with 195 additions and 87 deletions

View File

@ -21,6 +21,7 @@ use Session;
class BankController extends Controller class BankController extends Controller
{ {
/** /**
* This method must ask the user all parameters necessary to start importing data. This may not be enough * This method must ask the user all parameters necessary to start importing data. This may not be enough
* to finish the import itself (ie. mapping) but it should be enough to begin: accounts to import from, * to finish the import itself (ie. mapping) but it should be enough to begin: accounts to import from,
@ -42,6 +43,49 @@ class BankController extends Controller
$object->setUser(auth()->user()); $object->setUser(auth()->user());
$remoteAccounts = $object->getAccounts(); $remoteAccounts = $object->getAccounts();
return view('import.bank.form', compact('remoteAccounts', 'bank'));
}
/**
* With the information given in the submitted form Firefly III will call upon the bank's classes to return transaction
* information as requested. The user will be able to map unknown data and continue. Or maybe, it's put into some kind of
* fake CSV file and forwarded to the import routine.
*
* @param Request $request
* @param string $bank
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function postForm(Request $request, string $bank)
{
$class = config(sprintf('firefly.import_pre.%s', $bank));
/** @var PrerequisitesInterface $object */
$object = app($class);
$object->setUser(auth()->user());
if ($object->hasPrerequisites()) {
return redirect(route('import.bank.prerequisites', [$bank]));
}
$remoteAccounts = $request->get('do_import');
if (!is_array($remoteAccounts) || count($remoteAccounts) === 0) {
Session::flash('error', 'Must select accounts');
return redirect(route('import.bank.form', [$bank]));
}
$remoteAccounts = array_keys($remoteAccounts);
$class = config(sprintf('firefly.import_pre.%s', $bank));
var_dump($remoteAccounts);exit;
// get import file
// get import config
} }
/** /**
@ -66,6 +110,7 @@ class BankController extends Controller
$object->setUser(auth()->user()); $object->setUser(auth()->user());
if (!$object->hasPrerequisites()) { if (!$object->hasPrerequisites()) {
Log::debug(sprintf('No more prerequisites for %s, move to form.', $bank)); Log::debug(sprintf('No more prerequisites for %s, move to form.', $bank));
return redirect(route('import.bank.form', [$bank])); return redirect(route('import.bank.form', [$bank]));
} }
Log::debug('Going to store entered preprerequisites.'); Log::debug('Going to store entered preprerequisites.');
@ -102,6 +147,7 @@ class BankController extends Controller
return view($view, $parameters); return view($view, $parameters);
} }
return redirect(route('import.bank.form', [$bank])); return redirect(route('import.bank.form', [$bank]));
} }

View File

@ -65,5 +65,4 @@ class Alias extends BunqObject
} }
} }

View File

@ -54,5 +54,4 @@ class Amount extends BunqObject
} }
} }

View File

@ -62,56 +62,6 @@ class MonetaryAccountBank extends BunqObject
/** @var int */ /** @var int */
private $userId = 0; private $userId = 0;
/**
* @return string
*/
public function getDescription(): string
{
return $this->description;
}
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @return array
*/
public function getAliases(): array
{
return $this->aliases;
}
/**
* @return string
*/
public function getCurrency(): string
{
return $this->currency;
}
/**
* @return Amount
*/
public function getBalance(): Amount
{
return $this->balance;
}
/**
* @return MonetaryAccountSetting
*/
public function getSetting(): MonetaryAccountSetting
{
return $this->setting;
}
/** /**
* MonetaryAccountBank constructor. * MonetaryAccountBank constructor.
* *
@ -150,4 +100,52 @@ class MonetaryAccountBank extends BunqObject
return; return;
} }
/**
* @return array
*/
public function getAliases(): array
{
return $this->aliases;
}
/**
* @return Amount
*/
public function getBalance(): Amount
{
return $this->balance;
}
/**
* @return string
*/
public function getCurrency(): string
{
return $this->currency;
}
/**
* @return string
*/
public function getDescription(): string
{
return $this->description;
}
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @return MonetaryAccountSetting
*/
public function getSetting(): MonetaryAccountSetting
{
return $this->setting;
}
} }

View File

@ -37,6 +37,7 @@ class MonetaryAccountProfile extends BunqObject
$this->profileFill = null; $this->profileFill = null;
$this->profileActionRequired = $data['profile_action_required']; $this->profileActionRequired = $data['profile_action_required'];
$this->profileAmountRequired = new Amount($data['profile_amount_required']); $this->profileAmountRequired = new Amount($data['profile_amount_required']);
return; return;
} }

View File

@ -36,6 +36,7 @@ class MonetaryAccountSetting extends BunqObject
$this->color = $data['color']; $this->color = $data['color'];
$this->defaultAvatarStatus = $data['default_avatar_status']; $this->defaultAvatarStatus = $data['default_avatar_status'];
$this->restrictionChat = $data['restriction_chat']; $this->restrictionChat = $data['restriction_chat'];
return; return;
} }

View File

@ -24,7 +24,8 @@ class NotificationFilter extends BunqObject
* *
* @param array $data * @param array $data
*/ */
public function __construct(array $data) { public function __construct(array $data)
{
var_dump($data); var_dump($data);
exit; exit;
} }

View File

@ -27,16 +27,9 @@ class ServerPublicKey extends BunqObject
* *
* @param array $response * @param array $response
*/ */
public function __construct(array $response) { public function __construct(array $response)
$this->publicKey = $response['server_public_key'];
}
/**
* @param string $publicKey
*/
public function setPublicKey(string $publicKey)
{ {
$this->publicKey = $publicKey; $this->publicKey = $response['server_public_key'];
} }
/** /**
@ -47,5 +40,13 @@ class ServerPublicKey extends BunqObject
return $this->publicKey; return $this->publicKey;
} }
/**
* @param string $publicKey
*/
public function setPublicKey(string $publicKey)
{
$this->publicKey = $publicKey;
}
} }

View File

@ -103,5 +103,4 @@ class UserCompany extends BunqObject
} }
} }

View File

@ -51,7 +51,7 @@ class UserLight extends BunqObject
*/ */
public function __construct(array $data) public function __construct(array $data)
{ {
if(count($data) === 0) { if (count($data) === 0) {
return; return;
} }
$this->id = intval($data['id']); $this->id = intval($data['id']);

View File

@ -45,6 +45,7 @@ abstract class BunqRequest
*/ */
public function __construct() public function __construct()
{ {
$this->server = config('firefly.bunq.server');
} }
/** /**
@ -60,14 +61,6 @@ abstract class BunqRequest
return $this->server; return $this->server;
} }
/**
* @param string $server
*/
public function setServer(string $server)
{
$this->server = $server;
}
/** /**
* @param string $privateKey * @param string $privateKey
*/ */

View File

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace FireflyIII\Support\Import\Information; namespace FireflyIII\Support\Import\Information;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Services\Bunq\Object\Alias; use FireflyIII\Services\Bunq\Object\Alias;
use FireflyIII\Services\Bunq\Object\MonetaryAccountBank; use FireflyIII\Services\Bunq\Object\MonetaryAccountBank;
use FireflyIII\Services\Bunq\Request\DeleteDeviceSessionRequest; use FireflyIII\Services\Bunq\Request\DeleteDeviceSessionRequest;
@ -20,6 +21,7 @@ use FireflyIII\Services\Bunq\Request\DeviceSessionRequest;
use FireflyIII\Services\Bunq\Request\ListMonetaryAccountRequest; use FireflyIII\Services\Bunq\Request\ListMonetaryAccountRequest;
use FireflyIII\Services\Bunq\Request\ListUserRequest; use FireflyIII\Services\Bunq\Request\ListUserRequest;
use FireflyIII\Services\Bunq\Token\SessionToken; use FireflyIII\Services\Bunq\Token\SessionToken;
use FireflyIII\Support\CacheProperties;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Log; use Log;
@ -56,22 +58,28 @@ class BunqInformation implements InformationInterface
*/ */
public function getAccounts(): array public function getAccounts(): array
{ {
// cache for an hour:
$cache = new CacheProperties;
$cache->addProperty('bunq.get-accounts');
$cache->addProperty(date('dmy h'));
if ($cache->has()) {
return $cache->get(); // @codeCoverageIgnore
}
Log::debug('Now in getAccounts()'); Log::debug('Now in getAccounts()');
$sessionToken = $this->startSession(); $sessionToken = $this->startSession();
$id = $this->getUserInformation($sessionToken); $id = $this->getUserInformation($sessionToken);
// get list of Bunq accounts: // get list of Bunq accounts:
$accounts = $this->getMonetaryAccounts($sessionToken, $id); $accounts = $this->getMonetaryAccounts($sessionToken, $id);
$return = []; $return = [];
/** @var MonetaryAccountBank $account */ /** @var MonetaryAccountBank $account */
foreach ($accounts as $account) { foreach ($accounts as $account) {
$current = [ $current = [
'id' => $account->getId(), 'id' => $account->getId(),
'name' => $account->getDescription(), 'name' => $account->getDescription(),
'currency' => $account->getCurrency(), 'currency' => $account->getCurrency(),
'balance' => $account->getBalance()->getValue(), 'balance' => $account->getBalance()->getValue(),
'color' => $account->getSetting()->getColor(), 'color' => $account->getSetting()->getColor(),
]; ];
/** @var Alias $alias */ /** @var Alias $alias */
foreach ($account->getAliases() as $alias) { foreach ($account->getAliases() as $alias) {
@ -81,6 +89,7 @@ class BunqInformation implements InformationInterface
} }
$return[] = $current; $return[] = $current;
} }
$cache->store($return);
$this->closeSession($sessionToken); $this->closeSession($sessionToken);
@ -105,11 +114,9 @@ class BunqInformation implements InformationInterface
Log::debug('Going to close session'); Log::debug('Going to close session');
$apiKey = Preferences::getForUser($this->user, 'bunq_api_key')->data; $apiKey = Preferences::getForUser($this->user, 'bunq_api_key')->data;
$serverPublicKey = Preferences::getForUser($this->user, 'bunq_server_public_key')->data; $serverPublicKey = Preferences::getForUser($this->user, 'bunq_server_public_key')->data;
$server = config('firefly.bunq.server');
$privateKey = Preferences::getForUser($this->user, 'bunq_private_key')->data; $privateKey = Preferences::getForUser($this->user, 'bunq_private_key')->data;
$request = new DeleteDeviceSessionRequest(); $request = new DeleteDeviceSessionRequest();
$request->setSecret($apiKey); $request->setSecret($apiKey);
$request->setServer($server);
$request->setPrivateKey($privateKey); $request->setPrivateKey($privateKey);
$request->setServerPublicKey($serverPublicKey); $request->setServerPublicKey($serverPublicKey);
$request->setSessionToken($sessionToken); $request->setSessionToken($sessionToken);
@ -128,14 +135,12 @@ class BunqInformation implements InformationInterface
{ {
$apiKey = Preferences::getForUser($this->user, 'bunq_api_key')->data; $apiKey = Preferences::getForUser($this->user, 'bunq_api_key')->data;
$serverPublicKey = Preferences::getForUser($this->user, 'bunq_server_public_key')->data; $serverPublicKey = Preferences::getForUser($this->user, 'bunq_server_public_key')->data;
$server = config('firefly.bunq.server');
$privateKey = Preferences::getForUser($this->user, 'bunq_private_key')->data; $privateKey = Preferences::getForUser($this->user, 'bunq_private_key')->data;
$request = new ListMonetaryAccountRequest; $request = new ListMonetaryAccountRequest;
$request->setSessionToken($sessionToken); $request->setSessionToken($sessionToken);
$request->setSecret($apiKey); $request->setSecret($apiKey);
$request->setServerPublicKey($serverPublicKey); $request->setServerPublicKey($serverPublicKey);
$request->setServer($server);
$request->setPrivateKey($privateKey); $request->setPrivateKey($privateKey);
$request->setUserId($userId); $request->setUserId($userId);
$request->call(); $request->call();
@ -154,13 +159,11 @@ class BunqInformation implements InformationInterface
{ {
$apiKey = Preferences::getForUser($this->user, 'bunq_api_key')->data; $apiKey = Preferences::getForUser($this->user, 'bunq_api_key')->data;
$serverPublicKey = Preferences::getForUser($this->user, 'bunq_server_public_key')->data; $serverPublicKey = Preferences::getForUser($this->user, 'bunq_server_public_key')->data;
$server = config('firefly.bunq.server');
$privateKey = Preferences::getForUser($this->user, 'bunq_private_key')->data; $privateKey = Preferences::getForUser($this->user, 'bunq_private_key')->data;
$request = new ListUserRequest; $request = new ListUserRequest;
$request->setSessionToken($sessionToken); $request->setSessionToken($sessionToken);
$request->setSecret($apiKey); $request->setSecret($apiKey);
$request->setServerPublicKey($serverPublicKey); $request->setServerPublicKey($serverPublicKey);
$request->setServer($server);
$request->setPrivateKey($privateKey); $request->setPrivateKey($privateKey);
$request->call(); $request->call();
// return the first that isn't null? // return the first that isn't null?
@ -183,13 +186,11 @@ class BunqInformation implements InformationInterface
Log::debug('Now in startSession.'); Log::debug('Now in startSession.');
$apiKey = Preferences::getForUser($this->user, 'bunq_api_key')->data; $apiKey = Preferences::getForUser($this->user, 'bunq_api_key')->data;
$serverPublicKey = Preferences::getForUser($this->user, 'bunq_server_public_key')->data; $serverPublicKey = Preferences::getForUser($this->user, 'bunq_server_public_key')->data;
$server = config('firefly.bunq.server');
$privateKey = Preferences::getForUser($this->user, 'bunq_private_key')->data; $privateKey = Preferences::getForUser($this->user, 'bunq_private_key')->data;
$installationToken = Preferences::getForUser($this->user, 'bunq_installation_token')->data; $installationToken = Preferences::getForUser($this->user, 'bunq_installation_token')->data;
$request = new DeviceSessionRequest(); $request = new DeviceSessionRequest();
$request->setSecret($apiKey); $request->setSecret($apiKey);
$request->setServerPublicKey($serverPublicKey); $request->setServerPublicKey($serverPublicKey);
$request->setServer($server);
$request->setPrivateKey($privateKey); $request->setPrivateKey($privateKey);
$request->setInstallationToken($installationToken); $request->setInstallationToken($installationToken);
$request->call(); $request->call();

View File

@ -157,7 +157,6 @@ class BunqPrerequisites implements PrerequisitesInterface
$request->setInstallationToken($installationToken); $request->setInstallationToken($installationToken);
$request->setServerPublicKey($serverPublicKey); $request->setServerPublicKey($serverPublicKey);
$request->setPrivateKey($this->getPrivateKey()); $request->setPrivateKey($this->getPrivateKey());
$request->setServer(config('firefly.bunq.server'));
$request->call(); $request->call();
$devices = $request->getDevices(); $devices = $request->getDevices();
/** @var DeviceServer $device */ /** @var DeviceServer $device */
@ -186,7 +185,6 @@ class BunqPrerequisites implements PrerequisitesInterface
// verify bunq api code: // verify bunq api code:
$publicKey = $this->getPublicKey(); $publicKey = $this->getPublicKey();
$request = new InstallationTokenRequest; $request = new InstallationTokenRequest;
$request->setServer(strval(config('firefly.bunq.server')));
$request->setPublicKey($publicKey); $request->setPublicKey($publicKey);
$request->call(); $request->call();
Log::debug('Sent request'); Log::debug('Sent request');
@ -301,7 +299,6 @@ class BunqPrerequisites implements PrerequisitesInterface
$serverPublicKey = $this->getServerPublicKey(); $serverPublicKey = $this->getServerPublicKey();
$apiKey = Preferences::getForUser($this->user, 'bunq_api_key', ''); $apiKey = Preferences::getForUser($this->user, 'bunq_api_key', '');
$request = new DeviceServerRequest; $request = new DeviceServerRequest;
$request->setServer(strval(config('firefly.bunq.server')));
$request->setPrivateKey($this->getPrivateKey()); $request->setPrivateKey($this->getPrivateKey());
$request->setDescription('Firefly III v' . config('firefly.version') . ' for ' . $this->user->email); $request->setDescription('Firefly III v' . config('firefly.version') . ' for ' . $this->user->email);
$request->setSecret($apiKey->data); $request->setSecret($apiKey->data);

View File

@ -45,6 +45,9 @@ return [
'import_info' => [ 'import_info' => [
'bunq' => 'FireflyIII\Support\Import\Information\BunqInformation', 'bunq' => 'FireflyIII\Support\Import\Information\BunqInformation',
], ],
'import_transactions' => [
'bunq' => 'FireflyIII\Support\Import\Transactions\BunqTransactions',
],
'bunq' => [ 'bunq' => [
'server' => 'https://sandbox.public.api.bunq.com', 'server' => 'https://sandbox.public.api.bunq.com',
], ],

View File

@ -0,0 +1,69 @@
{% extends "./layout/default" %}
{% block breadcrumbs %}
{{ Breadcrumbs.renderIfExists }}
{% endblock %}
{% block content %}
<div class="row">
<form class="form-horizontal" action="{{ route('import.bank.form.post',[bank]) }}" 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('bank.bank_form_title') }}</h3>
</div>
<div class="box-body">
<div class="row">
<div class="col-lg-8">
<p>
{{ trans('bank.bank_form_text') }}
</p>
</div>
</div>
<div class="row">
<div class="col-lg-8">
<table class="table">
<thead>
<tr>
<th colspan="2">Account</th>
<th>Current balance</th>
</tr>
</thead>
<tbody>
{% for remoteAccount in remoteAccounts %}
<tr>
<td>
<input type="checkbox" name="do_import[{{ remoteAccount.id }}]" checked id="do_import_{{ remoteAccount.id }}" />
</td>
<td>
<strong {% if remoteAccount.color !='' %} style="color:{{ remoteAccount.color }}"{% endif %}>
{{ remoteAccount.name }}
</strong>
<br />{{ remoteAccount.number }}
</td>
<td>
{{ remoteAccount.currency }}
{{ remoteAccount.balance }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn pull-right btn-success">
{{ ('submit')|_ }}
</button>
</div>
</div>
</div>
</form>
</div>
{% endblock %}
{% block scripts %}
{% endblock %}
{% block styles %}
{% endblock %}

View File

@ -5,7 +5,7 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="row"> <div class="row">
<form class="form-horizontal" id="report-form" action="{{ route('import.bank.prerequisites.post',['bunq']) }}" method="post"> <form class="form-horizontal" action="{{ route('import.bank.prerequisites.post',['bunq']) }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/> <input type="hidden" name="_token" value="{{ csrf_token() }}"/>
<div class="col-lg-12 col-md-12 col-sm-12"> <div class="col-lg-12 col-md-12 col-sm-12">
<div class="box box-default"> <div class="box box-default">