CSV file fix for ING Belgium

Parse the description and opposing account information (IBAN and name) from ING Belgium CSV files.
This commit is contained in:
Sander Kleykens 2019-06-23 22:24:52 +02:00
parent 43d753e5bd
commit 9e9e5bd6dd
4 changed files with 276 additions and 1 deletions

View File

@ -0,0 +1,139 @@
<?php
/**
* IngBelgium.php
* Copyright (C) 2019 Sander Kleykens <sander@kleykens.com>
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Import\Specifics;
/**
* Class IngBelgium.
*
* Parses the description and opposing account information (IBAN and name) from CSV files for ING Belgium bank accounts.
*
*/
class IngBelgium implements SpecificInterface
{
/**
* Description of the current specific.
*
* @return string
* @codeCoverageIgnore
*/
public static function getDescription(): string
{
return 'import.specific_ingbelgium_descr';
}
/**
* Name of the current specific.
*
* @return string
* @codeCoverageIgnore
*/
public static function getName(): string
{
return 'import.specific_ingbelgium_name';
}
/**
* Run the specific code.
*
* @param array $row
*
* @return array
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function run(array $row): array
{
return IngBelgium::processTransactionDetails($row);
}
/**
* Gets the description and opposing account information (IBAN and name) from the transaction details and adds
* them to the row of data.
*
* @return array the row containing the description and opposing account's IBAN
*/
protected static function processTransactionDetails(array $row): array
{
if(isset($row[9])) {
$transactionDetails = $row[9];
$row[11] = IngBelgium::opposingAccountName($transactionDetails);
$row[12] = IngBelgium::opposingAccountIban($transactionDetails);
$row[13] = IngBelgium::description($transactionDetails);
}
return $row;
}
/**
* Gets the opposing account name from the transaction details.
*
* @return string the opposing account name
*/
protected static function opposingAccountName(string $transactionDetails): string
{
return IngBelgium::parseInformationFromTransactionDetails($transactionDetails, '/Van:\s*(.+?)(?=\s{2,})/');
}
/**
* Gets the opposing account's IBAN from the transaction details.
*
* @return string the opposing account's IBAN
*/
protected static function opposingAccountIban(string $transactionDetails): string
{
return IngBelgium::parseInformationFromTransactionDetails($transactionDetails, '/IBAN:\s*(.+?)(?=\s+)/');
}
/**
* Gets the description from the transaction details and makes sure structured descriptions are in the
* "+++090/9337/55493+++" format.
*
* @return string the description
*/
protected static function description(string $transactionDetails): string
{
$description = IngBelgium::parseInformationFromTransactionDetails($transactionDetails, '/Mededeling:\s*(.+)$/');
return IngBelgium::convertStructuredDescriptionToProperFormat($description);
}
private static function convertStructuredDescriptionToProperFormat(string $description): string
{
preg_match('/^\*\*\*(\d{3}\/\d{4}\/\d{5})\*\*\*$/', $description, $matches);
if(isset($matches[1])) {
return '+++' . $matches[1] . '+++';
}
return $description;
}
private static function parseInformationFromTransactionDetails(string $transactionDetails, string $regex): string
{
if(isset($transactionDetails)) {
preg_match($regex, $transactionDetails, $matches);
if (isset($matches[1])) {
return trim($matches[1]);
}
}
return '';
}
}

View File

@ -27,6 +27,7 @@ use FireflyIII\Import\Specifics\IngDescription;
use FireflyIII\Import\Specifics\PresidentsChoice;
use FireflyIII\Import\Specifics\SnsDescription;
use FireflyIII\Import\Specifics\Belfius;
use FireflyIII\Import\Specifics\IngBelgium;
return [
@ -38,7 +39,8 @@ return [
'AbnAmroDescription' => AbnAmroDescription::class,
'SnsDescription' => SnsDescription::class,
'PresidentsChoice' => PresidentsChoice::class,
'Belfius' => Belfius::class
'Belfius' => Belfius::class,
'IngBelgium' => IngBelgium::class
],
/*

View File

@ -209,6 +209,8 @@ return [
'specific_pres_descr' => 'Fixes potential problems with PC files',
'specific_belfius_name' => 'Belfius BE',
'specific_belfius_descr' => 'Fixes potential problems with Belfius files',
'specific_ingbelgium_name' => 'ING BE',
'specific_ingbelgium_descr' => 'Fixes potential problems with ING Belgium files',
// job configuration for file provider (stage: roles)
'job_config_roles_title' => 'Import setup (3/4) - Define each column\'s role',
'job_config_roles_text' => 'Each column in your CSV file contains certain data. Please indicate what kind of data the importer should expect. The option to "map" data means that you will link each entry found in the column to a value in your database. An often mapped column is the column that contains the IBAN of the opposing account. That can be easily matched to IBAN\'s present in your database already.',

View File

@ -0,0 +1,132 @@
<?php
/**
* IngBelgiumTest.php
* Copyright (c) 2019 Sander Kleykens <sander@kleykens.com>
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace Tests\Unit\Import\Specifics;
use FireflyIII\Import\Specifics\IngBelgium;
use Log;
use Tests\TestCase;
/**
* Class IngBelgiumTest
*/
class IngBelgiumTest extends TestCase
{
/**
*
*/
public function setUp(): void
{
parent::setUp();
Log::info(sprintf('Now in %s.', get_class($this)));
}
/**
* Should return the exact same array.
*
* @covers \FireflyIII\Import\Specifics\IngBelgium
*/
public function testEmptyRow(): void
{
$row = [0, 1, 2, 3, 4];
$parser = new IngBelgium;
$result = $parser->run($row);
$this->assertEquals($row, $result);
}
/**
* Data with description and opposing account information.
*
* @covers \FireflyIII\Import\Specifics\IngBelgium
*/
public function testParseDescriptionAndOpposingAccountInformation(): void
{
$row = [
0,
1,
2,
3,
4,
5,
6,
7,
8,
'Europese overschrijving Van: DE H JOHN DOE De Laan 123 1000 BRUSSEL België IBAN: BE01123456789012 Mededeling: A random description ',
10
];
$parser = new IngBelgium;
$result = $parser->run($row);
$this->assertEquals($row, array_slice($result, 0, 11));
$this->assertEquals('DE H JOHN DOE', $result[11]);
$this->assertEquals('BE01123456789012', $result[12]);
$this->assertEquals('A random description', $result[13]);
}
/**
* Data with structured description.
*
* @covers \FireflyIII\Import\Specifics\IngBelgium
*/
public function testParseStructuredDescription(): void
{
$row = [
0,
1,
2,
3,
4,
5,
6,
7,
8,
'Europese overschrijving Mededeling: ***090/9337/55493*** ',
10
];
$parser = new IngBelgium;
$result = $parser->run($row);
$this->assertEquals($row, array_slice($result, 0, 11));
$this->assertEquals('+++090/9337/55493+++', $result[13]);
}
/**
* Empty transaction details
*
* @covers \FireflyIII\Import\Specifics\IngBelgium
*/
public function testEmptyTransactionDetails(): void
{
$row = [0, 1, 2, 3, 4, 5, 6, 7, 8, '', 10];
$parser = new IngBelgium;
$result = $parser->run($row);
$this->assertEquals($row, array_slice($result, 0, 11));
$this->assertEquals('', $result[11]);
$this->assertEquals('', $result[12]);
$this->assertEquals('', $result[13]);
}
}