feat : DTOs et mapper pour IpBGetSortiesPresumees

This commit is contained in:
2026-04-21 08:59:33 +02:00
parent d2839f91b5
commit 6493c8a1a7
4 changed files with 153 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Malio\EdnotifBundle\Bovin\Dto;
use DateTimeImmutable;
final readonly class PresumedExitDto
{
public function __construct(
public ?BovinRef $bovin,
public ?DateTimeImmutable $exitDate,
) {}
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Malio\EdnotifBundle\Bovin\Dto;
use Malio\EdnotifBundle\Shared\Dto\StandardResponseDto;
final readonly class PresumedExitsDto
{
/**
* @param list<PresumedExitDto> $presumedExits
*/
public function __construct(
public StandardResponseDto $standardResponse,
public int $nbBovins,
public array $presumedExits,
public ?object $rawSoapResponse,
) {}
}

View File

@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace Malio\EdnotifBundle\Bovin\Mapper;
use Malio\EdnotifBundle\Bovin\Dto\PresumedExitDto;
use Malio\EdnotifBundle\Bovin\Dto\PresumedExitsDto;
use Malio\EdnotifBundle\Shared\Mapper\StandardResponseMapper;
final class PresumedExitsMapper
{
use BovinNodeMappingTrait;
public function __construct(
private readonly StandardResponseMapper $standardResponseMapper,
) {}
public function map(object $soapResponse, ?object $unzippedMessage): PresumedExitsDto
{
$standardResponse = $this->standardResponseMapper->map($soapResponse->ReponseStandard ?? null);
$nbBovins = $this->toNullableInt($soapResponse->ReponseSpecifique->NbBovins ?? null) ?? 0;
$presumedExits = [];
if (is_object($unzippedMessage)) {
$exitsNode = $unzippedMessage->SortiesPresumees->SortiePresumee ?? null;
foreach ($this->normalizeToList($exitsNode) as $exitNode) {
if (!is_object($exitNode)) {
continue;
}
$presumedExits[] = new PresumedExitDto(
bovin: $this->mapBovinRef($exitNode->Bovin ?? null),
exitDate: $this->toNullableDate($exitNode->DateSortie ?? null),
);
}
}
return new PresumedExitsDto(
standardResponse: $standardResponse,
nbBovins: $nbBovins,
presumedExits: $presumedExits,
rawSoapResponse: $soapResponse,
);
}
}

View File

@@ -0,0 +1,72 @@
<?php
declare(strict_types=1);
namespace Malio\EdnotifBundle\Tests\Unit\Bovin\Mapper;
use DateTimeImmutable;
use Malio\EdnotifBundle\Bovin\Dto\PresumedExitsDto;
use Malio\EdnotifBundle\Bovin\Mapper\PresumedExitsMapper;
use Malio\EdnotifBundle\Shared\Mapper\StandardResponseMapper;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use stdClass;
/**
* @internal
*/
#[CoversClass(PresumedExitsMapper::class)]
final class PresumedExitsMapperTest extends TestCase
{
public function testMapWithExits(): void
{
$soapResponse = new stdClass();
$soapResponse->ReponseStandard = new stdClass();
$soapResponse->ReponseStandard->Resultat = true;
$soapResponse->ReponseSpecifique = new stdClass();
$soapResponse->ReponseSpecifique->NbBovins = 2;
$message = new stdClass();
$message->SortiesPresumees = new stdClass();
$message->SortiesPresumees->SortiePresumee = [
$this->makeExit('FR111', '2026-02-15'),
$this->makeExit('FR222', null),
];
$dto = new PresumedExitsMapper(new StandardResponseMapper())->map($soapResponse, $message);
self::assertInstanceOf(PresumedExitsDto::class, $dto);
self::assertSame(2, $dto->nbBovins);
self::assertCount(2, $dto->presumedExits);
self::assertSame('FR111', $dto->presumedExits[0]->bovin?->nationalNumber);
self::assertEquals(new DateTimeImmutable('2026-02-15'), $dto->presumedExits[0]->exitDate);
self::assertNull($dto->presumedExits[1]->exitDate);
}
public function testMapWithoutMessageReturnsEmpty(): void
{
$soapResponse = new stdClass();
$soapResponse->ReponseStandard = new stdClass();
$soapResponse->ReponseStandard->Resultat = true;
$soapResponse->ReponseSpecifique = new stdClass();
$soapResponse->ReponseSpecifique->NbBovins = 0;
$dto = new PresumedExitsMapper(new StandardResponseMapper())->map($soapResponse, null);
self::assertSame(0, $dto->nbBovins);
self::assertSame([], $dto->presumedExits);
}
private function makeExit(string $nationalNumber, ?string $exitDate): object
{
$node = new stdClass();
$node->Bovin = new stdClass();
$node->Bovin->CodePays = 'FR';
$node->Bovin->NumeroNational = $nationalNumber;
if (null !== $exitDate) {
$node->DateSortie = $exitDate;
}
return $node;
}
}