mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			230 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * AbnAmroDescription.php
 | |
|  * Copyright (C) 2016 thegrumpydictator@gmail.com
 | |
|  *
 | |
|  * This software may be modified and distributed under the terms of the
 | |
|  * Creative Commons Attribution-ShareAlike 4.0 International License.
 | |
|  *
 | |
|  * See the LICENSE file for details.
 | |
|  */
 | |
| 
 | |
| declare(strict_types = 1);
 | |
| 
 | |
| namespace FireflyIII\Import\Specifics;
 | |
| 
 | |
| /**
 | |
|  * Class AbnAmroDescription
 | |
|  *
 | |
|  * Parses the description from txt files for ABN AMRO bank accounts.
 | |
|  *
 | |
|  * Based on the logic as described in the following Gist:
 | |
|  * https://gist.github.com/vDorst/68d555a6a90f62fec004
 | |
|  *
 | |
|  * @package FireflyIII\Import\Specifics
 | |
|  */
 | |
| class AbnAmroDescription implements SpecificInterface
 | |
| {
 | |
|     /** @var  array */
 | |
|     public $row;
 | |
| 
 | |
|     /**
 | |
|      * @return string
 | |
|      */
 | |
|     public static function getDescription(): string
 | |
|     {
 | |
|         return 'Fixes possible problems with ABN Amro descriptions.';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @return string
 | |
|      */
 | |
|     public static function getName(): string
 | |
|     {
 | |
|         return 'ABN Amro description';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @param array $row
 | |
|      *
 | |
|      * @return array
 | |
|      */
 | |
|     public function run(array $row): array
 | |
|     {
 | |
|         $this->row = $row;
 | |
| 
 | |
|         if (!isset($row[7])) {
 | |
|             return $row;
 | |
|         }
 | |
| 
 | |
|         // 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->row[8] = trans('firefly.unknown'); // opposing-account-name
 | |
|         }
 | |
| 
 | |
|         return $this->row;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Parses the current description with costs from ABN AMRO itself
 | |
|      *
 | |
|      * @return bool true if the description is GEA/BEA-format, false otherwise
 | |
|      */
 | |
|     protected function parseABNAMRODescription()
 | |
|     {
 | |
|         // See if the current description is formatted in ABN AMRO format
 | |
|         if (preg_match('/ABN AMRO.{24} (.*)/', $this->row[7], $matches)) {
 | |
| 
 | |
|             $this->row[8] = 'ABN AMRO'; // this one is new (opposing account name)
 | |
|             $this->row[7] = $matches[1]; // this is the description
 | |
| 
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Parses the current description in GEA/BEA format
 | |
|      *
 | |
|      * @return bool 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->row[7], $matches)) {
 | |
| 
 | |
|             // description and opposing account will be the same.
 | |
|             $this->row[8] = $matches[4]; // 'opposing-account-name'
 | |
|             $this->row[7] = $matches[4]; // 'description'
 | |
| 
 | |
|             if ($matches[1] == 'GEA') {
 | |
|                 $this->row[7] = 'GEA ' . $matches[4]; // 'description'
 | |
|             }
 | |
| 
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Parses the current description in SEPA format
 | |
|      *
 | |
|      * @return bool 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->row[7], $matches)) {
 | |
| 
 | |
|             $type           = $matches[1];
 | |
|             $reference      = '';
 | |
|             $name           = '';
 | |
|             $newDescription = '';
 | |
| 
 | |
|             // 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->row[7], $matches, PREG_SET_ORDER);
 | |
| 
 | |
|             if (is_array($matches)) {
 | |
|                 foreach ($matches as $match) {
 | |
|                     $key   = $match[1];
 | |
|                     $value = trim($match[2]);
 | |
|                     switch (strtoupper($key)) {
 | |
|                         case 'OMSCHRIJVING':
 | |
|                             $newDescription = $value;
 | |
|                             break;
 | |
|                         case 'NAAM':
 | |
|                             $this->row[8] = $value;
 | |
|                             $name         = $value;
 | |
|                             break;
 | |
|                         case 'KENMERK':
 | |
|                             $reference = $value;
 | |
|                             break;
 | |
|                         case 'IBAN':
 | |
|                             $this->row[9] = $value;
 | |
|                             break;
 | |
|                         default:
 | |
|                             // Ignore the rest
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // Set a new description for the current transaction. If none was given
 | |
|             // set the description to type, name and reference
 | |
|             $this->row[7] = $newDescription;
 | |
|             if (strlen($newDescription) === 0) {
 | |
|                 $this->row[7] = sprintf('%s - %s (%s)', $type, $name, $reference);
 | |
|             }
 | |
| 
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Parses the current description in TRTP format
 | |
|      *
 | |
|      * @return bool 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->row[7], $matches, PREG_SET_ORDER)) {
 | |
| 
 | |
|             $type           = '';
 | |
|             $name           = '';
 | |
|             $reference      = '';
 | |
|             $newDescription = '';
 | |
| 
 | |
|             // Search for properties specified in the TRTP format. If no description
 | |
|             // is provided, use the type, name and reference as new description
 | |
|             if (is_array($matches)) {
 | |
|                 foreach ($matches as $match) {
 | |
|                     $key   = $match[1];
 | |
|                     $value = trim($match[2]);
 | |
| 
 | |
|                     switch (strtoupper($key)) {
 | |
|                         case 'NAME':
 | |
|                             $this->row[8] = $name = $value;
 | |
|                             break;
 | |
|                         case 'REMI':
 | |
|                             $newDescription = $value;
 | |
|                             break;
 | |
|                         case 'IBAN':
 | |
|                             $this->row[9] = $value;
 | |
|                             break;
 | |
|                         case 'EREF':
 | |
|                             $reference = $value;
 | |
|                             break;
 | |
|                         case 'TRTP':
 | |
|                             $type = $value;
 | |
|                             break;
 | |
|                         default:
 | |
|                             // Ignore the rest
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 // Set a new description for the current transaction. If none was given
 | |
|                 // set the description to type, name and reference
 | |
|                 $this->row[7] = $newDescription;
 | |
|                 if (strlen($newDescription) === 0) {
 | |
|                     $this->row[7] = sprintf('%s - %s (%s)', $type, $name, $reference);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
| 
 | |
| }
 |