feat: ajout OrderNumberService pour generer les numeros de commande

src/Service/OrderNumberService.php (nouveau):
- Format: MM/YYYY-XXXXX (ex: 04/2026-00001, 04/2026-00002, etc.)
- Le compteur XXXXX est par mois: reset a 00001 a chaque nouveau mois
- generate(): cherche le dernier numOrder du mois courant via LIKE
  'MM/YYYY-%' ORDER BY DESC, extrait le compteur, incremente de 1,
  pad sur 5 chiffres, persiste et flush le nouvel OrderNumber
- generateAndUse(): genere + markAsUsed() en une operation
- preview(): retourne le prochain numero sans le creer en BDD

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-04-02 22:20:45 +02:00
parent 423ee779e0
commit 85220c6200

View File

@@ -0,0 +1,84 @@
<?php
namespace App\Service;
use App\Entity\OrderNumber;
use App\Repository\OrderNumberRepository;
use Doctrine\ORM\EntityManagerInterface;
class OrderNumberService
{
public function __construct(
private OrderNumberRepository $repository,
private EntityManagerInterface $em,
) {
}
/**
* Genere le prochain numero de commande au format MM/YYYY-XXXXX.
* Le compteur XXXXX est incremente par mois (reset a 00001 chaque nouveau mois).
*/
public function generate(): OrderNumber
{
$now = new \DateTimeImmutable();
$prefix = $now->format('m/Y').'-';
$lastOrder = $this->repository->createQueryBuilder('o')
->where('o.numOrder LIKE :prefix')
->setParameter('prefix', $prefix.'%')
->orderBy('o.numOrder', 'DESC')
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
if (null !== $lastOrder) {
$lastNum = (int) substr($lastOrder->getNumOrder(), \strlen($prefix));
$nextNum = $lastNum + 1;
} else {
$nextNum = 1;
}
$numOrder = $prefix.str_pad((string) $nextNum, 5, '0', \STR_PAD_LEFT);
$orderNumber = new OrderNumber($numOrder);
$this->em->persist($orderNumber);
$this->em->flush();
return $orderNumber;
}
/**
* Genere et marque comme utilise en une seule operation.
*/
public function generateAndUse(): OrderNumber
{
$orderNumber = $this->generate();
$orderNumber->markAsUsed();
$this->em->flush();
return $orderNumber;
}
/**
* Recupere le prochain numero sans le creer.
*/
public function preview(): string
{
$now = new \DateTimeImmutable();
$prefix = $now->format('m/Y').'-';
$lastOrder = $this->repository->createQueryBuilder('o')
->where('o.numOrder LIKE :prefix')
->setParameter('prefix', $prefix.'%')
->orderBy('o.numOrder', 'DESC')
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
$nextNum = null !== $lastOrder
? (int) substr($lastOrder->getNumOrder(), \strlen($prefix)) + 1
: 1;
return $prefix.str_pad((string) $nextNum, 5, '0', \STR_PAD_LEFT);
}
}