diff --git a/modules/banking_import/src/Form/CAMTImportForm.php b/modules/banking_import/src/Form/CAMTImportForm.php index 6922d527add34d91474afe57af62687964dc61bf..dd087b503c11cd6f1749afbe2daec43795ac4b00 100644 --- a/modules/banking_import/src/Form/CAMTImportForm.php +++ b/modules/banking_import/src/Form/CAMTImportForm.php @@ -3,9 +3,12 @@ namespace Drupal\banking_import\Form; use Drupal\Core\Form\FormBase; +use Drupal\Core\Form\FormState; use Drupal\Core\Form\FormStateInterface; -use Drupal\file\Entity\File; +use Drupal\Core\Plugin\PluginFormInterface; +use Drupal\Component\Utility\NestedArray; +use Drupal\file\Entity\File; use Drupal\banking_import\Exception\BankingImportException; /** @@ -56,15 +59,39 @@ class CAMTImportForm extends FormBase { 'file_validate_extensions' => ['xml xda bc2 cod csv'], ], '#upload_location' => 'private://', + '#weight' => '1', ]; + $wrapper_id = 'ajax-wrapper-22'; $form['format'] = [ '#type' => 'select', '#title' => $this->t('File format'), '#options' => $format_options, - '#weight' => '0', + '#weight' => '5', '#required' => TRUE, + '#ajax' => [ + 'callback' => [get_called_class(), 'updatePlugin'], + 'wrapper' => $wrapper_id, + ], + ]; + + $form['plugin_settings_wrapper'] = [ + '#weight' => '10', + '#tree' => TRUE, + '#prefix' => '<div id="' . $wrapper_id . '">', + '#suffix' => '</div>', ]; + + if ($form_state->getValue('format')) { + $plugin_id = $form_state->getValue('format'); + $plugin_values = $form_state->getValue(['plugin_settings_wrapper']); + $plugin = $format_manager->createInstance($plugin_id, $plugin_values ? $plugin_values : []); + if ($plugin instanceof PluginFormInterface) { + $form['plugin_settings_wrapper'] += $plugin->buildConfigurationForm([], $form_state); + } + } + $form['submit'] = [ + '#weight' => '20', '#type' => 'submit', '#value' => $this->t('Submit'), ]; @@ -72,6 +99,14 @@ class CAMTImportForm extends FormBase { return $form; } + /** + * {@inheritdoc} + */ + public static function updatePlugin(array $form, FormStateInterface $form_state) { + $subform = NestedArray::getValue($form, ['plugin_settings_wrapper']); + return $subform; + } + /** * {@inheritdoc} */ @@ -95,6 +130,16 @@ class CAMTImportForm extends FormBase { 'file', $e->getMessage()); } + + $this->manager = \Drupal::service('plugin.manager.banking_import_format_definitions'); + if ($form_state->getValue('format')) { + $plugin_id = $form_state->getValue('format'); + $plugin = $this->manager->createInstance($plugin_id, []); + $plugin_values = $form_state->getValue(['plugin_settings_wrapper']); + if ($plugin_values) { + $plugin->validateConfigurationForm($form, $form_state); + } + } } /** @@ -103,6 +148,13 @@ class CAMTImportForm extends FormBase { public function submitForm(array &$form, FormStateInterface $form_state) { $definition = \Drupal::service('plugin.manager.banking_import_format_definitions') ->createInstance($form_state->getValue('format'), []); + $plugin_values = $form_state->getValue(['plugin_settings_wrapper']); + if ($plugin_values) { + $sub_form_state = new FormState(); + $sub_form_state->setValues($plugin_values); + $definition->submitConfigurationForm($form, $sub_form_state); + } + $file = File::load(reset($form_state->getValue('file'))); $batch = $definition->importFileBatch($file); diff --git a/modules/banking_import/src/Plugin/BankingImportFormat/CAMT053.php b/modules/banking_import/src/Plugin/BankingImportFormat/CAMT053.php index 0a72aefda0ad21874e8594809591aa855bf2ba13..97aac54c4d2e74fc1d03d7f2ec800d247f625038 100644 --- a/modules/banking_import/src/Plugin/BankingImportFormat/CAMT053.php +++ b/modules/banking_import/src/Plugin/BankingImportFormat/CAMT053.php @@ -2,8 +2,12 @@ namespace Drupal\banking_import\Plugin\BankingImportFormat; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\PluginFormInterface; +use Drupal\banking\Entity\BankAccount; use Drupal\banking_import\Exception\BankingImportException; use Drupal\banking_import\Plugin\BankingImportFormatDefinitionBase; +use Drupal\banking_import\Plugin\DuplicateDayCheckTrait; use Money\Currencies\ISOCurrencies; use Money\Formatter\DecimalMoneyFormatter; @@ -14,9 +18,6 @@ use Genkgo\Camt\DTO\Creditor; use Genkgo\Camt\DTO\Debtor; use Genkgo\Camt\DTO\IbanAccount; -use Drupal\banking\Entity\BankTransaction; -use Drupal\banking\Entity\BankAccount; - /** * Import bank transactions from CAMT053 files. * @@ -25,7 +26,8 @@ use Drupal\banking\Entity\BankAccount; * label = @Translation("CAMT053"), * ) */ -class CAMT053 extends BankingImportFormatDefinitionBase { +class CAMT053 extends BankingImportFormatDefinitionBase implements PluginFormInterface { + use DuplicateDayCheckTrait; /** * {@inheritdoc} @@ -119,21 +121,11 @@ class CAMT053 extends BankingImportFormatDefinitionBase { ]; foreach ($message->getRecords() as $statement) { - - $bank_account = BankAccount::loadByAccountNumber($statement->getAccount()->getIban()); - $statement_from_date = $statement->getFromDate()->format('Y-m-d'); - $statement_to_date = $statement->getToDate()->format('Y-m-d'); - $query = \Drupal::entityQuery('bank_transaction') - ->condition('date', $statement_from_date, '>=') - ->condition('date', $statement_to_date, '<=') - ->condition('bank_account_id', $bank_account->id()); - $values = $query->execute(); - $dates = []; - foreach (BankTransaction::loadMultiple(array_keys($values)) as $transactie) { - if (!in_array($transactie->getDate(), $dates)) { - $dates[] = $transactie->getDate(); - } - } + $dates = $this->getPreviouslyImportedDates( + $statement->getAccount()->getIban(), + $statement->getFromDate()->format('Y-m-d'), + $statement->getToDate()->format('Y-m-d') + ); $batch['operations'][] = [ '\Drupal\banking_import\Plugin\BankingImportFormat\CAMT053::importStatement', [ @@ -159,16 +151,18 @@ class CAMT053 extends BankingImportFormatDefinitionBase { foreach ($statement->getEntries() as $batch_entry) { if (in_array($batch_entry->getBookingDate()->format('Y-m-d'), $dates)) { \Drupal::messenger()->addWarning( - t("Not importing entry for day @day and account @account: there are already transactions for this day!", + t( + "Not importing entry for day @day and account @account: there are already transactions for this day!", [ '@day' => $batch_entry->getBookingDate()->format('Y-m-d'), '@account' => $statement->getAccount()->getIban(), ]), 'warning'); - // continue;. + continue; } $transaction_idx = 0; + $transaction = FALSE; foreach ($batch_entry->getTransactionDetails() as $entry) { if ($entry->getAmountDetails() && $entry->getAmountDetails()->getAmount()) { $amount = $entry->getAmountDetails()->getAmount(); @@ -250,7 +244,7 @@ class CAMT053 extends BankingImportFormatDefinitionBase { } } - \Drupal::service('banking_import.default')->createImportedTransaction($transaction_data); + $transaction = \Drupal::service('banking_import.default')->createImportedTransaction($transaction_data); $transaction_idx++; $all_transaction_for_statement_idx++; } @@ -259,7 +253,18 @@ class CAMT053 extends BankingImportFormatDefinitionBase { $context['results']['count'] = 0; } - $context['results']['count'] += 1; + if ($transaction) { + $context['results']['count'] += 1; + } + else { + \Drupal::messenger()->addWarning( + t("Failed to import entry '@name' for account @account!", + [ + '@name' => $statement->getId() . '/' . $all_transaction_for_statement_idx, + '@account' => $bank_account->getNumber(), + ]), + 'warning'); + } } } diff --git a/modules/banking_import/src/Plugin/BankingImportFormat/CSV.php b/modules/banking_import/src/Plugin/BankingImportFormat/CSV.php index 2eceec7b0b104e4779232f15a76d3f45c7635b11..f6c9714a7e9129181863e998aaccb2deb054fda3 100644 --- a/modules/banking_import/src/Plugin/BankingImportFormat/CSV.php +++ b/modules/banking_import/src/Plugin/BankingImportFormat/CSV.php @@ -2,17 +2,18 @@ namespace Drupal\banking_import\Plugin\BankingImportFormat; +use Drupal\Core\Plugin\PluginFormInterface; +use Drupal\banking\Entity\BankTransaction; +use Drupal\banking\Entity\BankAccount; use Drupal\banking_import\Exception\BankingImportException; use Drupal\banking_import\Plugin\BankingImportFormatDefinitionBase; +use Drupal\banking_import\Plugin\DuplicateDayCheckTrait; use Money\Currencies\ISOCurrencies; use Money\Currency; use Money\Formatter\DecimalMoneyFormatter; use Money\Parser\IntlLocalizedDecimalParser; -use Drupal\banking\Entity\BankTransaction; -use Drupal\banking\Entity\BankAccount; - use League\Csv\Reader; /** @@ -23,7 +24,8 @@ use League\Csv\Reader; * label = @Translation("CSV"), * ) */ -class CSV extends BankingImportFormatDefinitionBase { +class CSV extends BankingImportFormatDefinitionBase implements PluginFormInterface { + use DuplicateDayCheckTrait; /** * Get required headers for CSV file. @@ -107,20 +109,16 @@ class CSV extends BankingImportFormatDefinitionBase { $records = $csv->getRecords(); foreach ($records as $offset => $transaction) { + $transaction_date = \DateTime::createFromFormat('!d/m/Y', $transaction['Datum'])->getTimestamp(); + $dates = array_merge( + $dates, + $this->getPreviouslyImportedDates( + $transaction['Rekeningnummer'], + date("Y-m-d", $transaction_date), + date("Y-m-d", $transaction_date) + ) + ); - $bank_account = BankAccount::loadByAccountNumber($transaction['Rekeningnummer']); - $statement_from_date = date('Y-m-d', \DateTime::createFromFormat('!d/m/Y', $transaction['Datum'])->getTimestamp()); - $statement_to_date = $statement_from_date; - $query = \Drupal::entityQuery('bank_transaction') - ->condition('date', $statement_from_date, '>=') - ->condition('date', $statement_to_date, '<=') - ->condition('bank_account_id', $bank_account->id()); - $values = $query->execute(); - foreach (BankTransaction::loadMultiple(array_keys($values)) as $transactie) { - if (!in_array($transactie->getDate(), $dates)) { - $dates[] = $transactie->getDate(); - } - } if (!isset($statements[$transaction['Afschriftnummer']])) { $statements[$transaction['Afschriftnummer']] = []; } @@ -201,12 +199,23 @@ class CSV extends BankingImportFormatDefinitionBase { ) ); - \Drupal::service('banking_import.default')->createImportedTransaction($transaction_data); - if (!isset($context['results']['count'])) { $context['results']['count'] = 0; } - $context['results']['count'] += 1; + + $transaction_ent = \Drupal::service('banking_import.default')->createImportedTransaction($transaction_data); + if ($transaction_ent) { + $context['results']['count'] += 1; + } + else { + \Drupal::messenger()->addWarning( + t("Failed to import entry '@name' for account @account!", + [ + '@name' => $transaction['Afschriftnummer'] . '/' . $n, + '@account' => $bank_account->getNumber(), + ]), + 'warning'); + } $n++; } } diff --git a/modules/banking_import/src/Plugin/BankingImportFormatDefinitionBase.php b/modules/banking_import/src/Plugin/BankingImportFormatDefinitionBase.php index 9a2c40461d0145e6bd9b5f5197c39a34a0c34960..ee2a1dda1aabba5a12df436552070b70c2831280 100644 --- a/modules/banking_import/src/Plugin/BankingImportFormatDefinitionBase.php +++ b/modules/banking_import/src/Plugin/BankingImportFormatDefinitionBase.php @@ -2,6 +2,7 @@ namespace Drupal\banking_import\Plugin; +use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Component\Plugin\PluginBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -9,6 +10,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * {@inheritdoc} */ abstract class BankingImportFormatDefinitionBase extends PluginBase implements BankingImportFormatDefinitionInterface { + use StringTranslationTrait; /** * {@inheritdoc} diff --git a/modules/banking_import/src/Plugin/DuplicateDayCheckTrait.php b/modules/banking_import/src/Plugin/DuplicateDayCheckTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..4ebe9cf669453cba1fe52089f166818503909685 --- /dev/null +++ b/modules/banking_import/src/Plugin/DuplicateDayCheckTrait.php @@ -0,0 +1,60 @@ +<?php + +namespace Drupal\banking_import\Plugin; + +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\PluginFormInterface; +use Drupal\banking\Entity\BankAccount; +use Drupal\banking\Entity\BankTransaction; + + +trait DuplicateDayCheckTrait { + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { + $form['sameday'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Allow to reimport day for same day.'), + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + $this->configuration['form_values'] = $form_state->getValues(); + } + + public function getPreviouslyImportedDates($iban, $from, $to) { + if (isset($this->configuration['form_values']['sameday']) && + $this->configuration['form_values']['sameday']) { + return []; + } + + $dates = []; + $bank_account = BankAccount::loadByAccountNumber($iban); + $query = \Drupal::entityQuery('bank_transaction') + ->accessCheck(FALSE) + ->condition('date', $from, '>=') + ->condition('date', $to, '<=') + ->condition('bank_account_id', $bank_account->id()); + $values = $query->execute(); + foreach (BankTransaction::loadMultiple(array_keys($values)) as $transaction) { + if (!in_array($transaction->getDate(), $dates)) { + $dates[] = $transaction->getDate(); + } + } + return $dates; + } + +} diff --git a/modules/banking_import/tests/data/mutations.csv b/modules/banking_import/tests/data/mutations.csv new file mode 100644 index 0000000000000000000000000000000000000000..8c45d93622ce6d88cf5b2d445ea0c02a0edd3907 --- /dev/null +++ b/modules/banking_import/tests/data/mutations.csv @@ -0,0 +1,5 @@ +Rekeningnummer;Rubrieknaam;Naam;Munt;Afschriftnummer;Datum;Omschrijving;Valuta;Bedrag;Saldo;Credit;Debet;Rekening tegenpartij;BIC code tegenpartij;Naam tegenpartij;Adres tegenpartij;gestructureerde mededeling;vrije mededeling +BE72363200506316;UITGIFTE Aandeel B2;dardemo cv;EUR;66;11/05/2022;Overschrijving in euro (SEPA);11/05/2022;25;25;25;;BE49 6511 5740 8471;;Tim Janssens;;+++519/0000/80793+++; +BE72363200506316;UITGIFTE Aandeel B2;dardemo cv;EUR;64;13/05/2022;Instantoverschrijving in euro;13/05/2022;500;500;500;;BE07 3350 6610 7566;;Perquy – Gaasbeek;;+++519/0000/80995+++; +BE72363200506316;UITGIFTE Aandeel B2;dardemo cv;EUR;62;16/05/2022;Instantoverschrijving in euro;16/05/2022;500;500;500;;BE08 3700 9343 2713;;Wilfried nollens;;+++519/0000/78571+++; +BE72363200506316;UITGIFTE Aandeel B2;dardemo cv;EUR;58;17/05/2022;Overschrijving in euro (SEPA);17/05/2022;5000;5000;5000;;BE96 0001 2112 4405;;Jos vermeulen;;+++519/0000/81504+++;