Commit ae3f3033 by Damien Moulard

Merge branch '8214-add-external-data-to-adherent-admin' into 'develop'

8214 add external data to adherent admin

See merge request !150
parents 194e2dd0 187ab678
......@@ -54,6 +54,7 @@ SIMPLIFIED_HOUSEHOLD_BASED_ALLOWANCE=0
SSA_FRIENDLY_FLUX_TYPE_NAMES=0
CCAS_MODE=0
EXTRA_SECURITY_ADMIN_PASSWORD=ChangeMe
USE_EXTERNAL_DATA=0
EMAIL_ERROR=technique@kohinos.net
EMAIL_USER_FROM=noreply@kohinos.fr
......
......@@ -61,6 +61,7 @@ Copier le fichier .env.dist en .env et configurer :
- en environnement TAV, la variable SIMPLIFIED_HOUSEHOLD_BASED_ALLOWANCE permet d'activer un mode simplifié d'allocation en fonction de la composition du foyer (pas de minimum de cotisation, moins de détails dans la composition du foyer de l'adhérent, pas de renseignement de territoire dans la fiche adhérent, calcul de l'allocation simplifié, pas de plafond de solde). /!\ Requiert l'activation de HOUSEHOLD_BASED_ALLOWANCE.
- en environnement TAV, la variable SSA_FRIENDLY_FLUX_TYPE_NAMES permet d'adapter le nommage des types de flux et les écrans de visualisation des flux à un projet de type SSA
- en environnement TAV, la varialble CCAS_MODE permet d'activer les fonctionnalités de branchement avec une CCAS. Attention : Pour activer CCAS_MODE, le paramètre AUTOMATISATION_RECONVERSION doit OBLIGATOIREMENT être activé.
- en environnement TAV, la varialble USE_EXTERNAL_DATA permet d'indiquer que l'instance stocke des données externes à l'application dans un but de visualisation par une application tierce (i.e. Metabase). Si ce paramètre est actif, certaines de ces données peuvent être renseignées dans la page admin d'un.e adhérent.e.
Si vous utilisez Payzen comme moyen de paiement par CB :
......
......@@ -21,6 +21,7 @@ parameters:
ssa_friendly_flux_type_names: '%env(SSA_FRIENDLY_FLUX_TYPE_NAMES)%'
extra_security_admin_password: '%env(EXTRA_SECURITY_ADMIN_PASSWORD)%'
ccas_mode: '%env(CCAS_MODE)%'
use_external_data: '%env(USE_EXTERNAL_DATA)%'
# PARAMETRES DES IMPORTS POSSIBLE POUR L'APPLICATION DE GESTION DE MONNAIE LOCALE COMPLEMENTAIRE
......
......@@ -12,12 +12,15 @@ use App\Entity\Groupe;
use App\Entity\User;
use App\Entity\Usergroup;
use App\Entity\ProfilDeCotisation;
use App\Entity\ExternalAdherentDatedData;
use App\Enum\CurrencyEnum;
use App\Events\MLCEvents;
use App\Exporter\CustomDoctrineORMQuerySourceIterator;
use App\Form\Type\DependentChildFormType;
use App\Form\Type\GeolocFormType;
use App\Form\Type\UserFormType;
use App\Form\Type\ExternalAdherentDataFormType;
use App\Form\Type\ExternalAdherentDatedDataFormType;
use App\Utils\TAVCotisationUtils;
use Doctrine\ORM\Query;
use FOS\UserBundle\Event\UserEvent;
......@@ -145,17 +148,19 @@ class AdherentAdmin extends AbstractAdmin
protected function configureFormFields(FormMapper $formMapper): void
{
// params
$em = $this->getConfigurationPool()->getContainer()->get('doctrine')->getManager();
$tav_env = $this->getConfigurationPool()->getContainer()->getParameter('tav_env');
$household_based_allowance = $this->getConfigurationPool()->getContainer()->getParameter('household_based_allowance');
$simplified_household_based_allowance = $this->getConfigurationPool()->getContainer()->getParameter('simplified_household_based_allowance');
$container = $this->getConfigurationPool()->getContainer();
$em = $container->get('doctrine')->getManager();
$tav_env = $container->getParameter('tav_env');
$household_based_allowance = $container->getParameter('household_based_allowance');
$simplified_household_based_allowance = $container->getParameter('simplified_household_based_allowance');
$use_external_data = $container->getParameter('use_external_data');
// Initialize adherent
$adherent = $this->getSubject();
$now = new \DateTime();
if ($this->isCurrentRoute('create')) {
$user = $this->userManager->createUser();
$groupe = $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(Usergroup::class)->findOneByName('Adherent');
$groupe = $container->get('doctrine')->getRepository(Usergroup::class)->findOneByName('Adherent');
$user->setEnabled(true);
$user->addPossiblegroup($groupe);
$user->setGroups([$groupe]);
......@@ -197,7 +202,7 @@ class AdherentAdmin extends AbstractAdmin
->add('groupe', ChoiceType::class, [
'required' => true,
'label' => 'Groupe local :',
'choices' => $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(Groupe::class)->findAll(),
'choices' => $container->get('doctrine')->getRepository(Groupe::class)->findAll(),
'choice_label' => 'name',
'placeholder' => 'Choisir un groupe',
])
......@@ -208,7 +213,7 @@ class AdherentAdmin extends AbstractAdmin
if ($tav_env) {
$mlc = $em->getRepository(GlobalParameter::class)->val(GlobalParameter::MLC_SYMBOL);
if ($this->getConfigurationPool()->getContainer()->getParameter('ccas_mode')) {
if ($container->getParameter('ccas_mode')) {
$formMapper
->tab('General')
->with('Identité')
......@@ -545,6 +550,33 @@ class AdherentAdmin extends AbstractAdmin
->end();
}
}
if ($use_external_data) {
$formMapper
->tab('General')
->with('Données de suivi', [
'class' => 'col-md-7',
])
->add('externalData', ExternalAdherentDataFormType::class, [
'label' => false,
'required' => false,
])
->add('externalDatedDataCollection', CollectionType::class, [
'entry_type' => ExternalAdherentDatedDataFormType::class,
'required' => false,
'entry_options' => [
'label' => true,
'data_class' => ExternalAdherentDatedData::class,
'attr' => ['class' => 'border pl-3 pr-3 pt-2']
],
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'label' => "Données datées"
])
->end()
->end();
}
}
$formMapper->getFormBuilder()->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($em) {
......@@ -705,6 +737,10 @@ class AdherentAdmin extends AbstractAdmin
$this->tavCotisationUtils->calculateAllowanceAccordingToHousehold($adherent);
}
if ($adherent->getExternalData()) {
$adherent->getExternalData()->setAdherent($adherent);
}
$em->persist($adherent->getUser());
$em->persist($adherent);
$em->flush();
......
......@@ -166,11 +166,21 @@ class Adherent extends AccountableObject implements AccountableInterface
*/
private $anonymousToken;
/**
* @ORM\OneToOne(targetEntity="ExternalAdherentData", cascade={"persist", "remove"}, mappedBy="adherent", orphanRemoval=true)
*/
private ?ExternalAdherentData $externalData = null;
/**
* @ORM\OneToMany(targetEntity=ExternalAdherentDatedData::class, mappedBy="adherent", orphanRemoval=true, cascade={"persist"})
*/
private $externalDatedDataCollection;
public function __construct()
{
$this->accounts = new ArrayCollection();
$this->dependentChildren = new ArrayCollection();
$this->externalDatedDataCollection = new ArrayCollection();
}
public function getId()
......@@ -522,4 +532,48 @@ class Adherent extends AccountableObject implements AccountableInterface
return $this;
}
/**
* @return ExternalAdherentData
*/
public function getExternalData(): ?ExternalAdherentData
{
return $this->externalData;
}
/**
* @param ExternalAdherentData $externalData
*
* @return Adherent
*/
public function setExternalData(?ExternalAdherentData $externalData): self
{
$this->externalData = $externalData;
return $this;
}
/**
* @return Collection<int, ExternalAdherentDatedData>
*/
public function getExternalDatedDataCollection(): Collection
{
return $this->externalDatedDataCollection;
}
public function addExternalDatedDataCollection(ExternalAdherentDatedData $externalDatedData): self
{
if (!$this->externalDatedDataCollection->contains($externalDatedData)) {
$this->externalDatedDataCollection[] = $externalDatedData;
$externalDatedData->setAdherent($this);
}
return $this;
}
public function removeExternalDatedDataCollection(ExternalAdherentDatedData $externalDatedData): self
{
$this->externalDatedDataCollection->removeElement($externalDatedData);
return $this;
}
}
......@@ -8,6 +8,8 @@ use Ramsey\Uuid\Doctrine\UuidGenerator;
/**
* @ORM\Entity
* @ORM\Table(name="external_adherent_data")
*
* This table stores data to be visualised in a Metabase instance
*/
class ExternalAdherentData
{
......@@ -22,10 +24,10 @@ class ExternalAdherentData
private $id;
/**
* @ORM\OneToOne(targetEntity="Adherent")
* @ORM\OneToOne(targetEntity="Adherent", inversedBy="externalData")
* @ORM\JoinColumn(name="adherent_id", referencedColumnName="id", nullable=false, unique=true)
*/
private $adherent;
private ?Adherent $adherent = null;
/**
* @ORM\ManyToOne(targetEntity="ExternalDataAgeGroup")
......@@ -54,7 +56,7 @@ class ExternalAdherentData
*/
private $externalDataCCMemberStatus;
public function setAdherent(Adherent $adherent): self
public function setAdherent(?Adherent $adherent): self
{
$this->adherent = $adherent;
......@@ -110,7 +112,7 @@ class ExternalAdherentData
return $this;
}
public function getAdherent(): Adherent
public function getAdherent(): ?Adherent
{
return $this->adherent;
}
......
......@@ -4,10 +4,16 @@ namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Doctrine\UuidGenerator;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity
* @ORM\Table(name="external_adherent_dated_data")
* @ORM\Table(name="external_adherent_dated_data", uniqueConstraints={@ORM\UniqueConstraint(name="adherentyear", columns={"adherent_id", "year"})})
* @UniqueEntity(
* fields={"adherent", "year"},
* errorPath="adherent",
* message="Une entrée existe déjà pour cet adhérent et cette année"
* )
*/
class ExternalAdherentDatedData
{
......@@ -22,8 +28,8 @@ class ExternalAdherentDatedData
private $id;
/**
* @ORM\OneToOne(targetEntity="Adherent")
* @ORM\JoinColumn(name="adherent_id", referencedColumnName="id", nullable=false, unique=true)
* @ORM\ManyToOne(targetEntity=Adherent::class, inversedBy="externalDatedData")
* @ORM\JoinColumn(name="adherent_id", referencedColumnName="id", nullable=false)
*/
private $adherent;
......@@ -79,7 +85,7 @@ class ExternalAdherentDatedData
return $this->adherent;
}
public function getYear(): int
public function getYear(): ?int
{
return $this->year;
}
......
......@@ -76,6 +76,7 @@ class GlobalParameter
const GEOLOC_QUARTIER_LIST_VALUES = 'GEOLOC_QUARTIER_LIST_VALUES';
const GEOLOC_WITH_SUBTERRITORY = 'GEOLOC_WITH_SUBTERRITORY';
const COMPTOIR_PAYMENT_TYPES = 'COMPTOIR_PAYMENT_TYPES';
const SSA_ADH_EXTERNAL_DATA_COHORTES_LIST = 'SSA_ADH_EXTERNAL_DATA_COHORTES_LIST';
/**
* @var \Ramsey\Uuid\UuidInterface
......
<?php
namespace App\Form\Type;
use App\Entity\ExternalAdherentData;
use App\Entity\GlobalParameter;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityManagerInterface;
class ExternalAdherentDataFormType extends AbstractType
{
protected $em;
public function __construct(EntityManagerInterface $em) {
$this->em = $em;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$cohortesList = $this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::SSA_ADH_EXTERNAL_DATA_COHORTES_LIST);
$cohortesListArr = [];
foreach (explode(",", $cohortesList) as $cohorte) {
$cohortesListArr[$cohorte] = $cohorte;
}
$builder
->add('cohort',ChoiceType::class, [
'choices' => $cohortesListArr,
'label' => "Cohorte",
'required' => false,
'attr' => [
'autocomplete' => 'off'
],
'placeholder' => "Choix de la cohorte",
])
->add('external_id', TextType::class, [
'label' => 'ID externe',
'required' => false,
'attr' => [
'autocomplete' => 'off'
],
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => ExternalAdherentData::class,
]);
}
public function getBlockPrefix()
{
return 'formExternalAdherentData';
}
}
<?php
namespace App\Form\Type;
use App\Entity\ExternalAdherentDatedData;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityManagerInterface;
class ExternalAdherentDatedDataFormType extends AbstractType
{
protected $em;
public function __construct(EntityManagerInterface $em) {
$this->em = $em;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('year', NumberType::class, [
'label' => 'Année',
'required' => true,
'attr' => [
'autocomplete' => 'off'
],
])
->add('annual_income', NumberType::class, [
'label' => 'Revenu annuel',
'required' => false,
'attr' => [
'autocomplete' => 'off'
],
])
->add('monthly_income', NumberType::class, [
'label' => 'Revenu mensuel',
'required' => false,
'attr' => [
'autocomplete' => 'off'
],
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => ExternalAdherentDatedData::class,
]);
}
public function getBlockPrefix()
{
return 'formExternalAdherentDatedData';
}
}
<?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 Version20251002091120 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 external_adherent_dated_data DROP INDEX UNIQ_23A421FE25F06C53, ADD INDEX IDX_23A421FE25F06C53 (adherent_id)');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE external_adherent_dated_data DROP INDEX IDX_23A421FE25F06C53, ADD UNIQUE INDEX UNIQ_23A421FE25F06C53 (adherent_id)');
}
}
<?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 Version20251009075632 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 caissier DROP FOREIGN KEY FK_1F038BC2A76ED395');
$this->addSql('ALTER TABLE caissier DROP FOREIGN KEY FK_1F038BC2BE3DB2B7');
$this->addSql('ALTER TABLE caissier CHANGE last_transactions_export_datetime last_transactions_export_datetime DATETIME DEFAULT NULL');
$this->addSql('DROP INDEX idx_ff8e6fc2a76ed395 ON caissier');
$this->addSql('CREATE INDEX IDX_1F038BC2A76ED395 ON caissier (user_id)');
$this->addSql('DROP INDEX idx_ff8e6fc2be3db2b7 ON caissier');
$this->addSql('CREATE INDEX IDX_1F038BC2BE3DB2B7 ON caissier (prestataire_id)');
$this->addSql('ALTER TABLE caissier ADD CONSTRAINT FK_1F038BC2A76ED395 FOREIGN KEY (user_id) REFERENCES user (id)');
$this->addSql('ALTER TABLE caissier ADD CONSTRAINT FK_1F038BC2BE3DB2B7 FOREIGN KEY (prestataire_id) REFERENCES prestataire (id)');
$this->addSql('CREATE UNIQUE INDEX adherentyear ON external_adherent_dated_data (adherent_id, year)');
$this->addSql('ALTER TABLE prestataire CHANGE iban iban LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:personal_data)\'');
$this->addSql("INSERT INTO global_parameter (id, name, description, value, mandatory) VALUES (UUID(), 'SSA_ADH_EXTERNAL_DATA_COHORTES_LIST', 'Si les données de suivi sont activées (paramètre USE_EXTERNAL_DATA), définit les valeurs de la liste des roulantes des cohortes. Insérer les valeurs désirées dans l\'ordre séparées par une virgule sans espace.', NULL, '0')");
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE caissier DROP FOREIGN KEY FK_1F038BC2A76ED395');
$this->addSql('ALTER TABLE caissier DROP FOREIGN KEY FK_1F038BC2BE3DB2B7');
$this->addSql('ALTER TABLE caissier CHANGE last_transactions_export_datetime last_transactions_export_datetime DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\'');
$this->addSql('DROP INDEX idx_1f038bc2be3db2b7 ON caissier');
$this->addSql('CREATE INDEX IDX_FF8E6FC2BE3DB2B7 ON caissier (prestataire_id)');
$this->addSql('DROP INDEX idx_1f038bc2a76ed395 ON caissier');
$this->addSql('CREATE INDEX IDX_FF8E6FC2A76ED395 ON caissier (user_id)');
$this->addSql('ALTER TABLE caissier ADD CONSTRAINT FK_1F038BC2A76ED395 FOREIGN KEY (user_id) REFERENCES user (id)');
$this->addSql('ALTER TABLE caissier ADD CONSTRAINT FK_1F038BC2BE3DB2B7 FOREIGN KEY (prestataire_id) REFERENCES prestataire (id)');
$this->addSql('DROP INDEX adherentyear ON external_adherent_dated_data');
$this->addSql('ALTER TABLE prestataire CHANGE iban iban LONGTEXT CHARACTER SET utf8mb3 DEFAULT NULL COLLATE `utf8mb3_general_ci` COMMENT \'(DC2Type:personal_data)\'');
$this->addSql("DELETE FROM global_parameter where name='SSA_ADH_EXTERNAL_DATA_COHORTES_LIST'");
}
}
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