src/ApplicationBundle/Modules/Document/Controller/DocumentController.php line 25

Open in your IDE?
  1. <?php
  2. namespace ApplicationBundle\Modules\Document\Controller;
  3. use ApplicationBundle\Controller\GenericController;
  4. use ApplicationBundle\Interfaces\SessionCheckInterface;
  5. use ApplicationBundle\Modules\Document\DocumentNumberService;
  6. use Symfony\Component\HttpFoundation\JsonResponse;
  7. use Symfony\Component\HttpFoundation\Request;
  8. /**
  9.  * S2.4 — Document Number Sequence admin controller.
  10.  *
  11.  * Provides:
  12.  *  - DocumentPrefixListAction  GET  /document/prefix_list
  13.  *  - DocumentPrefixResetAction POST /document/prefix_reset        (admin only)
  14.  *  - DocumentSequenceApiAction GET  /document/next_number/{type}  (internal dev/test)
  15.  */
  16. class DocumentController extends GenericController implements SessionCheckInterface
  17. {
  18.     /**
  19.      * List all active prefix sequences (current year), grouped by prefix.
  20.      * Admin page — information card.
  21.      */
  22.     public function DocumentPrefixListAction(Request $request)
  23.     {
  24.         $em       $this->getDoctrine()->getManager();
  25.         $year     = (int)date('Y');
  26.         $tenantId 1;
  27.         $conn $em->getConnection();
  28.         // `document_number_sequences` is created by NOTHING in this codebase: it has no
  29.         // Entity and no .orm.yml, so update_database_schema will never provision it, and
  30.         // DocumentNumberService writes to it with raw SQL assuming it is already there.
  31.         // On a tenant without the table this page 500'd outright. An admin information
  32.         // page must not be the thing that breaks — it now says the sequences are not
  33.         // provisioned and stays readable, which is also what tells an admin WHY the
  34.         // numbering feature is doing nothing.
  35.         $rows          = [];
  36.         $tableMissing  false;
  37.         try {
  38.             $rows $conn->fetchAllAssociative(
  39.                 'SELECT prefix, year, last_seq, tenant_id
  40.                    FROM document_number_sequences
  41.                   WHERE tenant_id = ?
  42.                   ORDER BY prefix ASC, year DESC',
  43.                 [$tenantId]
  44.             );
  45.         } catch (\Throwable $e) {
  46.             // Only a missing table is tolerated; anything else is a real fault and
  47.             // should keep surfacing rather than hiding behind an empty list.
  48.             if (stripos($e->getMessage(), 'document_number_sequences') === false) {
  49.                 throw $e;
  50.             }
  51.             $tableMissing true;
  52.         }
  53.         // Build prefix description map from service
  54.         $typeToPrefix DocumentNumberService::getTypeToPrefix();
  55.         $prefixToType array_flip($typeToPrefix);
  56.         return $this->render('@Document/pages/list/list_document_prefixes.html.twig', [
  57.             'page_title'    => 'Document Number Sequences',
  58.             'rows'          => $rows,
  59.             'prefixToType'  => $prefixToType,
  60.             'currentYear'   => $year,
  61.             'tableMissing'  => $tableMissing,
  62.         ]);
  63.     }
  64.     /**
  65.      * AJAX: return the next formatted document number without consuming it.
  66.      * Used by forms to preview the number that will be assigned.
  67.      * GET /document/peek_number/{type}
  68.      */
  69.     public function DocumentPeekNumberAction(Request $requeststring $type 'offer')
  70.     {
  71.         $em       $this->getDoctrine()->getManager();
  72.         $tenantId 1;
  73.         $year     = (int)date('Y');
  74.         $conn $em->getConnection();
  75.         try {
  76.             $prefix DocumentNumberService::prefixForType($type);
  77.         } catch (\RuntimeException $e) {
  78.             return new JsonResponse(['error' => $e->getMessage()], 400);
  79.         }
  80.         $row $conn->fetchAssociative(
  81.             'SELECT last_seq FROM document_number_sequences WHERE tenant_id=? AND prefix=? AND year=?',
  82.             [$tenantId$prefix$year]
  83.         );
  84.         $nextSeq $row ? (int)$row['last_seq'] + 1;
  85.         return new JsonResponse([
  86.             'type'   => $type,
  87.             'prefix' => $prefix,
  88.             'year'   => $year,
  89.             'nextSeq'=> $nextSeq,
  90.             'number' => DocumentNumberService::format($prefix$year$nextSeq),
  91.         ]);
  92.     }
  93. }