fix : DSD saisi conservé en pesée manuelle (ERP-193)
En pesée manuelle, le serveur incrémentait automatiquement le DSD et ignorait la saisie de l'opérateur. Désormais l'opérateur saisit le poids ET le DSD (le numéro du pont réellement utilisé), conservés tels quels — plus d'auto-incrément. Le champ « Numéro de pesée » séparé (manualNumber) est supprimé : pour le client c'est la même chose que le DSD. Pas de contrainte d'unicité sur le DSD (doublons autorisés). Colonnes empty_manual_number/full_manual_number droppées.
This commit is contained in:
@@ -56,18 +56,16 @@ final class WeighbridgeReadingApiTest extends AbstractApiTestCase
|
||||
self::assertLessThanOrEqual(50000, $data['weight']);
|
||||
self::assertIsInt($data['dsd']);
|
||||
self::assertGreaterThanOrEqual(1, $data['dsd']);
|
||||
// manualNumber est null en mode bascule (cle potentiellement omise si
|
||||
// skip_null_values est actif — tolerant aux deux cas).
|
||||
self::assertNull($data['manualNumber'] ?? null);
|
||||
}
|
||||
|
||||
public function testManualWeighingKeepsWeightAndAllocatesDsd(): void
|
||||
public function testManualWeighingKeepsWeightAndEnteredDsd(): void
|
||||
{
|
||||
$client = $this->manageClientWithCurrentSite();
|
||||
|
||||
$response = $client->request('POST', '/api/weighbridge_readings', [
|
||||
'headers' => ['Content-Type' => 'application/ld+json'],
|
||||
'json' => ['mode' => 'MANUAL', 'weight' => 23187, 'manualNumber' => 'PAP-555'],
|
||||
// Le DSD est SAISI par l'operateur et conserve tel quel (ERP-193).
|
||||
'json' => ['mode' => 'MANUAL', 'weight' => 23187, 'dsd' => 16619],
|
||||
]);
|
||||
|
||||
self::assertResponseStatusCodeSame(200);
|
||||
@@ -75,8 +73,7 @@ final class WeighbridgeReadingApiTest extends AbstractApiTestCase
|
||||
|
||||
self::assertSame('MANUAL', $data['mode']);
|
||||
self::assertSame(23187, $data['weight']);
|
||||
self::assertSame('PAP-555', $data['manualNumber']);
|
||||
self::assertGreaterThanOrEqual(1, $data['dsd']);
|
||||
self::assertSame(16619, $data['dsd'], 'Le DSD saisi est conserve, pas d\'auto-increment.');
|
||||
}
|
||||
|
||||
public function testManagePermissionIsRequired(): void
|
||||
@@ -117,11 +114,25 @@ final class WeighbridgeReadingApiTest extends AbstractApiTestCase
|
||||
'json' => ['mode' => 'MANUAL'],
|
||||
]);
|
||||
|
||||
// Garde-fou ERP-101 : la 422 doit cibler `weight` (Callback validateManualWeight).
|
||||
// Garde-fou ERP-101 : la 422 doit cibler `weight` (Callback validateManualFields).
|
||||
self::assertResponseStatusCodeSame(422);
|
||||
self::assertViolationOnPath($response, 'weight');
|
||||
}
|
||||
|
||||
public function testManualWeighingRequiresDsd(): void
|
||||
{
|
||||
$client = $this->manageClientWithCurrentSite();
|
||||
|
||||
$response = $client->request('POST', '/api/weighbridge_readings', [
|
||||
'headers' => ['Content-Type' => 'application/ld+json'],
|
||||
'json' => ['mode' => 'MANUAL', 'weight' => 23187],
|
||||
]);
|
||||
|
||||
// En manuel, le DSD est saisi → obligatoire (Callback validateManualFields).
|
||||
self::assertResponseStatusCodeSame(422);
|
||||
self::assertViolationOnPath($response, 'dsd');
|
||||
}
|
||||
|
||||
/**
|
||||
* Garde-fou ERP-101 (miroir AbstractWeighingTicketApiTestCase) : une 422 doit
|
||||
* porter une violation sur le `propertyPath` attendu, consommable inline par
|
||||
|
||||
+11
-28
@@ -5,7 +5,6 @@ declare(strict_types=1);
|
||||
namespace App\Tests\Module\Logistique\Infrastructure\ApiPlatform\State\Processor;
|
||||
|
||||
use ApiPlatform\Metadata\Post;
|
||||
use App\Module\Logistique\Application\Service\DsdAllocatorInterface;
|
||||
use App\Module\Logistique\Domain\Contract\WeighbridgeReaderInterface;
|
||||
use App\Module\Logistique\Domain\Exception\WeighbridgeUnavailableException;
|
||||
use App\Module\Logistique\Domain\Weighbridge\WeighbridgeReading;
|
||||
@@ -21,8 +20,8 @@ use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
|
||||
* Processor de l'action `POST /api/weighbridge_readings` (§ 4.2).
|
||||
*
|
||||
* Couvre les 4 chemins sans BDD ni HTTP (stubs purs) : AUTO (lecture pont),
|
||||
* MANUAL (allocation DSD seule), indisponibilite → 503 (RG-5.06) et absence de
|
||||
* site courant → 400.
|
||||
* MANUAL (poids ET DSD saisis conserves tels quels, ERP-193), indisponibilite →
|
||||
* 503 (RG-5.06) et absence de site courant → 400.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
@@ -30,8 +29,7 @@ final class WeighbridgeReadingProcessorTest extends TestCase
|
||||
{
|
||||
private function site(): Site
|
||||
{
|
||||
// getId() reste null (non persiste) — sans incidence : reader et allocator
|
||||
// sont stubbes dans ces tests unitaires.
|
||||
// getId() reste null (non persiste) — sans incidence : reader stubbe.
|
||||
return new Site('Châtellerault', 'Rue du Pont', null, '86000', 'Châtellerault', '#112233');
|
||||
}
|
||||
|
||||
@@ -43,11 +41,7 @@ final class WeighbridgeReadingProcessorTest extends TestCase
|
||||
$reader = $this->createStub(WeighbridgeReaderInterface::class);
|
||||
$reader->method('read')->willReturn(new WeighbridgeReading(23000, 42));
|
||||
|
||||
$processor = new WeighbridgeReadingProcessor(
|
||||
$siteProvider,
|
||||
$reader,
|
||||
$this->createStub(DsdAllocatorInterface::class),
|
||||
);
|
||||
$processor = new WeighbridgeReadingProcessor($siteProvider, $reader);
|
||||
|
||||
$resource = new WeighbridgeReadingResource();
|
||||
$resource->mode = 'AUTO';
|
||||
@@ -56,34 +50,28 @@ final class WeighbridgeReadingProcessorTest extends TestCase
|
||||
|
||||
self::assertSame(23000, $result->weight);
|
||||
self::assertSame(42, $result->dsd);
|
||||
self::assertNull($result->manualNumber);
|
||||
self::assertSame('AUTO', $result->mode);
|
||||
}
|
||||
|
||||
public function testManualModeKeepsWeightAndAllocatesDsd(): void
|
||||
public function testManualModeKeepsWeightAndDsdAsEntered(): void
|
||||
{
|
||||
$siteProvider = $this->createStub(CurrentSiteProviderInterface::class);
|
||||
$siteProvider->method('get')->willReturn($this->site());
|
||||
|
||||
$allocator = $this->createStub(DsdAllocatorInterface::class);
|
||||
$allocator->method('next')->willReturn(43);
|
||||
|
||||
$processor = new WeighbridgeReadingProcessor(
|
||||
$siteProvider,
|
||||
$this->createStub(WeighbridgeReaderInterface::class),
|
||||
$allocator,
|
||||
);
|
||||
|
||||
$resource = new WeighbridgeReadingResource();
|
||||
$resource->mode = 'MANUAL';
|
||||
$resource->weight = 23187;
|
||||
$resource->manualNumber = 'PAP-555';
|
||||
$resource = new WeighbridgeReadingResource();
|
||||
$resource->mode = 'MANUAL';
|
||||
$resource->weight = 23187;
|
||||
$resource->dsd = 16619; // DSD saisi par l'operateur
|
||||
|
||||
$result = $processor->process($resource, new Post());
|
||||
|
||||
self::assertSame(23187, $result->weight, 'Le poids saisi est conserve en manuel.');
|
||||
self::assertSame(43, $result->dsd);
|
||||
self::assertSame('PAP-555', $result->manualNumber);
|
||||
self::assertSame(16619, $result->dsd, 'Le DSD saisi est conserve tel quel — pas d\'auto-increment (ERP-193).');
|
||||
self::assertSame('MANUAL', $result->mode);
|
||||
}
|
||||
|
||||
@@ -95,11 +83,7 @@ final class WeighbridgeReadingProcessorTest extends TestCase
|
||||
$reader = $this->createStub(WeighbridgeReaderInterface::class);
|
||||
$reader->method('read')->willThrowException(new WeighbridgeUnavailableException());
|
||||
|
||||
$processor = new WeighbridgeReadingProcessor(
|
||||
$siteProvider,
|
||||
$reader,
|
||||
$this->createStub(DsdAllocatorInterface::class),
|
||||
);
|
||||
$processor = new WeighbridgeReadingProcessor($siteProvider, $reader);
|
||||
|
||||
$resource = new WeighbridgeReadingResource();
|
||||
$resource->mode = 'AUTO';
|
||||
@@ -121,7 +105,6 @@ final class WeighbridgeReadingProcessorTest extends TestCase
|
||||
$processor = new WeighbridgeReadingProcessor(
|
||||
$siteProvider,
|
||||
$this->createStub(WeighbridgeReaderInterface::class),
|
||||
$this->createStub(DsdAllocatorInterface::class),
|
||||
);
|
||||
|
||||
$resource = new WeighbridgeReadingResource();
|
||||
|
||||
Reference in New Issue
Block a user