feat(logistique) : pesée pont bascule stub + allocateur DSD + endpoint (ERP-184)
- WeighbridgeReaderInterface (contrat) + RandomWeighbridgeReader (stub,
poids aléatoire ∈ [10000,50000] kg, RG-5.06) + WeighbridgeUnavailableException
- DsdAllocator : compteur DSD par site (weighbridge_dsd_counter) incrémenté
sous verrou ligne SELECT ... FOR UPDATE (RG-5.04, § 2.7)
- endpoint POST /api/weighbridge_readings : ressource virtuelle
WeighbridgeReadingResource + WeighbridgeReadingProcessor (pas de controller)
- AUTO -> {weight, dsd, mode} ; MANUAL -> {weight, dsd, manualNumber, mode}
- WeighbridgeUnavailableException -> HTTP 503 explicite (RG-5.06)
- site courant via CurrentSiteProviderInterface (contrat Sites)
- is_granted('logistique.weighing_tickets.manage')
- dsd renvoyé prévisionnel : attribution autoritaire refaite à la création
du ticket (ERP-185)
- tests : WeighbridgeReaderStubTest, DsdAllocatorTest, processor (503/400),
WeighbridgeReadingApiTest (RBAC + AUTO/MANUAL + 422)
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Module\Logistique\Domain\Contract;
|
||||
|
||||
use App\Module\Logistique\Domain\Exception\WeighbridgeUnavailableException;
|
||||
use App\Module\Logistique\Domain\Weighbridge\WeighbridgeReading;
|
||||
use App\Shared\Domain\Contract\SiteInterface;
|
||||
|
||||
/**
|
||||
* Contrat de lecture du pont bascule (§ 2.6).
|
||||
*
|
||||
* Abstraction posee au M5 pour decoupler l'API du materiel : l'implementation
|
||||
* livree est un stub (RandomWeighbridgeReader, poids aleatoire ∈ [10000,50000]
|
||||
* kg). Le driver materiel reel (protocole serie/TCP de l'indicateur de pesage)
|
||||
* est hors perimetre M5 (HP-M5-02) : le jour venu on substitue l'implementation
|
||||
* derriere cette interface — zero impact sur les ecrans / l'API.
|
||||
*/
|
||||
interface WeighbridgeReaderInterface
|
||||
{
|
||||
/**
|
||||
* Effectue une pesee « bascule » (AUTO) pour le site donne : renvoie le poids
|
||||
* lu et le DSD (index de pesee du pont) attribue pour ce site (RG-5.04).
|
||||
*
|
||||
* @throws WeighbridgeUnavailableException si la bascule ne repond pas
|
||||
* (le Processor traduit en HTTP 503 →
|
||||
* bascule manuelle, RG-5.06)
|
||||
*/
|
||||
public function read(SiteInterface $site): WeighbridgeReading;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Module\Logistique\Domain\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Levee lorsque le pont bascule ne repond pas / est indisponible (RG-5.06).
|
||||
*
|
||||
* Exception de DOMAINE (pure, sans dependance HTTP) : c'est le Processor de
|
||||
* l'endpoint de pesee qui la traduit en reponse HTTP 503 « Pont bascule
|
||||
* indisponible — passez en pesee manuelle » (cf. WeighbridgeReadingProcessor).
|
||||
*
|
||||
* Au M5, le stub (RandomWeighbridgeReader) ne la leve jamais, mais le chemin
|
||||
* d'erreur est implemente et teste pour le jour ou un driver materiel reel
|
||||
* (HP-M5-02) sera branche derriere WeighbridgeReaderInterface.
|
||||
*/
|
||||
final class WeighbridgeUnavailableException extends RuntimeException {}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Module\Logistique\Domain\Weighbridge;
|
||||
|
||||
/**
|
||||
* Resultat immuable d'une lecture du pont bascule (§ 2.6 / RG-5.06).
|
||||
*
|
||||
* Porte le couple {poids, DSD} renvoye par une pesee « bascule » (AUTO) :
|
||||
* - weight : poids brut lu, en kilogrammes ;
|
||||
* - dsd : index de pesee du pont (compteur par site, RG-5.04).
|
||||
*
|
||||
* Au M5 le pont est un stub (RandomWeighbridgeReader) ; un driver materiel reel
|
||||
* (HP-M5-02) produira le meme objet derriere WeighbridgeReaderInterface, sans
|
||||
* impact sur l'API.
|
||||
*/
|
||||
final readonly class WeighbridgeReading
|
||||
{
|
||||
public function __construct(
|
||||
public int $weight,
|
||||
public int $dsd,
|
||||
) {}
|
||||
}
|
||||
Reference in New Issue
Block a user