Skip to content

Commit

Permalink
Merge branch 'EsupPortail:main' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
julienbdx authored Dec 4, 2024
2 parents f7ac823 + 27bb963 commit 9fdf2b3
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 39 deletions.
44 changes: 23 additions & 21 deletions backend/src/ApiResource/Demande.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

namespace App\ApiResource;

use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Doctrine\Orm\State\Options;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiProperty;
Expand All @@ -23,6 +23,7 @@
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use App\Filter\CampagneNonArchiveeFilter;
use App\Filter\DemandeDisciplineSportiveFilter;
use App\Filter\DemandeFormatFilter;
use App\Filter\DerniereInscriptionSearchFilter;
Expand All @@ -39,43 +40,43 @@
use Symfony\Component\Validator\Constraints as Assert;

#[ApiResource(
operations : [
operations: [
new Get(
uriTemplate : self::ITEM_URI,
uriTemplate: self::ITEM_URI,
uriVariables: ['id'],
security : "is_granted('" . self::VOIR_DEMANDE . "', object)"
security: "is_granted('" . self::VOIR_DEMANDE . "', object)"
),
new GetCollection(
uriTemplate: self::COLLECTION_URI,
forceEager : false
forceEager: false
),
new GetCollection(
uriTemplate : self::COLLECTION_UTILISATEUR_URI,
uriTemplate: self::COLLECTION_UTILISATEUR_URI,
uriVariables: ['uid'],
security : "is_granted('ROLE_GESTIONNAIRE') or request.get('uid') == user.getUid()",
forceEager : false,
provider : DemandesUtilisateurProvider::class,
security: "is_granted('ROLE_GESTIONNAIRE') or request.get('uid') == user.getUid()",
forceEager: false,
provider: DemandesUtilisateurProvider::class,
),
new Post(
uriTemplate : self::COLLECTION_URI,
denormalizationContext : ['groups' => [self::GROUP_IN]],
uriTemplate: self::COLLECTION_URI,
denormalizationContext: ['groups' => [self::GROUP_IN]],
securityPostDenormalize: "is_granted('ROLE_GESTIONNAIRE') or object.demandeur.uid == user.getUid()",
read : false,
processor : PostDemandeProcessor::class,
read: false,
processor: PostDemandeProcessor::class,
),
new Patch(
uriTemplate : self::ITEM_URI,
uriVariables : ['id'],
denormalizationContext : ['groups' => [self::GROUP_CHANGEMENT_ETAT]],
uriTemplate: self::ITEM_URI,
uriVariables: ['id'],
denormalizationContext: ['groups' => [self::GROUP_CHANGEMENT_ETAT]],
securityPostDenormalize: "is_granted('" . self::MAJ_DEMANDE . "', [previous_object, object])",
processor : PatchDemandeProcessor::class
processor: PatchDemandeProcessor::class
),
],
normalizationContext : ['groups' => [self::GROUP_OUT]],
normalizationContext: ['groups' => [self::GROUP_OUT]],
denormalizationContext: ['groups' => [self::GROUP_IN]],
openapi : new Operation(tags: ['Demandes']),
provider : DemandeProvider::class,
stateOptions : new Options(entityClass: \App\Entity\Demande::class),
openapi: new Operation(tags: ['Demandes']),
provider: DemandeProvider::class,
stateOptions: new Options(entityClass: \App\Entity\Demande::class),
)]
#[ApiFilter(SearchFilter::class, properties: [
'demandeur.nom' => 'ipartial',
Expand Down Expand Up @@ -118,6 +119,7 @@
#[ApiFilter(DemandeDisciplineSportiveFilter::class)]
#[ApiFilter(OrderFilter::class, properties: ['demandeur.nom', 'dateDepot'])]
#[ApiFilter(DemandeFormatFilter::class)]
#[ApiFilter(CampagneNonArchiveeFilter::class)]
#[DemandeUniqueParCampagneConstraint]
#[DemandeWorkflowConstraint]
class Demande
Expand Down
46 changes: 30 additions & 16 deletions backend/src/ApiResource/TauxHoraire.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,60 +13,73 @@
namespace App\ApiResource;

use ApiPlatform\Doctrine\Orm\State\Options;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use App\Filter\TauxHoraireDateFilter;
use App\State\TauxHoraire\TauxHoraireCollectionProvider;
use App\State\TauxHoraire\TauxHoraireProcessor;
use App\State\TauxHoraire\TauxHoraireProvider;
use DateTimeInterface;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;

#[ApiResource(
operations : [
operations: [
new GetCollection(
uriTemplate: self::COLLECTION_URI,
uriVariables: [
'typeId' => new Link(fromProperty: 'id', toProperty: 'typeEvenement', fromClass: TypeEvenement::class,),
],
provider: TauxHoraireCollectionProvider::class,
),
new Get(
uriTemplate : self::ITEM_URI,
uriTemplate: self::ITEM_URI,
uriVariables: [
'typeId', 'id',
],
),
new Post(
uriTemplate : self::COLLECTION_URI,
uriTemplate: self::COLLECTION_URI,
uriVariables: [
'typeId',
],
security : "is_granted('ROLE_ADMIN')",
read : false,
security: "is_granted('ROLE_ADMIN')",
read: false,
),
new Patch(
uriTemplate : self::ITEM_URI,
uriTemplate: self::ITEM_URI,
uriVariables: [
'typeId', 'id',
],
security : "is_granted('ROLE_ADMIN')",
security: "is_granted('ROLE_ADMIN')",
),
new Delete(
uriTemplate : self::ITEM_URI,
uriTemplate: self::ITEM_URI,
uriVariables: [
'typeId', 'id',
],
security : "is_granted('ROLE_ADMIN')",
security: "is_granted('ROLE_ADMIN')",
),
],

normalizationContext : ['groups' => [self::GROUP_OUT]],
normalizationContext: ['groups' => [self::GROUP_OUT]],
denormalizationContext: ['groups' => [self::GROUP_IN]],
openapi : new Operation(tags: ['Referentiel']),
order : ['debut' => 'DESC '],
security : "is_granted('ROLE_PLANIFICATEUR') or is_granted('ROLE_INTERVENANT')",
provider : TauxHoraireProvider::class,
processor : TauxHoraireProcessor::class,
stateOptions : new Options(entityClass: \App\Entity\TauxHoraire::class)
openapi: new Operation(tags: ['Referentiel']),
order: ['debut' => 'DESC '],
security: "is_granted('ROLE_PLANIFICATEUR') or is_granted('ROLE_INTERVENANT')",
provider: TauxHoraireProvider::class,
processor: TauxHoraireProcessor::class,
stateOptions: new Options(entityClass: \App\Entity\TauxHoraire::class)
)]
#[ApiFilter(TauxHoraireDateFilter::class)]
class TauxHoraire
{
public const string COLLECTION_URI = '/types_evenements/{typeId}/taux';
Expand All @@ -80,6 +93,7 @@ class TauxHoraire

//copie juste pour gérer facilement les IRI
public int $typeId;
public TypeEvenement $typeEvenement;

#[Assert\NotBlank]
#[Assert\Length(max: 5)]
Expand Down
49 changes: 49 additions & 0 deletions backend/src/Filter/CampagneNonArchiveeFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace App\Filter;

use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Metadata\Operation;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Clock\ClockAwareTrait;
use Symfony\Component\PropertyInfo\Type;

class CampagneNonArchiveeFilter extends AbstractFilter
{

use ClockAwareTrait;

public const string PROPERTY = 'archivees';

protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void
{
if ($property !== self::PROPERTY || !is_string($value) || $value != 'false') {
return;
}

$rootAlias = $queryBuilder->getRootAliases()[0];
$campagneAlias = $queryNameGenerator->generateJoinAlias('campagne');

$queryBuilder->join(sprintf('%s.campagne', $rootAlias), $campagneAlias)
->andWhere(sprintf('%1$s.dateArchivage IS NULL or %1$s.dateArchivage >= :now', $campagneAlias))
->setParameter('now', $this->now());
}

public function getDescription(string $resourceClass): array
{
return [
'archivees' => [
'property' => "archivees",
'type' => Type::BUILTIN_TYPE_BOOL,
'required' => false,
'is_collection' => false,
'openapi' => [
'description' => "inclure les demandes des campagnes archivées?",
'name' => 'archivees',
'type' => 'boolean',
],
]
];
}
}
53 changes: 53 additions & 0 deletions backend/src/Filter/TauxHoraireDateFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace App\Filter;

use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Metadata\Operation;
use DateTime;
use Doctrine\ORM\QueryBuilder;
use Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\PropertyInfo\Type;

class TauxHoraireDateFilter extends AbstractFilter
{

protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void
{
if ($property !== 'date') {
return;
}

$rootAlias = $queryBuilder->getRootAliases()[0];

try {
$date = new DateTime($value);
} catch (Exception) {
throw new HttpException(400, "date mal formée");
}

$queryBuilder
->andWhere(sprintf('%1$s.debut <= :date AND (%1$s.fin >= :date or %1$s.fin is null)', $rootAlias))
->setParameter('date', $date);

}

public function getDescription(string $resourceClass): array
{
return [
'date' => [
'property' => 'date',
'type' => Type::BUILTIN_TYPE_STRING,
'required' => false,
'openapi' => [
'description' => 'Taux horaire valide pour la date passée',
'name' => 'profil',
'type' => 'string',
'format' => 'date'
],
],
];
}
}
27 changes: 27 additions & 0 deletions backend/src/State/TauxHoraire/TauxHoraireCollectionProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace App\State\TauxHoraire;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\ApiResource\TauxHoraire;
use App\State\TransformerService;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

class TauxHoraireCollectionProvider implements ProviderInterface
{
public function __construct(
#[Autowire(service: 'api_platform.doctrine.orm.state.collection_provider')] private readonly ProviderInterface $collectionProvider,
private readonly TransformerService $transformerService
)
{

}

public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
$data = $this->collectionProvider->provide($operation, $uriVariables, $context);

return array_map(fn($taux) => $this->transformerService->transform($taux, TauxHoraire::class), iterator_to_array($data));
}
}
7 changes: 5 additions & 2 deletions backend/src/State/TauxHoraire/TauxHoraireProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Operation;
use App\ApiResource\TauxHoraire;
use App\ApiResource\TypeEvenement;
use App\State\AbstractEntityProvider;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;

Expand All @@ -41,9 +42,9 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
->withUriVariables([$link]);

$taux = parent::provide(
operation : $relevantOperation,
operation: $relevantOperation,
uriVariables: $relevantVariables,
context : $context
context: $context
);

//devrait être une contrainte de validation
Expand All @@ -65,6 +66,8 @@ public function transform($entity): TauxHoraire
$resource->typeId = $entity->getTypeEvenement()->getId();
$resource->debut = $entity->getDebut();
$resource->fin = $entity->getFin();
$resource->typeEvenement = new TypeEvenement();
$resource->typeEvenement->id = $resource->typeId;
return $resource;
}
}

0 comments on commit 9fdf2b3

Please sign in to comment.