From 2ff806dedc999025bf83fd45324cfcf020d660e7 Mon Sep 17 00:00:00 2001 From: Robert Horlings Date: Fri, 15 Jan 2016 16:48:09 +0100 Subject: [PATCH 1/8] Initial version of ABN AMRO import specifix with amount correction and SEPA description parser --- .../Csv/Specifix/AbnAmroDescription.php | 183 ++++++++++++++++++ config/csv.php | 1 + 2 files changed, 184 insertions(+) create mode 100644 app/Helpers/Csv/Specifix/AbnAmroDescription.php diff --git a/app/Helpers/Csv/Specifix/AbnAmroDescription.php b/app/Helpers/Csv/Specifix/AbnAmroDescription.php new file mode 100644 index 0000000000..890bbeff4e --- /dev/null +++ b/app/Helpers/Csv/Specifix/AbnAmroDescription.php @@ -0,0 +1,183 @@ +handleAmount(); + $this->parseSepaDescription(); + + return $this->data; + + } + + /** + * @param array $data + */ + public function setData($data) + { + $this->data = $data; + } + + /** + * @param array $row + */ + public function setRow($row) + { + $this->row = $row; + } + + protected function handleAmount() { + $this->data['amount'] = floatval(str_replace(',', '.', $this->row[6])); + } + + /** + * Parses the current description in SEPA format + * @return boolean true if the description is SEPA format, false otherwise + */ + protected function parseSepaDescription() + { + // See if the current description is formatted as a SEPA plain description + if( preg_match( "/^SEPA(.{28})/", $this->data[ "description" ], $matches ) ) { + Log::debug('AbnAmroSpecifix: Description is structured as SEPA plain description.'); + $type = trim($matches[1]); + + // SEPA plain descriptions contain several key-value pairs, split by a colon + preg_match_all( "/([A-Za-z]+(?=:\s)):\s([A-Za-z 0-9.-]+(?=\s))/", $this->data[ "description" ], $matches, PREG_SET_ORDER ); + + foreach( $matches as $match ) { + $key = $match[1]; + $value = trim($match[2]); + + switch( strtoupper($key) ) { + case 'OMSCHRIJVING': + $this->data['description'] = $value; + break; + case 'NAAM': + $this->data['opposing-account-name'] = $value; + break; + case 'IBAN': + $this->data['opposing-account-iban'] = $value; + break; + default: + // Ignore the rest + } + } + + // Add the type to the description + $this->data['description'] .= ' (' . $type . ')'; + + return true; + } + + return false; + } + +/*** + * +def ParseDescription(desc): + values = None + ### SEPA PLAIN: SEPA iDEAL IBAN: NL12RABO0121212212 BIC: RABONL2U Naam: Silver Ocean B.V. Omschrijving: 1232138 1232131233 412321 iBOOD.com iBOOD.com B.V. Kenmerk: 12-12-2014 21:03 002000 0213123238 + sepa = re.findall(r"(?P^SEPA.{28})", desc, re.I) + if (sepa): + values = {} + value = sepa[0] + values["TRTP"] = value.strip() + values["EREF"] = "" + values["REMI"] = "" + sepa = re.findall(r"(?P[A-Za-z]+(?=:\s)):\s(?P[A-Za-z 0-9.-]+(?=\s))", desc, re.I) + for line in sepa: + key = line[0] + if key.upper() == 'OMSCHRIJVING': + key = 'REMI' + if key.upper() == 'KENMERK': + key = 'EREF' + if key.upper() == 'NAAM': + key = 'NAME' + value = line[1] + values[key] = value.strip() + # print (values) + # continue + if len(values["REMI"]) > 19: + values["REMI"] = values["REMI"][0:18] + values["REMI"][19:] + if values["REMI"] == "": + values["REMI"] = values["TRTP"] + + ### TRTP ENCODED: /TRTP/SEPA OVERBOEKING/IBAN/NL23ABNA0000000000/BIC/ABNANL2A/NAME/baasd dsdsT CJ/REMI/Nullijn/EREF/NOTPROVIDED + trtp = re.findall(r"\/(?P[A-Z]{3,4})\/(?P.*?(?:(?=\/[A-Z]{3,4}\/)|$))",desc, re.I) + if (trtp): + values = {} + values["EREF"] = "" + values["REMI"] = "" + for line in trtp: + key = line[0] + value = line[1] + values[key] = value.strip() + # print (values) + # continue + if values["REMI"] == "": + values["REMI"] = values["TRTP"] + + ### BEA: BEA NR:00AJ01 31.01.01/19.54 Van HarenSchoenen132 UDE,PAS333 + trtp = re.findall(r"(?P[BG]EA) +(?PNR:[a-zA-Z:0-9]+) +(?P[0-9.\/]+) +(?P[^,]*)", desc, re.I) + if (trtp): + values = {} + values["TRTP"] = str(trtp[0][0]).strip() + values["NAME"] = str(trtp[0][3]).strip() + values["EREF"] = str(trtp[0][1]).strip() + values["DATE"] = str(trtp[0][2]).strip() + values["REMI"] = values["TRTP"] + " " + values["NAME"] + # print (values) + # continue + + ### OLD: 12.21.22.222 BNP aaaaaaa aaaaaa SCH BETALINGSKENM. 2323233232323323 MAAND* APRIL 01 REF* 1212121-42-41 + trtp = re.findall(r"^ ?(?P[0-9.]{12,15})\W+(?P.{32})", desc, re.I) + if (trtp): + values = {} + values["TRTP"] = "OLD" + values["IBAN"] = str(trtp[0][0]).strip() + values["NAME"] = str(trtp[0][1]).strip() + values["EREF"] = "" + values["REMI"] = values["TRTP"] + " " + values["NAME"] + # print (values) + # continue + ### ABN AMRO Bank N.V. Prive pakket 3,25 + abn = re.findall(r"^ABN AMRO.{24} (?P.*)", desc, re.I) + if (abn): + values = {} + values["TRTP"] = "ABN AMBRO" + values["NAME"] = "ABN AMBRO" + values["EREF"] = str(abn[0]).strip() + values["REMI"] = values["EREF"] + # print (values) + # continue + if (values == None): + # print ("Unkown: ### %s ###" % ( desc )) + return None + return values * + * + */ + +} diff --git a/config/csv.php b/config/csv.php index ba1ae72f47..d8cbd4daa5 100644 --- a/config/csv.php +++ b/config/csv.php @@ -2,6 +2,7 @@ return [ 'specifix' => [ 'RabobankDescription', + 'AbnAmroDescription', 'Dummy' ], 'post_processors' => [ From 323c16ebe1737c3a2d7c26b1713e3211cd6d47e7 Mon Sep 17 00:00:00 2001 From: Robert Horlings Date: Sun, 17 Jan 2016 15:25:47 +0100 Subject: [PATCH 2/8] Implemented additional ABNAMRO description formats --- .../Csv/Specifix/AbnAmroDescription.php | 174 +++++++++--------- 1 file changed, 86 insertions(+), 88 deletions(-) diff --git a/app/Helpers/Csv/Specifix/AbnAmroDescription.php b/app/Helpers/Csv/Specifix/AbnAmroDescription.php index 890bbeff4e..5f17c62ed4 100644 --- a/app/Helpers/Csv/Specifix/AbnAmroDescription.php +++ b/app/Helpers/Csv/Specifix/AbnAmroDescription.php @@ -27,10 +27,16 @@ class AbnAmroDescription public function fix() { $this->handleAmount(); - $this->parseSepaDescription(); - + + // Try to parse the description in known formats. + $parsed = $this->parseSepaDescription() || $this->parseTRTPDescription() || $this->parseGEABEADescription() || $this->parseABNAMRODescription(); + + // If the description could not be parsed, specify an unknown opposing account, as an opposing account is required + if( !$parsed ) { + $this->data[ "opposing-account-name" ] = trans('unknown'); + } + return $this->data; - } /** @@ -87,97 +93,89 @@ class AbnAmroDescription } // Add the type to the description - $this->data['description'] .= ' (' . $type . ')'; + if( $type ) + $this->data['description'] .= ' (' . $type . ')'; return true; } return false; } + + /** + * Parses the current description in TRTP format + * @return boolean true if the description is TRTP format, false otherwise + */ + protected function parseTRTPDescription() + { + // See if the current description is formatted in TRTP format + if( preg_match_all( "!\/([A-Z]{3,4})\/([^/]*)!", $this->data[ "description" ], $matches, PREG_SET_ORDER ) ) { + Log::debug('AbnAmroSpecifix: Description is structured as TRTP format.'); -/*** - * -def ParseDescription(desc): - values = None - ### SEPA PLAIN: SEPA iDEAL IBAN: NL12RABO0121212212 BIC: RABONL2U Naam: Silver Ocean B.V. Omschrijving: 1232138 1232131233 412321 iBOOD.com iBOOD.com B.V. Kenmerk: 12-12-2014 21:03 002000 0213123238 - sepa = re.findall(r"(?P^SEPA.{28})", desc, re.I) - if (sepa): - values = {} - value = sepa[0] - values["TRTP"] = value.strip() - values["EREF"] = "" - values["REMI"] = "" - sepa = re.findall(r"(?P[A-Za-z]+(?=:\s)):\s(?P[A-Za-z 0-9.-]+(?=\s))", desc, re.I) - for line in sepa: - key = line[0] - if key.upper() == 'OMSCHRIJVING': - key = 'REMI' - if key.upper() == 'KENMERK': - key = 'EREF' - if key.upper() == 'NAAM': - key = 'NAME' - value = line[1] - values[key] = value.strip() - # print (values) - # continue - if len(values["REMI"]) > 19: - values["REMI"] = values["REMI"][0:18] + values["REMI"][19:] - if values["REMI"] == "": - values["REMI"] = values["TRTP"] - - ### TRTP ENCODED: /TRTP/SEPA OVERBOEKING/IBAN/NL23ABNA0000000000/BIC/ABNANL2A/NAME/baasd dsdsT CJ/REMI/Nullijn/EREF/NOTPROVIDED - trtp = re.findall(r"\/(?P[A-Z]{3,4})\/(?P.*?(?:(?=\/[A-Z]{3,4}\/)|$))",desc, re.I) - if (trtp): - values = {} - values["EREF"] = "" - values["REMI"] = "" - for line in trtp: - key = line[0] - value = line[1] - values[key] = value.strip() - # print (values) - # continue - if values["REMI"] == "": - values["REMI"] = values["TRTP"] - - ### BEA: BEA NR:00AJ01 31.01.01/19.54 Van HarenSchoenen132 UDE,PAS333 - trtp = re.findall(r"(?P[BG]EA) +(?PNR:[a-zA-Z:0-9]+) +(?P[0-9.\/]+) +(?P[^,]*)", desc, re.I) - if (trtp): - values = {} - values["TRTP"] = str(trtp[0][0]).strip() - values["NAME"] = str(trtp[0][3]).strip() - values["EREF"] = str(trtp[0][1]).strip() - values["DATE"] = str(trtp[0][2]).strip() - values["REMI"] = values["TRTP"] + " " + values["NAME"] - # print (values) - # continue - - ### OLD: 12.21.22.222 BNP aaaaaaa aaaaaa SCH BETALINGSKENM. 2323233232323323 MAAND* APRIL 01 REF* 1212121-42-41 - trtp = re.findall(r"^ ?(?P[0-9.]{12,15})\W+(?P.{32})", desc, re.I) - if (trtp): - values = {} - values["TRTP"] = "OLD" - values["IBAN"] = str(trtp[0][0]).strip() - values["NAME"] = str(trtp[0][1]).strip() - values["EREF"] = "" - values["REMI"] = values["TRTP"] + " " + values["NAME"] - # print (values) - # continue - ### ABN AMRO Bank N.V. Prive pakket 3,25 - abn = re.findall(r"^ABN AMRO.{24} (?P.*)", desc, re.I) - if (abn): - values = {} - values["TRTP"] = "ABN AMBRO" - values["NAME"] = "ABN AMBRO" - values["EREF"] = str(abn[0]).strip() - values["REMI"] = values["EREF"] - # print (values) - # continue - if (values == None): - # print ("Unkown: ### %s ###" % ( desc )) - return None - return values * - * - */ + foreach( $matches as $match ) { + $key = $match[1]; + $value = trim($match[2]); + + switch( strtoupper($key) ) { + case 'TRTP': + $type = $value; + break; + case 'NAME': + $this->data['opposing-account-name'] = $value; + break; + case 'REMI': + $this->data['description'] = $value; + break; + case 'IBAN': + $this->data['opposing-account-iban'] = $value; + break; + default: + // Ignore the rest + } + } + + // Add the type to the description + if( $type ) + $this->data['description'] .= ' (' . $type . ')'; + + return true; + } + + return false; + } + /** + * Parses the current description in GEA/BEA format + * @return boolean true if the description is GEA/BEAformat, false otherwise + */ + protected function parseGEABEADescription() + { + // See if the current description is formatted in GEA/BEA format + if( preg_match( "/([BG]EA) +(NR:[a-zA-Z:0-9]+) +([0-9.\/]+) +([^,]*)/", $this->data[ "description" ], $matches ) ) { + Log::debug('AbnAmroSpecifix: Description is structured as GEA or BEA format.'); + + $this->data[ "opposing-account-name" ] = $matches[4]; + $this->data[ "description" ] = $matches[4] . " (" . $matches[1] . ")"; + } + + return false; + } + + /** + * Parses the current description with costs from ABN AMRO itself + * @return boolean true if the description is GEA/BEAformat, false otherwise + */ + protected function parseABNAMRODescription() + { + // See if the current description is formatted in ABN AMRO format + if( preg_match( "/ABN AMRO.{24} (.*)/", $this->data[ "description" ], $matches ) ) { + Log::debug('AbnAmroSpecifix: Description is structured as costs from ABN AMRO itself.'); + + $this->data[ "opposing-account-name" ] = "ABN AMRO"; + $this->data[ "description" ] = $matches[1]; + } + + return false; + } + } From 4909fcc8b4bb744d2dceb74065dbec3a6ca43c80 Mon Sep 17 00:00:00 2001 From: Robert Horlings Date: Sun, 17 Jan 2016 15:37:49 +0100 Subject: [PATCH 3/8] Moved parsing of amount with decimal separator to Converter object --- app/Helpers/Csv/Converter/AmountComma.php | 30 +++++++++++++++++++ .../Csv/Specifix/AbnAmroDescription.php | 6 ---- config/csv.php | 6 ++++ 3 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 app/Helpers/Csv/Converter/AmountComma.php diff --git a/app/Helpers/Csv/Converter/AmountComma.php b/app/Helpers/Csv/Converter/AmountComma.php new file mode 100644 index 0000000000..2427361148 --- /dev/null +++ b/app/Helpers/Csv/Converter/AmountComma.php @@ -0,0 +1,30 @@ +value ); + + if (is_numeric($value)) { + return floatval($value); + } + + return 0; + } +} diff --git a/app/Helpers/Csv/Specifix/AbnAmroDescription.php b/app/Helpers/Csv/Specifix/AbnAmroDescription.php index 5f17c62ed4..6a422a5a24 100644 --- a/app/Helpers/Csv/Specifix/AbnAmroDescription.php +++ b/app/Helpers/Csv/Specifix/AbnAmroDescription.php @@ -26,8 +26,6 @@ class AbnAmroDescription */ public function fix() { - $this->handleAmount(); - // Try to parse the description in known formats. $parsed = $this->parseSepaDescription() || $this->parseTRTPDescription() || $this->parseGEABEADescription() || $this->parseABNAMRODescription(); @@ -55,10 +53,6 @@ class AbnAmroDescription $this->row = $row; } - protected function handleAmount() { - $this->data['amount'] = floatval(str_replace(',', '.', $this->row[6])); - } - /** * Parses the current description in SEPA format * @return boolean true if the description is SEPA format, false otherwise diff --git a/config/csv.php b/config/csv.php index d8cbd4daa5..dfdcc3d26f 100644 --- a/config/csv.php +++ b/config/csv.php @@ -177,6 +177,12 @@ return [ 'converter' => 'Amount', 'field' => 'amount', ], + 'amount-comma-separated' => [ + 'name' => 'Amount (comma as decimal separator)', + 'mappable' => false, + 'converter' => 'AmountComma', + 'field' => 'amount', + ], 'sepa-ct-id' => [ 'name' => 'SEPA Credit Transfer end-to-end ID', 'mappable' => false, From cbe1f762ca2e9ec88c9ff009595089f2d28a01b9 Mon Sep 17 00:00:00 2001 From: Robert Horlings Date: Mon, 18 Jan 2016 09:09:30 +0100 Subject: [PATCH 4/8] Fixing a bug with expense account being set to unknown --- app/Helpers/Csv/Specifix/AbnAmroDescription.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/Helpers/Csv/Specifix/AbnAmroDescription.php b/app/Helpers/Csv/Specifix/AbnAmroDescription.php index 6a422a5a24..49295b28e9 100644 --- a/app/Helpers/Csv/Specifix/AbnAmroDescription.php +++ b/app/Helpers/Csv/Specifix/AbnAmroDescription.php @@ -150,6 +150,8 @@ class AbnAmroDescription $this->data[ "opposing-account-name" ] = $matches[4]; $this->data[ "description" ] = $matches[4] . " (" . $matches[1] . ")"; + + return true; } return false; @@ -167,6 +169,8 @@ class AbnAmroDescription $this->data[ "opposing-account-name" ] = "ABN AMRO"; $this->data[ "description" ] = $matches[1]; + + return true; } return false; From cc712b0c75535f1cb9dd5027c8a1f86d6ac93a30 Mon Sep 17 00:00:00 2001 From: Robert Horlings Date: Mon, 18 Jan 2016 12:31:45 +0100 Subject: [PATCH 5/8] Updated message identifier for unknown opposing account --- app/Helpers/Csv/Specifix/AbnAmroDescription.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Helpers/Csv/Specifix/AbnAmroDescription.php b/app/Helpers/Csv/Specifix/AbnAmroDescription.php index 49295b28e9..6e6dc4f02a 100644 --- a/app/Helpers/Csv/Specifix/AbnAmroDescription.php +++ b/app/Helpers/Csv/Specifix/AbnAmroDescription.php @@ -29,9 +29,10 @@ class AbnAmroDescription // Try to parse the description in known formats. $parsed = $this->parseSepaDescription() || $this->parseTRTPDescription() || $this->parseGEABEADescription() || $this->parseABNAMRODescription(); - // If the description could not be parsed, specify an unknown opposing account, as an opposing account is required + // If the description could not be parsed, specify an unknown opposing + // account, as an opposing account is required if( !$parsed ) { - $this->data[ "opposing-account-name" ] = trans('unknown'); + $this->data[ "opposing-account-name" ] = trans('firefly.unknown'); } return $this->data; From bd5d73d1e6693fbb67dc83837370219337ed9204 Mon Sep 17 00:00:00 2001 From: Robert Horlings Date: Mon, 18 Jan 2016 12:37:06 +0100 Subject: [PATCH 6/8] Removed transaction type from the description --- app/Helpers/Csv/Specifix/AbnAmroDescription.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/app/Helpers/Csv/Specifix/AbnAmroDescription.php b/app/Helpers/Csv/Specifix/AbnAmroDescription.php index 6e6dc4f02a..75d708e39e 100644 --- a/app/Helpers/Csv/Specifix/AbnAmroDescription.php +++ b/app/Helpers/Csv/Specifix/AbnAmroDescription.php @@ -87,10 +87,6 @@ class AbnAmroDescription } } - // Add the type to the description - if( $type ) - $this->data['description'] .= ' (' . $type . ')'; - return true; } @@ -129,10 +125,6 @@ class AbnAmroDescription } } - // Add the type to the description - if( $type ) - $this->data['description'] .= ' (' . $type . ')'; - return true; } @@ -150,7 +142,7 @@ class AbnAmroDescription Log::debug('AbnAmroSpecifix: Description is structured as GEA or BEA format.'); $this->data[ "opposing-account-name" ] = $matches[4]; - $this->data[ "description" ] = $matches[4] . " (" . $matches[1] . ")"; + $this->data[ "description" ] = $matches[4]; return true; } From 10ea60daaffda541a05aa3b2812565fd1dd493b2 Mon Sep 17 00:00:00 2001 From: Robert Horlings Date: Mon, 18 Jan 2016 15:42:56 +0100 Subject: [PATCH 7/8] Improved SEPA description parsing --- app/Helpers/Csv/Specifix/AbnAmroDescription.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Helpers/Csv/Specifix/AbnAmroDescription.php b/app/Helpers/Csv/Specifix/AbnAmroDescription.php index 75d708e39e..2b6b3c97d5 100644 --- a/app/Helpers/Csv/Specifix/AbnAmroDescription.php +++ b/app/Helpers/Csv/Specifix/AbnAmroDescription.php @@ -28,7 +28,7 @@ class AbnAmroDescription { // Try to parse the description in known formats. $parsed = $this->parseSepaDescription() || $this->parseTRTPDescription() || $this->parseGEABEADescription() || $this->parseABNAMRODescription(); - + // If the description could not be parsed, specify an unknown opposing // account, as an opposing account is required if( !$parsed ) { @@ -66,7 +66,7 @@ class AbnAmroDescription $type = trim($matches[1]); // SEPA plain descriptions contain several key-value pairs, split by a colon - preg_match_all( "/([A-Za-z]+(?=:\s)):\s([A-Za-z 0-9.-]+(?=\s))/", $this->data[ "description" ], $matches, PREG_SET_ORDER ); + preg_match_all( "/([A-Za-z]+(?=:\s)):\s([A-Za-z 0-9._#-]+(?=\s))/", $this->data[ "description" ], $matches, PREG_SET_ORDER ); foreach( $matches as $match ) { $key = $match[1]; From f39f25760a81af7b3bc4b9db05b5e84906f539f5 Mon Sep 17 00:00:00 2001 From: Robert Horlings Date: Mon, 18 Jan 2016 15:43:30 +0100 Subject: [PATCH 8/8] Added messages for new specifix --- resources/lang/en_US/firefly.php | 2 ++ resources/lang/nl_NL/firefly.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index be816a7d26..d30005be04 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -257,6 +257,7 @@ return [ 'csv_column_account-id' => 'Asset account ID (matching Firefly)', 'csv_column_account-name' => 'Asset account (name)', 'csv_column_amount' => 'Amount', + 'csv_column_amount-comma-separated' => 'Amount (comma as decimal separator)', 'csv_column_bill-id' => 'Bill ID (matching Firefly)', 'csv_column_bill-name' => 'Bill name', 'csv_column_budget-id' => 'Budget ID (matching Firefly)', @@ -280,6 +281,7 @@ return [ 'csv_column_tags-comma' => 'Tags (comma separated)', 'csv_column_tags-space' => 'Tags (space separated)', 'csv_specifix_RabobankDescription' => 'Select this when you\'re importing Rabobank CSV export files.', + 'csv_specifix_AbnAmroDescription' => 'Select this when you\'re importing ABN AMRO CSV export files.', 'csv_specifix_Dummy' => 'Checking this has no effect whatsoever.', 'csv_import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the CSV belong to.', 'csv_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.', diff --git a/resources/lang/nl_NL/firefly.php b/resources/lang/nl_NL/firefly.php index 3493ef0643..a2fc14f54e 100755 --- a/resources/lang/nl_NL/firefly.php +++ b/resources/lang/nl_NL/firefly.php @@ -257,6 +257,7 @@ return [ 'csv_column_account-id' => 'Betaalrekening (ID gelijk aan Firefly)', 'csv_column_account-name' => 'Betaalrekeningnaam', 'csv_column_amount' => 'Bedrag', + 'csv_column_amount-comma-separated' => 'Bedrag (komma as decimaalscheidingsteken)', 'csv_column_bill-id' => 'Contract (ID gelijk aan Firefly)', 'csv_column_bill-name' => 'Contractnaam', 'csv_column_budget-id' => 'Budget (ID gelijk aan Firefly)', @@ -280,6 +281,7 @@ return [ 'csv_column_tags-comma' => 'Tags (kommagescheiden)', 'csv_column_tags-space' => 'Tags (spatiegescheiden)', 'csv_specifix_RabobankDescription' => 'Vink dit aan als je Rabobank bestanden importeert.', + 'csv_specifix_AbnAmroDescription' => 'Vink dit aan als je ABN AMRO CSV bestanden importeert.', 'csv_specifix_Dummy' => 'Dit vinkje doet niks (dummy).', 'csv_import_account_help' => 'Als jouw CSV bestand geen referenties bevat naar jouw rekening(en), geef dan hier aan om welke rekening het gaat.', 'csv_delimiter_help' => 'Kies het veldscheidingsteken dat in het invoerbestand is gebruikt. Bij twijfel is de komma de veiligste optie.',