Commit e38430b7 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

wip

parent e0c1720a
Loading
Loading
Loading
Loading
+0 −53
Changes for bin/entity_elements/Module/src/Module/Entity/Db/Repository/ThingRepository.php: 0 added lines, 53 removed lines.
Original line number Diff line number Diff line
<?php

namespace Module\Entity\Db\Repository;

use Application\Entity\Db\Repository\DefaultEntityRepository;
use Doctrine\ORM\Exception\ORMException;
use Doctrine\ORM\Query\Expr\Join;
use These\Entity\Db\These;
use Module\Entity\Db\Thing;
use Webmozart\Assert\Assert;

class ThingRepository extends DefaultEntityRepository
{
    public function find($id, $lockMode = null, $lockVersion = null): ?Thing
    {
        $qb = $this->createQueryBuilder('c')
            ->leftJoin('c.presences', 'pr', Join::WITH, 'pr.histoDestruction is null')->addSelect('pr')
            ->andWhere('c = :id')->setParameter('id', $id);

        try {
            return $qb->getQuery()->setLockMode($lockMode)->getOneOrNullResult();
        } catch (ORMException $e) {
            throw new \RuntimeException("Erreur rencontrée lors de la requête !", previous: $e);
        }
    }

    public function findOneByThese(These $these): ?Thing
    {
        $qb = $this->createQueryBuilder('cotut')
            ->join('cotut.these', 'th')->addSelect('th')
            ->join('cotut.etablissement', 'etab')->addSelect('etab')
            ->leftJoin('cotut.avenants', 'a', Join::WITH, 'a.histoDestruction is null')->addSelect('a')
            ->leftJoin('a.fichier', 'af')->addSelect('af')
            ->leftJoin('cotut.fichiers', 'f', Join::WITH, 'f.histoDestruction is null')->addSelect('f')
            ->leftJoin('f.fichier', 'ff')->addSelect('ff')
            ->leftJoin('cotut.presences', 'p', Join::WITH, 'p.histoDestruction is null')->addSelect('p')
            ->leftJoin('p.etablissement', 'pe')->addSelect('pe')
            ->leftJoin('p.justifPresenceFichier', 'pf')->addSelect('pf')
            ->andWhereNotHistorise('p')
            ->andWhere('th = :these')->setParameter('these', $these);

        /** @var Thing[] $things */
        $things = $qb->getQuery()->getResult();

        if (count($things) === 0) {
            return null;
        }

        Assert::count($things, 1, "Anomalie : plusieurs cotutelles non historisées trouvées pour une même thèse !");

        return reset($things);
    }
}
 No newline at end of file
+0 −15
Changes for bin/entity_elements/Module/src/Module/Entity/Db/Service/ThingServiceAwareTrait.php: 0 added lines, 15 removed lines.
Original line number Diff line number Diff line
<?php

namespace Module\Entity\Db\Service;

use Module\Entity\Db\Service\ThingService;

trait ThingServiceAwareTrait
{
    protected ThingService $thingService;

    public function setThingService($thingService): void
    {
        $this->thingService = $thingService;
    }
}
 No newline at end of file
+0 −192
Changes for bin/entity_elements/Module/src/Module/Entity/Db/Thing.php: 0 added lines, 192 removed lines.
Original line number Diff line number Diff line
<?php

namespace Module\Entity\Db;

use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Laminas\Permissions\Acl\Resource\ResourceInterface;
use Structure\Entity\Db\Etablissement;
use These\Entity\Db\These;
use UnicaenUtilisateur\Entity\Db\HistoriqueAwareInterface;
use UnicaenUtilisateur\Entity\Db\HistoriqueAwareTrait;

class Thing implements HistoriqueAwareInterface, ResourceInterface
{
    use HistoriqueAwareTrait;

    // Attention : constantes correspondant au type Postgres énuméré "these_cotutelle_etat_enum".
    public const ETAT_ADMINISTRATIF_EN_COURS_DE_NEGOCIATION = 'En cours de négociation';
    public const ETAT_ADMINISTRATIF_EN_COURS_DE_SIGNATURE = 'En cours de signature';
    public const ETAT_ADMINISTRATIF_SIGNE = 'Signé';
    public const ETAT_ADMINISTRATIF_PROJET_ABANDONNE = 'Projet abandonné';

    public const ETATS_ADMINISTRATIFS = [
        self::ETAT_ADMINISTRATIF_EN_COURS_DE_NEGOCIATION => self::ETAT_ADMINISTRATIF_EN_COURS_DE_NEGOCIATION,
        self::ETAT_ADMINISTRATIF_EN_COURS_DE_SIGNATURE => self::ETAT_ADMINISTRATIF_EN_COURS_DE_SIGNATURE,
        self::ETAT_ADMINISTRATIF_SIGNE => self::ETAT_ADMINISTRATIF_SIGNE,
        self::ETAT_ADMINISTRATIF_PROJET_ABANDONNE => self::ETAT_ADMINISTRATIF_PROJET_ABANDONNE,
    ];

    private ?int $id = null;
    private These $these;
    private ?Etablissement $etablissement = null;
    private ?DateTime $dateDebut;
    private ?DateTime $dateFin = null;
    private string $etatAdministratif;
    private ?string $commentaire = null;
    private Collection $fichiers;
    private Collection $avenants;

    public function __construct(These $these)
    {
        $this->setThese($these);
        $this->setDateDebut(date_create());
        $this->setEtatAdministratif(self::ETAT_ADMINISTRATIF_EN_COURS_DE_NEGOCIATION);
        $this->fichiers = new ArrayCollection();
        $this->avenants = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function setId(int $id): self
    {
        $this->id = $id;
        return $this;
    }

    public function setThese(These $these): static
    {
        $this->these = $these;

        return $this;
    }

    public function getThese(): These
    {
        return $this->these;
    }

    public function getEtablissement(): ?Etablissement
    {
        return $this->etablissement;
    }

    public function setEtablissement(Etablissement $etablissement): self
    {
        $this->etablissement = $etablissement;
        return $this;
    }

    public function getEtatAdministratif(): string
    {
        return $this->etatAdministratif;
    }

    public function setEtatAdministratif(string $etatAdministratif): self
    {
        $this->etatAdministratif = $etatAdministratif;
        return $this;
    }

    public function getDateDebut(): DateTime
    {
        return $this->dateDebut;
    }

    public function setDateDebut(DateTime $dateDebut): self
    {
        $this->dateDebut = $dateDebut;
        return $this;
    }

    public function getDateFin(): ?DateTime
    {
        return $this->dateFin;
    }

    public function setDateFin(DateTime $dateFin): self
    {
        $this->dateFin = $dateFin;
        return $this;
    }

    public function getCommentaire(): ?string
    {
        return $this->commentaire;
    }

    public function setCommentaire(?string $commentaire): self
    {
        $this->commentaire = $commentaire;
        return $this;
    }

    /**
     * @return \Doctrine\Common\Collections\Collection<\Thing\Entity\Db\ThingFichier>
     */
    public function getThingFichiers(): Collection
    {
        return $this->fichiers;
    }

    /**
     * @param \Doctrine\Common\Collections\Collection<\Thing\Entity\Db\ThingFichier> $thingFichiers
     */
    public function addThingFichiers(Collection $thingFichiers): self
    {
        foreach ($thingFichiers as $fichier) {
            $this->fichiers->add($fichier);
        }
        return $this;
    }

    /**
     * @param \Doctrine\Common\Collections\Collection<\Thing\Entity\Db\ThingFichier> $thingFichiers
     */
    public function removeThingFichiers(Collection $thingFichiers): self
    {
        foreach ($thingFichiers as $fichier) {
            $this->fichiers->removeElement($fichier);
        }
        return $this;
    }

    /**
     * @return \Doctrine\Common\Collections\Collection<\Thing\Entity\Db\ThingAvenant>
     */
    public function getAvenants(): Collection
    {
        return $this->avenants;
    }

    /**
     * @param \Doctrine\Common\Collections\Collection<\Thing\Entity\Db\ThingAvenant> $avenants
     */
    public function addAvenants(Collection $avenants): self
    {
        foreach ($avenants as $avenant) {
            $this->avenants->add($avenant);
        }
        return $this;
    }

    /**
     * @param \Doctrine\Common\Collections\Collection<\Thing\Entity\Db\ThingAvenant> $avenants
     */
    public function removeAvenants(Collection $avenants): self
    {
        foreach ($avenants as $avenant) {
            $this->avenants->removeElement($avenant);
        }
        return $this;
    }

    public function getResourceId(): string
    {
        return 'Thing';
    }
}
+0 −244
Changes for bin/entity_elements/Module/src/Module/Form/ThingForm.php: 0 added lines, 244 removed lines.
Original line number Diff line number Diff line
<?php

namespace Module\Form;

use AllowDynamicProperties;
use Application\Utils\FormUtils;
use DoctrineModule\Form\Element\ObjectSelect;
use Laminas\Filter\StringTrim;
use Laminas\Filter\ToNull;
use Laminas\Form\Element\Checkbox;
use Laminas\Form\Element\Date;
use Laminas\Form\Element\Hidden;
use Laminas\Form\Element\Select;
use Laminas\Form\Element\Textarea;
use Laminas\Form\Form;
use Laminas\InputFilter\InputFilterProviderInterface;
use Laminas\Validator\Callback;
use RapportActivite\Fieldset\FormationFieldset;
use Structure\Entity\Db\Repository\EtablissementRepository;
use Module\Entity\Db\Repository\ThingMotifFinRepository;
use Module\Entity\Db\Thing;
use Module\Entity\Db\ThingMotifFin;
use Module\Entity\Validator\CotutelleDateValidator;
use UnicaenApp\Form\Element\Collection;
use UnicaenApp\Form\Element\SearchAndSelect;
use UnicaenApp\Service\EntityManagerAwareTrait;

/**
 * @property \Thing\Entity\Db\Thing $object
 * @method Thing getObject()
 */
class ThingForm extends Form implements InputFilterProviderInterface
{
    use EntityManagerAwareTrait;

    private string $urlEtablissement;
    private ThingMotifFinRepository $motifFinRepository;
    private EtablissementRepository $etablissementRepository;

    public function setThingMotifFinRepository(ThingMotifFinRepository $motifFinRepository): void
    {
        $this->motifFinRepository = $motifFinRepository;
    }
    public function setUrlEtablissement(string $urlEtablissement): void
    {
        $this->urlEtablissement = $urlEtablissement;
    }

    public function setEtablissementRepository(EtablissementRepository $etablissementRepository): void
    {
        $this->etablissementRepository = $etablissementRepository;
    }

    public function init(): void
    {
        parent::init();

        $asterisk = FormUtils::generateAsteriskSpan();

        $this->add([
            'type' => Hidden::class,
            'name' => 'id',
        ]);

        $etablissement = new SearchAndSelect('etablissement', [
            'label' => "Établissement étranger $asterisk :",
            'label_options' => ['disable_html_escape' => true],
        ]);
        $etablissement
            ->setAutocompleteSource($this->urlEtablissement)
            ->setRequired()
            ->setSelectionRequired()
            ->setAttributes([
                'id' => 'etablissement',
                'placeholder' => "Entrez au moins 2 lettres pour rechercher l'etablissement...",
            ]);
        $this->add($etablissement);

        $this->add([
            'type' => Date::class,
            'name' => 'dateDebut',
            'options' => [
                'label' => "Date de début de cotutelle $asterisk : ",
                'label_options' => ['disable_html_escape' => true],
            ],
            'attributes' => [
                'id' => 'dateDebut',
            ],
        ]);

        $this->add([
            'type' => Date::class,
            'name' => 'dateFin',
            'options' => [
                'label' => "Date de fin de cotutelle $asterisk : ",
                'label_options' => ['disable_html_escape' => true],
            ],
            'attributes' => [
                'id' => 'dateFin',
            ],
        ]);

        $this->add([
            'type' => Date::class,
            'name' => 'dateSignature',
            'options' => [
                'label' => "Date de signature institutionnelle : ",
                'label_options' => ['disable_html_escape' => true],
            ],
            'attributes' => [
                'id' => 'dateSignature',
            ],
        ]);

        $this->add([
            'type' => Select::class,
            'name' => 'etatAdministratif',
            'options' => [
                'label' => "État administratif $asterisk :",
                'value_options' => Thing::ETATS_ADMINISTRATIFS,
                'empty_option' => "(Sélectionnez une valeur...)",
                'label_options' => ['disable_html_escape' => true],
            ],
            'attributes' => [
                'id' => 'etatAdministratif',
            ],
        ]);

        $motiFinSelect = new ObjectSelect('motifFinCotutelle', [
            'object_manager' => $this->entityManager,
            'target_class' => ThingMotifFin::class,
//            'property' => 'motifFinCotutelle',
            //'find_method' => null,
            'display_empty_item' => true,
            'empty_item_label' => "(Non applicable)",
        ]);
        $motiFinSelect
            ->setLabel("Motif de fin de cotutelle (le cas échéant) :")
            ->setAttributes(['id' => 'motifFinCotutelle']);
        $this->add($motiFinSelect);

        $this->add([
            'type' => Checkbox::class,
            'name' => 'soutenanceDansEtablissementEtranger',
            'options' => [
                'label' => "La soutenance a lieu dans l'établissement étranger",
                'label_options' => ['disable_html_escape' => true],
            ],
        ]);

        $this->add([
            'type' => Textarea::class,
            'name' => 'commentaire',
            'options' => [
                'label' => "Commentaires éventuels :",
                'label_options' => ['disable_html_escape' => true],
            ],
            'attributes' => [
                'rows' => 3,
            ],
        ]);

        FormUtils::addCsrfButton($this);
        FormUtils::addSaveButton($this);
    }

    public function getInputFilterSpecification(): array
    {
        return [
            'etablissement' => [
                'name' => 'etablissement',
                'required' => true,
                'validators' => [
                    [
                        'name' => Callback::class,
                        'options' => [
                            'messages' => [
                                Callback::INVALID_VALUE =>
                                    "L'établissement sélectionné n'a pas de pays renseigné, vous devez compléter sa fiche au préalable",
                            ],
                            'callback' => function ($value, $context) {
                                $e = $this->etablissementRepository->find($value['id']);
                                return $e?->getStructure()->getPays() !== null;
                            },
                        ],
                    ],
                ],
            ],
            'dateDebut' => [
                'name' => 'dateDebut',
                'required' => true,
                'validators' => [
                    [
                        'name' => CotutelleDateValidator::class,
                        'options' => [
                            'thing' => $this->object,
                            'isDateDebut' => true,
                        ],
                    ],
                ],
            ],
            'dateFin' => [
                'name' => 'dateFin',
                'required' => true,
                'validators' => [
                    [
                        'name' => CotutelleDateValidator::class,
                        'options' => [
                            'thing' => $this->object,
                            'isDateDebut' => false,
                        ],
                    ],
                ],
            ],
            'dateSignature' => [
                'name' => 'dateSignature',
                'required' => false,
            ],
            'etatAdministratif' => [
                'name' => 'etatAdministratif',
                'required' => true,
            ],
            'motifFinCotutelle' => [
                'name' => 'motifFinCotutelle',
                'required' => false,
                'filters' => [
                    ['name' => ToNull::class],
                    ['name' => StringTrim::class],
                ],
            ],
            'soutenanceDansEtablissementEtranger' => [
                'name' => 'soutenanceDansEtablissementEtranger',
                'required' => false,
            ],
            'commentaire' => [
                'name' => 'commentaire',
                'required' => false,
                'filters' => [
                    ['name' => StringTrim::class],
                ],
            ],
        ];
    }
}
 No newline at end of file
+0 −41
Changes for bin/entity_elements/Module/src/Module/Form/ThingFormFactory.php: 0 added lines, 41 removed lines.
Original line number Diff line number Diff line
<?php

namespace Module\Form;

use Laminas\ServiceManager\Factory\FactoryInterface;
use Psr\Container\ContainerInterface;
use Structure\Entity\Db\Etablissement;
use Structure\Entity\Db\Repository\EtablissementRepository;
use Module\Entity\Db\ThingMotifFin;
use Module\Hydrator\ThingHydrator;

class ThingFormFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null): ThingForm
    {
        $form = new ThingForm();

        /** @var \Application\View\Renderer\PhpRenderer $renderer*/
        $renderer = $container->get('ViewRenderer');
        $form->setUrlEtablissement($renderer->url('these/cotutelle/rechercherEtablissement'));
        /** @see \Structure\Controller\EtablissementController::rechercherAction() */

        /** @var \Thing\Hydrator\ThingHydrator $hydrator */
        $hydrator = $container->get('HydratorManager')->get(ThingHydrator::class);
        $form->setHydrator($hydrator);

        /** @var \Doctrine\ORM\EntityManager $em */
        $em = $container->get('doctrine.entitymanager.orm_default');
        $form->setEntityManager($em);

        /** @var \Thing\Entity\Db\Repository\ThingMotifFinRepository $motifFinRepository */
        $motifFinRepository = $container->get('doctrine.entitymanager.orm_default')->getRepository(ThingMotifFin::class);
        $form->setThingMotifFinRepository($motifFinRepository);

        /** @var \Structure\Entity\Db\Repository\EtablissementRepository $etablissementRepository */
        $etablissementRepository = $container->get('doctrine.entitymanager.orm_default')->getRepository(Etablissement::class);
        $form->setEtablissementRepository($etablissementRepository);

        return $form;
    }
}
 No newline at end of file
Loading