[#203] Réceptions — Parcours de pesée multi-étapes (première partie) (!3)

| Numéro du ticket | Titre du ticket |
|------------------|-----------------|
|        #203          |      Réceptions — Parcours de pesée multi-étapes         |

## Description de la PR
[#203] Réceptions — Parcours de pesée multi-étapes

## Modification du .env

## Check list

- [x] Pas de régression
- [x] TU/TI/TF rédigée
- [x] TU/TI/TF OK
- [x] CHANGELOG modifié

Reviewed-on: https://gitea.malio.fr/MALIO-DEV/Ferme/pulls/3
Reviewed-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr>
Co-authored-by: AUTIN Tristan <tristan@yuno.malio.fr>
Co-committed-by: AUTIN Tristan <tristan@yuno.malio.fr>
This commit is contained in:
AUTIN Tristan
2026-01-14 07:17:34 +00:00
committed by Autin
parent 9fb0fc12b8
commit 4a77449a41
44 changed files with 1976 additions and 73 deletions
+68
View File
@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace App\Service;
use App\Dto\PontBasculeReading;
use App\Exception\PontBasculeException;
final class PontBasculePayloadDecoder
{
public function decode(string $body): PontBasculeReading
{
// Payload is JSON with a "response_ascii" string containing STX (0x02) segments.
$payload = json_decode($body, true);
if (!is_array($payload)) {
throw PontBasculeException::invalidPayload();
}
$ascii = $payload['response_ascii'] ?? null;
if (!is_string($ascii)) {
throw PontBasculeException::missingPayloadField('response_ascii');
}
$dsd = null;
$net = null;
// Each segment starts with a 2-digit code followed by the numeric value.
$segments = preg_split('/\\x02/', $ascii) ?: [];
foreach ($segments as $segment) {
$segment = trim($segment);
if ('' === $segment) {
continue;
}
if (!preg_match('/^(\d{2})(\d+)(?:\.kg)?/', $segment, $matches)) {
continue;
}
$code = $matches[1];
$value = $matches[2];
// Code 99 holds the DSD value.
if ('99' === $code) {
$dsd = (int) ltrim($value, '0');
if (0 === $dsd && '' !== $value) {
$dsd = 0;
}
continue;
}
// Code 03 is the net weight; other codes are ignored for now.
if ('03' === $code) {
$net = (float) ltrim($value, '0');
if (0.0 === $net && '' !== $value) {
$net = 0.0;
}
}
}
if (null === $dsd && null === $net) {
throw PontBasculeException::unreadableValues();
}
return new PontBasculeReading($dsd, $net);
}
}