Commit 2fcc12d1 by Yvon Kerdoncuff

Merge branch '5669-produce-bank-transfer-files' into 'ssa-gironde'

5669 produce bank transfer files

See merge request cooperatic/kohinos-tav!78
parents 03e66087 c6a08fa0
...@@ -66,3 +66,6 @@ templates/themes/custom/ ...@@ -66,3 +66,6 @@ templates/themes/custom/
#INTELLIJ #INTELLIJ
.idea/ .idea/
#dir containg exported reconversions xml
/reconversions/
...@@ -15,6 +15,7 @@ Extensions PHP : ...@@ -15,6 +15,7 @@ Extensions PHP :
iconv iconv
mariadb (ou mysql > 8.0) mariadb (ou mysql > 8.0)
gd gd
bcmath (en environnement tav/ssa)
Installer composer si besoin Installer composer si besoin
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
"ext-intl": "*", "ext-intl": "*",
"ext-json": "*", "ext-json": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"andrew-svirin/ebics-client-php": "^2.1",
"api-platform/core": "^2.6", "api-platform/core": "^2.6",
"beberlei/doctrineextensions": "^1.3", "beberlei/doctrineextensions": "^1.3",
"composer/package-versions-deprecated": "1.*", "composer/package-versions-deprecated": "1.*",
......
...@@ -15,3 +15,4 @@ twig: ...@@ -15,3 +15,4 @@ twig:
presta_self_init_and_eval: '%env(PRESTA_SELF_INIT_AND_EVAL)%' presta_self_init_and_eval: '%env(PRESTA_SELF_INIT_AND_EVAL)%'
presta_extra_data: '%env(PRESTA_EXTRA_DATA)%' presta_extra_data: '%env(PRESTA_EXTRA_DATA)%'
household_based_allowance: '%env(HOUSEHOLD_BASED_ALLOWANCE)%' household_based_allowance: '%env(HOUSEHOLD_BASED_ALLOWANCE)%'
automatisation_reconversion: '%env(AUTOMATISATION_RECONVERSION)%'
\ No newline at end of file
...@@ -206,6 +206,11 @@ class PrestataireAdmin extends AbstractAdmin ...@@ -206,6 +206,11 @@ class PrestataireAdmin extends AbstractAdmin
'label' => 'SIRET :', 'label' => 'SIRET :',
'required' => false, 'required' => false,
]) ])
//bic is new field in kohinos-ssa (I think it's OK to add it for non-tav env as well)
->add('bic', TextType::class, [
'label' => 'BIC :',
'required' => false,
])
->add('iban', PersonalDataType::class, [ ->add('iban', PersonalDataType::class, [
'label' => 'IBAN :', 'label' => 'IBAN :',
'required' => false, 'required' => false,
......
...@@ -96,4 +96,8 @@ class ReconversionAdmin extends FluxAdmin ...@@ -96,4 +96,8 @@ class ReconversionAdmin extends FluxAdmin
'Reconverti ?' => 'reconverti', 'Reconverti ?' => 'reconverti',
]; ];
} }
public function isReconversionAdmin() {
return true;
}
} }
...@@ -2,11 +2,14 @@ ...@@ -2,11 +2,14 @@
namespace App\Controller; namespace App\Controller;
use AndrewSvirin\Ebics\Builders\CustomerCreditTransfer\CustomerCreditTransferBuilder;
use App\Entity\Adherent; use App\Entity\Adherent;
use App\Entity\Don; use App\Entity\Don;
use App\Entity\Flux; use App\Entity\Flux;
use App\Entity\GlobalParameter;
use App\Entity\Groupe; use App\Entity\Groupe;
use App\Entity\Prestataire; use App\Entity\Prestataire;
use App\Entity\Reconversion;
use App\Entity\User; use App\Entity\User;
use App\Enum\CurrencyEnum; use App\Enum\CurrencyEnum;
use App\Flux\FluxInterface; use App\Flux\FluxInterface;
...@@ -16,6 +19,7 @@ use App\Utils\TAVCotisationUtils; ...@@ -16,6 +19,7 @@ use App\Utils\TAVCotisationUtils;
use FOS\UserBundle\Model\UserManagerInterface; use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface; use FOS\UserBundle\Util\TokenGeneratorInterface;
use Gamez\Symfony\Component\Serializer\Normalizer\UuidNormalizer; use Gamez\Symfony\Component\Serializer\Normalizer\UuidNormalizer;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sonata\Exporter\Handler; use Sonata\Exporter\Handler;
use Sonata\Exporter\Source\DoctrineORMQuerySourceIterator; use Sonata\Exporter\Source\DoctrineORMQuerySourceIterator;
use Sonata\Exporter\Writer\CsvWriter; use Sonata\Exporter\Writer\CsvWriter;
...@@ -30,6 +34,7 @@ use Symfony\Component\HttpFoundation\Response; ...@@ -30,6 +34,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Encoder\JsonEncoder;
...@@ -75,6 +80,7 @@ class FluxController extends AbstractController ...@@ -75,6 +80,7 @@ class FluxController extends AbstractController
protected $tokenGenerator; protected $tokenGenerator;
protected $validator; protected $validator;
protected $userManager; protected $userManager;
protected $router;
public function __construct( public function __construct(
Security $security, Security $security,
...@@ -88,7 +94,8 @@ class FluxController extends AbstractController ...@@ -88,7 +94,8 @@ class FluxController extends AbstractController
TokenGeneratorInterface $tokenGenerator, TokenGeneratorInterface $tokenGenerator,
ValidatorInterface $validator, ValidatorInterface $validator,
CsrfTokenManagerInterface $tokenManager, CsrfTokenManagerInterface $tokenManager,
UserManagerInterface $userManager UserManagerInterface $userManager,
RouterInterface $router
) { ) {
$this->security = $security; $this->security = $security;
$this->em = $em; $this->em = $em;
...@@ -102,6 +109,7 @@ class FluxController extends AbstractController ...@@ -102,6 +109,7 @@ class FluxController extends AbstractController
$this->tokenManager = $tokenManager; $this->tokenManager = $tokenManager;
$this->tavCotisationsUtils = $tavCotisationsUtils; $this->tavCotisationsUtils = $tavCotisationsUtils;
$this->userManager = $userManager; $this->userManager = $userManager;
$this->router = $router;
} }
protected function manageFluxForm(Request $request, Form $form, $template = '@kohinos/flux/transaction.html.twig', $params = []) protected function manageFluxForm(Request $request, Form $form, $template = '@kohinos/flux/transaction.html.twig', $params = [])
...@@ -171,6 +179,101 @@ class FluxController extends AbstractController ...@@ -171,6 +179,101 @@ class FluxController extends AbstractController
} }
/** /**
* @param Request $request
* @Route("/credit-transfer-file", name="credit_transfer_file")
* @IsGranted({"ROLE_TRESORIER", "ROLE_SUPER_ADMIN"})
* @return Response
*/
public function creditTransferFileAction(Request $request)
{
//raison, bic and iban from debitor are fetched in global parameters
$globalParametersRepository = $this->em->getRepository(GlobalParameter::class);
$raison = $globalParametersRepository->val(GlobalParameter::VIREMENT_RECONVERSION_RAISON_GESTIONNAIRE);
$bic = $globalParametersRepository->val(GlobalParameter::VIREMENT_RECONVERSION_BIC_GESTIONNAIRE);
$iban = $globalParametersRepository->val(GlobalParameter::VIREMENT_RECONVERSION_IBAN_GESTIONNAIRE);
//make sure raison, bic and iban are not empty
if(!$raison || !$bic || !$iban) {
$this->addFlash(
'sonata_flash_error',
"Opération annulée car la raison, l'IBAN ou le BIC du gestionnaire pour les virements de reconversions est vide."
);
return $this->redirect($this->router->generate('index') . 'admin/app/reconversion/list');
}
//SEPA
$builder = new CustomerCreditTransferBuilder();
$customerCreditTransfer = $builder
->createInstance(
$bic,
$iban,
$raison
);
$reconversions = $this->em->getRepository(Reconversion::class)->findBy(["reconverti" => false]);
if(!$reconversions) {
$this->addFlash(
'sonata_flash_error',
"Aucune reconversion à traiter."
);
return $this->redirect($this->router->generate('index') . 'admin/app/reconversion/list');
}
foreach($reconversions as $r) {
/* @var Reconversion $r */
/* @var Prestataire $presta */
$presta = $r->getExpediteur();
if(!$presta || !$presta->isEnabled()) {
//fail ; do not flush : we don't want to toggle reconverti when file can't be generated
$this->addFlash(
'sonata_flash_error',
"Opération annulée car le prestataire " . $presta->getRaison() . " est désactivé ou introuvable."
);
return $this->redirect($this->router->generate('index') . 'admin/app/reconversion/list');
}
if(!$presta->getIban() || !$presta->getBic()) {
//fail ; do not flush : we don't want to toggle reconverti when file can't be generated
$this->addFlash(
'sonata_flash_error',
"Opération annulée car l'IBAN ou le BIC du prestataire " . $presta->getRaison() . " est vide."
);
return $this->redirect($this->router->generate('index') . 'admin/app/reconversion/list');
}
$customerCreditTransfer
->addTransaction(
$presta->getBic(),
$presta->getIban(),
$presta->getRaison(),
$r->getMontant(),
'EUR',
'Reconversion MonA vers EUR'
);
$r->setReconverti(true);
}
$filename = sprintf(
'credit_transfer_file_%s.%s',
date('Y_m_d_H_i_s', strtotime('now')),
'xml'
);
//projectDir is composer.json
$dir = $this->getParameter('kernel.project_dir') . "/reconversions";
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}
$path = $dir . "/" . $filename;
$customerCreditTransfer->popInstance()->save($path);
$this->em->flush();
return $this->file($path);
}
/**
* Export all operations for a user role. * Export all operations for a user role.
* *
* @param Request $request Request * @param Request $request Request
......
...@@ -51,6 +51,9 @@ class GlobalParameter ...@@ -51,6 +51,9 @@ class GlobalParameter
const HELLOASSO_URL_COTISATION_ADHERENT = 'HELLOASSO_URL_COTISATION_ADHERENT'; const HELLOASSO_URL_COTISATION_ADHERENT = 'HELLOASSO_URL_COTISATION_ADHERENT';
const HELLOASSO_URL_COTISATION_PRESTATAIRE = 'HELLOASSO_URL_COTISATION_PRESTATAIRE'; const HELLOASSO_URL_COTISATION_PRESTATAIRE = 'HELLOASSO_URL_COTISATION_PRESTATAIRE';
const CONTACT_FORM_PHONE_NUMBER = 'CONTACT_FORM_PHONE_NUMBER'; const CONTACT_FORM_PHONE_NUMBER = 'CONTACT_FORM_PHONE_NUMBER';
const VIREMENT_RECONVERSION_RAISON_GESTIONNAIRE = 'VIREMENT_RECONVERSION_RAISON_GESTIONNAIRE';
const VIREMENT_RECONVERSION_BIC_GESTIONNAIRE = 'VIREMENT_RECONVERSION_BIC_GESTIONNAIRE';
const VIREMENT_RECONVERSION_IBAN_GESTIONNAIRE = 'VIREMENT_RECONVERSION_IBAN_GESTIONNAIRE';
/** /**
* @var \Ramsey\Uuid\UuidInterface * @var \Ramsey\Uuid\UuidInterface
......
...@@ -146,6 +146,19 @@ class Prestataire extends AccountableObject implements AccountableInterface ...@@ -146,6 +146,19 @@ class Prestataire extends AccountableObject implements AccountableInterface
private $iban; private $iban;
/** /**
* Bank Identifier Code.
*
* @var string
*
* @ORM\Column(name="bic", type="string", nullable=true)
*
* @Assert\Bic(
* ibanPropertyPath="iban"
* )
*/
private $bic;
/**
* @var string * @var string
* *
* @ORM\Column(name="siret", type="string", length=50, nullable=true) * @ORM\Column(name="siret", type="string", length=50, nullable=true)
...@@ -541,6 +554,26 @@ class Prestataire extends AccountableObject implements AccountableInterface ...@@ -541,6 +554,26 @@ class Prestataire extends AccountableObject implements AccountableInterface
/** /**
* @return string * @return string
*/ */
public function getBic(): ?string
{
return $this->bic;
}
/**
* @param string $bic
*
* @return Prestataire
*/
public function setBic(?string $bic): self
{
$this->bic = $bic;
return $this;
}
/**
* @return string
*/
public function getSiret(): ?string public function getSiret(): ?string
{ {
return $this->siret; return $this->siret;
......
...@@ -331,6 +331,27 @@ class GlobalConfigurationFormType extends AbstractType ...@@ -331,6 +331,27 @@ class GlobalConfigurationFormType extends AbstractType
'required' => false, 'required' => false,
'_placeholder' => '', '_placeholder' => '',
]) ])
->add('raisongestionnairevirementreconversion', GlobalParameterType::class, [
'label' => 'Raison du gestionnaire pour les virements de reconversion automatisés',
'_description' => 'Raison du gestionnaire pour les virements de reconversion automatisés',
'name_param' => GlobalParameter::VIREMENT_RECONVERSION_RAISON_GESTIONNAIRE,
'required' => false,
'_placeholder' => '',
])
->add('bicgestionnairevirementreconversion', GlobalParameterType::class, [
'label' => 'BIC du gestionnaire pour les virements de reconversion automatisés',
'_description' => 'BIC du gestionnaire pour les virements de reconversion automatisés',
'name_param' => GlobalParameter::VIREMENT_RECONVERSION_BIC_GESTIONNAIRE,
'required' => false,
'_placeholder' => '',
])
->add('ibangestionnairevirementreconversion', GlobalParameterType::class, [
'label' => 'IBAN du gestionnaire pour les virements de reconversion automatisés',
'_description' => 'IBAN du gestionnaire pour les virements de reconversion automatisés',
'name_param' => GlobalParameter::VIREMENT_RECONVERSION_IBAN_GESTIONNAIRE,
'required' => false,
'_placeholder' => '',
])
; ;
} }
......
...@@ -66,6 +66,11 @@ class PrestataireInfosFormType extends AbstractType ...@@ -66,6 +66,11 @@ class PrestataireInfosFormType extends AbstractType
'label' => 'SIRET :', 'label' => 'SIRET :',
'required' => false, 'required' => false,
]) ])
//bic is new field in kohinos-ssa (I think it's OK to add it for non-tav env as well)
->add('bic', TextType::class, [
'label' => 'BIC :',
'required' => false,
])
->add('iban', TextType::class, [ ->add('iban', TextType::class, [
'label' => 'IBAN :', 'label' => 'IBAN :',
'required' => false, 'required' => false,
......
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240320144059 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE prestataire ADD bic VARCHAR(8) DEFAULT NULL, CHANGE iban iban LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:personal_data)\'');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE prestataire DROP bic, CHANGE iban iban LONGTEXT CHARACTER SET utf8 DEFAULT NULL COLLATE `utf8_general_ci` COMMENT \'(DC2Type:personal_data)\'');
}
}
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240320153828 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE prestataire CHANGE iban iban LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:personal_data)\', CHANGE bic bic VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE prestataire CHANGE iban iban LONGTEXT CHARACTER SET utf8 DEFAULT NULL COLLATE `utf8_general_ci` COMMENT \'(DC2Type:personal_data)\', CHANGE bic bic VARCHAR(8) CHARACTER SET utf8 DEFAULT NULL COLLATE `utf8_general_ci`');
}
}
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240321101500 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql("INSERT INTO global_parameter (id, name, description, value, mandatory) VALUES (UUID(), 'VIREMENT_RECONVERSION_RAISON_GESTIONNAIRE', 'Raison du gestionnaire pour les virements de reconversion automatisés', null, '1')");
$this->addSql("INSERT INTO global_parameter (id, name, description, value, mandatory) VALUES (UUID(), 'VIREMENT_RECONVERSION_BIC_GESTIONNAIRE', 'Bic du gestionnaire pour les virements de reconversion automatisés', null, '1')");
$this->addSql("INSERT INTO global_parameter (id, name, description, value, mandatory) VALUES (UUID(), 'VIREMENT_RECONVERSION_IBAN_GESTIONNAIRE', 'Iban du gestionnaire pour les virements de reconversion automatisés', null, '1')");
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
}
}
...@@ -161,9 +161,6 @@ ...@@ -161,9 +161,6 @@
"egulias/email-validator": { "egulias/email-validator": {
"version": "2.1.6" "version": "2.1.6"
}, },
"ekyna/payum-payzen": {
"version": "1.5.x-dev"
},
"exsyst/swagger": { "exsyst/swagger": {
"version": "v0.4.1" "version": "v0.4.1"
}, },
......
...@@ -33,6 +33,12 @@ ...@@ -33,6 +33,12 @@
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
{% if tav_env and automatisation_reconversion and admin.isReconversionAdmin is defined and admin.isReconversionAdmin %}
<a href="{{ path('credit_transfer_file') }}" type="button" class="btn btn-default">
<i class="fa fa-share-square-o" aria-hidden="true"></i>
Générer SEPA
</a>
{% endif %}
</div> </div>
</div> </div>
{% if admin.total is defined and admin.total > 0 %} {% if admin.total is defined and admin.total > 0 %}
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
</div> </div>
{% endif %} {% endif %}
{{ form_row(form.siret) }} {{ form_row(form.siret) }}
{{ form_row(form.bic) }}
{{ form_row(form.iban) }} {{ form_row(form.iban) }}
{{ form_row(form.responsable) }} {{ form_row(form.responsable) }}
{{ form_row(form.metier) }} {{ form_row(form.metier) }}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment