mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-22 20:16:22 +00:00
Remove import code.
This commit is contained in:
@@ -1,111 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ImportProvider.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Binder;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Routing\Route;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Class ImportProvider.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
class ImportProvider implements BinderInterface
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public static function getProviders(): array
|
||||
{
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
// get and filter all import routines:
|
||||
|
||||
if (!auth()->check()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var array $config */
|
||||
$providerNames = array_keys(config('import.enabled'));
|
||||
$providers = [];
|
||||
$isDemoUser = $repository->hasRole($user, 'demo');
|
||||
$isDebug = (bool)config('app.debug');
|
||||
foreach ($providerNames as $providerName) {
|
||||
// only consider enabled providers
|
||||
$enabled = (bool)config(sprintf('import.enabled.%s', $providerName));
|
||||
$allowedForUser = (bool)config(sprintf('import.allowed_for_user.%s', $providerName));
|
||||
$allowedForDemo = (bool)config(sprintf('import.allowed_for_demo.%s', $providerName));
|
||||
if (false === $enabled) {
|
||||
continue;
|
||||
}
|
||||
if (false === $allowedForUser && !$isDemoUser) {
|
||||
continue;
|
||||
}
|
||||
if (false === $allowedForDemo && $isDemoUser) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$providers[$providerName] = [
|
||||
'has_prereq' => (bool)config('import.has_prereq.' . $providerName),
|
||||
'allowed_for_demo' => (bool)config(sprintf('import.allowed_for_demo.%s', $providerName)),
|
||||
];
|
||||
$class = (string)config(sprintf('import.prerequisites.%s', $providerName));
|
||||
$result = false;
|
||||
if ('' !== $class && class_exists($class)) {
|
||||
//Log::debug('Will not check prerequisites.');
|
||||
/** @var PrerequisitesInterface $object */
|
||||
$object = app($class);
|
||||
$object->setUser($user);
|
||||
$result = $object->isComplete();
|
||||
}
|
||||
$providers[$providerName]['prereq_complete'] = $result;
|
||||
}
|
||||
//Log::debug(sprintf('Enabled providers: %s', json_encode(array_keys($providers))));
|
||||
|
||||
return $providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
*/
|
||||
public static function routeBinder(string $value, Route $route): string
|
||||
{
|
||||
$providers = array_keys(self::getProviders());
|
||||
if (in_array($value, $providers, true)) {
|
||||
return $value;
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
}
|
@@ -1,122 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FinTS.php
|
||||
* Copyright (c) 2019 https://github.com/bnw
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\FinTS;
|
||||
|
||||
use Fhp\Model\SEPAAccount;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
* Class FinTS
|
||||
*/
|
||||
class FinTS
|
||||
{
|
||||
/** @var \Fhp\FinTs */
|
||||
private $finTS;
|
||||
|
||||
/**
|
||||
* @param array $config
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function __construct(array $config)
|
||||
{
|
||||
if (!isset($config['fints_url'], $config['fints_port'], $config['fints_bank_code'], $config['fints_username'], $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']) // verified
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|string
|
||||
*/
|
||||
public function checkConnection()
|
||||
{
|
||||
try {
|
||||
$this->finTS->getSEPAAccounts();
|
||||
|
||||
return true;
|
||||
} catch (\Exception $exception) {
|
||||
return $exception->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $accountNumber
|
||||
*
|
||||
* @return SEPAAccount
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getAccount(string $accountNumber): SEPAAccount
|
||||
{
|
||||
$accounts = $this->getAccounts();
|
||||
$filteredAccounts = array_filter(
|
||||
$accounts, function (SEPAAccount $account) use ($accountNumber) {
|
||||
return $account->getAccountNumber() === $accountNumber;
|
||||
}
|
||||
);
|
||||
if (1 !== count($filteredAccounts)) {
|
||||
throw new FireflyException(sprintf('Cannot find account with number "%s"', $accountNumber));
|
||||
}
|
||||
|
||||
return reset($filteredAccounts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SEPAAccount[]
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getAccounts(): ?array
|
||||
{
|
||||
try {
|
||||
return $this->finTS->getSEPAAccounts();
|
||||
} catch (\Exception $exception) {
|
||||
throw new FireflyException($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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());
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* MetadataParser.php
|
||||
* Copyright (c) 2019 https://github.com/bnw
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\FinTS;
|
||||
|
||||
use Fhp\Model\StatementOfAccount\Transaction as FinTSTransaction;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
* Class MetadataParser
|
||||
*/
|
||||
class MetadataParser
|
||||
{
|
||||
/**
|
||||
* @param FinTSTransaction $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(FinTSTransaction $transaction): string
|
||||
{
|
||||
//Given a description like 'EREF+AbcCRED+DE123SVWZ+DefABWA+Ghi' or 'EREF+AbcCRED+DE123SVWZ+Def' return 'Def'
|
||||
$finTSDescription = $transaction->getDescription1();
|
||||
$matches = [];
|
||||
if (1 === preg_match('/SVWZ\+([^\+]*)([A-Z]{4}\+|$)/', $finTSDescription, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
return $finTSDescription;
|
||||
}
|
||||
}
|
@@ -27,9 +27,6 @@ use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Requests\NewUserFormRequest;
|
||||
use FireflyIII\Import\JobConfiguration\JobConfigurationInterface;
|
||||
use FireflyIII\Import\Storage\ImportArrayStorage;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
@@ -174,46 +171,4 @@ trait CreateStuff
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a configurator object.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return JobConfigurationInterface
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function makeConfigurator(ImportJob $importJob): JobConfigurationInterface // make object
|
||||
{
|
||||
$key = sprintf('import.configuration.%s', $importJob->provider);
|
||||
$className = (string)config($key);
|
||||
if (null === $className || !class_exists($className)) {
|
||||
throw new FireflyException(sprintf('Cannot find configurator class for job with provider "%s".', $importJob->provider)); // @codeCoverageIgnore
|
||||
}
|
||||
Log::debug(sprintf('Going to create class "%s"', $className));
|
||||
/** @var JobConfigurationInterface $configurator */
|
||||
$configurator = app($className);
|
||||
$configurator->setImportJob($importJob);
|
||||
|
||||
return $configurator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the transactions.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function storeTransactions(ImportJob $importJob): void // make object + execute
|
||||
{
|
||||
/** @var ImportArrayStorage $storage */
|
||||
$storage = app(ImportArrayStorage::class);
|
||||
$storage->setImportJob($importJob);
|
||||
try {
|
||||
$storage->store();
|
||||
} catch (FireflyException|Exception $e) {
|
||||
throw new FireflyException($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,110 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* GetSpectreCustomerTrait.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Information;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Services\Spectre\Object\Customer;
|
||||
use FireflyIII\Services\Spectre\Request\ListCustomersRequest;
|
||||
use FireflyIII\Services\Spectre\Request\NewCustomerRequest;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Trait GetSpectreCustomerTrait
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
trait GetSpectreCustomerTrait
|
||||
{
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return Customer
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function getCustomer(ImportJob $importJob): Customer
|
||||
{
|
||||
Log::debug('Now in GetSpectreCustomerTrait::getCustomer()');
|
||||
$customer = $this->getExistingCustomer($importJob);
|
||||
if (null === $customer) {
|
||||
Log::debug('The customer is NULL, will fire a newCustomerRequest.');
|
||||
/** @var NewCustomerRequest $request */
|
||||
$request = app(NewCustomerRequest::class);
|
||||
$request->setUser($importJob->user);
|
||||
$request->call();
|
||||
|
||||
$customer = $request->getCustomer();
|
||||
|
||||
}
|
||||
|
||||
Log::debug('The customer is not null.');
|
||||
|
||||
return $customer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return Customer|null
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function getExistingCustomer(ImportJob $importJob): ?Customer
|
||||
{
|
||||
Log::debug('Now in GetSpectreCustomerTrait::getExistingCustomer()');
|
||||
$customer = null;
|
||||
|
||||
// check users preferences.
|
||||
$preference = app('preferences')->getForUser($importJob->user, 'spectre_customer', null);
|
||||
if (null !== $preference) {
|
||||
Log::debug('Customer is in user configuration');
|
||||
$customer = new Customer($preference->data);
|
||||
|
||||
return $customer;
|
||||
}
|
||||
|
||||
/** @var ListCustomersRequest $request */
|
||||
$request = app(ListCustomersRequest::class);
|
||||
$request->setUser($importJob->user);
|
||||
$request->call();
|
||||
$customers = $request->getCustomers();
|
||||
|
||||
Log::debug(sprintf('Found %d customer(s)', count($customers)));
|
||||
/** @var Customer $current */
|
||||
foreach ($customers as $current) {
|
||||
if ('default_ff3_customer' === $current->getIdentifier()) {
|
||||
$customer = $current;
|
||||
Log::debug('Found the correct customer.');
|
||||
break;
|
||||
}
|
||||
Log::debug(sprintf('Skip customer with name "%s"', $current->getIdentifier()));
|
||||
}
|
||||
if (null !== $customer) {
|
||||
// store in preferences.
|
||||
app('preferences')->setForUser($importJob->user, 'spectre_customer', $customer->toArray());
|
||||
}
|
||||
|
||||
return $customer;
|
||||
}
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* GetSpectreTokenTrait.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Information;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Services\Spectre\Object\Customer;
|
||||
use FireflyIII\Services\Spectre\Object\Token;
|
||||
use FireflyIII\Services\Spectre\Request\CreateTokenRequest;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Trait GetSpectreTokenTrait
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
trait GetSpectreTokenTrait
|
||||
{
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
* @param Customer $customer
|
||||
*
|
||||
* @return Token
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
*/
|
||||
protected function getToken(ImportJob $importJob, Customer $customer): Token
|
||||
{
|
||||
Log::debug('Now in GetSpectreTokenTrait::ChooseLoginsHandler::getToken()');
|
||||
/** @var CreateTokenRequest $request */
|
||||
$request = app(CreateTokenRequest::class);
|
||||
$request->setUser($importJob->user);
|
||||
$request->setUri(route('import.job.status.index', [$importJob->key]));
|
||||
$request->setCustomer($customer);
|
||||
$request->call();
|
||||
Log::debug('Call to get token is finished');
|
||||
|
||||
return $request->getToken();
|
||||
}
|
||||
}
|
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* BunqJobConfigurationInterface.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Bunq;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* Interface BunqJobConfigurationInterface
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
interface BunqJobConfigurationInterface
|
||||
{
|
||||
/**
|
||||
* 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;
|
||||
|
||||
}
|
@@ -1,271 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ChooseAccountsHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Bunq;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account as AccountModel;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ChooseAccountsHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ChooseAccountsHandler implements BunqJobConfigurationInterface
|
||||
{
|
||||
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $currencyRepository;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Return true when this stage is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$mapping = $config['mapping'] ?? [];
|
||||
$complete = count($mapping) > 0;
|
||||
if (true === $complete) {
|
||||
// move job to correct stage to download transactions
|
||||
$this->repository->setStage($this->importJob, 'go-for-import');
|
||||
}
|
||||
|
||||
return $complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the job configuration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$accounts = $config['accounts'] ?? [];
|
||||
$mapping = $data['account_mapping'] ?? [];
|
||||
$applyRules = 1 === (int)($data['apply_rules'] ?? 0);
|
||||
$final = [];
|
||||
|
||||
/*
|
||||
* $ibanToAsset is used to map bunq IBAN's to Firefly III asset accounts. The array is structured like this:
|
||||
* 12BUNQ123456.. => 1,
|
||||
* 12BUNQ928811.. => 4,
|
||||
*
|
||||
* And contains the bunq asset account iban (left) and the FF3 asset ID (right).
|
||||
*
|
||||
* This is used to properly map transfers.
|
||||
*/
|
||||
$ibanToAsset = [];
|
||||
Log::debug('Going to map IBANs for easy mapping later on.');
|
||||
if (0 === count($accounts)) {
|
||||
throw new FireflyException('No bunq accounts found. Import cannot continue.'); // @codeCoverageIgnore
|
||||
}
|
||||
if (0 === count($mapping)) {
|
||||
$messages = new MessageBag;
|
||||
$messages->add('nomap', (string)trans('import.bunq_no_mapping'));
|
||||
|
||||
return $messages;
|
||||
}
|
||||
foreach ($mapping as $bunqId => $localId) {
|
||||
$bunqId = (int)$bunqId;
|
||||
$localId = (int)$localId;
|
||||
|
||||
Log::debug(sprintf('Now trying to link bunq acount #%d with Firefly III account %d', $bunqId, $localId));
|
||||
|
||||
// validate each
|
||||
$bunqId = $this->validBunqAccount($bunqId);
|
||||
$accountId = $this->validLocalAccount($localId);
|
||||
|
||||
Log::debug(sprintf('After validation: bunq account #%d with Firefly III account %d', $bunqId, $localId));
|
||||
|
||||
$bunqIban = $this->getBunqIban($bunqId);
|
||||
|
||||
Log::debug(sprintf('IBAN for bunq account #%d is "%s"', $bunqId, $bunqIban));
|
||||
if (null !== $bunqIban) {
|
||||
$ibanToAsset[$bunqIban] = $accountId; // @codeCoverageIgnore
|
||||
}
|
||||
$final[$bunqId] = $accountId;
|
||||
}
|
||||
$config['mapping'] = $final;
|
||||
$config['bunq-iban'] = $ibanToAsset;
|
||||
$config['apply-rules'] = $applyRules;
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
|
||||
Log::info('Account mapping: ', $final);
|
||||
Log::info('Bunq IBAN array: ', $ibanToAsset);
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for config view.
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$accounts = $config['accounts'] ?? [];
|
||||
if (0 === count($accounts)) {
|
||||
throw new FireflyException('No bunq accounts found. Import cannot continue.'); // @codeCoverageIgnore
|
||||
}
|
||||
// list the users accounts:
|
||||
$collection = $this->accountRepository->getAccountsByType([AccountType::ASSET]);
|
||||
|
||||
$localAccounts = [];
|
||||
/** @var AccountModel $localAccount */
|
||||
foreach ($collection as $localAccount) {
|
||||
$accountId = $localAccount->id;
|
||||
// TODO we can use getAccountCurrency() instead
|
||||
$currencyId = (int)$this->accountRepository->getMetaValue($localAccount, 'currency_id');
|
||||
$currency = $this->getCurrency($currencyId);
|
||||
$localAccounts[$accountId] = [
|
||||
'name' => $localAccount->name,
|
||||
'iban' => $localAccount->iban,
|
||||
'code' => $currency->code,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'accounts' => $accounts,
|
||||
'local_accounts' => $localAccounts,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
return 'import.bunq.choose-accounts';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->currencyRepository->setUser($importJob->user);
|
||||
$this->accountRepository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $bunqId
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
private function getBunqIban(int $bunqId): ?string
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$accounts = $config['accounts'] ?? [];
|
||||
/** @var array $bunqAccount */
|
||||
foreach ($accounts as $bunqAccount) {
|
||||
if ((int)$bunqAccount['id'] === $bunqId) {
|
||||
return $bunqAccount['iban'] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $currencyId
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
private function getCurrency(int $currencyId): TransactionCurrency
|
||||
{
|
||||
$currency = $this->currencyRepository->findNull($currencyId);
|
||||
if (null === $currency) {
|
||||
return app('amount')->getDefaultCurrencyByUser($this->importJob->user);
|
||||
}
|
||||
|
||||
return $currency;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $bunqId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function validBunqAccount(int $bunqId): int
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$accounts = $config['accounts'] ?? [];
|
||||
/** @var array $bunqAccount */
|
||||
foreach ($accounts as $bunqAccount) {
|
||||
if ((int)$bunqAccount['id'] === $bunqId) {
|
||||
return $bunqId;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $accountId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function validLocalAccount(int $accountId): int
|
||||
{
|
||||
$account = $this->accountRepository->findNull($accountId);
|
||||
if (null === $account) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $accountId;
|
||||
}
|
||||
}
|
@@ -1,105 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* NewBunqJobHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Bunq;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class NewBunqJobHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class NewBunqJobHandler implements BunqJobConfigurationInterface
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Return true when this stage is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Store the job configuration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
Log::debug('NewBunqJobHandler::configureJob always returns an empty message bag.');
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Get data for config view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
Log::debug('NewBunqJobHandler::getNextData always returns an empty array.');
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
Log::debug('NewBunqJobHandler::getNextView always returns "".');
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
@@ -1,354 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ConfigureMappingHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\File;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Import\Mapper\MapperInterface;
|
||||
use FireflyIII\Import\Specifics\SpecificInterface;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use League\Csv\Exception;
|
||||
use League\Csv\Reader;
|
||||
use League\Csv\Statement;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ConfigureMappingHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ConfigureMappingHandler implements FileConfigurationInterface
|
||||
{
|
||||
/** @var AttachmentHelperInterface */
|
||||
private $attachments;
|
||||
/** @var array */
|
||||
private $columnConfig;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Apply the users selected specifics on the current row.
|
||||
*
|
||||
* @param array $config
|
||||
* @param array $row
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function applySpecifics(array $config, array $row): array
|
||||
{
|
||||
// run specifics here:
|
||||
// and this is the point where the specifix go to work.
|
||||
$validSpecifics = array_keys(config('csv.import_specifics'));
|
||||
$specifics = $config['specifics'] ?? [];
|
||||
$names = array_keys($specifics);
|
||||
foreach ($names as $name) {
|
||||
if (!in_array($name, $validSpecifics, true)) {
|
||||
continue;
|
||||
}
|
||||
$class = config(sprintf('csv.import_specifics.%s', $name));
|
||||
/** @var SpecificInterface $specific */
|
||||
$specific = app($class);
|
||||
|
||||
// it returns the row, possibly modified:
|
||||
$row = $specific->run($row);
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store data associated with current stage.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
$config = $this->importJob->configuration;
|
||||
|
||||
if (isset($data['mapping']) && is_array($data['mapping'])) {
|
||||
foreach ($data['mapping'] as $index => $array) {
|
||||
$config['column-mapping-config'][$index] = [];
|
||||
foreach ($array as $value => $mapId) {
|
||||
$mapId = (int)$mapId;
|
||||
if (0 !== $mapId) {
|
||||
$config['column-mapping-config'][$index][(string)$value] = $mapId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
$this->repository->setStage($this->importJob, 'ready_to_run');
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the "mapper" class that will eventually return the correct data for the user
|
||||
* to map against. For example: a list of asset accounts. A list of budgets. A list of tags.
|
||||
*
|
||||
* @param string $column
|
||||
*
|
||||
* @return MapperInterface
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function createMapper(string $column): MapperInterface
|
||||
{
|
||||
$mapperClass = config('csv.import_roles.' . $column . '.mapper');
|
||||
$mapperName = sprintf('FireflyIII\\Import\Mapper\\%s', $mapperClass);
|
||||
if (!class_exists($mapperName)) {
|
||||
throw new FireflyException(sprintf('Class "%s" does not exist. Cannot map "%s"', $mapperName, $column)); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return app($mapperName);
|
||||
}
|
||||
|
||||
/**
|
||||
* For each column in the configuration of the job, will:
|
||||
* - validate the role.
|
||||
* - validate if it can be used for mapping
|
||||
* - if so, create an entry in $columnConfig
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return array the column configuration.
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function doColumnConfig(array $config): array
|
||||
{
|
||||
/** @var array $requestMapping */
|
||||
$requestMapping = $config['column-do-mapping'] ?? [];
|
||||
$columnConfig = [];
|
||||
/**
|
||||
* @var int
|
||||
* @var bool $mustBeMapped
|
||||
*/
|
||||
foreach ($requestMapping as $index => $requested) {
|
||||
// sanitize column name, so we're sure it's valid.
|
||||
$column = $this->sanitizeColumnName($config['column-roles'][$index] ?? '_ignore');
|
||||
$doMapping = $this->doMapOfColumn($column, $requested);
|
||||
if ($doMapping) {
|
||||
// user want to map this column. And this is possible.
|
||||
$columnConfig[$index] = [
|
||||
'name' => $column,
|
||||
'options' => $this->createMapper($column)->getMap(),
|
||||
'preProcessMap' => $this->getPreProcessorName($column),
|
||||
'values' => [],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $columnConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* For each $name given, and if the user wants to map the column, will return
|
||||
* true when the column can also be mapped.
|
||||
*
|
||||
* Unmappable columns will always return false.
|
||||
* Mappable columns will return $requested.
|
||||
*
|
||||
* @param string $name
|
||||
* @param bool $requested
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function doMapOfColumn(string $name, bool $requested): bool
|
||||
{
|
||||
$canBeMapped = config('csv.import_roles.' . $name . '.mappable');
|
||||
|
||||
return true === $canBeMapped && true === $requested;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data necessary to show the configuration screen.
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
$config = $this->importJob->configuration;
|
||||
$columnConfig = $this->doColumnConfig($config);
|
||||
|
||||
// in order to actually map we also need to read the FULL file.
|
||||
try {
|
||||
$reader = $this->getReader();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
throw new FireflyException('Cannot get reader: ' . $e->getMessage());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// get ALL values for the mappable columns from the CSV file:
|
||||
$columnConfig = $this->getValuesForMapping($reader, $config, $columnConfig);
|
||||
|
||||
return $columnConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return the name of the pre-processor: a special class that will clean up any input that may be found
|
||||
* in the users input (aka the file uploaded). Only two examples exist at this time: a space or comma separated
|
||||
* list of tags.
|
||||
*
|
||||
* @param string $column
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPreProcessorName(string $column): string
|
||||
{
|
||||
$name = '';
|
||||
$hasPreProcess = config(sprintf('csv.import_roles.%s.pre-process-map', $column));
|
||||
$preProcessClass = config(sprintf('csv.import_roles.%s.pre-process-mapper', $column));
|
||||
|
||||
if (null !== $hasPreProcess && true === $hasPreProcess && null !== $preProcessClass) {
|
||||
$name = sprintf('FireflyIII\\Import\\MapperPreProcess\\%s', $preProcessClass);
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of a CSV file reader so content of the file can be read.
|
||||
*
|
||||
* @throws \League\Csv\Exception
|
||||
*/
|
||||
public function getReader(): Reader
|
||||
{
|
||||
$content = '';
|
||||
/** @var Collection $collection */
|
||||
$collection = $this->repository->getAttachments($this->importJob);
|
||||
/** @var Attachment $attachment */
|
||||
foreach ($collection as $attachment) {
|
||||
if ('import_file' === $attachment->filename) {
|
||||
$content = $this->attachments->getAttachmentContent($attachment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$reader = Reader::createFromString($content);
|
||||
$reader->setDelimiter($config['delimiter']);
|
||||
|
||||
return $reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the CSV file. For each row, check for each column:
|
||||
*
|
||||
* - If it can be mapped. And if so,
|
||||
* - Run the pre-processor
|
||||
* - Add the value to the list of "values" that the user must map.
|
||||
*
|
||||
* @param Reader $reader
|
||||
* @param array $config
|
||||
* @param array $columnConfig
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*
|
||||
*/
|
||||
public function getValuesForMapping(Reader $reader, array $config, array $columnConfig): array
|
||||
{
|
||||
$offset = isset($config['has-headers']) && true === $config['has-headers'] ? 1 : 0;
|
||||
try {
|
||||
$stmt = (new Statement)->offset($offset);
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
throw new FireflyException(sprintf('Could not create reader: %s', $e->getMessage()));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
$results = $stmt->process($reader);
|
||||
$mappableColumns = array_keys($columnConfig); // the actually columns that can be mapped.
|
||||
foreach ($results as $lineIndex => $line) {
|
||||
Log::debug(sprintf('Trying to collect values for line #%d', $lineIndex));
|
||||
$line = $this->applySpecifics($config, $line);
|
||||
|
||||
/** @var int $columnIndex */
|
||||
foreach ($mappableColumns as $columnIndex) { // this is simply 1, 2, 3, etc.
|
||||
if (!isset($line[$columnIndex])) {
|
||||
// don't need to handle this. Continue.
|
||||
continue;
|
||||
}
|
||||
$value = trim($line[$columnIndex]);
|
||||
if ('' === $value) {
|
||||
// value is empty, ignore it.
|
||||
continue;
|
||||
}
|
||||
$columnConfig[$columnIndex]['values'][] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// loop array again. This time, do uniqueness.
|
||||
// and remove arrays that have 0 values.
|
||||
foreach ($mappableColumns as $columnIndex) {
|
||||
$columnConfig[$columnIndex]['values'] = array_unique($columnConfig[$columnIndex]['values']);
|
||||
asort($columnConfig[$columnIndex]['values']);
|
||||
// if the count of this array is zero, there is nothing to map.
|
||||
if (0 === count($columnConfig[$columnIndex]['values'])) {
|
||||
unset($columnConfig[$columnIndex]); // @codeCoverageIgnore
|
||||
}
|
||||
}
|
||||
|
||||
return $columnConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* For each given column name, will return either the name (when it's a valid one)
|
||||
* or return the _ignore column.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sanitizeColumnName(string $name): string
|
||||
{
|
||||
/** @var array $validColumns */
|
||||
$validColumns = array_keys(config('csv.import_roles'));
|
||||
if (!in_array($name, $validColumns, true)) {
|
||||
$name = '_ignore';
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->columnConfig = [];
|
||||
}
|
||||
}
|
@@ -1,415 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ConfigureRolesHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\File;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Import\Specifics\SpecificInterface;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use League\Csv\Exception;
|
||||
use League\Csv\Reader;
|
||||
use League\Csv\Statement;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ConfigureRolesHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ConfigureRolesHandler implements FileConfigurationInterface
|
||||
{
|
||||
/** @var AttachmentHelperInterface */
|
||||
private $attachments;
|
||||
/** @var array */
|
||||
private $examples;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
/** @var int */
|
||||
private $totalColumns;
|
||||
|
||||
/**
|
||||
* Verifies that the configuration of the job is actually complete, and valid.
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return MessageBag
|
||||
*
|
||||
*/
|
||||
public function configurationComplete(array $config): MessageBag
|
||||
{
|
||||
/** @var array $roles */
|
||||
$roles = $config['column-roles'];
|
||||
$assigned = 0;
|
||||
|
||||
// check if data actually contains amount column (foreign amount does not count)
|
||||
$hasAmount = false;
|
||||
$hasForeignAmount = false;
|
||||
$hasForeignCode = false;
|
||||
foreach ($roles as $role) {
|
||||
if ('_ignore' !== $role) {
|
||||
++$assigned;
|
||||
}
|
||||
if (in_array($role, ['amount', 'amount_credit', 'amount_debit', 'amount_negated'])) {
|
||||
$hasAmount = true;
|
||||
}
|
||||
if ('foreign-currency-code' === $role) {
|
||||
$hasForeignCode = true;
|
||||
}
|
||||
if ('amount_foreign' === $role) {
|
||||
$hasForeignAmount = true;
|
||||
}
|
||||
}
|
||||
|
||||
// all assigned and correct foreign info
|
||||
if ($assigned > 0 && $hasAmount && ($hasForeignCode === $hasForeignAmount)) {
|
||||
return new MessageBag;
|
||||
}
|
||||
if (0 === $assigned || !$hasAmount) {
|
||||
$message = (string)trans('import.job_config_roles_rwarning');
|
||||
$messages = new MessageBag();
|
||||
$messages->add('error', $message);
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
// warn if has foreign amount but no currency code:
|
||||
if ($hasForeignAmount && !$hasForeignCode) {
|
||||
$message = (string)trans('import.job_config_roles_fa_warning');
|
||||
$messages = new MessageBag();
|
||||
$messages->add('error', $message);
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
|
||||
return new MessageBag; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/**
|
||||
* Store data associated with current stage.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
$config = $this->importJob->configuration;
|
||||
$count = $config['column-count'];
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$role = $data['role'][$i] ?? '_ignore';
|
||||
$mapping = (isset($data['map'][$i]) && '1' === $data['map'][$i]);
|
||||
$config['column-roles'][$i] = $role;
|
||||
$config['column-do-mapping'][$i] = $mapping;
|
||||
Log::debug(sprintf('Column %d has been given role %s (mapping: %s)', $i, $role, var_export($mapping, true)));
|
||||
}
|
||||
$config = $this->ignoreUnmappableColumns($config);
|
||||
$messages = $this->configurationComplete($config);
|
||||
|
||||
if (0 === $messages->count()) {
|
||||
$this->repository->setStage($this->importJob, 'ready_to_run');
|
||||
if ($this->isMappingNecessary($config)) {
|
||||
$this->repository->setStage($this->importJob, 'map');
|
||||
}
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts example data from a single row and store it in the class.
|
||||
*
|
||||
* @param array $line
|
||||
*/
|
||||
public function getExampleFromLine(array $line): void
|
||||
{
|
||||
foreach ($line as $column => $value) {
|
||||
$value = trim($value);
|
||||
if ('' != $value) {
|
||||
$this->examples[$column][] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExamples(): array
|
||||
{
|
||||
return $this->examples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a bunch of examples from the CSV file the user has uploaded.
|
||||
*
|
||||
* @param Reader $reader
|
||||
* @param array $config
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getExamplesFromFile(Reader $reader, array $config): void
|
||||
{
|
||||
$limit = (int)config('csv.example_rows', 5);
|
||||
$offset = isset($config['has-headers']) && true === $config['has-headers'] ? 1 : 0;
|
||||
|
||||
// make statement.
|
||||
try {
|
||||
$stmt = (new Statement)->limit($limit)->offset($offset);
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
throw new FireflyException($e->getMessage());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// grab the records:
|
||||
$records = $stmt->process($reader);
|
||||
/** @var array $line */
|
||||
foreach ($records as $line) {
|
||||
$line = array_values($line);
|
||||
$line = $this->processSpecifics($config, $line);
|
||||
$count = count($line);
|
||||
$this->totalColumns = $count > $this->totalColumns ? $count : $this->totalColumns;
|
||||
$this->getExampleFromLine($line);
|
||||
}
|
||||
// save column count:
|
||||
$this->saveColumCount();
|
||||
$this->makeExamplesUnique();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the header row, if one is present.
|
||||
*
|
||||
* @param Reader $reader
|
||||
* @param array $config
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getHeaders(Reader $reader, array $config): array
|
||||
{
|
||||
$headers = [];
|
||||
if (isset($config['has-headers']) && true === $config['has-headers']) {
|
||||
try {
|
||||
$stmt = (new Statement)->limit(1)->offset(0);
|
||||
$records = $stmt->process($reader);
|
||||
$headers = $records->fetchOne();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
throw new FireflyException($e->getMessage());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
Log::debug('Detected file headers:', $headers);
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data necessary to show the configuration screen.
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
try {
|
||||
$reader = $this->getReader();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
throw new FireflyException($e->getMessage());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
$configuration = $this->importJob->configuration;
|
||||
$headers = $this->getHeaders($reader, $configuration);
|
||||
|
||||
// get example rows:
|
||||
$this->getExamplesFromFile($reader, $configuration);
|
||||
|
||||
return [
|
||||
'examples' => $this->examples,
|
||||
'roles' => $this->getRoles(),
|
||||
'total' => $this->totalColumns,
|
||||
'headers' => $headers,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of a CSV file reader so content of the file can be read.
|
||||
*
|
||||
* @throws \League\Csv\Exception
|
||||
*/
|
||||
public function getReader(): Reader
|
||||
{
|
||||
$content = '';
|
||||
/** @var Collection $collection */
|
||||
$collection = $this->repository->getAttachments($this->importJob);
|
||||
/** @var Attachment $attachment */
|
||||
foreach ($collection as $attachment) {
|
||||
if ('import_file' === $attachment->filename) {
|
||||
$content = $this->attachments->getAttachmentContent($attachment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$reader = Reader::createFromString($content);
|
||||
$reader->setDelimiter($config['delimiter']);
|
||||
|
||||
return $reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all possible roles and translate their name. Then sort them.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public function getRoles(): array
|
||||
{
|
||||
$roles = [];
|
||||
foreach (array_keys(config('csv.import_roles')) as $role) {
|
||||
$roles[$role] = (string)trans('import.column_' . $role);
|
||||
}
|
||||
asort($roles);
|
||||
|
||||
return $roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user has checked columns that cannot be mapped to any value, this function will
|
||||
* uncheck them and return the configuration again.
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function ignoreUnmappableColumns(array $config): array
|
||||
{
|
||||
$count = $config['column-count'];
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$role = $config['column-roles'][$i] ?? '_ignore';
|
||||
$mapping = $config['column-do-mapping'][$i] ?? false;
|
||||
// if the column can be mapped depends on the config:
|
||||
$canMap = (bool)config(sprintf('csv.import_roles.%s.mappable', $role));
|
||||
$mapping = $mapping && $canMap;
|
||||
$config['column-do-mapping'][$i] = $mapping;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false when it's not necessary to map values. This saves time and is user friendly
|
||||
* (will skip to the next screen).
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMappingNecessary(array $config): bool
|
||||
{
|
||||
/** @var array $doMapping */
|
||||
$doMapping = $config['column-do-mapping'] ?? [];
|
||||
$toBeMapped = 0;
|
||||
foreach ($doMapping as $doMap) {
|
||||
if (true === $doMap) {
|
||||
++$toBeMapped;
|
||||
}
|
||||
}
|
||||
|
||||
return !(0 === $toBeMapped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the examples do not contain double data values.
|
||||
*/
|
||||
public function makeExamplesUnique(): void
|
||||
{
|
||||
foreach ($this->examples as $index => $values) {
|
||||
$this->examples[$index] = array_unique($values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if the user has configured specific fixes to be applied, they must be applied to the example data as well.
|
||||
*
|
||||
* @param array $config
|
||||
* @param array $line
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function processSpecifics(array $config, array $line): array
|
||||
{
|
||||
$validSpecifics = array_keys(config('csv.import_specifics'));
|
||||
$specifics = $config['specifics'] ?? [];
|
||||
$names = array_keys($specifics);
|
||||
foreach ($names as $name) {
|
||||
if (!in_array($name, $validSpecifics, true)) {
|
||||
continue;
|
||||
}
|
||||
/** @var SpecificInterface $specific */
|
||||
$specific = app('FireflyIII\Import\Specifics\\' . $name);
|
||||
$line = $specific->run($line);
|
||||
}
|
||||
|
||||
return $line;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the column count in the job. It's used in a later stage.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function saveColumCount(): void
|
||||
{
|
||||
$config = $this->importJob->configuration;
|
||||
$config['column-count'] = $this->totalColumns;
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set job and some start values.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->totalColumns = 0;
|
||||
$this->examples = [];
|
||||
}
|
||||
}
|
@@ -1,162 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ConfigureUploadHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\File;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
|
||||
/**
|
||||
* Class ConfigureUploadHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ConfigureUploadHandler implements FileConfigurationInterface
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepos;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Store data associated with current stage.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
$config = $this->importJob->configuration;
|
||||
$complete = true;
|
||||
|
||||
// collect values:
|
||||
$importId = isset($data['csv_import_account']) ? (int)$data['csv_import_account'] : 0;
|
||||
$delimiter = (string)$data['csv_delimiter'];
|
||||
$config['has-headers'] = 1 === (int)($data['has_headers'] ?? 0.0);
|
||||
$config['date-format'] = (string)$data['date_format'];
|
||||
$config['delimiter'] = 'tab' === $delimiter ? "\t" : $delimiter;
|
||||
$config['apply-rules'] = 1 === (int)($data['apply_rules'] ?? 0.0);
|
||||
$config['specifics'] = $this->getSpecifics($data);
|
||||
// validate values:
|
||||
$account = $this->accountRepos->findNull($importId);
|
||||
|
||||
// respond to invalid account:
|
||||
if (null === $account) {
|
||||
Log::error('Could not find anything for csv_import_account.', ['id' => $importId]);
|
||||
$complete = false;
|
||||
}
|
||||
if (null !== $account) {
|
||||
$config['import-account'] = $account->id;
|
||||
}
|
||||
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
if ($complete) {
|
||||
$this->repository->setStage($this->importJob, 'roles');
|
||||
}
|
||||
if (!$complete) {
|
||||
$messages = new MessageBag;
|
||||
$messages->add('account', (string)trans('import.invalid_import_account'));
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data necessary to show the configuration screen.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
$delimiters = [
|
||||
',' => (string)trans('form.csv_comma'),
|
||||
';' => (string)trans('form.csv_semicolon'),
|
||||
'tab' => (string)trans('form.csv_tab'),
|
||||
];
|
||||
$config = $this->importJob->configuration;
|
||||
$config['date-format'] = $config['date-format'] ?? 'Ymd';
|
||||
$specifics = [];
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
|
||||
// collect specifics.
|
||||
foreach (config('csv.import_specifics') as $name => $className) {
|
||||
$specifics[$name] = [
|
||||
'name' => trans($className::getName()),
|
||||
'description' => trans($className::getDescription()),
|
||||
];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'accounts' => [],
|
||||
'delimiters' => $delimiters,
|
||||
'specifics' => $specifics,
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSpecifics(array $data): array
|
||||
{
|
||||
$return = [];
|
||||
// check if specifics given are correct:
|
||||
if (isset($data['specifics']) && is_array($data['specifics'])) {
|
||||
|
||||
foreach ($data['specifics'] as $name) {
|
||||
// verify their content.
|
||||
$className = sprintf('FireflyIII\\Import\\Specifics\\%s', $name);
|
||||
if (class_exists($className)) {
|
||||
$return[$name] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
$this->accountRepos->setUser($importJob->user);
|
||||
|
||||
}
|
||||
}
|
@@ -1,55 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FileConfigurationInterface.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\File;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* Class FileConfigurationInterface.
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
interface FileConfigurationInterface
|
||||
{
|
||||
/**
|
||||
* 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;
|
||||
}
|
@@ -1,207 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* NewFileJobHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\File;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class NewFileJobHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class NewFileJobHandler implements FileConfigurationInterface
|
||||
{
|
||||
/** @var AttachmentHelperInterface */
|
||||
private $attachments;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Store data associated with current stage.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
// nothing to store, validate upload
|
||||
// and push to next stage.
|
||||
$messages = $this->validateAttachments();
|
||||
|
||||
if ($messages->count() > 0) {
|
||||
return $messages;
|
||||
}
|
||||
|
||||
// store config if it's in one of the attachments.
|
||||
$this->storeConfiguration();
|
||||
|
||||
// set file type in config:
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$config['file-type'] = $data['import_file_type'];
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
$this->repository->setStage($this->importJob, 'configure-upload');
|
||||
|
||||
return new MessageBag();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the data necessary to show the configuration screen.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
/** @var array $allowedTypes */
|
||||
$allowedTypes = config('import.options.file.import_formats');
|
||||
$importFileTypes = [];
|
||||
$defaultImportType = config('import.options.file.default_import_format');
|
||||
foreach ($allowedTypes as $type) {
|
||||
$importFileTypes[$type] = (string)trans('import.import_file_type_' . $type);
|
||||
}
|
||||
|
||||
return [
|
||||
'default_type' => $defaultImportType,
|
||||
'file_types' => $importFileTypes,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store config from job.
|
||||
*
|
||||
*/
|
||||
public function storeConfiguration(): void
|
||||
{
|
||||
/** @var Collection $attachments */
|
||||
$attachments = $this->repository->getAttachments($this->importJob);
|
||||
/** @var Attachment $attachment */
|
||||
foreach ($attachments as $attachment) {
|
||||
// if file is configuration file, store it into the job.
|
||||
if ('configuration_file' === $attachment->filename) {
|
||||
$this->storeConfig($attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all attachments are UTF8.
|
||||
*
|
||||
* @return MessageBag
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function validateAttachments(): MessageBag
|
||||
{
|
||||
$messages = new MessageBag;
|
||||
/** @var Collection $attachments */
|
||||
$attachments = $this->repository->getAttachments($this->importJob);
|
||||
/** @var Attachment $attachment */
|
||||
foreach ($attachments as $attachment) {
|
||||
|
||||
// check if content is UTF8:
|
||||
if (!$this->isUTF8($attachment)) {
|
||||
$message = (string)trans('import.file_not_utf8');
|
||||
Log::error($message);
|
||||
$messages->add('import_file', $message);
|
||||
// delete attachment:
|
||||
try {
|
||||
$attachment->delete();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
throw new FireflyException(sprintf('Could not delete attachment: %s', $e->getMessage()));
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
// if file is configuration file, store it into the job.
|
||||
if ('configuration_file' === $attachment->filename) {
|
||||
$this->storeConfig($attachment);
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isUTF8(Attachment $attachment): bool
|
||||
{
|
||||
$content = $this->attachments->getAttachmentContent($attachment);
|
||||
$result = mb_detect_encoding($content, 'UTF-8', true);
|
||||
if (false === $result) {
|
||||
return false;
|
||||
}
|
||||
if ('ASCII' !== $result && 'UTF-8' !== $result) {
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take attachment, extract config, and put in job.\
|
||||
*
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
*/
|
||||
private function storeConfig(Attachment $attachment): void
|
||||
{
|
||||
$content = $this->attachments->getAttachmentContent($attachment);
|
||||
$json = json_decode($content, true);
|
||||
if (null !== $json) {
|
||||
$this->repository->setConfiguration($this->importJob, $json);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,124 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ChooseAccountHandler.php
|
||||
* Copyright (c) 2019 https://github.com/bnw
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://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\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\FinTS\FinTS;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* Class ChooseAccountHandler
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class ChooseAccountHandler implements FinTSConfigurationInterface
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Store data associated with current stage.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$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' => $config]);
|
||||
$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
|
||||
*/
|
||||
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 .= sprintf(' - %s', $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);
|
||||
}
|
||||
}
|
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FinTSConfigurationInterface.php
|
||||
* Copyright (c) 2019 https://github.com/bnw
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\FinTS;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
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;
|
||||
}
|
@@ -1,131 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* NewFinTSJobHandler.php
|
||||
* Copyright (c) 2019 https://github.com/bnw
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://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
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class NewFinTSJobHandler implements FinTSConfigurationInterface
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Store data associated with current stage.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
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']) ?? ''); // verified
|
||||
$config['apply-rules'] = 1 === (int)($data['apply_rules'] ?? 0);
|
||||
|
||||
// sanitize FinTS URL.
|
||||
$config['fints_url'] = $this->validURI($config['fints_url']) ? $config['fints_url'] : '';
|
||||
|
||||
$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 (true !== ($checkConnection = $finTS->checkConnection())) {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fints_url
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validURI(string $fintsUri): bool
|
||||
{
|
||||
$res = filter_var($fintsUri, FILTER_VALIDATE_URL);
|
||||
if (false === $res) {
|
||||
return false;
|
||||
}
|
||||
$scheme = parse_url($fintsUri, PHP_URL_SCHEME);
|
||||
|
||||
return 'https' === $scheme;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,96 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* AuthenticatedHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Spectre;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class AuthenticatedHandler
|
||||
* @deprecated
|
||||
*/
|
||||
class AuthenticatedHandler implements SpectreJobConfigurationInterface
|
||||
{
|
||||
/**
|
||||
* Return true when this stage is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
Log::debug('AuthenticatedConfigHandler::configurationComplete() always returns true');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the job configuration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
Log::debug('AuthenticatedConfigHandler::configureJob() always returns empty message bag');
|
||||
|
||||
return new MessageBag();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for config view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
Log::debug('AuthenticatedConfigHandler::getNextData() always returns []');
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
Log::debug('AuthenticatedConfigHandler::getNextView() always returns ""');
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,255 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ChooseAccountsHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Spectre;
|
||||
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account as AccountModel;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Services\Spectre\Object\Account as SpectreAccount;
|
||||
use FireflyIII\Services\Spectre\Object\Login;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ChooseAccountsHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ChooseAccountsHandler implements SpectreJobConfigurationInterface
|
||||
{
|
||||
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $currencyRepository;
|
||||
/** @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 ChooseAccountsHandler::configurationComplete()');
|
||||
$config = $this->importJob->configuration;
|
||||
$importAccounts = $config['account_mapping'] ?? [];
|
||||
$complete = count($importAccounts) > 0 && $importAccounts !== [0 => 0];
|
||||
if ($complete) {
|
||||
Log::debug('Looks like user has mapped import accounts to Firefly III accounts', $importAccounts);
|
||||
$this->repository->setStage($this->importJob, 'go-for-import');
|
||||
}
|
||||
|
||||
return $complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the job configuration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
Log::debug('Now in ChooseAccountsHandler::configureJob()', $data);
|
||||
$config = $this->importJob->configuration;
|
||||
$mapping = $data['account_mapping'] ?? [];
|
||||
$final = [];
|
||||
$applyRules = 1 === (int)($data['apply_rules'] ?? 0);
|
||||
foreach ($mapping as $spectreId => $localId) {
|
||||
// validate each
|
||||
$spectreId = $this->validSpectreAccount((int)$spectreId);
|
||||
$accountId = $this->validLocalAccount((int)$localId);
|
||||
$final[$spectreId] = $accountId;
|
||||
|
||||
}
|
||||
Log::debug('Final mapping is:', $final);
|
||||
$messages = new MessageBag;
|
||||
$config['account_mapping'] = $final;
|
||||
$config['apply-rules'] = $applyRules;
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
if ($final === [0 => 0] || 0 === count($final)) {
|
||||
$messages->add('count', (string)trans('import.spectre_no_mapping'));
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for config view.
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
Log::debug('Now in ChooseAccountsHandler::getnextData()');
|
||||
$config = $this->importJob->configuration;
|
||||
$accounts = $config['accounts'] ?? [];
|
||||
if (0 === count($accounts)) {
|
||||
throw new FireflyException('It seems you have no accounts with this bank. The import cannot continue.'); // @codeCoverageIgnore
|
||||
}
|
||||
$converted = [];
|
||||
foreach ($accounts as $accountArray) {
|
||||
$converted[] = new SpectreAccount($accountArray);
|
||||
}
|
||||
|
||||
// get the provider that was used.
|
||||
$login = null;
|
||||
$logins = $config['all-logins'] ?? [];
|
||||
$selected = $config['selected-login'] ?? 0;
|
||||
if (0 === count($logins)) {
|
||||
throw new FireflyException('It seems you have no configured logins in this import job. The import cannot continue.'); // @codeCoverageIgnore
|
||||
}
|
||||
Log::debug(sprintf('Selected login to use is %d', $selected));
|
||||
if (0 === $selected) {
|
||||
$login = new Login($logins[0]);
|
||||
Log::debug(sprintf('Will use login %d (%s %s)', $login->getId(), $login->getProviderName(), $login->getCountryCode()));
|
||||
}
|
||||
if (0 !== $selected) {
|
||||
foreach ($logins as $loginArray) {
|
||||
$loginId = $loginArray['id'] ?? -1;
|
||||
if ($loginId === $selected) {
|
||||
$login = new Login($loginArray);
|
||||
Log::debug(sprintf('Will use login %d (%s %s)', $login->getId(), $login->getProviderName(), $login->getCountryCode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (null === $login) {
|
||||
throw new FireflyException('Was not able to determine which login to use. The import cannot continue.'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// list the users accounts:
|
||||
$accounts = $this->accountRepository->getAccountsByType([AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE]);
|
||||
|
||||
$array = [];
|
||||
/** @var AccountModel $account */
|
||||
foreach ($accounts as $account) {
|
||||
$accountId = $account->id;
|
||||
// TODO we can use getAccountCurrency() instead
|
||||
$currencyId = (int)$this->accountRepository->getMetaValue($account, 'currency_id');
|
||||
$currency = $this->getCurrency($currencyId);
|
||||
$array[$accountId] = [
|
||||
'name' => $account->name,
|
||||
'iban' => $account->iban,
|
||||
'code' => $currency->code,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'accounts' => $converted,
|
||||
'ff_accounts' => $array,
|
||||
'login' => $login,
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
return 'import.spectre.accounts';
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->currencyRepository->setUser($importJob->user);
|
||||
$this->accountRepository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $currencyId
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
private function getCurrency(int $currencyId): TransactionCurrency
|
||||
{
|
||||
$currency = $this->currencyRepository->findNull($currencyId);
|
||||
if (null === $currency) {
|
||||
return app('amount')->getDefaultCurrencyByUser($this->importJob->user);
|
||||
}
|
||||
|
||||
return $currency;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $accountId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function validLocalAccount(int $accountId): int
|
||||
{
|
||||
$account = $this->accountRepository->findNull($accountId);
|
||||
if (null === $account) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $accountId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $accountId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function validSpectreAccount(int $accountId): int
|
||||
{
|
||||
$config = $this->importJob->configuration;
|
||||
$accounts = $config['accounts'] ?? [];
|
||||
foreach ($accounts as $account) {
|
||||
if ((int)$account['id'] === $accountId) {
|
||||
return $accountId;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
@@ -1,146 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ChooseLoginHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Spectre;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Services\Spectre\Object\Login;
|
||||
use FireflyIII\Support\Import\Information\GetSpectreCustomerTrait;
|
||||
use FireflyIII\Support\Import\Information\GetSpectreTokenTrait;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
|
||||
/**
|
||||
* Class ChooseLoginHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ChooseLoginHandler implements SpectreJobConfigurationInterface
|
||||
{
|
||||
use GetSpectreCustomerTrait, GetSpectreTokenTrait;
|
||||
/** @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 ChooseLoginHandler::configurationComplete()');
|
||||
$config = $this->importJob->configuration;
|
||||
if (isset($config['selected-login'])) {
|
||||
Log::debug('config[selected-login] is set, return true.');
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug('config[selected-login] is not set, return false.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the job configuration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
Log::debug('Now in ChooseLoginHandler::configureJob()');
|
||||
$selectedLogin = (int)($data['spectre_login_id'] ?? 0.0);
|
||||
$config = $this->importJob->configuration;
|
||||
$config['selected-login'] = $selectedLogin;
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
Log::debug(sprintf('The selected login by the user is #%d', $selectedLogin));
|
||||
|
||||
// if selected login is zero, create a new one.
|
||||
if (0 === $selectedLogin) {
|
||||
Log::debug('Login is zero, get Spectre customer + token and store it in config.');
|
||||
$customer = $this->getCustomer($this->importJob);
|
||||
// get a token for the user and redirect to next stage
|
||||
$token = $this->getToken($this->importJob, $customer);
|
||||
$config['customer'] = $customer->toArray();
|
||||
$config['token'] = $token->toArray();
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
// move job to correct stage to redirect to Spectre:
|
||||
$this->repository->setStage($this->importJob, 'do-authenticate');
|
||||
|
||||
return new MessageBag;
|
||||
|
||||
}
|
||||
$this->repository->setStage($this->importJob, 'authenticated');
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for config view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
Log::debug('Now in ChooseLoginHandler::getNextData()');
|
||||
$config = $this->importJob->configuration;
|
||||
$data = ['logins' => []];
|
||||
$logins = $config['all-logins'] ?? [];
|
||||
Log::debug(sprintf('Count of logins in configuration is %d.', count($logins)));
|
||||
foreach ($logins as $login) {
|
||||
$data['logins'][] = new Login($login);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
return 'import.spectre.choose-login';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
@@ -1,130 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* DoAuthenticateHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Spectre;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Services\Spectre\Object\Token;
|
||||
use FireflyIII\Support\Import\Information\GetSpectreCustomerTrait;
|
||||
use FireflyIII\Support\Import\Information\GetSpectreTokenTrait;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class AuthenticateConfig
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class DoAuthenticateHandler implements SpectreJobConfigurationInterface
|
||||
{
|
||||
use GetSpectreTokenTrait, GetSpectreCustomerTrait;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Return true when this stage is complete.
|
||||
*
|
||||
* always returns false.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
Log::debug('DoAuthenticateHandler::configurationComplete() will always return false');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Store the job configuration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
Log::debug('DoAuthenticateHandler::configureJob() will do nothing.');
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for config view.
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
Log::debug('Now in DoAuthenticateHandler::getNextData()');
|
||||
|
||||
// getNextData() only makes sure the job is ready for the next stage.
|
||||
$this->repository->setStatus($this->importJob, 'ready_to_run');
|
||||
$this->repository->setStage($this->importJob, 'authenticated');
|
||||
|
||||
// get token from configuration:
|
||||
$config = $this->importJob->configuration;
|
||||
$token = isset($config['token']) ? new Token($config['token']) : null;
|
||||
|
||||
if (null === $token) {
|
||||
// get a new one from Spectre:
|
||||
Log::debug('No existing token, get a new one.');
|
||||
// get a new token from Spectre.
|
||||
$customer = $this->getCustomer($this->importJob);
|
||||
$token = $this->getToken($this->importJob, $customer);
|
||||
}
|
||||
|
||||
return ['token-url' => $token->getConnectUrl()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
return 'import.spectre.redirect';
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* 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);
|
||||
}
|
||||
}
|
@@ -1,98 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* NewSpectreJobHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Spectre;
|
||||
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class NewSpectreJobHandler
|
||||
* @deprecated
|
||||
*/
|
||||
class NewSpectreJobHandler implements SpectreJobConfigurationInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Return true when this stage is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
Log::debug('NewSpectreJobHandler::configurationComplete() always returns true');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the job configuration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
Log::debug('NewSpectreJobHandler::configureJob() always returns an empty message bag');
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for config view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
Log::debug('NewSpectreJobHandler::getNextData() always returns []');
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
Log::debug('NewSpectreJobHandler::getNextView() always returns ""');
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,75 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SpectreJobConfigurationInterface.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Spectre;
|
||||
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* Interface SpectreJobConfigurationInterface
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
interface SpectreJobConfigurationInterface
|
||||
{
|
||||
/**
|
||||
* 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;
|
||||
|
||||
}
|
@@ -1,260 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* NewYnabJobHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://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
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
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
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
*/
|
||||
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 \Psr\Container\NotFoundExceptionInterface
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @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
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@@ -1,241 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SelectAccountsHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Ynab;
|
||||
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class SelectAccountsHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class SelectAccountsHandler implements YnabJobConfigurationInterface
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $currencyRepository;
|
||||
/** @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 SelectAccountsHandler::configurationComplete()');
|
||||
$config = $this->importJob->configuration;
|
||||
$mapping = $config['mapping'] ?? [];
|
||||
if (count($mapping) > 0) {
|
||||
// mapping is complete.
|
||||
Log::debug('Looks like user has mapped YNAB accounts to Firefly III accounts', $mapping);
|
||||
$this->repository->setStage($this->importJob, 'go-for-import');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the job configuration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
Log::debug('Now in SelectAccountsHandler::configureJob()', $data);
|
||||
$config = $this->importJob->configuration;
|
||||
$mapping = $data['account_mapping'] ?? [];
|
||||
$final = [];
|
||||
$applyRules = 1 === (int)($data['apply_rules'] ?? 0);
|
||||
foreach ($mapping as $ynabId => $localId) {
|
||||
// validate each
|
||||
$ynabId = $this->validYnabAccount($ynabId);
|
||||
$accountId = $this->validLocalAccount((int)$localId);
|
||||
if (0 !== $accountId) {
|
||||
$final[$ynabId] = $accountId;
|
||||
}
|
||||
}
|
||||
Log::debug('Final mapping is:', $final);
|
||||
$messages = new MessageBag;
|
||||
$config['mapping'] = $final;
|
||||
$config['apply-rules'] = $applyRules;
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
if ($final === ['' => 0] || 0 === count($final)) {
|
||||
$messages->add('count', (string)trans('import.ynab_no_mapping'));
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for config view.
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
|
||||
Log::debug('Now in ChooseAccountsHandler::getnextData()');
|
||||
$config = $this->importJob->configuration;
|
||||
$ynabAccounts = $config['accounts'] ?? [];
|
||||
$budget = $this->getSelectedBudget();
|
||||
if (0 === count($ynabAccounts)) {
|
||||
throw new FireflyException('It seems you have no accounts with this budget. The import cannot continue.'); // @codeCoverageIgnore
|
||||
}
|
||||
// list the users accounts:
|
||||
$ffAccounts = $this->accountRepository->getAccountsByType([AccountType::ASSET]);
|
||||
|
||||
$array = [];
|
||||
/** @var Account $account */
|
||||
foreach ($ffAccounts as $account) {
|
||||
$accountId = $account->id;
|
||||
// TODO we can use getAccountCurrency() instead
|
||||
$currencyId = (int)$this->accountRepository->getMetaValue($account, 'currency_id');
|
||||
$currency = $this->getCurrency($currencyId);
|
||||
$array[$accountId] = [
|
||||
'name' => $account->name,
|
||||
'iban' => $account->iban,
|
||||
'code' => $currency->code,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'budget' => $budget,
|
||||
'ynab_accounts' => $ynabAccounts,
|
||||
'ff_accounts' => $array,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
return 'import.ynab.accounts';
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->currencyRepository->setUser($importJob->user);
|
||||
$this->accountRepository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $currencyId
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
private function getCurrency(int $currencyId): TransactionCurrency
|
||||
{
|
||||
$currency = $this->currencyRepository->findNull($currencyId);
|
||||
if (null === $currency) {
|
||||
return app('amount')->getDefaultCurrencyByUser($this->importJob->user);
|
||||
}
|
||||
|
||||
return $currency;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getSelectedBudget(): array
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$budgets = $config['budgets'] ?? [];
|
||||
$selected = $config['selected_budget'] ?? '';
|
||||
foreach ($budgets as $budget) {
|
||||
if ($budget['id'] === $selected) {
|
||||
return $budget;
|
||||
}
|
||||
}
|
||||
|
||||
return $budgets[0] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $accountId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function validLocalAccount(int $accountId): int
|
||||
{
|
||||
$account = $this->accountRepository->findNull($accountId);
|
||||
if (null === $account) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $accountId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $accountId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function validYnabAccount(string $accountId): string
|
||||
{
|
||||
$config = $this->importJob->configuration;
|
||||
$accounts = $config['accounts'] ?? [];
|
||||
foreach ($accounts as $account) {
|
||||
if ($account['id'] === $accountId) {
|
||||
return $accountId;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
@@ -1,187 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SelectBudgetHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Ynab;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class SelectBudgetHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class SelectBudgetHandler implements YnabJobConfigurationInterface
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
/** @var Collection */
|
||||
private $accounts;
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $currencyRepository;
|
||||
/** @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 SelectBudgetHandler::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 SelectBudgetHandler::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 SelectBudgetHandler::getNextData');
|
||||
$configuration = $this->repository->getConfiguration($this->importJob);
|
||||
$budgets = $configuration['budgets'] ?? [];
|
||||
$available = [];
|
||||
$notAvailable = [];
|
||||
$total = count($budgets);
|
||||
foreach ($budgets as $budget) {
|
||||
if ($this->haveAssetWithCurrency($budget['currency_code'])) {
|
||||
Log::debug('Add budget to available list.');
|
||||
$available[$budget['id']] = $budget['name'] . ' (' . $budget['currency_code'] . ')';
|
||||
continue;
|
||||
}
|
||||
Log::debug('Add budget to notAvailable list.');
|
||||
$notAvailable[$budget['id']] = $budget['name'] . ' (' . $budget['currency_code'] . ')';
|
||||
|
||||
}
|
||||
|
||||
return [
|
||||
'available' => $available,
|
||||
'not_available' => $notAvailable,
|
||||
'total' => $total,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view for this stage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
Log::debug('Now in SelectBudgetHandler::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->currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->currencyRepository->setUser($importJob->user);
|
||||
$this->accountRepository->setUser($importJob->user);
|
||||
|
||||
$this->accounts = $this->accountRepository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function haveAssetWithCurrency(string $code): bool
|
||||
{
|
||||
$currency = $this->currencyRepository->findByCodeNull($code);
|
||||
if (null === $currency) {
|
||||
Log::debug(sprintf('No currency X found with code "%s"', $code));
|
||||
|
||||
return false;
|
||||
}
|
||||
/** @var Account $account */
|
||||
foreach ($this->accounts as $account) {
|
||||
// TODO we can use getAccountCurrency() instead
|
||||
$currencyId = (int)$this->accountRepository->getMetaValue($account, 'currency_id');
|
||||
Log::debug(sprintf('Currency of %s is %d (looking for %d).', $account->name, $currencyId, $currency->id));
|
||||
if ($currencyId === $currency->id) {
|
||||
Log::debug('Return true!');
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Log::debug('Found nothing, return false.');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -1,73 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* YnabJobConfigurationInterface.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\JobConfiguration\Ynab;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* Interface YnabJobConfigurationInterface
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
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;
|
||||
}
|
@@ -1,116 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ColumnValue.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Placeholder;
|
||||
|
||||
/**
|
||||
* Class ColumnValue
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class ColumnValue
|
||||
{
|
||||
/** @var int */
|
||||
private $mappedValue;
|
||||
/** @var string */
|
||||
private $originalRole;
|
||||
/** @var string */
|
||||
private $role;
|
||||
/** @var string */
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* ColumnValue constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->mappedValue = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMappedValue(): int
|
||||
{
|
||||
return $this->mappedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $mappedValue
|
||||
*/
|
||||
public function setMappedValue(int $mappedValue): void
|
||||
{
|
||||
$this->mappedValue = $mappedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOriginalRole(): string
|
||||
{
|
||||
return $this->originalRole;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $originalRole
|
||||
*/
|
||||
public function setOriginalRole(string $originalRole): void
|
||||
{
|
||||
$this->originalRole = $originalRole;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRole(): string
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $role
|
||||
*/
|
||||
public function setRole(string $role): void
|
||||
{
|
||||
$this->role = $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setValue(string $value): void
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,446 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ImportTransaction.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Placeholder;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Import\Converter\Amount;
|
||||
use FireflyIII\Import\Converter\AmountCredit;
|
||||
use FireflyIII\Import\Converter\AmountDebit;
|
||||
use FireflyIII\Import\Converter\AmountNegated;
|
||||
use FireflyIII\Import\Converter\ConverterInterface;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ImportTransaction
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class ImportTransaction
|
||||
{
|
||||
/** @var string */
|
||||
public $accountBic;
|
||||
/** @var string */
|
||||
public $accountIban;
|
||||
/** @var int */
|
||||
public $accountId;
|
||||
/** @var string */
|
||||
public $accountName;
|
||||
/** @var string */
|
||||
public $accountNumber;
|
||||
/** @var string */
|
||||
public $amount;
|
||||
/** @var string */
|
||||
public $amountCredit;
|
||||
/** @var string */
|
||||
public $amountDebit;
|
||||
/** @var string */
|
||||
public $amountNegated;
|
||||
/** @var int */
|
||||
public $billId;
|
||||
/** @var string */
|
||||
public $billName;
|
||||
/** @var int */
|
||||
public $budgetId;
|
||||
/** @var string */
|
||||
public $budgetName;
|
||||
/** @var int */
|
||||
public $categoryId;
|
||||
/** @var string */
|
||||
public $categoryName;
|
||||
/** @var string */
|
||||
public $currencyCode;
|
||||
/** @var int */
|
||||
public $currencyId;
|
||||
/** @var string */
|
||||
public $currencyName;
|
||||
/** @var string */
|
||||
public $currencySymbol;
|
||||
/** @var string */
|
||||
public $date;
|
||||
/** @var string */
|
||||
public $description;
|
||||
/** @var string */
|
||||
public $externalId;
|
||||
/** @var string */
|
||||
public $foreignAmount;
|
||||
/** @var string */
|
||||
public $foreignCurrencyCode;
|
||||
/** @var int */
|
||||
public $foreignCurrencyId;
|
||||
/** @var array */
|
||||
public $meta;
|
||||
/** @var array */
|
||||
public $modifiers;
|
||||
/** @var string */
|
||||
public $note;
|
||||
/** @var string */
|
||||
public $opposingBic;
|
||||
/** @var string */
|
||||
public $opposingIban;
|
||||
/** @var int */
|
||||
public $opposingId;
|
||||
/** @var string */
|
||||
public $opposingName;
|
||||
/** @var string */
|
||||
public $opposingNumber;
|
||||
/** @var array */
|
||||
public $tags;
|
||||
|
||||
/**
|
||||
* ImportTransaction constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->tags = [];
|
||||
$this->modifiers = [];
|
||||
$this->meta = [];
|
||||
$this->description = '';
|
||||
$this->note = '';
|
||||
|
||||
// mappable items, set to 0:
|
||||
$this->accountId = 0;
|
||||
$this->budgetId = 0;
|
||||
$this->billId = 0;
|
||||
$this->currencyId = 0;
|
||||
$this->categoryId = 0;
|
||||
$this->foreignCurrencyId = 0;
|
||||
$this->opposingId = 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ColumnValue $columnValue
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
*/
|
||||
public function addColumnValue(ColumnValue $columnValue): void
|
||||
{
|
||||
$role = $columnValue->getRole();
|
||||
$basics = [
|
||||
'account-iban' => 'accountIban',
|
||||
'account-name' => 'accountName',
|
||||
'account-bic' => 'accountBic',
|
||||
'account-number' => 'accountNumber',
|
||||
'amount_debit' => 'amountDebit',
|
||||
'amount_credit' => 'amountCredit',
|
||||
'amount_negated' => 'amountNegated',
|
||||
'amount' => 'amount',
|
||||
'amount_foreign' => 'foreignAmount',
|
||||
'bill-name' => 'billName',
|
||||
'budget-name' => 'budgetName',
|
||||
'category-name' => 'categoryName',
|
||||
'currency-name' => 'currencyName',
|
||||
'currency-code' => 'currencyCode',
|
||||
'currency-symbol' => 'currencySymbol',
|
||||
'external-id' => 'externalId',
|
||||
'foreign-currency-code' => 'foreignCurrencyCode',
|
||||
'date-transaction' => 'date',
|
||||
'opposing-iban' => 'opposingIban',
|
||||
'opposing-name' => 'opposingName',
|
||||
'opposing-bic' => 'opposingBic',
|
||||
'opposing-number' => 'opposingNumber',
|
||||
];
|
||||
|
||||
$replaceOldRoles = [
|
||||
'original-source' => 'original_source',
|
||||
'sepa-cc' => 'sepa_cc',
|
||||
'sepa-ct-op' => 'sepa_ct_op',
|
||||
'sepa-ct-id' => 'sepa_ct_id',
|
||||
'sepa-db' => 'sepa_db',
|
||||
'sepa-country' => 'sepa_country',
|
||||
'sepa-ep' => 'sepa_ep',
|
||||
'sepa-ci' => 'sepa_ci',
|
||||
'sepa-batch-id' => 'sepa_batch_id',
|
||||
'internal-reference' => 'internal_reference',
|
||||
'date-interest' => 'date_interest',
|
||||
'date-invoice' => 'date_invoice',
|
||||
'date-book' => 'date_book',
|
||||
'date-payment' => 'date_payment',
|
||||
'date-process' => 'date_process',
|
||||
'date-due' => 'date_due',
|
||||
];
|
||||
if (array_key_exists($role, $replaceOldRoles)) {
|
||||
$role = $replaceOldRoles[$role];
|
||||
}
|
||||
|
||||
if (isset($basics[$role])) {
|
||||
$field = $basics[$role];
|
||||
$this->$field = $columnValue->getValue();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$mapped = [
|
||||
'account-id' => 'accountId',
|
||||
'bill-id' => 'billId',
|
||||
'budget-id' => 'budgetId',
|
||||
'category-id' => 'categoryId',
|
||||
'currency-id' => 'currencyId',
|
||||
'foreign-currency-id' => 'foreignCurrencyId',
|
||||
'opposing-id' => 'opposingId',
|
||||
];
|
||||
if (isset($mapped[$role])) {
|
||||
$field = $mapped[$role];
|
||||
$mappedValue = $this->getMappedValue($columnValue);
|
||||
$this->$field = $mappedValue;
|
||||
Log::debug(sprintf('Going to set the %s. Original value is "%s", mapped value is "%s".', $role, $columnValue->getValue(), $mappedValue));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$meta = ['sepa_ct_id', 'sepa_ct_op', 'sepa_db', 'sepa_cc', 'sepa_country', 'sepa_batch_id', 'sepa_ep', 'sepa_ci', 'internal_reference', 'date_interest',
|
||||
'date_invoice', 'date_book', 'date_payment', 'date_process', 'date_due', 'original_source'];
|
||||
Log::debug(sprintf('Now going to check role "%s".', $role));
|
||||
if (in_array($role, $meta, true)) {
|
||||
Log::debug(sprintf('Role "%s" is in allowed meta roles, so store its value "%s".', $role, $columnValue->getValue()));
|
||||
$this->meta[$role] = $columnValue->getValue();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$modifiers = ['generic-debit-credit', 'ing-debit-credit', 'rabo-debit-credit'];
|
||||
if (in_array($role, $modifiers, true)) {
|
||||
$this->modifiers[$role] = $columnValue->getValue();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($role) {
|
||||
default:
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException(
|
||||
sprintf('ImportTransaction cannot handle role "%s" with value "%s"', $role, $columnValue->getValue())
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
case 'description':
|
||||
$this->description = trim($this->description . ' ' . $columnValue->getValue());
|
||||
break;
|
||||
case 'note':
|
||||
$this->note = trim($this->note . ' ' . $columnValue->getValue());
|
||||
break;
|
||||
case 'tags-comma':
|
||||
$tags = explode(',', $columnValue->getValue());
|
||||
$this->tags = array_unique(array_merge($this->tags, $tags));
|
||||
break;
|
||||
case 'tags-space':
|
||||
$tags = explode(' ', $columnValue->getValue());
|
||||
$this->tags = array_unique(array_merge($this->tags, $tags));
|
||||
break;
|
||||
case '_ignore':
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the amount of this transaction.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function calculateAmount(): string
|
||||
{
|
||||
Log::debug('Now in importTransaction->calculateAmount()');
|
||||
$info = $this->selectAmountInput();
|
||||
$class = $info['class'] ?? '';
|
||||
if ('' === $class) {
|
||||
Log::error('No amount information (conversion class) for this row.');
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Converter class is %s', $info['class']));
|
||||
/** @var ConverterInterface $amountConverter */
|
||||
$amountConverter = app($info['class']);
|
||||
$result = $amountConverter->convert($info['amount']);
|
||||
Log::debug(sprintf('First attempt to convert gives "%s"', $result));
|
||||
// modify
|
||||
/**
|
||||
* @var string $role
|
||||
* @var string $modifier
|
||||
*/
|
||||
foreach ($this->modifiers as $role => $modifier) {
|
||||
$class = sprintf('FireflyIII\\Import\\Converter\\%s', config(sprintf('csv.import_roles.%s.converter', $role)));
|
||||
/** @var ConverterInterface $converter */
|
||||
$converter = app($class);
|
||||
Log::debug(sprintf('Now launching converter %s', $class));
|
||||
$conversion = $converter->convert($modifier);
|
||||
if ($conversion === -1) {
|
||||
$result = app('steam')->negative($result);
|
||||
}
|
||||
if (1 === $conversion) {
|
||||
$result = app('steam')->positive($result);
|
||||
}
|
||||
Log::debug(sprintf('convertedAmount after conversion is %s', $result));
|
||||
}
|
||||
|
||||
Log::debug(sprintf('After modifiers the result is: "%s"', $result));
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The method that calculates the foreign amount isn't nearly as complex,\
|
||||
* because Firefly III only supports one foreign amount field. So the foreign amount is there
|
||||
* or isn't. That's about it. However, if it's there, modifiers will be applied too.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function calculateForeignAmount(): string
|
||||
{
|
||||
if (null === $this->foreignAmount) {
|
||||
Log::debug('ImportTransaction holds no foreign amount info.');
|
||||
|
||||
return '';
|
||||
}
|
||||
/** @var ConverterInterface $amountConverter */
|
||||
$amountConverter = app(Amount::class);
|
||||
$result = $amountConverter->convert($this->foreignAmount);
|
||||
Log::debug(sprintf('First attempt to convert foreign amount gives "%s"', $result));
|
||||
/**
|
||||
* @var string $role
|
||||
* @var string $modifier
|
||||
*/
|
||||
foreach ($this->modifiers as $role => $modifier) {
|
||||
$class = sprintf('FireflyIII\\Import\\Converter\\%s', config(sprintf('csv.import_roles.%s.converter', $role)));
|
||||
/** @var ConverterInterface $converter */
|
||||
$converter = app($class);
|
||||
Log::debug(sprintf('Now launching converter %s', $class));
|
||||
$conversion = $converter->convert($modifier);
|
||||
if ($conversion === -1) {
|
||||
$result = app('steam')->negative($result);
|
||||
}
|
||||
if (1 === $conversion) {
|
||||
$result = app('steam')->positive($result);
|
||||
}
|
||||
Log::debug(sprintf('Foreign amount after conversion is %s', $result));
|
||||
}
|
||||
|
||||
Log::debug(sprintf('After modifiers the foreign amount is: "%s"', $result));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This array is being used to map the account the user is using.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public function getAccountData(): array
|
||||
{
|
||||
return [
|
||||
'iban' => $this->accountIban,
|
||||
'name' => $this->accountName,
|
||||
'number' => $this->accountNumber,
|
||||
'bic' => $this->accountBic,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public function getCurrencyData(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->currencyName,
|
||||
'code' => $this->currencyCode,
|
||||
'symbol' => $this->currencySymbol,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public function getForeignCurrencyData(): array
|
||||
{
|
||||
return [
|
||||
'code' => $this->foreignCurrencyCode,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public function getOpposingAccountData(): array
|
||||
{
|
||||
return [
|
||||
'iban' => $this->opposingIban,
|
||||
'name' => $this->opposingName,
|
||||
'number' => $this->opposingNumber,
|
||||
'bic' => $this->opposingBic,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mapped value if it exists in the ColumnValue object.
|
||||
*
|
||||
* @param ColumnValue $columnValue
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getMappedValue(ColumnValue $columnValue): int
|
||||
{
|
||||
return $columnValue->getMappedValue() > 0 ? $columnValue->getMappedValue() : (int)$columnValue->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods decides which input value to use for the amount calculation.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function selectAmountInput(): array
|
||||
{
|
||||
$info = [];
|
||||
$converterClass = '';
|
||||
if (null !== $this->amount) {
|
||||
Log::debug('Amount value is not NULL, assume this is the correct value.');
|
||||
$converterClass = Amount::class;
|
||||
$info['amount'] = $this->amount;
|
||||
}
|
||||
if (null !== $this->amountDebit) {
|
||||
Log::debug('Amount DEBIT value is not NULL, assume this is the correct value (overrules Amount).');
|
||||
$converterClass = AmountDebit::class;
|
||||
$info['amount'] = $this->amountDebit;
|
||||
}
|
||||
if (null !== $this->amountCredit) {
|
||||
Log::debug('Amount CREDIT value is not NULL, assume this is the correct value (overrules Amount and AmountDebit).');
|
||||
$converterClass = AmountCredit::class;
|
||||
$info['amount'] = $this->amountCredit;
|
||||
}
|
||||
if (null !== $this->amountNegated) {
|
||||
Log::debug('Amount NEGATED value is not NULL, assume this is the correct value (overrules Amount and AmountDebit and AmountCredit).');
|
||||
$converterClass = AmountNegated::class;
|
||||
$info['amount'] = $this->amountNegated;
|
||||
}
|
||||
$info['class'] = $converterClass;
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
}
|
@@ -1,251 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PaymentConverter.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Bunq;
|
||||
|
||||
use bunq\Model\Generated\Endpoint\Payment as BunqPayment;
|
||||
use bunq\Model\Generated\Object\LabelMonetaryAccount;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Factory\AccountFactory;
|
||||
use FireflyIII\Models\Account as LocalAccount;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class PaymentConverter
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class PaymentConverter
|
||||
{
|
||||
/** @var AccountFactory */
|
||||
private $accountFactory;
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepos;
|
||||
/** @var array */
|
||||
private $configuration;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $importJobRepos;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
$this->importJobRepos = app(ImportJobRepositoryInterface::class);
|
||||
$this->accountFactory = app(AccountFactory::class);
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a bunq transaction to a usable transaction for Firefly III.
|
||||
*
|
||||
* @param BunqPayment $payment
|
||||
*
|
||||
* @param LocalAccount $source
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function convert(BunqPayment $payment, LocalAccount $source): array
|
||||
{
|
||||
$paymentId = $payment->getId();
|
||||
Log::debug(sprintf('Now in convert() for payment with ID #%d', $paymentId));
|
||||
Log::debug(sprintf('Source account is assumed to be "%s" (#%d)', $source->name, $source->id));
|
||||
$type = TransactionType::WITHDRAWAL;
|
||||
$counterParty = $payment->getCounterpartyAlias();
|
||||
$amount = $payment->getAmount();
|
||||
|
||||
// some debug info:
|
||||
Log::debug('Assume its a witdrawal');
|
||||
Log::debug(sprintf('Subtype is %s', $payment->getSubType()));
|
||||
Log::debug(sprintf('Type is %s', $payment->getType()));
|
||||
Log::debug(sprintf('Amount is %s %s', $amount->getCurrency(), $amount->getValue()));
|
||||
|
||||
$expected = AccountType::EXPENSE;
|
||||
if (1 === bccomp($amount->getValue(), '0')) {
|
||||
// amount + means that its a deposit.
|
||||
$expected = AccountType::REVENUE;
|
||||
$type = TransactionType::DEPOSIT;
|
||||
Log::debug(sprintf('Amount is %s %s, so assume this is a deposit.', $amount->getCurrency(), $amount->getValue()));
|
||||
}
|
||||
Log::debug(sprintf('Now going to convert counter party to Firefly III account. Expect it to be a "%s" account.', $expected));
|
||||
$destination = $this->convertToAccount($counterParty, $expected);
|
||||
|
||||
// switch source and destination if necessary.
|
||||
if (1 === bccomp($amount->getValue(), '0')) {
|
||||
Log::debug('Because amount is > 0, will now swap source with destination.');
|
||||
[$source, $destination] = [$destination, $source];
|
||||
}
|
||||
|
||||
if ($source->accountType->type === AccountType::ASSET && $destination->accountType->type === AccountType::ASSET) {
|
||||
$type = TransactionType::TRANSFER;
|
||||
Log::debug('Because both transctions are asset, will make it a transfer.');
|
||||
}
|
||||
Log::debug(sprintf('Bunq created = %s', $payment->getCreated()));
|
||||
$created = new Carbon($payment->getCreated(), 'UTC');
|
||||
// correct timezone to system timezone.
|
||||
$created->setTimezone(config('app.timezone'));
|
||||
|
||||
$description = $payment->getDescription();
|
||||
if ('' === $payment->getDescription() && 'SAVINGS' === $payment->getType()) {
|
||||
$description = 'Auto-save for savings goal.';
|
||||
}
|
||||
|
||||
$storeData = [
|
||||
'user' => $this->importJob->user_id,
|
||||
'type' => $type,
|
||||
'date' => $created->format('Y-m-d H:i:s'),
|
||||
'timestamp' => $created->toAtomString(),
|
||||
'description' => $description,
|
||||
'piggy_bank_id' => null,
|
||||
'piggy_bank_name' => null,
|
||||
'bill_id' => null,
|
||||
'bill_name' => null,
|
||||
'tags' => [$payment->getType(), $payment->getSubType()],
|
||||
'internal_reference' => $paymentId,
|
||||
'external_id' => $paymentId,
|
||||
'notes' => null,
|
||||
'bunq_payment_id' => $paymentId,
|
||||
'original-source' => sprintf('bunq-v%s', config('firefly.version')),
|
||||
'transactions' => [
|
||||
// single transaction:
|
||||
[
|
||||
'description' => null,
|
||||
'amount' => $amount->getValue(),
|
||||
'currency_id' => null,
|
||||
'currency_code' => $amount->getCurrency(),
|
||||
'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,
|
||||
],
|
||||
],
|
||||
];
|
||||
Log::info(sprintf('Parsed %s: "%s" (%s).', $created->format('Y-m-d H:i:s'), $storeData['description'], $storeData['transactions'][0]['amount']));
|
||||
|
||||
return $storeData;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->accountRepos->setUser($importJob->user);
|
||||
$this->importJobRepos->setUser($importJob->user);
|
||||
$this->accountFactory->setUser($importJob->user);
|
||||
$this->configuration = $this->importJobRepos->getConfiguration($importJob);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LabelMonetaryAccount $party
|
||||
* @param string $expectedType
|
||||
*
|
||||
* @return LocalAccount
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function convertToAccount(LabelMonetaryAccount $party, string $expectedType): LocalAccount
|
||||
{
|
||||
Log::debug(sprintf('in convertToAccount() with LabelMonetaryAccount'));
|
||||
if (null !== $party->getIban()) {
|
||||
Log::debug(sprintf('Opposing party has IBAN "%s"', $party->getIban()));
|
||||
|
||||
// find account in 'bunq-iban' array first.
|
||||
$bunqIbans = $this->configuration['bunq-iban'] ?? [];
|
||||
Log::debug('Bunq ibans configuration is', $bunqIbans);
|
||||
|
||||
if (isset($bunqIbans[$party->getIban()])) {
|
||||
Log::debug('IBAN is known in array.');
|
||||
$accountId = (int)$bunqIbans[$party->getIban()];
|
||||
$result = $this->accountRepos->findNull($accountId);
|
||||
if (null !== $result) {
|
||||
Log::debug(sprintf('Search for #%s (IBAN "%s"), found "%s" (#%d)', $accountId, $party->getIban(), $result->name, $result->id));
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// find opposing party by IBAN second.
|
||||
$result = $this->accountRepos->findByIbanNull($party->getIban(), [$expectedType]);
|
||||
if (null !== $result) {
|
||||
Log::debug(sprintf('Search for "%s" resulted in account "%s" (#%d)', $party->getIban(), $result->name, $result->id));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// try to find asset account just in case:
|
||||
if ($expectedType !== AccountType::ASSET) {
|
||||
$result = $this->accountRepos->findByIbanNull($party->getIban(), [AccountType::ASSET]);
|
||||
if (null !== $result) {
|
||||
Log::debug(sprintf('Search for Asset "%s" resulted in account %s (#%d)', $party->getIban(), $result->name, $result->id));
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Log::debug('Found no account for opposing party, must create a new one.');
|
||||
|
||||
// create new account:
|
||||
$data = [
|
||||
'user_id' => $this->importJob->user_id,
|
||||
'iban' => $party->getIban(),
|
||||
'name' => $party->getLabelUser()->getDisplayName(),
|
||||
'account_type_id' => null,
|
||||
'account_type' => $expectedType,
|
||||
'virtual_balance' => null,
|
||||
'active' => true,
|
||||
];
|
||||
$account = $this->accountFactory->create($data);
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'Converted label monetary account "%s" to NEW "%s" account "%s" (#%d)',
|
||||
$party->getLabelUser()->getDisplayName(),
|
||||
$expectedType,
|
||||
$account->name, $account->id
|
||||
)
|
||||
);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,465 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageImportDataHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Bunq;
|
||||
|
||||
use bunq\Model\Generated\Endpoint\Payment as BunqPayment;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Factory\AccountFactory;
|
||||
use FireflyIII\Models\Account as LocalAccount;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Services\Bunq\ApiContext;
|
||||
use FireflyIII\Services\Bunq\Payment;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class StageImportDataHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class StageImportDataHandler
|
||||
{
|
||||
/** @var int */
|
||||
private const DOWNLOAD_BACKWARDS = 1;
|
||||
/** @var int */
|
||||
private const DOWNLOAD_FORWARDS = 2;
|
||||
|
||||
/** @var bool */
|
||||
public $stillRunning;
|
||||
/** @var AccountFactory */
|
||||
private $accountFactory;
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
/** @var PaymentConverter */
|
||||
private $converter;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var array */
|
||||
private $jobConfiguration;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
/** @var float */
|
||||
private $timeStart;
|
||||
/** @var array */
|
||||
private $transactions;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->stillRunning = true;
|
||||
$this->timeStart = microtime(true);
|
||||
$this->converter = app(PaymentConverter::class);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public function getTransactions(): array
|
||||
{
|
||||
return $this->transactions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isStillRunning(): bool
|
||||
{
|
||||
return $this->stillRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$this->getContext();
|
||||
$this->converter->setImportJob($this->importJob);
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$accounts = $config['accounts'] ?? [];
|
||||
$mapping = $config['mapping'] ?? [];
|
||||
$collection = [[]];
|
||||
$this->jobConfiguration = $config;
|
||||
/** @var array $bunqAccount */
|
||||
foreach ($accounts as $bunqAccount) {
|
||||
$bunqAccountId = $bunqAccount['id'] ?? 0;
|
||||
$localId = $mapping[$bunqAccountId] ?? 0;
|
||||
if (0 !== $localId && 0 !== $bunqAccountId) {
|
||||
Log::info(sprintf('Now at bunq account #%d and local account #%d', $bunqAccountId, $localId));
|
||||
$localAccount = $this->getLocalAccount((int)$localId);
|
||||
$collection[] = $this->getTransactionsFromBunq($bunqAccountId, $localAccount);
|
||||
}
|
||||
}
|
||||
$totalSet = array_merge(...$collection);
|
||||
$this->transactions = $totalSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->accountFactory = app(AccountFactory::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->accountRepository->setUser($importJob->user);
|
||||
$this->accountFactory->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BunqPayment $payment
|
||||
* @param LocalAccount $source
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function convertPayment(BunqPayment $payment, LocalAccount $source): array
|
||||
{
|
||||
Log::debug(sprintf('Now at payment with ID #%d', $payment->getId()));
|
||||
|
||||
return $this->converter->convert($payment, $source);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getContext(): void
|
||||
{
|
||||
/** @var Preference $preference */
|
||||
$preference = app('preferences')->getForUser($this->importJob->user, 'bunq_api_context', null);
|
||||
if (null !== $preference && '' !== (string)$preference->data) {
|
||||
// restore API context
|
||||
/** @var ApiContext $apiContext */
|
||||
$apiContext = app(ApiContext::class);
|
||||
$apiContext->fromJson($preference->data);
|
||||
|
||||
return;
|
||||
}
|
||||
throw new FireflyException('The bunq API context is unexpectedly empty.'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the direction in which we must download.
|
||||
*
|
||||
* @param int $bunqAccountId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getDirection(int $bunqAccountId): int
|
||||
{
|
||||
Log::debug(sprintf('Now in getDirection(%d)', $bunqAccountId));
|
||||
|
||||
// if oldest transaction ID is 0, AND the newest transaction is 0
|
||||
// we don't know about this account, so we must go backward in time.
|
||||
$oldest = \Preferences::getForUser($this->importJob->user, sprintf('bunq-oldest-transaction-%d', $bunqAccountId), 0);
|
||||
$newest = \Preferences::getForUser($this->importJob->user, sprintf('bunq-newest-transaction-%d', $bunqAccountId), 0);
|
||||
|
||||
if (0 === $oldest->data && 0 === $newest->data) {
|
||||
Log::debug(sprintf('Oldest tranaction ID is %d and newest tranasction ID is %d, so go backwards.', $oldest->data, $newest->data));
|
||||
|
||||
return self::DOWNLOAD_BACKWARDS;
|
||||
}
|
||||
|
||||
// if newest is not zero but oldest is zero, go forward.
|
||||
if (0 === $oldest->data && 0 !== $newest->data) {
|
||||
Log::debug(sprintf('Oldest tranaction ID is %d and newest tranasction ID is %d, so go forwards.', $oldest->data, $newest->data));
|
||||
|
||||
return self::DOWNLOAD_FORWARDS;
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Oldest tranaction ID is %d and newest tranasction ID is %d, so go backwards.', $oldest->data, $newest->data));
|
||||
|
||||
return self::DOWNLOAD_BACKWARDS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $accountId
|
||||
*
|
||||
* @return LocalAccount
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getLocalAccount(int $accountId): LocalAccount
|
||||
{
|
||||
$account = $this->accountRepository->findNull($accountId);
|
||||
if (null === $account) {
|
||||
throw new FireflyException(sprintf('Cannot find Firefly III asset account with ID #%d. Job must stop now.', $accountId)); // @codeCoverageIgnore
|
||||
}
|
||||
if ($account->accountType->type !== AccountType::ASSET) {
|
||||
throw new FireflyException(sprintf('Account with ID #%d is not an asset account. Job must stop now.', $accountId)); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $bunqAccountId
|
||||
* @param LocalAccount $localAccount
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getTransactionsFromBunq(int $bunqAccountId, LocalAccount $localAccount): array
|
||||
{
|
||||
Log::debug(sprintf('Now in getTransactionsFromBunq(%d).', $bunqAccountId));
|
||||
|
||||
$direction = $this->getDirection($bunqAccountId);
|
||||
$return = [];
|
||||
if (self::DOWNLOAD_BACKWARDS === $direction) {
|
||||
Log::info('For this account we go backwards in time.');
|
||||
// go back either from NULL or from ID.
|
||||
// ID is the very last transaction downloaded from bunq.
|
||||
$preference = \Preferences::getForUser($this->importJob->user, sprintf('bunq-oldest-transaction-%d', $bunqAccountId), 0);
|
||||
$transactionId = 0 === $preference->data ? null : $preference->data;
|
||||
$return = $this->goBackInTime($bunqAccountId, $localAccount, $transactionId);
|
||||
}
|
||||
if (self::DOWNLOAD_FORWARDS === $direction) {
|
||||
Log::info('For this account we go forwards in time.');
|
||||
// go forward from ID. There is no NULL, young padawan
|
||||
$return = $this->goForwardInTime($bunqAccountId, $localAccount);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method downloads the transactions from bunq going back in time. Assuming bunq
|
||||
* is fairly consistent with the transactions it provides through the API, the method
|
||||
* will store both the highest and the lowest transaction ID downloaded in this manner.
|
||||
*
|
||||
* The highest transaction ID is used to continue forward in time. The lowest is used to continue
|
||||
* even further back in time.
|
||||
*
|
||||
* The lowest transaction ID can also be given to this method as a parameter (as $startTransaction).
|
||||
*
|
||||
* @param int $bunqAccountId
|
||||
* @param LocalAccount $localAccount
|
||||
* @param int $startTransaction
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function goBackInTime(int $bunqAccountId, LocalAccount $localAccount, int $startTransaction = null): array
|
||||
{
|
||||
Log::debug(sprintf('Now in goBackInTime(#%d, #%s, #%s).', $bunqAccountId, $localAccount->id, $startTransaction));
|
||||
$hasMoreTransactions = true;
|
||||
$olderId = $startTransaction;
|
||||
$oldestTransaction = null;
|
||||
$newestTransaction = null;
|
||||
$count = 0;
|
||||
$return = [];
|
||||
|
||||
/*
|
||||
* Do a loop during which we run:
|
||||
*/
|
||||
while ($hasMoreTransactions && $this->timeRunning() < 25) {
|
||||
Log::debug(sprintf('Now in loop #%d', $count));
|
||||
Log::debug(sprintf('Now running for %s seconds.', $this->timeRunning()));
|
||||
|
||||
/*
|
||||
* Send request to bunq.
|
||||
*/
|
||||
/** @var Payment $paymentRequest */
|
||||
$paymentRequest = app(Payment::class);
|
||||
$params = ['count' => 197, 'older_id' => $olderId];
|
||||
$response = $paymentRequest->listing($bunqAccountId, $params);
|
||||
$pagination = $response->getPagination();
|
||||
Log::debug('Params for the request to bunq are: ', $params);
|
||||
|
||||
/*
|
||||
* If pagination is not null, we can go back even further.
|
||||
*/
|
||||
if (null !== $pagination) {
|
||||
$olderId = $pagination->getOlderId();
|
||||
Log::debug(sprintf('Pagination object is not null, new olderID is "%s"', $olderId));
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop the results from bunq
|
||||
*/
|
||||
Log::debug('Now looping results from bunq...');
|
||||
/** @var BunqPayment $payment */
|
||||
foreach ($response->getValue() as $index => $payment) {
|
||||
$return[] = $this->convertPayment($payment, $localAccount);
|
||||
$paymentId = $payment->getId();
|
||||
/*
|
||||
* If oldest and newest transaction are null, they have to be set:
|
||||
*/
|
||||
$oldestTransaction = $oldestTransaction ?? $paymentId;
|
||||
$newestTransaction = $newestTransaction ?? $paymentId;
|
||||
|
||||
/*
|
||||
* Then, overwrite if appropriate
|
||||
*/
|
||||
$oldestTransaction = $paymentId < $oldestTransaction ? $paymentId : $oldestTransaction;
|
||||
$newestTransaction = $paymentId > $newestTransaction ? $paymentId : $newestTransaction;
|
||||
}
|
||||
|
||||
/*
|
||||
* After the loop, check if Firefly III must loop again.
|
||||
*/
|
||||
Log::debug(sprintf('Count of result is now %d', count($return)));
|
||||
$count++;
|
||||
if (null === $olderId) {
|
||||
Log::debug('Older ID is NULL, so stop looping cause we are done!');
|
||||
$hasMoreTransactions = false;
|
||||
$this->stillRunning = false;
|
||||
/*
|
||||
* We no longer care about the oldest transaction ID:
|
||||
*/
|
||||
$oldestTransaction = 0;
|
||||
}
|
||||
if (null === $pagination) {
|
||||
Log::debug('No pagination object, stop looping.');
|
||||
$hasMoreTransactions = false;
|
||||
$this->stillRunning = false;
|
||||
/*
|
||||
* We no longer care about the oldest transaction ID:
|
||||
*/
|
||||
$oldestTransaction = 0;
|
||||
}
|
||||
// sleep 2 seconds to prevent hammering bunq.
|
||||
sleep(2);
|
||||
}
|
||||
// store newest and oldest tranasction ID to be used later:
|
||||
\Preferences::setForUser($this->importJob->user, sprintf('bunq-oldest-transaction-%d', $bunqAccountId), $oldestTransaction);
|
||||
\Preferences::setForUser($this->importJob->user, sprintf('bunq-newest-transaction-%d', $bunqAccountId), $newestTransaction);
|
||||
Log::info(sprintf('Downloaded and parsed %d transactions from bunq.', count($return)));
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $bunqAccountId
|
||||
* @param LocalAccount $localAccount
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function goForwardInTime(int $bunqAccountId, LocalAccount $localAccount): array
|
||||
{
|
||||
Log::debug(sprintf('Now in goForwardInTime(%d).', $bunqAccountId));
|
||||
$hasMoreTransactions = true;
|
||||
$count = 0;
|
||||
$return = [];
|
||||
$newestTransaction = null;
|
||||
|
||||
/*
|
||||
* Go forward from the newest transaction we know about:
|
||||
*/
|
||||
$preferenceName = sprintf('bunq-newest-transaction-%d', $bunqAccountId);
|
||||
$transactionPref = \Preferences::getForUser($this->importJob->user, $preferenceName, 0);
|
||||
$newerId = (int)$transactionPref->data;
|
||||
|
||||
/*
|
||||
* Run a loop.
|
||||
*/
|
||||
while ($hasMoreTransactions && $this->timeRunning() < 25) {
|
||||
/*
|
||||
* Debug information:
|
||||
*/
|
||||
Log::debug(sprintf('Now in loop #%d', $count));
|
||||
Log::debug(sprintf('Now running for %s seconds.', $this->timeRunning()));
|
||||
|
||||
/*
|
||||
* Send a request to bunq.
|
||||
*/
|
||||
/** @var Payment $paymentRequest */
|
||||
$paymentRequest = app(Payment::class);
|
||||
$params = ['count' => 197, 'newer_id' => $newerId];
|
||||
$response = $paymentRequest->listing($bunqAccountId, $params);
|
||||
$pagination = $response->getPagination();
|
||||
Log::debug('Submit payment request with params', $params);
|
||||
|
||||
/*
|
||||
* If pagination is not null, we can go forward even further.
|
||||
*/
|
||||
if (null !== $pagination) {
|
||||
$newerId = $pagination->getNewerId();
|
||||
Log::debug(sprintf('Pagination object is not null, newerID is "%s"', $newerId));
|
||||
}
|
||||
Log::debug('Now looping results...');
|
||||
/*
|
||||
* Process the bunq loop.
|
||||
*/
|
||||
/** @var BunqPayment $payment */
|
||||
foreach ($response->getValue() as $payment) {
|
||||
$return[] = $this->convertPayment($payment, $localAccount);
|
||||
$paymentId = $payment->getId();
|
||||
|
||||
/*
|
||||
* If oldest and newest transaction are null, they have to be set:
|
||||
*/
|
||||
$newestTransaction = $newestTransaction ?? $paymentId;
|
||||
|
||||
/*
|
||||
* Then, overwrite if appropriate
|
||||
*/
|
||||
$newestTransaction = $paymentId > $newestTransaction ? $paymentId : $newestTransaction;
|
||||
}
|
||||
|
||||
/*
|
||||
* After the loop, check if Firefly III must loop again.
|
||||
*/
|
||||
Log::debug(sprintf('Count of result is now %d', count($return)));
|
||||
$count++;
|
||||
if (null === $newerId) {
|
||||
Log::debug('Newer ID is NULL, so stop looping cause we are done!');
|
||||
$hasMoreTransactions = false;
|
||||
$this->stillRunning = false;
|
||||
}
|
||||
if (null === $pagination) {
|
||||
Log::debug('No pagination object, stop looping.');
|
||||
$hasMoreTransactions = false;
|
||||
$this->stillRunning = false;
|
||||
}
|
||||
// sleep 2 seconds to prevent hammering bunq.
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
// store newest tranasction ID to be used later:
|
||||
\Preferences::setForUser($this->importJob->user, sprintf('bunq-newest-transaction-%d', $bunqAccountId), $newestTransaction);
|
||||
Log::info(sprintf('Downloaded and parsed %d transactions from bunq.', count($return)));
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
private function timeRunning(): float
|
||||
{
|
||||
$time_end = microtime(true);
|
||||
|
||||
return $time_end - $this->timeStart;
|
||||
}
|
||||
}
|
@@ -1,379 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageNewHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Bunq;
|
||||
|
||||
use bunq\exception\BunqException;
|
||||
use bunq\Model\Generated\Endpoint\MonetaryAccount as BunqMonetaryAccount;
|
||||
use bunq\Model\Generated\Endpoint\MonetaryAccountBank;
|
||||
use bunq\Model\Generated\Endpoint\MonetaryAccountJoint;
|
||||
use bunq\Model\Generated\Endpoint\MonetaryAccountLight;
|
||||
use bunq\Model\Generated\Endpoint\MonetaryAccountSavings;
|
||||
use bunq\Model\Generated\Object\CoOwner;
|
||||
use bunq\Model\Generated\Object\Pointer;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Services\Bunq\ApiContext;
|
||||
use FireflyIII\Services\Bunq\MonetaryAccount;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class StageNewHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class StageNewHandler
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::info('Now in StageNewHandler::run()');
|
||||
/** @var Preference $preference */
|
||||
$preference = app('preferences')->getForUser($this->importJob->user, 'bunq_api_context', null);
|
||||
if (null !== $preference && '' !== (string)$preference->data) {
|
||||
// restore API context
|
||||
/** @var ApiContext $apiContext */
|
||||
$apiContext = app(ApiContext::class);
|
||||
$apiContext->fromJson($preference->data);
|
||||
|
||||
// list bunq accounts:
|
||||
$accounts = $this->listAccounts();
|
||||
|
||||
// store in job:
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$config['accounts'] = $accounts;
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
|
||||
return;
|
||||
}
|
||||
throw new FireflyException('The bunq API context is unexpectedly empty.'); // @codeCoverageIgnore
|
||||
} // @codeCoverageIgnore
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function listAccounts(): array
|
||||
{
|
||||
Log::debug('Now in StageNewHandler::listAccounts()');
|
||||
$accounts = [];
|
||||
/** @var MonetaryAccount $lister */
|
||||
$lister = app(MonetaryAccount::class);
|
||||
$result = $lister->listing();
|
||||
|
||||
/** @var BunqMonetaryAccount $monetaryAccount */
|
||||
foreach ($result->getValue() as $monetaryAccount) {
|
||||
try {
|
||||
$object = $monetaryAccount->getReferencedObject();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (BunqException $e) {
|
||||
throw new FireflyException($e->getMessage());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
if (null !== $object) {
|
||||
$array = null;
|
||||
switch (get_class($object)) {
|
||||
case MonetaryAccountBank::class:
|
||||
Log::debug('Going to convert a MonetaryAccountBank');
|
||||
/** @var MonetaryAccountBank $object */
|
||||
$array = $this->processMab($object);
|
||||
break;
|
||||
case MonetaryAccountJoint::class:
|
||||
Log::debug('Going to convert a MonetaryAccountJoint');
|
||||
/** @var MonetaryAccountJoint $object */
|
||||
$array = $this->processMaj($object);
|
||||
break;
|
||||
case MonetaryAccountLight::class:
|
||||
Log::debug('Going to convert a MonetaryAccountLight');
|
||||
/** @var MonetaryAccountLight $object */
|
||||
$array = $this->processMal($object);
|
||||
break;
|
||||
case MonetaryAccountSavings::class;
|
||||
Log::debug('Going to convert a MonetaryAccountSavings');
|
||||
/** @var MonetaryAccountSavings $object */
|
||||
$array = $this->processMas($object);
|
||||
break;
|
||||
default:
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException(sprintf('Bunq import routine cannot handle account of type "%s".', get_class($object)));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
if (null !== $array) {
|
||||
Log::debug('Array is not null');
|
||||
$accounts[] = $array;
|
||||
$this->reportFinding($array);
|
||||
}
|
||||
}
|
||||
}
|
||||
Log::info(sprintf('Found %d account(s) at bunq', count($accounts)), $accounts);
|
||||
|
||||
return $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MonetaryAccountBank $mab
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function processMab(MonetaryAccountBank $mab): array
|
||||
{
|
||||
$setting = $mab->getSetting();
|
||||
$return = [
|
||||
'id' => $mab->getId(),
|
||||
'currency_code' => $mab->getCurrency(),
|
||||
'description' => $mab->getDescription(),
|
||||
'balance' => $mab->getBalance(),
|
||||
'status' => $mab->getStatus(),
|
||||
'type' => 'MonetaryAccountBank',
|
||||
'iban' => null,
|
||||
'aliases' => [],
|
||||
];
|
||||
|
||||
if (null !== $setting) {
|
||||
$return['settings'] = [
|
||||
'color' => $mab->getSetting()->getColor(),
|
||||
'default_avatar_status' => $mab->getSetting()->getDefaultAvatarStatus(),
|
||||
'restriction_chat' => $mab->getSetting()->getRestrictionChat(),
|
||||
];
|
||||
}
|
||||
if (null !== $mab->getAlias()) {
|
||||
/** @var Pointer $alias */
|
||||
foreach ($mab->getAlias() as $alias) {
|
||||
$return['aliases'][] = [
|
||||
'type' => $alias->getType(),
|
||||
'name' => $alias->getName(),
|
||||
'value' => $alias->getValue(),
|
||||
];
|
||||
|
||||
// store IBAN alias separately:
|
||||
if ('IBAN' === $alias->getType()) {
|
||||
$return['iban'] = $alias->getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MonetaryAccountJoint $maj
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function processMaj(MonetaryAccountJoint $maj): array
|
||||
{
|
||||
Log::debug('Now processing a MAJ');
|
||||
$setting = $maj->getSetting();
|
||||
$return = [
|
||||
'id' => $maj->getId(),
|
||||
'currency_code' => $maj->getCurrency(),
|
||||
'description' => $maj->getDescription(),
|
||||
'balance' => $maj->getBalance(),
|
||||
'status' => $maj->getStatus(),
|
||||
'type' => 'MonetaryAccountJoint',
|
||||
'co-owners' => [],
|
||||
'aliases' => [],
|
||||
];
|
||||
|
||||
if (null !== $setting) {
|
||||
$return['settings'] = [
|
||||
'color' => $maj->getSetting()->getColor(),
|
||||
'default_avatar_status' => $maj->getSetting()->getDefaultAvatarStatus(),
|
||||
'restriction_chat' => $maj->getSetting()->getRestrictionChat(),
|
||||
];
|
||||
Log::debug('Setting is not null.');
|
||||
}
|
||||
if (null !== $maj->getAlias()) {
|
||||
Log::debug(sprintf('Alias is not NULL. Count is %d', count($maj->getAlias())));
|
||||
/** @var Pointer $alias */
|
||||
foreach ($maj->getAlias() as $alias) {
|
||||
$return['aliases'][] = [
|
||||
'type' => $alias->getType(),
|
||||
'name' => $alias->getName(),
|
||||
'value' => $alias->getValue(),
|
||||
];
|
||||
// store IBAN alias separately:
|
||||
if ('IBAN' === $alias->getType()) {
|
||||
$return['iban'] = $alias->getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
$coOwners = $maj->getAllCoOwner() ?? [];
|
||||
Log::debug(sprintf('Count of getAllCoOwner is %d', count($coOwners)));
|
||||
/** @var CoOwner $coOwner */
|
||||
foreach ($coOwners as $coOwner) {
|
||||
$alias = $coOwner->getAlias();
|
||||
if (null !== $alias) {
|
||||
Log::debug('Alias is not NULL');
|
||||
$name = (string)$alias->getDisplayName();
|
||||
Log::debug(sprintf('Name is "%s"', $name));
|
||||
if ('' !== $name) {
|
||||
$return['co-owners'][] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MonetaryAccountLight $mal
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function processMal(MonetaryAccountLight $mal): array
|
||||
{
|
||||
$setting = $mal->getSetting();
|
||||
$return = [
|
||||
'id' => $mal->getId(),
|
||||
'currency_code' => $mal->getCurrency(),
|
||||
'description' => $mal->getDescription(),
|
||||
'balance' => $mal->getBalance(),
|
||||
'status' => $mal->getStatus(),
|
||||
'type' => 'MonetaryAccountLight',
|
||||
'aliases' => [],
|
||||
];
|
||||
|
||||
if (null !== $setting) {
|
||||
$return['settings'] = [
|
||||
'color' => $mal->getSetting()->getColor(),
|
||||
'default_avatar_status' => $mal->getSetting()->getDefaultAvatarStatus(),
|
||||
'restriction_chat' => $mal->getSetting()->getRestrictionChat(),
|
||||
];
|
||||
}
|
||||
if (null !== $mal->getAlias()) {
|
||||
/** @var Pointer $alias */
|
||||
foreach ($mal->getAlias() as $alias) {
|
||||
$return['aliases'][] = [
|
||||
'type' => $alias->getType(),
|
||||
'name' => $alias->getName(),
|
||||
'value' => $alias->getValue(),
|
||||
];
|
||||
// store IBAN alias separately:
|
||||
if ('IBAN' === $alias->getType()) {
|
||||
$return['iban'] = $alias->getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MonetaryAccountSavings $object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function processMas(MonetaryAccountSavings $object): array
|
||||
{
|
||||
Log::debug('Now in processMas()');
|
||||
$setting = $object->getSetting();
|
||||
$return = [
|
||||
'id' => $object->getId(),
|
||||
'currency_code' => $object->getCurrency(),
|
||||
'description' => $object->getDescription(),
|
||||
'balance' => $object->getBalance(),
|
||||
'status' => $object->getStatus(),
|
||||
'type' => 'MonetaryAccountSavings',
|
||||
'aliases' => [],
|
||||
'savingsGoal' => [],
|
||||
];
|
||||
|
||||
if (null !== $setting) {
|
||||
$return['settings'] = [
|
||||
'color' => $object->getSetting()->getColor(),
|
||||
'default_avatar_status' => $object->getSetting()->getDefaultAvatarStatus(),
|
||||
'restriction_chat' => $object->getSetting()->getRestrictionChat(),
|
||||
];
|
||||
}
|
||||
if (null !== $object->getAlias()) {
|
||||
Log::debug('MAS has aliases');
|
||||
/** @var Pointer $alias */
|
||||
foreach ($object->getAlias() as $alias) {
|
||||
Log::debug(sprintf('Alias type is "%s", with name "%s" and value "%s"', $alias->getType(), $alias->getName(), $alias->getValue()));
|
||||
$return['aliases'][] = [
|
||||
'type' => $alias->getType(),
|
||||
'name' => $alias->getName(),
|
||||
'value' => $alias->getValue(),
|
||||
];
|
||||
// store IBAN alias separately:
|
||||
if ('IBAN' === $alias->getType()) {
|
||||
$return['iban'] = $alias->getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
$goal = $object->getSavingsGoal();
|
||||
$return['savingsGoal'] = [
|
||||
'currency' => $goal->getCurrency(),
|
||||
'value' => $goal->getValue(),
|
||||
'percentage' => $object->getSavingsGoalProgress(),
|
||||
];
|
||||
Log::debug('End of processMas()', $return);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic report method.
|
||||
*
|
||||
* @param array $array
|
||||
*/
|
||||
private function reportFinding(array $array): void
|
||||
{
|
||||
$bunqId = $array['id'] ?? '';
|
||||
$bunqDescription = $array['description'] ?? '';
|
||||
$bunqIBAN = '';
|
||||
|
||||
// find IBAN:
|
||||
$aliases = $array['aliases'] ?? [];
|
||||
foreach ($aliases as $alias) {
|
||||
$type = $alias['type'] ?? 'none';
|
||||
if ('IBAN' === $type) {
|
||||
$bunqIBAN = $alias['value'] ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
Log::info(sprintf('Found account at bunq. ID #%d, title "%s" and IBAN "%s" ', $bunqId, $bunqDescription, $bunqIBAN));
|
||||
}
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageAhoyHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Fake;
|
||||
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Class StageAhoyHandler
|
||||
* @deprecated
|
||||
*/
|
||||
class StageAhoyHandler
|
||||
{
|
||||
/**
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
Log::debug(sprintf('Am now in stage AHOY hander, sleeping... (%d)', $i));
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,157 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* StageFinalHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Fake;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Class StageFinalHandler
|
||||
* @deprecated
|
||||
*/
|
||||
class StageFinalHandler
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getTransactions(): array
|
||||
{
|
||||
$transactions = [];
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$transaction = [
|
||||
'type' => 'withdrawal',
|
||||
'date' => Carbon::now()->format('Y-m-d'),
|
||||
'tags' => '',
|
||||
'user' => $this->importJob->user_id,
|
||||
|
||||
// all custom fields:
|
||||
'internal_reference' => null,
|
||||
'notes' => null,
|
||||
|
||||
// journal data:
|
||||
'description' => 'Some random description #' . random_int(1, 10000),
|
||||
'piggy_bank_id' => null,
|
||||
'piggy_bank_name' => null,
|
||||
'bill_id' => null,
|
||||
'bill_name' => null,
|
||||
'original-source' => sprintf('fake-import-v%s', config('firefly.version')),
|
||||
|
||||
// transaction data:
|
||||
'transactions' => [
|
||||
[
|
||||
'type' => 'withdrawal',
|
||||
'date' => Carbon::now()->format('Y-m-d'),
|
||||
'currency_id' => null,
|
||||
'currency_code' => 'EUR',
|
||||
'description' => 'Some random description #' . random_int(1, 10000),
|
||||
'amount' => random_int(500, 5000) / 100,
|
||||
'tags' => [],
|
||||
'user' => $this->importJob->user_id,
|
||||
'budget_id' => null,
|
||||
'budget_name' => null,
|
||||
'category_id' => null,
|
||||
'category_name' => null,
|
||||
'source_id' => null,
|
||||
'source_name' => 'Checking Account',
|
||||
'destination_id' => null,
|
||||
'destination_name' => 'Random expense account #' . random_int(1, 10000),
|
||||
'foreign_currency_id' => null,
|
||||
'foreign_currency_code' => null,
|
||||
'foreign_amount' => null,
|
||||
'reconciled' => false,
|
||||
'identifier' => 0,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$transactions[] = $transaction;
|
||||
}
|
||||
|
||||
// add a transfer I know exists already
|
||||
$transactions[] = [
|
||||
'type' => 'transfer',
|
||||
'date' => '2017-02-28',
|
||||
'tags' => '',
|
||||
'user' => $this->importJob->user_id,
|
||||
|
||||
// all custom fields:
|
||||
'internal_reference' => null,
|
||||
'notes' => null,
|
||||
|
||||
// journal data:
|
||||
'description' => 'Saving money for February',
|
||||
'piggy_bank_id' => null,
|
||||
'piggy_bank_name' => null,
|
||||
'bill_id' => null,
|
||||
'bill_name' => null,
|
||||
|
||||
// transaction data:
|
||||
'transactions' => [
|
||||
[
|
||||
'type' => 'transfer',
|
||||
'user' => $this->importJob->user_id,
|
||||
'date' => '2017-02-28',
|
||||
'currency_id' => null,
|
||||
'currency_code' => 'EUR',
|
||||
'tags' => [],
|
||||
'description' => 'Saving money for February',
|
||||
'amount' => '140',
|
||||
'budget_id' => null,
|
||||
'budget_name' => null,
|
||||
'category_id' => null,
|
||||
'category_name' => null,
|
||||
'source_id' => 1,
|
||||
'source_name' => 'Checking Account',
|
||||
'destination_id' => 2,
|
||||
'destination_name' => null,
|
||||
'foreign_currency_id' => null,
|
||||
'foreign_currency_code' => null,
|
||||
'foreign_amount' => null,
|
||||
'reconciled' => false,
|
||||
'identifier' => 0,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
return $transactions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
}
|
||||
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageNewHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Fake;
|
||||
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Class StageNewHandler
|
||||
* @deprecated
|
||||
*/
|
||||
class StageNewHandler
|
||||
{
|
||||
/**
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
Log::debug(sprintf('Am now in stage new hander, sleeping... (%d)', $i));
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,135 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* AssetAccountMapper.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\File;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class AssetAccountMapper
|
||||
* Can also handle liability accounts.
|
||||
* @deprecated
|
||||
*/
|
||||
class AssetAccountMapper
|
||||
{
|
||||
/** @var int */
|
||||
private $defaultAccount;
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $repository;
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/** @var array */
|
||||
private $types;
|
||||
|
||||
/**
|
||||
* AssetAccountMapper constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->types = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
|
||||
}
|
||||
|
||||
/**
|
||||
* Based upon data in the importable, try to find or create the asset account account.
|
||||
*
|
||||
* @param int|null $accountId
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*
|
||||
*/
|
||||
public function map(?int $accountId, array $data): Account
|
||||
{
|
||||
Log::debug(sprintf('Now in AssetAccountMapper::map(%d)', $accountId), $data);
|
||||
if ((int)$accountId > 0) {
|
||||
// find asset account with this ID:
|
||||
$result = $this->repository->findNull($accountId);
|
||||
if (null !== $result && in_array($result->accountType->type, $this->types, true)) {
|
||||
Log::debug(sprintf('Found %s "%s" based on given ID %d', $result->accountType->type, $result->name, $accountId));
|
||||
|
||||
return $result;
|
||||
}
|
||||
if (null !== $result && in_array($result->accountType->type, $this->types, true)) {
|
||||
Log::warning(
|
||||
sprintf('Found account "%s" based on given ID %d but its a %s, return nothing.', $result->name, $accountId, $result->accountType->type)
|
||||
);
|
||||
}
|
||||
}
|
||||
// find by (respectively):
|
||||
// IBAN, accountNumber, name,
|
||||
$fields = ['iban' => 'findByIbanNull', 'number' => 'findByAccountNumber', 'name' => 'findByName'];
|
||||
foreach ($fields as $field => $function) {
|
||||
$value = (string)($data[$field] ?? '');
|
||||
if ('' === $value) {
|
||||
Log::debug(sprintf('Array does not contain a value for %s. Continue', $field));
|
||||
continue;
|
||||
}
|
||||
$result = $this->repository->$function($value, $this->types);
|
||||
Log::debug(sprintf('Going to run %s() with argument "%s" (asset account or liability)', $function, $value));
|
||||
if (null !== $result) {
|
||||
Log::debug(sprintf('Found asset account "%s". Return it!', $result->name));
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
Log::debug('Found nothing. Will return default account.');
|
||||
// still NULL? Return default account.
|
||||
$default = null;
|
||||
if ($this->defaultAccount > 0) {
|
||||
$default = $this->repository->findNull($this->defaultAccount);
|
||||
}
|
||||
if (null === $default) {
|
||||
Log::debug('Default account is NULL! Simply result first account in system.');
|
||||
$default = $this->repository->getAccountsByType([AccountType::ASSET])->first();
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Return default account "%s" (#%d). Return it!', $default->name, $default->id));
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $defaultAccount
|
||||
*/
|
||||
public function setDefaultAccount(int $defaultAccount): void
|
||||
{
|
||||
$this->defaultAccount = $defaultAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$this->defaultAccount = 0;
|
||||
$this->repository->setUser($user);
|
||||
|
||||
}
|
||||
}
|
@@ -1,91 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CSVProcessor.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\File;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Log;
|
||||
|
||||
|
||||
/**
|
||||
* Class CSVProcessor
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CSVProcessor implements FileProcessorInterface
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
|
||||
/**
|
||||
* Fires the file processor.
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): array
|
||||
{
|
||||
Log::debug('Now in CSVProcessor() run');
|
||||
|
||||
// create separate objects to handle separate tasks:
|
||||
/** @var LineReader $lineReader */
|
||||
$lineReader = app(LineReader::class);
|
||||
$lineReader->setImportJob($this->importJob);
|
||||
$lines = $lineReader->getLines();
|
||||
|
||||
// convert each line into a small set of "ColumnValue" objects,
|
||||
// joining each with its mapped counterpart.
|
||||
/** @var MappingConverger $mappingConverger */
|
||||
$mappingConverger = app(MappingConverger::class);
|
||||
$mappingConverger->setImportJob($this->importJob);
|
||||
$converged = $mappingConverger->converge($lines);
|
||||
|
||||
// validate mapped values:
|
||||
/** @var MappedValuesValidator $validator */
|
||||
$validator = app(MappedValuesValidator::class);
|
||||
$validator->setImportJob($this->importJob);
|
||||
$mappedValues = $validator->validate($mappingConverger->getMappedValues());
|
||||
|
||||
// make import transaction things from these objects.
|
||||
/** @var ImportableCreator $creator */
|
||||
$creator = app(ImportableCreator::class);
|
||||
$importables = $creator->convertSets($converged);
|
||||
|
||||
/** @var ImportableConverter $converter */
|
||||
$converter = app(ImportableConverter::class);
|
||||
$converter->setImportJob($this->importJob);
|
||||
$converter->setMappedValues($mappedValues);
|
||||
|
||||
return $converter->convert($importables);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
Log::debug('Now in setImportJob()');
|
||||
$this->importJob = $importJob;
|
||||
}
|
||||
}
|
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CurrencyMapper.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\File;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class CurrencyMapper
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CurrencyMapper
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $repository;
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @param int|null $currencyId
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionCurrency|null
|
||||
*/
|
||||
public function map(?int $currencyId, array $data): ?TransactionCurrency
|
||||
{
|
||||
Log::debug('Now in CurrencyMapper::map()');
|
||||
if ((int)$currencyId > 0) {
|
||||
$result = $this->repository->findNull($currencyId);
|
||||
if (null !== $result) {
|
||||
Log::debug(sprintf('Found currency %s based on ID, return it.', $result->code));
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
// try to find it by all other fields.
|
||||
$fields = ['code' => 'findByCodeNull', 'symbol' => 'findBySymbolNull', 'name' => 'findByNameNull'];
|
||||
foreach ($fields as $field => $function) {
|
||||
$value = (string)($data[$field] ?? '');
|
||||
if ('' === $value) {
|
||||
Log::debug(sprintf('Array does not contain a value for %s. Continue', $field));
|
||||
continue;
|
||||
}
|
||||
Log::debug(sprintf('Will search for currency using %s() and argument "%s".', $function, $value));
|
||||
$result = $this->repository->$function($value);
|
||||
if (null !== $result) {
|
||||
Log::debug(sprintf('Found result: Currency #%d, code "%s"', $result->id, $result->code));
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
if (!isset($data['code'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// if still nothing, and fields not null, try to create it
|
||||
$creation = [
|
||||
'code' => $data['code'],
|
||||
'name' => $data['name'] ?? $data['code'],
|
||||
'symbol' => $data['symbol'] ?? $data['code'],
|
||||
'enabled' => true,
|
||||
'decimal_places' => 2,
|
||||
];
|
||||
|
||||
// could be NULL
|
||||
return $this->repository->store($creation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
}
|
||||
|
||||
}
|
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FileProcessorInterface.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\File;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
|
||||
|
||||
/**
|
||||
* Interface FileProcessorInterface
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
interface FileProcessorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Fires the file processor.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function run(): array;
|
||||
|
||||
/**
|
||||
* Set values.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void;
|
||||
}
|
@@ -1,347 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ImportableConverter.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\File;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Carbon\Exceptions\InvalidDateException;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\Placeholder\ImportTransaction;
|
||||
use InvalidArgumentException;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ImportableConverter
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ImportableConverter
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
/** @var AssetAccountMapper */
|
||||
private $assetMapper;
|
||||
/** @var array */
|
||||
private $config;
|
||||
/** @var CurrencyMapper */
|
||||
private $currencyMapper;
|
||||
/** @var TransactionCurrency */
|
||||
private $defaultCurrency;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var array */
|
||||
private $mappedValues;
|
||||
/** @var OpposingAccountMapper */
|
||||
private $opposingMapper;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Convert ImportTransaction to factory-compatible array.
|
||||
*
|
||||
* @param array $importables
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function convert(array $importables): array
|
||||
{
|
||||
$total = count($importables);
|
||||
Log::debug(sprintf('Going to convert %d import transactions', $total));
|
||||
$result = [];
|
||||
/** @var ImportTransaction $importable */
|
||||
foreach ($importables as $index => $importable) {
|
||||
Log::debug(sprintf('Now going to parse importable %d of %d', $index + 1, $total));
|
||||
try {
|
||||
$entry = $this->convertSingle($importable);
|
||||
} catch (FireflyException $e) {
|
||||
$this->repository->addErrorMessage($this->importJob, sprintf('Row #%d: %s', $index + 1, $e->getMessage()));
|
||||
continue;
|
||||
}
|
||||
if (null !== $entry) {
|
||||
$result[] = $entry;
|
||||
Log::debug('Final result of importable converter', $entry);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->config = $importJob->configuration;
|
||||
|
||||
// repository is used for error messages
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
|
||||
// asset account mapper can map asset accounts (makes sense right?)
|
||||
$this->assetMapper = app(AssetAccountMapper::class);
|
||||
$this->assetMapper->setUser($importJob->user);
|
||||
$this->assetMapper->setDefaultAccount($this->config['import-account'] ?? 0);
|
||||
|
||||
// asset account repository is used for currency information
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->accountRepository->setUser($importJob->user);
|
||||
|
||||
// opposing account mapper:
|
||||
$this->opposingMapper = app(OpposingAccountMapper::class);
|
||||
$this->opposingMapper->setUser($importJob->user);
|
||||
|
||||
// currency mapper:
|
||||
$this->currencyMapper = app(CurrencyMapper::class);
|
||||
$this->currencyMapper->setUser($importJob->user);
|
||||
$this->defaultCurrency = app('amount')->getDefaultCurrencyByUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param array $mappedValues
|
||||
*/
|
||||
public function setMappedValues(array $mappedValues): void
|
||||
{
|
||||
$this->mappedValues = $mappedValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $date
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function convertDateValue(string $date = null): ?string
|
||||
{
|
||||
$result = null;
|
||||
if (null !== $date) {
|
||||
try {
|
||||
// add exclamation mark for better parsing. http://php.net/manual/en/datetime.createfromformat.php
|
||||
$dateFormat = $this->config['date-format'] ?? 'Ymd';
|
||||
if ('!' !== $dateFormat[0]) {
|
||||
$dateFormat = '!' . $dateFormat;
|
||||
}
|
||||
$object = Carbon::createFromFormat($dateFormat, $date);
|
||||
$result = $object->format('Y-m-d H:i:s');
|
||||
Log::debug(sprintf('createFromFormat: Turning "%s" into "%s" using "%s"', $date, $result, $this->config['date-format'] ?? 'Ymd'));
|
||||
} catch (InvalidDateException|InvalidArgumentException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportTransaction $importable
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function convertSingle(ImportTransaction $importable): array
|
||||
{
|
||||
Log::debug(sprintf('Description is: "%s"', $importable->description));
|
||||
$foreignAmount = $importable->calculateForeignAmount();
|
||||
$amount = $importable->calculateAmount();
|
||||
|
||||
Log::debug('All meta data: ', $importable->meta);
|
||||
|
||||
if ('' === $amount) {
|
||||
$amount = $foreignAmount;
|
||||
}
|
||||
if ('' === $amount) {
|
||||
throw new FireflyException('No transaction amount information.');
|
||||
}
|
||||
|
||||
// amount is 0? skip
|
||||
if (0 === bccomp($amount, '0')) {
|
||||
throw new FireflyException('Amount of transaction is zero.');
|
||||
}
|
||||
|
||||
$source = $this->assetMapper->map($importable->accountId, $importable->getAccountData());
|
||||
$destination = $this->opposingMapper->map($importable->opposingId, $amount, $importable->getOpposingAccountData());
|
||||
|
||||
// if the amount is positive, switch source and destination (account and opposing account)
|
||||
if (1 === bccomp($amount, '0')) {
|
||||
$source = $this->opposingMapper->map($importable->opposingId, $amount, $importable->getOpposingAccountData());
|
||||
$destination = $this->assetMapper->map($importable->accountId, $importable->getAccountData());
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'%s is positive, so "%s" (#%d) is now source and "%s" (#%d) is now destination.',
|
||||
$amount, $source->name, $source->id, $destination->name, $destination->id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$currency = $this->currencyMapper->map($importable->currencyId, $importable->getCurrencyData());
|
||||
$foreignCurrency = $this->currencyMapper->map($importable->foreignCurrencyId, $importable->getForeignCurrencyData());
|
||||
|
||||
Log::debug(sprintf('"%s" (#%d) is source and "%s" (#%d) is destination.', $source->name, $source->id, $destination->name, $destination->id));
|
||||
|
||||
|
||||
if ($destination->id === $source->id) {
|
||||
throw new FireflyException(
|
||||
sprintf(
|
||||
'Source ("%s", #%d) and destination ("%s", #%d) are the same account.', $source->name, $source->id, $destination->name, $destination->id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$transactionType = $this->getTransactionType($source->accountType->type, $destination->accountType->type);
|
||||
$currency = $currency ?? $this->getCurrency($source, $destination);
|
||||
|
||||
if ('unknown' === $transactionType) {
|
||||
$message = sprintf(
|
||||
'Cannot determine transaction type. Source account is a %s, destination is a %s', $source->accountType->type, $destination->accountType->type
|
||||
);
|
||||
Log::error($message, ['source' => $source->toArray(), 'dest' => $destination->toArray()]);
|
||||
throw new FireflyException($message);
|
||||
}
|
||||
|
||||
return [
|
||||
|
||||
'user' => $this->importJob->user_id,
|
||||
'group_title' => null,
|
||||
'transactions' => [
|
||||
[
|
||||
'user' => $this->importJob->user_id,
|
||||
'type' => strtolower($transactionType),
|
||||
'date' => $this->convertDateValue($importable->date) ?? Carbon::now()->format('Y-m-d H:i:s'),
|
||||
'order' => 0,
|
||||
|
||||
'currency_id' => $currency->id,
|
||||
'currency_code' => null,
|
||||
|
||||
'foreign_currency_id' => $importable->foreignCurrencyId,
|
||||
'foreign_currency_code' => null === $foreignCurrency ? null : $foreignCurrency->code,
|
||||
|
||||
'amount' => $amount,
|
||||
'foreign_amount' => $foreignAmount,
|
||||
|
||||
'description' => $importable->description,
|
||||
|
||||
'source_id' => $source->id,
|
||||
'source_name' => null,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_name' => null,
|
||||
|
||||
'budget_id' => $importable->budgetId,
|
||||
'budget_name' => $importable->budgetName,
|
||||
|
||||
'category_id' => $importable->categoryId,
|
||||
'category_name' => $importable->categoryName,
|
||||
|
||||
'bill_id' => $importable->billId,
|
||||
'bill_name' => $importable->billName,
|
||||
|
||||
'piggy_bank_id' => null,
|
||||
'piggy_bank_name' => null,
|
||||
|
||||
'reconciled' => false,
|
||||
|
||||
'notes' => $importable->note,
|
||||
'tags' => $importable->tags,
|
||||
|
||||
'internal_reference' => $importable->meta['internal_reference'] ?? null,
|
||||
'external_id' => $importable->externalId,
|
||||
'original_source' => $importable->meta['original_source'] ?? null,
|
||||
|
||||
'sepa_cc' => $importable->meta['sepa_cc'] ?? null,
|
||||
'sepa_ct_op' => $importable->meta['sepa_ct_op'] ?? null,
|
||||
'sepa_ct_id' => $importable->meta['sepa_ct_id'] ?? null,
|
||||
'sepa_db' => $importable->meta['sepa_db'] ?? null,
|
||||
'sepa_country' => $importable->meta['sepa_country'] ?? null,
|
||||
'sepa_ep' => $importable->meta['sepa_ep'] ?? null,
|
||||
'sepa_ci' => $importable->meta['sepa_ci'] ?? null,
|
||||
'sepa_batch_id' => $importable->meta['sepa_batch_id'] ?? null,
|
||||
|
||||
'interest_date' => $this->convertDateValue($importable->meta['date_interest'] ?? null),
|
||||
'book_date' => $this->convertDateValue($importable->meta['date_book'] ?? null),
|
||||
'process_date' => $this->convertDateValue($importable->meta['date_process'] ?? null),
|
||||
'due_date' => $this->convertDateValue($importable->meta['date_due'] ?? null),
|
||||
'payment_date' => $this->convertDateValue($importable->meta['date_payment'] ?? null),
|
||||
'invoice_date' => $this->convertDateValue($importable->meta['date_invoice'] ?? null),
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $source
|
||||
* @param Account $destination
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
private function getCurrency(Account $source, Account $destination): TransactionCurrency
|
||||
{
|
||||
$currency = null;
|
||||
if ($destination->accountType->type === AccountType::ASSET) {
|
||||
// destination is asset, might have currency preference:
|
||||
$destinationCurrencyId = (int)$this->accountRepository->getMetaValue($destination, 'currency_id');
|
||||
$currency = 0 === $destinationCurrencyId ? $this->defaultCurrency : $this->currencyMapper->map($destinationCurrencyId, []);
|
||||
Log::debug(sprintf('Destination is an asset account, and has currency preference %s', $currency->code));
|
||||
}
|
||||
|
||||
if ($source->accountType->type === AccountType::ASSET) {
|
||||
// source is asset, might have currency preference:
|
||||
$sourceCurrencyId = (int)$this->accountRepository->getMetaValue($source, 'currency_id');
|
||||
$currency = 0 === $sourceCurrencyId ? $this->defaultCurrency : $this->currencyMapper->map($sourceCurrencyId, []);
|
||||
Log::debug(sprintf('Source is an asset account, and has currency preference %s', $currency->code));
|
||||
}
|
||||
if (null === $currency) {
|
||||
Log::debug(sprintf('Could not map currency, use default (%s)', $this->defaultCurrency->code));
|
||||
$currency = $this->defaultCurrency;
|
||||
}
|
||||
|
||||
return $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
* @param string $destination
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getTransactionType(string $source, string $destination): string
|
||||
{
|
||||
$type = 'unknown';
|
||||
|
||||
$newType = config(sprintf('firefly.account_to_transaction.%s.%s', $source, $destination));
|
||||
if (null !== $newType) {
|
||||
Log::debug(sprintf('Source is %s, destination is %s, so this is a %s.', $source, $destination, $newType));
|
||||
|
||||
return (string)$newType;
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
}
|
@@ -1,73 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ImportableCreator.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\File;
|
||||
|
||||
use FireflyIII\Support\Import\Placeholder\ColumnValue;
|
||||
use FireflyIII\Support\Import\Placeholder\ImportTransaction;
|
||||
|
||||
/**
|
||||
* Takes an array of arrays of ColumnValue objects and returns one (1) ImportTransaction
|
||||
* for each line.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class ImportableCreator
|
||||
*/
|
||||
class ImportableCreator
|
||||
{
|
||||
/**
|
||||
* @param array $sets
|
||||
*
|
||||
* @return array
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
*/
|
||||
public function convertSets(array $sets): array
|
||||
{
|
||||
$return = [];
|
||||
foreach ($sets as $set) {
|
||||
$return[] = $this->convertSet($set);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $set
|
||||
*
|
||||
* @return ImportTransaction
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
*/
|
||||
private function convertSet(array $set): ImportTransaction
|
||||
{
|
||||
$transaction = new ImportTransaction;
|
||||
/** @var ColumnValue $entry */
|
||||
foreach ($set as $entry) {
|
||||
$transaction->addColumnValue($entry);
|
||||
}
|
||||
|
||||
return $transaction;
|
||||
}
|
||||
|
||||
}
|
@@ -1,189 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* LineReader.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\File;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Import\Specifics\SpecificInterface;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use League\Csv\Reader;
|
||||
use League\Csv\Statement;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class LineReader
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class LineReader
|
||||
{
|
||||
/** @var AttachmentHelperInterface */
|
||||
private $attachments;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Grab all lines from the import job.
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getLines(): array
|
||||
{
|
||||
try {
|
||||
$reader = $this->getReader();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
throw new FireflyException('Cannot get reader: ' . $e->getMessage());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
// get all lines from file:
|
||||
$lines = $this->getAllLines($reader);
|
||||
|
||||
// apply specifics and return.
|
||||
return $this->applySpecifics($lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $lines
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function applySpecifics(array $lines): array
|
||||
{
|
||||
$config = $this->importJob->configuration;
|
||||
$validSpecifics = array_keys(config('csv.import_specifics'));
|
||||
$specifics = $config['specifics'] ?? [];
|
||||
$names = array_keys($specifics);
|
||||
$toApply = [];
|
||||
foreach ($names as $name) {
|
||||
if (!in_array($name, $validSpecifics, true)) {
|
||||
continue;
|
||||
}
|
||||
$class = config(sprintf('csv.import_specifics.%s', $name));
|
||||
$toApply[] = app($class);
|
||||
}
|
||||
$return = [];
|
||||
/** @var array $line */
|
||||
foreach ($lines as $line) {
|
||||
/** @var SpecificInterface $specific */
|
||||
foreach ($toApply as $specific) {
|
||||
$line = $specific->run($line);
|
||||
}
|
||||
$return[] = $line;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getAllLines(Reader $reader): array
|
||||
{
|
||||
/** @var array $config */
|
||||
$config = $this->importJob->configuration;
|
||||
Log::debug('now in getLines()');
|
||||
$offset = isset($config['has-headers']) && true === $config['has-headers'] ? 1 : 0;
|
||||
try {
|
||||
$stmt = (new Statement)->offset($offset);
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
throw new FireflyException(sprintf('Could not execute statement: %s', $e->getMessage()));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
$results = $stmt->process($reader);
|
||||
$lines = [];
|
||||
foreach ($results as $line) {
|
||||
|
||||
$lineValues = array_values($line);
|
||||
|
||||
// do a first sanity check on whatever comes out of the CSV file.
|
||||
array_walk(
|
||||
$lineValues, static function ($element) {
|
||||
$element = str_replace(' ', ' ', (string)$element);
|
||||
|
||||
return $element;
|
||||
}
|
||||
);
|
||||
|
||||
$lines[] = $lineValues;
|
||||
}
|
||||
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Reader
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getReader(): Reader
|
||||
{
|
||||
Log::debug('Now in getReader()');
|
||||
$content = '';
|
||||
$collection = $this->repository->getAttachments($this->importJob);
|
||||
/** @var Attachment $attachment */
|
||||
foreach ($collection as $attachment) {
|
||||
if ('import_file' === $attachment->filename) {
|
||||
$content = $this->attachments->getAttachmentContent($attachment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$reader = Reader::createFromString($content);
|
||||
try {
|
||||
$reader->setDelimiter($config['delimiter'] ?? ',');
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (\League\Csv\Exception $e) {
|
||||
throw new FireflyException(sprintf('Cannot set delimiter: %s', $e->getMessage()));
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return $reader;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,134 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* MappedValuesValidator.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\File;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class MappedValuesValidator
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class MappedValuesValidator
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepos;
|
||||
/** @var BillRepositoryInterface */
|
||||
private $billRepos;
|
||||
/** @var BudgetRepositoryInterface */
|
||||
private $budgetRepos;
|
||||
/** @var CategoryRepositoryInterface */
|
||||
private $catRepos;
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $currencyRepos;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
$this->billRepos = app(BillRepositoryInterface::class);
|
||||
$this->budgetRepos = app(BudgetRepositoryInterface::class);
|
||||
$this->catRepos = app(CategoryRepositoryInterface::class);
|
||||
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->accountRepos->setUser($importJob->user);
|
||||
$this->currencyRepos->setUser($importJob->user);
|
||||
$this->billRepos->setUser($importJob->user);
|
||||
$this->budgetRepos->setUser($importJob->user);
|
||||
$this->catRepos->setUser($importJob->user);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $mappings
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*
|
||||
*/
|
||||
public function validate(array $mappings): array
|
||||
{
|
||||
$return = [];
|
||||
Log::debug('Now in validateMappedValues()');
|
||||
foreach ($mappings as $role => $values) {
|
||||
Log::debug(sprintf('Now at role "%s"', $role));
|
||||
$values = array_unique($values);
|
||||
if (count($values) > 0) {
|
||||
switch ($role) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Cannot validate mapped values for role "%s"', $role)); // @codeCoverageIgnore
|
||||
case 'opposing-id':
|
||||
case 'account-id':
|
||||
$set = $this->accountRepos->getAccountsById($values);
|
||||
$valid = $set->pluck('id')->toArray();
|
||||
$return[$role] = $valid;
|
||||
break;
|
||||
case 'currency-id':
|
||||
case 'foreign-currency-id':
|
||||
$set = $this->currencyRepos->getByIds($values);
|
||||
$valid = $set->pluck('id')->toArray();
|
||||
$return[$role] = $valid;
|
||||
break;
|
||||
case 'bill-id':
|
||||
$set = $this->billRepos->getByIds($values);
|
||||
$valid = $set->pluck('id')->toArray();
|
||||
$return[$role] = $valid;
|
||||
break;
|
||||
case 'budget-id':
|
||||
$set = $this->budgetRepos->getByIds($values);
|
||||
$valid = $set->pluck('id')->toArray();
|
||||
$return[$role] = $valid;
|
||||
break;
|
||||
case 'category-id':
|
||||
Log::debug('Going to validate these category ids: ', $values);
|
||||
$set = $this->catRepos->getByIds($values);
|
||||
$valid = $set->pluck('id')->toArray();
|
||||
$return[$role] = $valid;
|
||||
Log::debug('Valid category IDs are: ', $valid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
@@ -1,216 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* MappingConverger.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\File;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\Placeholder\ColumnValue;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class MappingConverger
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class MappingConverger
|
||||
{
|
||||
/** @var array */
|
||||
private $doMapping;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var array */
|
||||
private $mappedValues;
|
||||
/** @var array */
|
||||
private $mapping;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
/** @var array */
|
||||
private $roles;
|
||||
|
||||
/**
|
||||
* Each cell in the CSV file could be linked to a mapped value. This depends on the role of
|
||||
* the column and the content of the cell. This method goes over all cells, and using their
|
||||
* associated role, will see if it has been linked to a mapped value. These mapped values
|
||||
* are all IDs of objects in the Firefly III database.
|
||||
*
|
||||
* If such a mapping exists the role of the cell changes to whatever the mapped value is.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* - Cell with content "Checking Account" and role "account-name". Mapping links "Checking Account" to account-id 2.
|
||||
* - Cell with content "Checking Account" and role "description". No mapping, so value and role remains the same.
|
||||
*
|
||||
* @param array $lines
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function converge(array $lines): array
|
||||
{
|
||||
Log::debug('Start converging process.');
|
||||
$collection = [];
|
||||
$total = count($lines);
|
||||
/** @var array $line */
|
||||
foreach ($lines as $lineIndex => $line) {
|
||||
Log::debug(sprintf('Now converging line %d out of %d.', $lineIndex + 1, $total));
|
||||
$set = $this->processLine($line);
|
||||
$collection[] = $set;
|
||||
}
|
||||
|
||||
return $collection;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public function getMappedValues(): array
|
||||
{
|
||||
return $this->mappedValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->mappedValues = [];
|
||||
$config = $importJob->configuration;
|
||||
$this->roles = $config['column-roles'] ?? [];
|
||||
$this->mapping = $config['column-mapping-config'] ?? [];
|
||||
$this->doMapping = $config['column-do-mapping'] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* If the value in the column is mapped to a certain ID,
|
||||
* the column where this ID must be placed will change.
|
||||
*
|
||||
* For example, if you map role "budget-name" with value "groceries" to 1,
|
||||
* then that should become the budget-id. Not the name.
|
||||
*
|
||||
* @param int $column
|
||||
* @param int $mapped
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getRoleForColumn(int $column, int $mapped): string
|
||||
{
|
||||
$role = $this->roles[$column] ?? '_ignore';
|
||||
if (0 === $mapped) {
|
||||
Log::debug(sprintf('Column #%d with role "%s" is not mapped.', $column, $role));
|
||||
|
||||
return $role;
|
||||
}
|
||||
if (!(isset($this->doMapping[$column]) && true === $this->doMapping[$column])) {
|
||||
|
||||
// if the mapping has been filled in already by a role with a higher priority,
|
||||
// ignore the mapping.
|
||||
Log::debug(sprintf('Column #%d ("%s") has something.', $column, $role));
|
||||
|
||||
|
||||
return $role;
|
||||
}
|
||||
$roleMapping = [
|
||||
'account-id' => 'account-id',
|
||||
'account-name' => 'account-id',
|
||||
'account-iban' => 'account-id',
|
||||
'account-number' => 'account-id',
|
||||
'bill-id' => 'bill-id',
|
||||
'bill-name' => 'bill-id',
|
||||
'budget-id' => 'budget-id',
|
||||
'budget-name' => 'budget-id',
|
||||
'currency-id' => 'currency-id',
|
||||
'currency-name' => 'currency-id',
|
||||
'currency-code' => 'currency-id',
|
||||
'currency-symbol' => 'currency-id',
|
||||
'category-id' => 'category-id',
|
||||
'category-name' => 'category-id',
|
||||
'foreign-currency-id' => 'foreign-currency-id',
|
||||
'foreign-currency-code' => 'foreign-currency-id',
|
||||
'opposing-id' => 'opposing-id',
|
||||
'opposing-name' => 'opposing-id',
|
||||
'opposing-iban' => 'opposing-id',
|
||||
'opposing-number' => 'opposing-id',
|
||||
];
|
||||
if (!isset($roleMapping[$role])) {
|
||||
throw new FireflyException(sprintf('Cannot indicate new role for mapped role "%s"', $role)); // @codeCoverageIgnore
|
||||
}
|
||||
$newRole = $roleMapping[$role];
|
||||
Log::debug(sprintf('Role was "%s", but because of mapping (mapped to #%d), role becomes "%s"', $role, $mapped, $newRole));
|
||||
|
||||
// also store the $mapped values in a "mappedValues" array.
|
||||
$this->mappedValues[$newRole][] = $mapped;
|
||||
Log::debug(sprintf('Values mapped to role "%s" are: ', $newRole), $this->mappedValues[$newRole]);
|
||||
|
||||
return $newRole;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $line
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function processLine(array $line): array
|
||||
{
|
||||
$return = [];
|
||||
foreach ($line as $columnIndex => $value) {
|
||||
$value = trim($value);
|
||||
$originalRole = $this->roles[$columnIndex] ?? '_ignore';
|
||||
Log::debug(sprintf('Now at column #%d (%s), value "%s"', $columnIndex, $originalRole, $value));
|
||||
if ('_ignore' !== $originalRole && '' != $value) {
|
||||
|
||||
// is a mapped value present?
|
||||
$mapped = $this->mapping[$columnIndex][$value] ?? 0;
|
||||
// the role might change.
|
||||
$role = $this->getRoleForColumn($columnIndex, $mapped);
|
||||
|
||||
$columnValue = new ColumnValue;
|
||||
$columnValue->setValue($value);
|
||||
$columnValue->setRole($role);
|
||||
$columnValue->setMappedValue($mapped);
|
||||
$columnValue->setOriginalRole($originalRole);
|
||||
$return[] = $columnValue;
|
||||
}
|
||||
if ('' === $value) {
|
||||
Log::debug('Column skipped because value is empty.');
|
||||
}
|
||||
}
|
||||
// add a special column value for the "source"
|
||||
$columnValue = new ColumnValue;
|
||||
$columnValue->setValue(sprintf('csv-import-v%s', config('firefly.version')));
|
||||
$columnValue->setMappedValue(0);
|
||||
$columnValue->setRole('original-source');
|
||||
$return[] = $columnValue;
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
@@ -1,121 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* OFXProcessor.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\File;
|
||||
|
||||
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Log;
|
||||
use OfxParser\Entities\BankAccount;
|
||||
use OfxParser\Entities\Transaction;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class OFXProcessor
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class OFXProcessor implements FileProcessorInterface
|
||||
{
|
||||
/** @var AttachmentHelperInterface */
|
||||
private $attachments;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Fires the file processor.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function run(): array
|
||||
{
|
||||
$collection = $this->repository->getAttachments($this->importJob);
|
||||
$content = '';
|
||||
/** @var Attachment $attachment */
|
||||
foreach ($collection as $attachment) {
|
||||
if ('import_file' === $attachment->filename) {
|
||||
$content = $this->attachments->getAttachmentContent($attachment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
try {
|
||||
Log::debug('Now in OFXProcessor() run');
|
||||
$ofxParser = new \OfxParser\Parser();
|
||||
$ofx = $ofxParser->loadFromString($content);
|
||||
} catch (\Exception $e) {
|
||||
echo $e->getMessage();
|
||||
exit;
|
||||
}
|
||||
reset($ofx->bankAccounts);
|
||||
/** @var BankAccount $bankAccount */
|
||||
foreach ($ofx->bankAccounts as $bankAccount) {
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($bankAccount->statement->transactions as $transaction) {
|
||||
//var_dump($transaction);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// // Get the statement start and end dates
|
||||
// $startDate = $bankAccount->statement->startDate;
|
||||
// $endDate = $bankAccount->statement->endDate;
|
||||
// var_dump($startDate);
|
||||
// var_dump($endDate);
|
||||
//
|
||||
// // Get the statement transactions for the account
|
||||
// $transactions = $bankAccount->statement->transactions;
|
||||
// foreach($transactions as $transaction) {
|
||||
// var_dump($transaction);
|
||||
// }
|
||||
//
|
||||
// die('I am here.');
|
||||
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set values.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
Log::debug('Now in setImportJob()');
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
|
||||
$this->repository->setUser($importJob->user);
|
||||
|
||||
}
|
||||
}
|
@@ -1,144 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* OpposingAccountMapper.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\File;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class OpposingAccountMapper
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class OpposingAccountMapper
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $repository;
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @param int|null $accountId
|
||||
* @param string $amount
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*
|
||||
*/
|
||||
public function map(?int $accountId, string $amount, array $data): Account
|
||||
{
|
||||
Log::debug(sprintf('Now in OpposingAccountMapper::map(%d, "%s")', $accountId, $amount), $data);
|
||||
// default assumption is we're looking for an expense account.
|
||||
$expectedType = AccountType::EXPENSE;
|
||||
$result = null;
|
||||
Log::debug(sprintf('Going to search for accounts of type %s', $expectedType));
|
||||
if (1 === bccomp($amount, '0')) {
|
||||
// more than zero.
|
||||
$expectedType = AccountType::REVENUE;
|
||||
Log::debug(sprintf('Because amount is %s, will instead search for accounts of type %s', $amount, $expectedType));
|
||||
}
|
||||
|
||||
// append expected types with liability types:
|
||||
$expectedTypes = [$expectedType, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
|
||||
|
||||
|
||||
if ((int)$accountId > 0) {
|
||||
// find any account with this ID:
|
||||
$result = $this->repository->findNull($accountId);
|
||||
if (null !== $result && (in_array($result->accountType->type, $expectedTypes, true) || $result->accountType->type === AccountType::ASSET)) {
|
||||
Log::debug(sprintf('Found account "%s" (%s) based on given ID %d. Return it!', $result->name, $result->accountType->type, $accountId));
|
||||
|
||||
return $result;
|
||||
}
|
||||
if (null !== $result && !in_array($result->accountType->type, $expectedTypes, true)) {
|
||||
Log::warning(
|
||||
sprintf(
|
||||
'Found account "%s" (%s) based on given ID %d, but need a %s. Return nothing.', $result->name, $result->accountType->type, $accountId,
|
||||
$expectedType
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
// if result is not null, system has found an account
|
||||
// but it's of the wrong type. If we dont have a name, use
|
||||
// the result's name, iban in the search below.
|
||||
if (null !== $result && '' === (string)($data['name'] ?? '')) {
|
||||
Log::debug(sprintf('Will search for account with name "%s" instead of NULL.', $result->name));
|
||||
$data['name'] = $result->name;
|
||||
}
|
||||
if (null !== $result && '' !== (string)$result->iban && '' === ($data['iban'] ?? '')) {
|
||||
Log::debug(sprintf('Will search for account with IBAN "%s" instead of NULL.', $result->iban));
|
||||
$data['iban'] = $result->iban;
|
||||
}
|
||||
|
||||
// first search for $expectedType, then find asset:
|
||||
$searchTypes = [$expectedType, AccountType::ASSET, AccountType::DEBT, AccountType::MORTGAGE, AccountType::LOAN];
|
||||
foreach ($searchTypes as $type) {
|
||||
// find by (respectively):
|
||||
// IBAN, accountNumber, name,
|
||||
$fields = ['iban' => 'findByIbanNull', 'number' => 'findByAccountNumber', 'name' => 'findByName'];
|
||||
foreach ($fields as $field => $function) {
|
||||
$value = (string)($data[$field] ?? '');
|
||||
if ('' === $value) {
|
||||
Log::debug(sprintf('Array does not contain a value for %s. Continue', $field));
|
||||
continue;
|
||||
}
|
||||
Log::debug(sprintf('Will search for account of type "%s" using %s() and argument "%s".', $type, $function, $value));
|
||||
$result = $this->repository->$function($value, [$type]);
|
||||
if (null !== $result) {
|
||||
Log::debug(sprintf('Found result: Account #%d, named "%s"', $result->id, $result->name));
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
// not found? Create it!
|
||||
$creation = [
|
||||
'name' => $data['name'] ?? '(no name)',
|
||||
'iban' => $data['iban'] ?? null,
|
||||
'account_number' => $data['number'] ?? null,
|
||||
'account_type_id' => null,
|
||||
'account_type' => $expectedType,
|
||||
'active' => true,
|
||||
'BIC' => $data['bic'] ?? null,
|
||||
];
|
||||
Log::debug('Will try to store a new account: ', $creation);
|
||||
|
||||
return $this->repository->store($creation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
}
|
||||
}
|
@@ -1,193 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageImportDataHandler.php
|
||||
* Copyright (c) 2019 https://github.com/bnw
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\FinTS;
|
||||
|
||||
|
||||
use Fhp\Model\StatementOfAccount\Transaction;
|
||||
use Fhp\Model\StatementOfAccount\Transaction as FinTSTransaction;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account as LocalAccount;
|
||||
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\Support\FinTS\MetadataParser;
|
||||
use FireflyIII\Support\Import\Routine\File\OpposingAccountMapper;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class StageImportDataHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class StageImportDataHandler
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var OpposingAccountMapper */
|
||||
private $mapper;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
/** @var array */
|
||||
private $transactions;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransactions(): array
|
||||
{
|
||||
return $this->transactions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::debug('Now in StageImportDataHandler::run()');
|
||||
|
||||
$localAccount = $this->accountRepository->findNull((int)$this->importJob->configuration['local_account']);
|
||||
if (null === $localAccount) {
|
||||
throw new FireflyException(sprintf('Cannot find Firefly account with id #%d ', $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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FinTSTransaction $transaction
|
||||
* @param LocalAccount $source
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function convertTransaction(FinTSTransaction $transaction, LocalAccount $source): array
|
||||
{
|
||||
Log::debug(sprintf('Start converting transaction %s', $transaction->getDescription1()));
|
||||
|
||||
$amount = (string)$transaction->getAmount();
|
||||
$debitOrCredit = $transaction->getCreditDebit();
|
||||
// assume deposit.
|
||||
$type = TransactionType::DEPOSIT;
|
||||
Log::debug(sprintf('Amount is %s', $amount));
|
||||
|
||||
// inverse if not.
|
||||
if ($debitOrCredit !== Transaction::CD_CREDIT) {
|
||||
$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.');
|
||||
}
|
||||
|
||||
$metadataParser = new MetadataParser();
|
||||
$description = $metadataParser->getDescription($transaction);
|
||||
|
||||
$storeData = [
|
||||
'user' => $this->importJob->user_id,
|
||||
'type' => $type,
|
||||
'date' => $transaction->getValutaDate()->format('Y-m-d'),
|
||||
'description' => null,
|
||||
'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:
|
||||
[
|
||||
'type' => $type,
|
||||
'description' => $description,
|
||||
'date' => $transaction->getValutaDate()->format('Y-m-d'),
|
||||
'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;
|
||||
}
|
||||
}
|
@@ -1,153 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageAuthenticatedHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Spectre;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Services\Spectre\Object\Account;
|
||||
use FireflyIII\Services\Spectre\Object\Login;
|
||||
use FireflyIII\Services\Spectre\Request\ListAccountsRequest;
|
||||
use FireflyIII\Services\Spectre\Request\ListLoginsRequest;
|
||||
use FireflyIII\Support\Import\Information\GetSpectreCustomerTrait;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class StageAuthenticatedHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class StageAuthenticatedHandler
|
||||
{
|
||||
use GetSpectreCustomerTrait;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* User has selected a login (a bank). Will grab all accounts from this bank.
|
||||
* Then make user pick some to import from.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::debug('Now in StageAuthenticatedHandler::run()');
|
||||
// grab a list of logins.
|
||||
$config = $this->importJob->configuration;
|
||||
$logins = $config['all-logins'] ?? [];
|
||||
Log::debug(sprintf('%d logins in config', count($logins)));
|
||||
if (0 === count($logins)) {
|
||||
// get logins from Spectre.
|
||||
$logins = $this->getLogins();
|
||||
$config['all-logins'] = $logins;
|
||||
}
|
||||
|
||||
$selectedLogin = $config['selected-login'] ?? 0;
|
||||
$login = null;
|
||||
Log::debug(sprintf('$selectedLogin is %d', $selectedLogin));
|
||||
foreach ($logins as $loginArray) {
|
||||
$loginId = $loginArray['id'] ?? -1;
|
||||
if ($loginId === $selectedLogin) {
|
||||
$login = new Login($loginArray);
|
||||
Log::debug(sprintf('Selected login "%s" ("%s") which is in the array with logins.', $login->getProviderName(), $login->getCountryCode()));
|
||||
}
|
||||
}
|
||||
if (null === $login) {
|
||||
$login = new Login($logins[0]);
|
||||
Log::debug(sprintf('Login is null, simply use the first one "%s" ("%s") from the array.', $login->getProviderName(), $login->getCountryCode()));
|
||||
}
|
||||
|
||||
// with existing login we can grab accounts from this login.
|
||||
$accounts = $this->getAccounts($login);
|
||||
$config['accounts'] = [];
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
Log::debug(sprintf('Found account #%d ("%s") within Login.', $account->getId(), $account->getName()));
|
||||
$config['accounts'][] = $account->toArray();
|
||||
}
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Login $login
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getAccounts(Login $login): array
|
||||
{
|
||||
Log::debug(sprintf('Now in StageAuthenticatedHandler::getAccounts() for login #%d', $login->getId()));
|
||||
/** @var ListAccountsRequest $request */
|
||||
$request = app(ListAccountsRequest::class);
|
||||
$request->setUser($this->importJob->user);
|
||||
$request->setLogin($login);
|
||||
$request->call();
|
||||
$accounts = $request->getAccounts();
|
||||
Log::debug(sprintf('Found %d accounts using login', count($accounts)));
|
||||
|
||||
return $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getLogins(): array
|
||||
{
|
||||
Log::debug('Now in StageAuthenticatedHandler::getLogins().');
|
||||
$customer = $this->getCustomer($this->importJob);
|
||||
|
||||
/** @var ListLoginsRequest $request */
|
||||
$request = app(ListLoginsRequest::class);
|
||||
$request->setUser($this->importJob->user);
|
||||
$request->setCustomer($customer);
|
||||
$request->call();
|
||||
$logins = $request->getLogins();
|
||||
$return = [];
|
||||
|
||||
Log::debug(sprintf('Found %d logins in users Spectre account.', count($logins)));
|
||||
|
||||
/** @var Login $login */
|
||||
foreach ($logins as $login) {
|
||||
$return[] = $login->toArray();
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,291 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageImportDataHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Spectre;
|
||||
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account as LocalAccount;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Services\Spectre\Object\Account as SpectreAccount;
|
||||
use FireflyIII\Services\Spectre\Object\Transaction as SpectreTransaction;
|
||||
use FireflyIII\Services\Spectre\Request\ListTransactionsRequest;
|
||||
use FireflyIII\Support\Import\Routine\File\OpposingAccountMapper;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class StageImportDataHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
*/
|
||||
class StageImportDataHandler
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var OpposingAccountMapper */
|
||||
private $mapper;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::debug('Now in StageImportDataHandler::run()');
|
||||
$config = $this->importJob->configuration;
|
||||
$accounts = $config['accounts'] ?? [];
|
||||
Log::debug(sprintf('Count of accounts in array is %d', count($accounts)));
|
||||
if (0 === count($accounts)) {
|
||||
throw new FireflyException('There are no accounts in this import job. Cannot continue.'); // @codeCoverageIgnore
|
||||
}
|
||||
$toImport = $config['account_mapping'] ?? [];
|
||||
$totalSet = [[]];
|
||||
foreach ($toImport as $spectreId => $localId) {
|
||||
if ((int)$localId > 0) {
|
||||
Log::debug(sprintf('Will get transactions from Spectre account #%d and save them in Firefly III account #%d', $spectreId, $localId));
|
||||
$spectreAccount = $this->getSpectreAccount((int)$spectreId);
|
||||
$localAccount = $this->getLocalAccount((int)$localId);
|
||||
$merge = $this->getTransactions($spectreAccount, $localAccount);
|
||||
$totalSet[] = $merge;
|
||||
Log::debug(
|
||||
sprintf('Found %d transactions in account "%s" (%s)', count($merge), $spectreAccount->getName(), $spectreAccount->getCurrencyCode())
|
||||
);
|
||||
continue;
|
||||
}
|
||||
Log::debug(sprintf('Local account is = zero, will not import from Spectr account with ID #%d', $spectreId));
|
||||
}
|
||||
$totalSet = array_merge(...$totalSet);
|
||||
Log::debug(sprintf('Found %d transactions in total.', count($totalSet)));
|
||||
|
||||
$this->repository->setTransactions($this->importJob, $totalSet);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->mapper = app(OpposingAccountMapper::class);
|
||||
$this->accountRepository->setUser($importJob->user);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->mapper->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $transactions
|
||||
* @param SpectreAccount $spectreAccount
|
||||
* @param LocalAccount $originalSource
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
private function convertToArray(array $transactions, SpectreAccount $spectreAccount, LocalAccount $originalSource): array
|
||||
{
|
||||
$array = [];
|
||||
$total = count($transactions);
|
||||
Log::debug(sprintf('Now in StageImportDataHandler::convertToArray() with count %d', count($transactions)));
|
||||
/** @var SpectreTransaction $transaction */
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
Log::debug(sprintf('Now creating array for transaction %d of %d', $index + 1, $total));
|
||||
$extra = [];
|
||||
if (null !== $transaction->getExtra()) {
|
||||
$extra = $transaction->getExtra()->toArray();
|
||||
}
|
||||
$destinationData = $transaction->getOpposingAccountData();
|
||||
$amount = $transaction->getAmount();
|
||||
$source = $originalSource;
|
||||
$destination = $this->mapper->map(null, $amount, $destinationData);
|
||||
$notes = trans('import.imported_from_account', ['account' => $spectreAccount->getName()]) . ' ' . "\n";
|
||||
$foreignAmount = null;
|
||||
$foreignCurrencyCode = null;
|
||||
|
||||
$currencyCode = $transaction->getCurrencyCode();
|
||||
$type = 'withdrawal';
|
||||
// switch source and destination if amount is greater than zero.
|
||||
if (1 === bccomp($amount, '0')) {
|
||||
[$source, $destination] = [$destination, $source];
|
||||
$type = 'deposit';
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Mapped destination to #%d ("%s")', $destination->id, $destination->name));
|
||||
Log::debug(sprintf('Set source to #%d ("%s")', $source->id, $source->name));
|
||||
|
||||
// put some data in tags:
|
||||
$tags = [];
|
||||
$tags[] = $transaction->getMode();
|
||||
$tags[] = $transaction->getStatus();
|
||||
if ($transaction->isDuplicated()) {
|
||||
$tags[] = 'possibly-duplicated';
|
||||
}
|
||||
|
||||
// get extra fields:
|
||||
foreach ($extra as $key => $value) {
|
||||
if ('' === (string)$value) {
|
||||
continue;
|
||||
}
|
||||
switch ($key) {
|
||||
case 'original_category':
|
||||
case 'original_subcategory':
|
||||
case 'customer_category_code':
|
||||
case 'customer_category_name':
|
||||
$tags[] = $value;
|
||||
break;
|
||||
case 'original_amount':
|
||||
$foreignAmount = $value;
|
||||
Log::debug(sprintf('Foreign amount is now %s', $value));
|
||||
break;
|
||||
case 'original_currency_code':
|
||||
$foreignCurrencyCode = $value;
|
||||
Log::debug(sprintf('Foreign currency code is now %s', $value));
|
||||
break;
|
||||
case 'time':
|
||||
// ignore time because it breaks the duplicate detector.
|
||||
break;
|
||||
default:
|
||||
$notes .= $key . ': ' . $value . ' ' . "\n"; // for newline in Markdown.
|
||||
}
|
||||
}
|
||||
|
||||
$entry = [
|
||||
// transaction data:
|
||||
'transactions' => [
|
||||
[
|
||||
'date' => $transaction->getMadeOn()->format('Y-m-d'),
|
||||
'tags' => $tags,
|
||||
'user' => $this->importJob->user_id,
|
||||
'notes' => trim($notes),
|
||||
|
||||
// all custom fields:
|
||||
'external_id' => (string)$transaction->getId(),
|
||||
|
||||
// journal data:
|
||||
'description' => $transaction->getDescription(),
|
||||
'piggy_bank_id' => null,
|
||||
'piggy_bank_name' => null,
|
||||
'bill_id' => null,
|
||||
'bill_name' => null,
|
||||
'original-source' => sprintf('spectre-v%s', config('firefly.version')),
|
||||
'type' => $type,
|
||||
'currency_id' => null,
|
||||
'currency_code' => $currencyCode,
|
||||
'amount' => $amount,
|
||||
'budget_id' => null,
|
||||
'budget_name' => null,
|
||||
'category_id' => null,
|
||||
'category_name' => $transaction->getCategory(),
|
||||
'source_id' => $source->id,
|
||||
'source_name' => null,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_name' => null,
|
||||
'foreign_currency_id' => null,
|
||||
'foreign_currency_code' => $foreignCurrencyCode,
|
||||
'foreign_amount' => $foreignAmount,
|
||||
'reconciled' => false,
|
||||
'identifier' => 0,
|
||||
],
|
||||
],
|
||||
];
|
||||
$array[] = $entry;
|
||||
}
|
||||
Log::debug(sprintf('Return %d entries', count($array)));
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $accountId
|
||||
*
|
||||
* @return LocalAccount
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getLocalAccount(int $accountId): LocalAccount
|
||||
{
|
||||
$account = $this->accountRepository->findNull($accountId);
|
||||
if (null === $account) {
|
||||
throw new FireflyException(sprintf('Cannot find Firefly III asset account with ID #%d. Job must stop now.', $accountId)); // @codeCoverageIgnore
|
||||
}
|
||||
if (!in_array($account->accountType->type, [AccountType::ASSET, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT], true)) {
|
||||
throw new FireflyException(
|
||||
sprintf('Account with ID #%d is not an asset/loan/mortgage/debt account. Job must stop now.', $accountId)
|
||||
); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $accountId
|
||||
*
|
||||
* @return SpectreAccount
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getSpectreAccount(int $accountId): SpectreAccount
|
||||
{
|
||||
$config = $this->importJob->configuration;
|
||||
$accounts = $config['accounts'] ?? [];
|
||||
foreach ($accounts as $account) {
|
||||
$spectreId = (int)($account['id'] ?? 0.0);
|
||||
if ($spectreId === $accountId) {
|
||||
return new SpectreAccount($account);
|
||||
}
|
||||
}
|
||||
throw new FireflyException(sprintf('Cannot find Spectre account with ID #%d in configuration. Job will exit.', $accountId)); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SpectreAccount $spectreAccount
|
||||
* @param LocalAccount $localAccount
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getTransactions(SpectreAccount $spectreAccount, LocalAccount $localAccount): array
|
||||
{
|
||||
// grab all transactions
|
||||
/** @var ListTransactionsRequest $request */
|
||||
$request = app(ListTransactionsRequest::class);
|
||||
$request->setUser($this->importJob->user);
|
||||
|
||||
$request->setAccount($spectreAccount);
|
||||
$request->call();
|
||||
|
||||
$transactions = $request->getTransactions();
|
||||
|
||||
return $this->convertToArray($transactions, $spectreAccount, $localAccount);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,109 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageNewHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Spectre;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Services\Spectre\Object\Login;
|
||||
use FireflyIII\Services\Spectre\Request\ListLoginsRequest;
|
||||
use FireflyIII\Support\Import\Information\GetSpectreCustomerTrait;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class StageNewHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
*/
|
||||
class StageNewHandler
|
||||
{
|
||||
use GetSpectreCustomerTrait;
|
||||
/** @var int */
|
||||
private $countLogins = 0;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return int
|
||||
*/
|
||||
public function getCountLogins(): int
|
||||
{
|
||||
return $this->countLogins;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tasks for this stage:
|
||||
*
|
||||
* - List all of the users logins.
|
||||
* - If zero, return to "get-token" stage and make user make a login. That stage redirects here.
|
||||
* - If one or more, list and let user select.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::debug('Now in ManageLoginsHandler::run()');
|
||||
$customer = $this->getCustomer($this->importJob);
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
|
||||
Log::debug('Going to get a list of logins.');
|
||||
/** @var ListLoginsRequest $request */
|
||||
$request = app(ListLoginsRequest::class);
|
||||
$request->setUser($this->importJob->user);
|
||||
$request->setCustomer($customer);
|
||||
$request->call();
|
||||
|
||||
$list = $request->getLogins();
|
||||
|
||||
// count is zero?
|
||||
$this->countLogins = count($list);
|
||||
Log::debug(sprintf('Number of logins is %d', $this->countLogins));
|
||||
if ($this->countLogins > 0) {
|
||||
$store = [];
|
||||
/** @var Login $login */
|
||||
foreach ($list as $login) {
|
||||
$store[] = $login->toArray();
|
||||
}
|
||||
|
||||
$config['all-logins'] = $store;
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
Log::debug('Stored all logins in configuration.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
}
|
@@ -1,82 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* GetAccountsHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://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
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
@@ -1,290 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ImportDataHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Ynab;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Services\Ynab\Request\GetTransactionsRequest;
|
||||
use FireflyIII\Support\Import\Routine\File\OpposingAccountMapper;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ImportDataHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ImportDataHandler
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
/** @var TransactionCurrency */
|
||||
private $defaultCurrency;
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var OpposingAccountMapper */
|
||||
private $mapper;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Get list of accounts for the selected budget.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$this->defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->importJob->user);
|
||||
$token = $config['access_token'];
|
||||
// make request for each mapping:
|
||||
$mapping = $config['mapping'] ?? [];
|
||||
$total = [[]];
|
||||
|
||||
/**
|
||||
* @var string $ynabId
|
||||
* @var string $localId
|
||||
*/
|
||||
foreach ($mapping as $ynabId => $localId) {
|
||||
$localAccount = $this->getLocalAccount((int)$localId);
|
||||
$transactions = $this->getTransactions($token, $ynabId);
|
||||
$converted = $this->convertToArray($transactions, $localAccount);
|
||||
$total[] = $converted;
|
||||
}
|
||||
|
||||
$totalSet = array_merge(...$total);
|
||||
Log::debug(sprintf('Found %d transactions in total.', count($totalSet)));
|
||||
$this->repository->setTransactions($this->importJob, $totalSet);
|
||||
|
||||
// assuming this works, store today's date as a preference
|
||||
// (combined with the budget from which FF3 imported)
|
||||
$budgetId = $this->getSelectedBudget()['id'] ?? '';
|
||||
if ('' !== $budgetId) {
|
||||
app('preferences')->set('ynab_' . $budgetId, Carbon::now()->format('Y-m-d'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->mapper = app(OpposingAccountMapper::class);
|
||||
$this->accountRepository->setUser($importJob->user);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->mapper->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $transactions
|
||||
* @param Account $localAccount
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function convertToArray(array $transactions, Account $localAccount): array
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$array = [];
|
||||
$total = count($transactions);
|
||||
$budget = $this->getSelectedBudget();
|
||||
Log::debug(sprintf('Now in StageImportDataHandler::convertToArray() with count %d', count($transactions)));
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
$description = $transaction['memo'] ?? '(empty)';
|
||||
Log::debug(sprintf('Now creating array for transaction %d of %d ("%s")', $index + 1, $total, $description));
|
||||
$amount = (string)($transaction['amount'] ?? 0);
|
||||
if ('0' === $amount) {
|
||||
Log::debug(sprintf('Amount is zero (%s), skip this transaction.', $amount));
|
||||
continue;
|
||||
}
|
||||
Log::debug(sprintf('Amount detected is %s', $amount));
|
||||
$source = $localAccount;
|
||||
$type = 'withdrawal';
|
||||
$tags = [
|
||||
$transaction['cleared'] ?? '',
|
||||
$transaction['approved'] ? 'approved' : 'not-approved',
|
||||
$transaction['flag_color'] ?? '',
|
||||
];
|
||||
$possibleDestinationId = null;
|
||||
if (null !== $transaction['transfer_account_id']) {
|
||||
// indication that it is a transfer.
|
||||
$possibleDestinationId = $config['mapping'][$transaction['transfer_account_id']] ?? null;
|
||||
Log::debug(sprintf('transfer_account_id has value %s', $transaction['transfer_account_id']));
|
||||
Log::debug(sprintf('Can map this to the following FF3 asset account: %d', $possibleDestinationId));
|
||||
$type = 'transfer';
|
||||
|
||||
}
|
||||
|
||||
$destinationData = [
|
||||
'name' => str_replace('Transfer: ', '', $transaction['payee_name']),
|
||||
'iban' => null,
|
||||
'number' => $transaction['payee_id'],
|
||||
'bic' => null,
|
||||
];
|
||||
|
||||
$destination = $this->mapper->map($possibleDestinationId, $amount, $destinationData);
|
||||
if (1 === bccomp($amount, '0')) {
|
||||
[$source, $destination] = [$destination, $source];
|
||||
$type = 'transfer' === $type ? 'transfer' : 'deposit';
|
||||
Log::debug(sprintf('Amount is %s, so switch source/dest and make this a %s', $amount, $type));
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Final source account: #%d ("%s")', $source->id, $source->name));
|
||||
Log::debug(sprintf('Final destination account: #%d ("%s")', $destination->id, $destination->name));
|
||||
|
||||
$entry = [
|
||||
'type' => $type,
|
||||
'date' => $transaction['date'] ?? date('Y-m-d'),
|
||||
'tags' => $tags,
|
||||
'user' => $this->importJob->user_id,
|
||||
'notes' => null,
|
||||
|
||||
// all custom fields:
|
||||
'external_id' => $transaction['id'] ?? '',
|
||||
|
||||
// journal data:
|
||||
'description' => $description,
|
||||
'piggy_bank_id' => null,
|
||||
'piggy_bank_name' => null,
|
||||
'bill_id' => null,
|
||||
'bill_name' => null,
|
||||
'original-source' => sprintf('ynab-v%s', config('firefly.version')),
|
||||
|
||||
// transaction data:
|
||||
'transactions' => [
|
||||
[
|
||||
'type' => $type,
|
||||
'date' => $transaction['date'] ?? date('Y-m-d'),
|
||||
'tags' => $tags,
|
||||
'user' => $this->importJob->user_id,
|
||||
'notes' => null,
|
||||
'currency_id' => null,
|
||||
'currency_code' => $budget['currency_code'] ?? $this->defaultCurrency->code,
|
||||
'amount' => bcdiv((string)$transaction['amount'], '1000'),
|
||||
'budget_id' => null,
|
||||
'original-source' => sprintf('ynab-v%s', config('firefly.version')),
|
||||
'budget_name' => null,
|
||||
'category_id' => null,
|
||||
'category_name' => $transaction['category_name'],
|
||||
'source_id' => $source->id,
|
||||
'source_name' => null,
|
||||
// all custom fields:
|
||||
'external_id' => $transaction['id'] ?? '',
|
||||
|
||||
// journal data:
|
||||
'description' => $description,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_name' => null,
|
||||
'foreign_currency_id' => null,
|
||||
'foreign_currency_code' => null,
|
||||
'foreign_amount' => null,
|
||||
'reconciled' => false,
|
||||
'identifier' => 0,
|
||||
],
|
||||
],
|
||||
];
|
||||
Log::debug(sprintf('Done with entry #%d', $index));
|
||||
$array[] = $entry;
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $accountId
|
||||
*
|
||||
* @return Account
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getLocalAccount(int $accountId): Account
|
||||
{
|
||||
$account = $this->accountRepository->findNull($accountId);
|
||||
if (null === $account) {
|
||||
throw new FireflyException(sprintf('Cannot find Firefly III asset account with ID #%d. Job must stop now.', $accountId)); // @codeCoverageIgnore
|
||||
}
|
||||
if ($account->accountType->type !== AccountType::ASSET) {
|
||||
throw new FireflyException(sprintf('Account with ID #%d is not an asset account. Job must stop now.', $accountId)); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getSelectedBudget(): array
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$budgets = $config['budgets'] ?? [];
|
||||
$selected = $config['selected_budget'] ?? '';
|
||||
|
||||
if ('' === $selected) {
|
||||
$firstBudget = $config['budgets'][0] ?? false;
|
||||
if (false === $firstBudget) {
|
||||
throw new FireflyException('The configuration contains no budget. Erroring out.');
|
||||
}
|
||||
$selected = $firstBudget['id'];
|
||||
}
|
||||
|
||||
foreach ($budgets as $budget) {
|
||||
if ($budget['id'] === $selected) {
|
||||
return $budget;
|
||||
}
|
||||
}
|
||||
|
||||
return $budgets[0] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $token
|
||||
* @param string $account
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getTransactions(string $token, string $account): array
|
||||
{
|
||||
$budget = $this->getSelectedBudget();
|
||||
$request = new GetTransactionsRequest;
|
||||
$request->budgetId = $budget['id'];
|
||||
$request->accountId = $account;
|
||||
|
||||
// todo grab latest date for $ynabId
|
||||
$request->setAccessToken($token);
|
||||
$request->call();
|
||||
|
||||
return $request->transactions;
|
||||
}
|
||||
}
|
@@ -1,110 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageGetAccessHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Import\Routine\Ynab;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Log;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class StageGetAccessHandler
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class StageGetAccessHandler
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Send a token request to YNAB. Return with access token (if all goes well).
|
||||
*
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$clientId = app('preferences')->get('ynab_client_id', '')->data;
|
||||
$clientSecret = app('preferences')->get('ynab_client_secret', '')->data;
|
||||
$redirectUri = route('import.callback.ynab');
|
||||
$code = $config['auth_code'];
|
||||
$uri = sprintf(
|
||||
'https://app.youneedabudget.com/oauth/token?client_id=%s&client_secret=%s&redirect_uri=%s&grant_type=authorization_code&code=%s', $clientId,
|
||||
$clientSecret, $redirectUri, $code
|
||||
);
|
||||
$client = new Client;
|
||||
try {
|
||||
$res = $client->request('POST', $uri);
|
||||
} catch (GuzzleException|Exception $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);
|
||||
|
||||
Log::debug('end of StageGetAccessHandler::run()');
|
||||
|
||||
$refreshToken = (string)($json['refresh_token'] ?? '');
|
||||
if ('' !== $refreshToken) {
|
||||
app('preferences')->set('ynab_refresh_token', $refreshToken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
}
|
@@ -1,77 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageGetBudgetsHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://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
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
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 (0 === count($request->budgets)) {
|
||||
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);
|
||||
}
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageGetTransactionsHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://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
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* StageMatchAccountsHandler.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://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
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
@@ -45,7 +45,6 @@ class Telemetry
|
||||
* - execute-cli-command [value]
|
||||
* - use-help-pages
|
||||
* - has-created-bill
|
||||
* - do-big-import
|
||||
* - first-time-install
|
||||
* - more
|
||||
*
|
||||
|
Reference in New Issue
Block a user