var/cache/dev/twig/d8/d870db3d83d599a25c164da448e6a1b232a66ca42b5ac3f35473f1ab251c5448.php line 240

Open in your IDE?
  1. <?php
  2. use Twig\Environment;
  3. use Twig\Error\LoaderError;
  4. use Twig\Error\RuntimeError;
  5. use Twig\Extension\CoreExtension;
  6. use Twig\Extension\SandboxExtension;
  7. use Twig\Markup;
  8. use Twig\Sandbox\SecurityError;
  9. use Twig\Sandbox\SecurityNotAllowedTagError;
  10. use Twig\Sandbox\SecurityNotAllowedFilterError;
  11. use Twig\Sandbox\SecurityNotAllowedFunctionError;
  12. use Twig\Source;
  13. use Twig\Template;
  14. /* stock/index.html.twig */
  15. class __TwigTemplate_7980a79027e80f293081524482224d25a29e05232ab1d3465b2a9c77b546042b extends Template
  16. {
  17.     private $source;
  18.     private $macros = [];
  19.     public function __construct(Environment $env)
  20.     {
  21.         parent::__construct($env);
  22.         $this->source = $this->getSourceContext();
  23.         $this->blocks = [
  24.             'title' => [$this, 'block_title'],
  25.             'stylesheets' => [$this, 'block_stylesheets'],
  26.             'body' => [$this, 'block_body'],
  27.             'javascripts' => [$this, 'block_javascripts'],
  28.         ];
  29.     }
  30.     protected function doGetParent(array $context)
  31.     {
  32.         // line 1
  33.         return "backoffice.base.html.twig";
  34.     }
  35.     protected function doDisplay(array $context, array $blocks = [])
  36.     {
  37.         $macros = $this->macros;
  38.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  39.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template", "stock/index.html.twig"));
  40.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  41.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template", "stock/index.html.twig"));
  42.         $this->parent = $this->loadTemplate("backoffice.base.html.twig", "stock/index.html.twig", 1);
  43.         yield from $this->parent->unwrap()->yield($context, array_merge($this->blocks, $blocks));
  44.         
  45.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  46.         
  47.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  48.     }
  49.     // line 3
  50.     public function block_title($context, array $blocks = [])
  51.     {
  52.         $macros = $this->macros;
  53.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  54.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "title"));
  55.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  56.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "title"));
  57.         yield "Gestion du Stock";
  58.         
  59.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  60.         
  61.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  62.         return; yield '';
  63.     }
  64.     // line 5
  65.     public function block_stylesheets($context, array $blocks = [])
  66.     {
  67.         $macros = $this->macros;
  68.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  69.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "stylesheets"));
  70.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  71.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "stylesheets"));
  72.         // line 6
  73.         yield from $this->yieldParentBlock("stylesheets", $context, $blocks);
  74.         yield "
  75. <style>
  76.     /* Styles personnalisés */
  77.     .card {
  78.         border-radius: 12px;
  79.         box-shadow: 0 4px 20px rgba(0,0,0,0.05);
  80.         border: none;
  81.     }
  82.     
  83.     .card-header {
  84.         background-color: #f8f9fa;
  85.         border-bottom: 1px solid #eee;
  86.         padding: 1.5rem 1.5rem;
  87.     }
  88.     
  89.     .table {
  90.         font-size: 0.95rem;
  91.     }
  92.     
  93.     .table thead th {
  94.         border-bottom-width: 1px;
  95.         font-weight: 600;
  96.         color: #6c757d;
  97.         text-transform: uppercase;
  98.         letter-spacing: 0.5px;
  99.         font-size: 0.75rem;
  100.     }
  101.     
  102.     .table > :not(:last-child) > :last-child > * {
  103.         border-bottom-color: #f1f1f1;
  104.     }
  105.     
  106.     .btn-outline-primary {
  107.         border-width: 2px;
  108.         font-weight: 500;
  109.     }
  110.     
  111.     .btn-sm {
  112.         padding: 0.35rem 0.75rem;
  113.         font-size: 0.85rem;
  114.     }
  115.     
  116.     .menu-sub {
  117.         box-shadow: 0 5px 25px rgba(0,0,0,0.1);
  118.         border: none;
  119.         border-radius: 8px;
  120.     }
  121.     
  122.     .menu-link {
  123.         transition: all 0.2s;
  124.         font-weight: 500;
  125.     }
  126.     
  127.     .menu-link:hover {
  128.         background-color: #f3f6f9;
  129.         color: #009ef7;
  130.     }
  131.     
  132.     tr {
  133.         transition: all 0.2s;
  134.     }
  135.     
  136.     tr:hover {
  137.         background-color: #fbfbfb;
  138.     }
  139.     
  140.     .quantity-badge {
  141.         display: inline-block;
  142.         padding: 0.25rem 0.5rem;
  143.         border-radius: 50px;
  144.         font-weight: 600;
  145.         font-size: 0.8rem;
  146.         min-width: 30px;
  147.         text-align: center;
  148.     }
  149.     
  150.     .export-btn {
  151.         border-radius: 8px;
  152.         font-weight: 600;
  153.         padding: 0.5rem 1.25rem;
  154.     }
  155.     
  156.     /* Modal styles */
  157.     #deleteStockModal .modal-header {
  158.         background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  159.         border-bottom: 2px solid #dee2e6;
  160.     }
  161.     
  162.     #deleteStockModal .modal-title {
  163.         font-weight: 600;
  164.         color: #dc3545;
  165.     }
  166.     
  167.     #deleteStockModal .btn-danger {
  168.         background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
  169.         border: none;
  170.         transition: all 0.3s ease;
  171.     }
  172.     
  173.     #deleteStockModal .btn-danger:hover {
  174.         transform: translateY(-2px);
  175.         box-shadow: 0 4px 8px rgba(220, 53, 69, 0.3);
  176.     }
  177.     
  178.     #deleteStockModal .input-group-text {
  179.         background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  180.         border-right: none;
  181.     }
  182.     
  183.     #deleteStockModal .form-control:focus {
  184.         border-color: #dc3545;
  185.         box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
  186.     }
  187.     
  188.     .menu-link.text-muted {
  189.         opacity: 0.6;
  190.         cursor: not-allowed;
  191.         pointer-events: none;
  192.         background-color: #f8f9fa;
  193.     }
  194.     
  195.     .menu-link.text-muted:hover {
  196.         background-color: #f8f9fa !important;
  197.         color: #6c757d !important;
  198.     }
  199.     
  200.     @keyframes shake {
  201.         0%, 100% { transform: translateX(0); }
  202.         10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
  203.         20%, 40%, 60%, 80% { transform: translateX(5px); }
  204.     }
  205.     
  206.     .shake-animation {
  207.         animation: shake 0.5s ease-in-out;
  208.     }
  209. </style>
  210. ";
  211.         
  212.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  213.         
  214.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  215.         return; yield '';
  216.     }
  217.     // line 144
  218.     public function block_body($context, array $blocks = [])
  219.     {
  220.         $macros = $this->macros;
  221.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  222.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "body"));
  223.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  224.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "body"));
  225.         // line 145
  226.         yield Twig\Extension\CoreExtension::include($this->env, $context, "Base/_sidebar_admin.html.twig");
  227.         yield "
  228. <div class=\"post d-flex flex-column-fluid\" id=\"kt_post\">
  229.     <div id=\"kt_content_container\" class=\"container-xxl\">
  230.         <div class=\"card shadow-sm\">
  231.             <div class=\"card-header border-0 pt-6\">
  232.                 <div class=\"card-title\">
  233.                     <h2 class=\"fw-bolder mb-0\">Gestion du Stock</h2>
  234.                 </div>
  235.                 <div class=\"card-toolbar\">
  236.                     <div class=\"d-flex justify-content-end\" data-kt-customer-table-toolbar=\"base\">
  237.                         <a class=\"btn btn-light-primary btn-hover-rise me-2\" href=\"";
  238.         // line 156
  239.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("inventaire_index");
  240.         yield "\">
  241.                             <i class=\"fas fa-clipboard-list me-2\"></i>Rapports d'inventaire
  242.                         </a>
  243.                         <a class=\"btn btn-light-primary btn-hover-rise export-btn\" href=\"";
  244.         // line 159
  245.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("export_donnees_csv_stock");
  246.         yield "\">
  247.                             <i class=\"fas fa-file-export me-2\"></i>Exporter en CSV
  248.                         </a>
  249.                     </div>
  250.                 </div>
  251.             </div>
  252.             <div class=\"card-body pt-0\">
  253.                 <div class=\"mb-5\">
  254.                     <div class=\"position-relative\">
  255.                         <i class=\"fas fa-search position-absolute ms-4 fs-4\" style=\"top:50%;transform:translateY(-50%);color:#a1a5b7;\"></i>
  256.                         <input type=\"text\" id=\"stockSearchInput\" class=\"form-control form-control-solid ps-13\"
  257.                                style=\"height:48px;font-size:1rem;\"
  258.                                placeholder=\"Rechercher par code-barre, nom de pièce ou référence...\">
  259.                     </div>
  260.                     <div id=\"stockSearchEmpty\" class=\"text-center py-10 d-none\">
  261.                         <i class=\"fas fa-search fs-4x text-muted mb-4\"></i>
  262.                         <div class=\"text-muted fw-bold fs-5\">Aucun résultat pour cette recherche</div>
  263.                     </div>
  264.                 </div>
  265.                 <!-- Message flash -->
  266.                 ";
  267.         // line 180
  268.         $context['_parent'] = $context;
  269.         $context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, (isset($context["app"]) || array_key_exists("app", $context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.', 180, $this->source); })()), "flashes", [], "any", false, false, false, 180));
  270.         foreach ($context['_seq'] as $context["label"] => $context["messages"]) {
  271.             // line 181
  272.             yield "                    ";
  273.             $context['_parent'] = $context;
  274.             $context['_seq'] = CoreExtension::ensureTraversable($context["messages"]);
  275.             foreach ($context['_seq'] as $context["_key"] => $context["message"]) {
  276.                 // line 182
  277.                 yield "                        <div class=\"alert alert-dismissible bg-light-";
  278.                 yield (((0 === CoreExtension::compare($context["label"], "error"))) ? ("danger") : ((((0 === CoreExtension::compare($context["label"], "success"))) ? ("success") : ("info"))));
  279.                 yield " d-flex flex-column flex-sm-row p-5 mb-10\">
  280.                             <div class=\"d-flex flex-column pe-0 pe-sm-10\">
  281.                                 <span>";
  282.                 // line 184
  283.                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($context["message"], "html", null, true);
  284.                 yield "</span>
  285.                             </div>
  286.                             <button type=\"button\" class=\"position-absolute position-sm-relative m-2 m-sm-0 top-0 end-0 btn btn-icon ms-sm-auto\" data-bs-dismiss=\"alert\">
  287.                                 <span class=\"svg-icon svg-icon-1\">
  288.                                     <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">
  289.                                         <rect opacity=\"0.5\" x=\"6\" y=\"17.3137\" width=\"16\" height=\"2\" rx=\"1\" transform=\"rotate(-45 6 17.3137)\" fill=\"currentColor\"/>
  290.                                         <rect x=\"7.41422\" y=\"6\" width=\"16\" height=\"2\" rx=\"1\" transform=\"rotate(45 7.41422 6)\" fill=\"currentColor\"/>
  291.                                     </svg>
  292.                                 </span>
  293.                             </button>
  294.                         </div>
  295.                     ";
  296.             }
  297.             $_parent = $context['_parent'];
  298.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['message'], $context['_parent'], $context['loop']);
  299.             $context = array_intersect_key($context, $_parent) + $_parent;
  300.             // line 196
  301.             yield "                ";
  302.         }
  303.         $_parent = $context['_parent'];
  304.         unset($context['_seq'], $context['_iterated'], $context['label'], $context['messages'], $context['_parent'], $context['loop']);
  305.         $context = array_intersect_key($context, $_parent) + $_parent;
  306.         // line 197
  307.         yield "                
  308.                 <div class=\"table-responsive\">
  309.                     <table class=\"table align-middle table-row-dashed fs-6 gy-5\" id=\"kt_customers_table\">
  310.                         <thead>
  311.                             <tr class=\"text-start text-gray-600 fw-bolder fs-7 text-uppercase gs-0\">
  312.                                 <th class=\"min-w-25px\">
  313.                                     <div class=\"form-check form-check-sm form-check-custom form-check-solid\">
  314.                                         <input class=\"form-check-input\" type=\"checkbox\" value=\"1\" data-kt-check=\"true\" data-kt-check-target=\".widget-9-check\"/>
  315.                                     </div>
  316.                                 </th>
  317.                                 <th class=\"min-w-100px\">Pièce</th>
  318.                                 <th class=\"text-center min-w-80px\">Quantité</th>
  319.                                 <th class=\"min-w-100px\">Montant HTVA</th>
  320.                                 <th class=\"min-w-100px\">Num. BL</th>
  321.                                 <th class=\"min-w-120px\">Référence</th>
  322.                                 <th class=\"min-w-150px\">Code-barres</th>
  323.                                 <th class=\"text-end min-w-100px\">Actions</th>
  324.                             </tr>
  325.                         </thead>
  326.                         <tbody class=\"fw-semibold text-gray-700\">
  327.                             ";
  328.         // line 217
  329.         $context['_parent'] = $context;
  330.         $context['_seq'] = CoreExtension::ensureTraversable((isset($context["stocks"]) || array_key_exists("stocks", $context) ? $context["stocks"] : (function () { throw new RuntimeError('Variable "stocks" does not exist.', 217, $this->source); })()));
  331.         $context['_iterated'] = false;
  332.         foreach ($context['_seq'] as $context["_key"] => $context["stock"]) {
  333.             // line 218
  334.             yield "                            ";
  335.             $context["nomPiece"] = ((CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "piece", [], "any", false, false, false, 218)) ?: (((CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "idProduit", [], "any", false, false, false, 218)) ? (CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "idProduit", [], "any", false, false, false, 218), "description", [], "any", false, false, false, 218)) : (null))));
  336.             // line 219
  337.             yield "                            <tr class=\"stock-row\" data-search=\"";
  338.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::lower($this->env->getCharset(), (((((isset($context["nomPiece"]) || array_key_exists("nomPiece", $context) ? $context["nomPiece"] : (function () { throw new RuntimeError('Variable "nomPiece" does not exist.', 219, $this->source); })()) . " ") . CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "reference", [], "any", false, false, false, 219)) . " ") . CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "codeBarre", [], "any", false, false, false, 219))), "html", null, true);
  339.             yield "\">
  340.                                 <td>
  341.                                     <div class=\"form-check form-check-sm form-check-custom form-check-solid\">
  342.                                         <input class=\"form-check-input widget-9-check\" type=\"checkbox\" value=\"1\"/>
  343.                                     </div>
  344.                                 </td>
  345.                                 <td>
  346.                                     <div class=\"d-flex align-items-center\">
  347.                                         <div class=\"symbol symbol-40px me-3\">
  348.                                             <span class=\"symbol-label bg-light-primary\">
  349.                                                 <i class=\"fas fa-box-open text-primary\"></i>
  350.                                             </span>
  351.                                         </div>
  352.                                         <div>
  353.                                             <span class=\"text-dark fw-bold d-block\">
  354.                                                 ";
  355.             // line 234
  356.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(((CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "piece", [], "any", false, false, false, 234)) ?: (((((CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "idProduit", [], "any", false, false, false, 234)) ? (CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "idProduit", [], "any", false, false, false, 234), "description", [], "any", false, false, false, 234)) : (null))) ?: (((CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "reference", [], "any", false, false, false, 234)) ?: ("N/A")))))), "html", null, true);
  357.             yield "
  358.                                             </span>
  359.                                         </div>
  360.                                     </div>
  361.                                 </td>
  362.                                 <td class=\"text-center\">
  363.                                     ";
  364.             // line 240
  365.             $context["stock_class"] = "success";
  366.             // line 241
  367.             yield "                                    ";
  368.             if ((0 >= CoreExtension::compare(CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "quantite", [], "any", false, false, false, 241), 5))) {
  369.                 // line 242
  370.                 yield "                                        ";
  371.                 $context["stock_class"] = "danger";
  372.                 // line 243
  373.                 yield "                                    ";
  374.             } elseif ((0 >= CoreExtension::compare(CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "quantite", [], "any", false, false, false, 243), 10))) {
  375.                 // line 244
  376.                 yield "                                        ";
  377.                 $context["stock_class"] = "warning";
  378.                 // line 245
  379.                 yield "                                    ";
  380.             }
  381.             // line 246
  382.             yield "                                    <span class=\"quantity-badge bg-light-";
  383.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["stock_class"]) || array_key_exists("stock_class", $context) ? $context["stock_class"] : (function () { throw new RuntimeError('Variable "stock_class" does not exist.', 246, $this->source); })()), "html", null, true);
  384.             yield " text-";
  385.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["stock_class"]) || array_key_exists("stock_class", $context) ? $context["stock_class"] : (function () { throw new RuntimeError('Variable "stock_class" does not exist.', 246, $this->source); })()), "html", null, true);
  386.             yield "\">
  387.                                         ";
  388.             // line 247
  389.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "quantite", [], "any", false, false, false, 247), "html", null, true);
  390.             yield "
  391.                                     </span>
  392.                                 </td>
  393.                                 <td>";
  394.             // line 250
  395.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "montantHTVA", [], "any", false, false, false, 250), 2, ",", " "), "html", null, true);
  396.             yield " TND</td>
  397.                                 <td>
  398.                                     <span class=\"badge badge-light-primary\">";
  399.             // line 252
  400.             ((CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "numBl", [], "any", false, false, false, 252)) ? (yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "numBl", [], "any", false, false, false, 252), "html", null, true)) : (yield "N/A"));
  401.             yield "</span>
  402.                                 </td>
  403.                                 <td>
  404.                                     <span class=\"text-dark fw-bold\">";
  405.             // line 255
  406.             ((CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "reference", [], "any", false, false, false, 255)) ? (yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "reference", [], "any", false, false, false, 255), "html", null, true)) : (yield "N/A"));
  407.             yield "</span>
  408.                                 </td>
  409.                                 <td>
  410.                                     <span class=\"badge badge-light-dark\">";
  411.             // line 258
  412.             ((CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "codeBarre", [], "any", false, false, false, 258)) ? (yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "codeBarre", [], "any", false, false, false, 258), "html", null, true)) : (yield "N/A"));
  413.             yield "</span>
  414.                                 </td>
  415.                                 <td class=\"text-end\">
  416.                                     <div class=\"dropdown\">
  417.                                         <button class=\"btn btn-sm btn-icon btn-color-gray-400 btn-active-light-primary\" data-bs-toggle=\"dropdown\">
  418.                                             <span class=\"svg-icon svg-icon-2\">
  419.                                                 <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">
  420.                                                     <rect x=\"10\" y=\"10\" width=\"4\" height=\"4\" rx=\"2\" fill=\"currentColor\"/>
  421.                                                     <rect x=\"10\" y=\"3\" width=\"4\" height=\"4\" rx=\"2\" fill=\"currentColor\"/>
  422.                                                     <rect x=\"10\" y=\"17\" width=\"4\" height=\"4\" rx=\"2\" fill=\"currentColor\"/>
  423.                                                 </svg>
  424.                                             </span>
  425.                                         </button>
  426.                                         <div class=\"dropdown-menu menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-600 menu-state-bg-light-primary fw-bold fs-7 w-150px py-4\" data-kt-menu=\"true\">
  427.                                             <div class=\"menu-item px-3\">
  428.                                                 <a href=\"";
  429.             // line 273
  430.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("app_stock_show", ["id" => CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "id", [], "any", false, false, false, 273)]), "html", null, true);
  431.             yield "\" class=\"menu-link px-3\">
  432.                                                     <span class=\"svg-icon svg-icon-3 me-2\">
  433.                                                         <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">
  434.                                                             <path d=\"M21.7 18.9L18.6 15.8C17.9 16.9 16.9 17.9 15.8 18.6L18.9 21.7C19.3 22.1 19.9 22.1 20.3 21.7L21.7 20.3C22.1 19.9 22.1 19.3 21.7 18.9Z\" fill=\"currentColor\"/>
  435.                                                             <path opacity=\"0.3\" d=\"M11 20C6 20 2 16 2 11C2 6 6 2 11 2C16 2 20 6 20 11C20 16 16 20 11 20ZM11 4C7.1 4 4 7.1 4 11C4 14.9 7.1 18 11 18C14.9 18 18 14.9 18 11C18 7.1 14.9 4 11 4ZM8 11C8 9.3 9.3 8 11 8C11.6 8 12 7.6 12 7C12 6.4 11.6 6 11 6C8.2 6 6 8.2 6 11C6 11.6 6.4 12 7 12C7.6 12 8 11.6 8 11Z\" fill=\"currentColor\"/>
  436.                                                         </svg>
  437.                                                     </span>
  438.                                                     Afficher
  439.                                                 </a>
  440.                                             </div>
  441.                                             <div class=\"menu-item px-3\">
  442.                                                 <a href=\"";
  443.             // line 284
  444.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("app_stock_edit", ["id" => CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "id", [], "any", false, false, false, 284)]), "html", null, true);
  445.             yield "\" class=\"menu-link px-3\">
  446.                                                     <span class=\"svg-icon svg-icon-3 me-2\">
  447.                                                         <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">
  448.                                                             <path opacity=\"0.3\" d=\"M21.4 8.35303L19.241 10.511L13.485 4.755L15.643 2.59595C16.0248 2.21423 16.5426 1.99988 17.0825 1.99988C17.6224 1.99988 18.1402 2.21423 18.522 2.59595L21.4 5.474C21.7817 5.85581 21.9962 6.37355 21.9962 6.91345C21.9962 7.45335 21.7817 7.97122 21.4 8.35303ZM3.68699 21.932L9.88699 19.865L4.13099 14.109L2.06399 20.309C1.98815 20.5354 1.97703 20.7787 2.03189 21.0111C2.08674 21.2436 2.2054 21.4561 2.37449 21.6248C2.54359 21.7934 2.75641 21.9115 2.989 21.9658C3.22158 22.0201 3.4647 22.0084 3.69099 21.932H3.68699Z\" fill=\"currentColor\"/>
  449.                                                             <path d=\"M5.574 21.3L3.692 21.928C3.46591 22.0032 3.22334 22.0141 2.99144 21.9594C2.75954 21.9046 2.54744 21.7864 2.3789 21.6179C2.21036 21.4495 2.09202 21.2375 2.03711 21.0056C1.9822 20.7737 1.99289 20.5312 2.06799 20.3051L2.696 18.422L5.574 21.3ZM4.13499 14.105L9.891 19.861L19.245 10.507L13.489 4.75098L4.13499 14.105Z\" fill=\"currentColor\"/>
  450.                                                         </svg>
  451.                                                     </span>
  452.                                                     Modifier
  453.                                                 </a>
  454.                                             </div>
  455.                                             <div class=\"menu-item px-3\">
  456.                                                 <a href=\"javascript:void(0)\" 
  457.                                                    class=\"menu-link px-3 text-danger\" 
  458.                                                    onclick=\"if (typeof checkAndOpenDeleteStockModal === 'function') checkAndOpenDeleteStockModal(";
  459.             // line 297
  460.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "id", [], "any", false, false, false, 297), "html", null, true);
  461.             yield ", '";
  462.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::replace((((CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "reference", [], "any", true, true, false, 297) &&  !(null === CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "reference", [], "any", false, false, false, 297)))) ? (CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "reference", [], "any", false, false, false, 297)) : ((((CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "piece", [], "any", true, true, false, 297) &&  !(null === CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "piece", [], "any", false, false, false, 297)))) ? (CoreExtension::getAttribute($this->env, $this->source, $context["stock"], "piece", [], "any", false, false, false, 297)) : ("Stock")))), ["'" => "\\'", "\"" => "&quot;"]), "html", null, true);
  463.             yield "'); else alert('Fonction de suppression non chargée');\">
  464.                                                     <span class=\"svg-icon svg-icon-3 me-2\">
  465.                                                         <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">
  466.                                                             <path d=\"M5 9C5 8.44772 5.44772 8 6 8H18C18.5523 8 19 8.44772 19 9V18C19 19.6569 17.6569 21 16 21H8C6.34315 21 5 19.6569 5 18V9Z\" fill=\"currentColor\"/>
  467.                                                             <path opacity=\"0.5\" d=\"M5 5C5 4.44772 5.44772 4 6 4H18C18.5523 4 19 4.44772 19 5C19 5.55228 18.5523 6 18 6H6C5.44772 6 5 5.55228 5 5Z\" fill=\"currentColor\"/>
  468.                                                             <path opacity=\"0.5\" d=\"M9 4C9 3.44772 9.44772 3 10 3H14C14.5523 3 15 3.44772 15 4C15 4.55228 14.5523 5 14 5H10C9.44772 5 9 4.55228 9 4Z\" fill=\"currentColor\"/>
  469.                                                         </svg>
  470.                                                     </span>
  471.                                                     Supprimer
  472.                                                 </a>
  473.                                             </div>
  474.                                         </div>
  475.                                     </div>
  476.                                 </td>
  477.                             </tr>
  478.                             ";
  479.             $context['_iterated'] = true;
  480.         }
  481.         if (!$context['_iterated']) {
  482.             // line 313
  483.             yield "                            <tr>
  484.                                 <td colspan=\"8\" class=\"text-center py-10\">
  485.                                     <div class=\"d-flex flex-column align-items-center\">
  486.                                         <i class=\"fas fa-box-open fs-4x text-muted mb-4\"></i>
  487.                                         <span class=\"text-muted fw-bold fs-5\">Aucun article en stock</span>
  488.                                     </div>
  489.                                 </td>
  490.                             </tr>
  491.                             ";
  492.         }
  493.         $_parent = $context['_parent'];
  494.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['stock'], $context['_parent'], $context['loop']);
  495.         $context = array_intersect_key($context, $_parent) + $_parent;
  496.         // line 322
  497.         yield "                        </tbody>
  498.                     </table>
  499.                 </div>
  500.             </div>
  501.         </div>
  502.         <!-- MODAL DE SUPPRESSION STOCK -->
  503.         <div class=\"modal fade\" id=\"deleteStockModal\" tabindex=\"-1\" aria-labelledby=\"deleteStockModalLabel\" aria-hidden=\"true\">
  504.             <div class=\"modal-dialog\">
  505.                 <div class=\"modal-content\">
  506.                     <div class=\"modal-header\">
  507.                         <h5 class=\"modal-title\" id=\"deleteStockModalLabel\">
  508.                             <i class=\"bi bi-exclamation-triangle-fill text-warning me-2\"></i>
  509.                             Confirmer la suppression
  510.                         </h5>
  511.                         <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button>
  512.                     </div>
  513.                     <div class=\"modal-body\">
  514.                         <div id=\"deleteStockMessage\"></div>
  515.                         <form id=\"deleteStockForm\">
  516.                             <input type=\"hidden\" name=\"stock_id\" id=\"stockIdInput\" value=\"\">
  517.                             <div class=\"mb-3\">
  518.                                 <label for=\"deleteStockCode\" class=\"form-label\">
  519.                                     <strong>Code de confirmation</strong>
  520.                                 </label>
  521.                                 <div class=\"input-group\">
  522.                                     <span class=\"input-group-text bg-light\">
  523.                                         <i class=\"bi bi-shield-lock\"></i>
  524.                                     </span>
  525.                                     <input type=\"password\" class=\"form-control\" id=\"deleteStockCode\" 
  526.                                            name=\"delete_code\" placeholder=\"Saisissez 123123\" required maxlength=\"6\">
  527.                                 </div>
  528.                                 <div class=\"form-text text-muted\">
  529.                                     <i class=\"bi bi-info-circle\"></i> Entrez le code de sécurité 123123 pour confirmer
  530.                                 </div>
  531.                             </div>
  532.                             <input type=\"hidden\" name=\"_token\" value=\"";
  533.         // line 358
  534.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->env->getRuntime('Symfony\Component\Form\FormRenderer')->renderCsrfToken("delete_stock"), "html", null, true);
  535.         yield "\">
  536.                         </form>
  537.                     </div>
  538.                     <div class=\"modal-footer\">
  539.                         <button type=\"button\" class=\"btn btn-secondary\" data-bs-dismiss=\"modal\">
  540.                             <i class=\"bi bi-x-circle me-1\"></i>
  541.                             Annuler
  542.                         </button>
  543.                         <button type=\"button\" class=\"btn btn-danger\" id=\"confirmDeleteStockBtn\">
  544.                             <span class=\"spinner-border spinner-border-sm d-none me-2\" role=\"status\" aria-hidden=\"true\"></span>
  545.                             <i class=\"bi bi-trash me-1\"></i>
  546.                             Supprimer le stock
  547.                         </button>
  548.                     </div>
  549.                 </div>
  550.             </div>
  551.         </div>
  552.     </div>
  553. </div>
  554. <div class=\"modal fade\" id=\"kt_modal_add_customer_ok\" tabindex=\"-1\" aria-hidden=\"true\">
  555.     <div class=\"modal-dialog modal-dialog-centered mw-650px\">
  556.         <div class=\"modal-content\">
  557.             <form class=\"form\" method=\"post\" action=\"";
  558.         // line 381
  559.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("app_stock_new");
  560.         yield "\"
  561.                   id=\"kt_modal_add_customer_form\" data-kt-redirect=\"apps/customers/list.html\">
  562.                 <div class=\"post d-flex flex-column-fluid\" id=\"kt_post\">
  563.                     <div id=\"kt_content_container\" class=\"container\">
  564.                         <div class=\"card\">
  565.                             <div class=\"card-header border-0 pt-6\"></div>
  566.                             <div class=\"card-body pt-0\">
  567.                                 ";
  568.         // line 388
  569.         yield $this->env->getRuntime('Symfony\Bridge\Twig\Extension\HttpKernelRuntime')->renderFragment($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("app_stock_new"));
  570.         yield "
  571.                             </div>
  572.                         </div>
  573.                     </div>
  574.                 </div>
  575.             </form>
  576.         </div>
  577.     </div>
  578. </div>
  579. ";
  580.         
  581.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  582.         
  583.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  584.         return; yield '';
  585.     }
  586.     // line 399
  587.     public function block_javascripts($context, array $blocks = [])
  588.     {
  589.         $macros = $this->macros;
  590.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  591.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "javascripts"));
  592.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  593.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "javascripts"));
  594.         // line 400
  595.         yield from $this->yieldParentBlock("javascripts", $context, $blocks);
  596.         yield "
  597. <script src=\"https://cdn.jsdelivr.net/npm/sweetalert2@11\"></script>
  598. <script>
  599. (function() {
  600.     'use strict';
  601.     
  602.     let currentStockId = null;
  603.     // ✅ FONCTION GLOBALE DISPONIBLE IMMÉDIATEMENT
  604.     window.checkAndOpenDeleteStockModal = async function(stockId, stockName) {
  605.         try {
  606.             currentStockId = stockId;
  607.             
  608.             // Appel AJAX pour vérifier si le stock peut être supprimé
  609.             const response = await fetch(`/stock/check-delete/\${stockId}`);
  610.             
  611.             if (!response.ok) {
  612.                 throw new Error(`HTTP error! status: \${response.status}`);
  613.             }
  614.             
  615.             const data = await response.json();
  616.             if (data.success && data.canDelete) {
  617.                 // Peut supprimer : ouvrir modal
  618.                 const stockIdInput = document.getElementById('stockIdInput');
  619.                 const deleteMessage = document.getElementById('deleteStockMessage');
  620.                 const deleteCode = document.getElementById('deleteStockCode');
  621.                 
  622.                 if (stockIdInput) stockIdInput.value = stockId;
  623.                 
  624.                 if (deleteMessage) {
  625.                     deleteMessage.innerHTML = 
  626.                         `<div class=\"alert alert-warning d-flex align-items-center mb-3\">
  627.                             <i class=\"bi bi-exclamation-triangle-fill fs-3 me-3\"></i>
  628.                             <div>
  629.                                 <strong>Attention !</strong>
  630.                                 <p class=\"mb-0\">Voulez-vous vraiment supprimer cette ligne de stock <strong>\"\${stockName}\"</strong> ?</p>
  631.                             </div>
  632.                         </div>
  633.                         <div class=\"alert alert-success d-flex align-items-center\">
  634.                             <i class=\"bi bi-check-circle-fill me-2\"></i>
  635.                             <span>Cette ligne de stock peut être supprimée</span>
  636.                         </div>`;
  637.                 }
  638.                 
  639.                 if (deleteCode) {
  640.                     deleteCode.value = '';
  641.                     setTimeout(() => deleteCode.focus(), 500);
  642.                 }
  643.                 
  644.                 // Ouvrir modal
  645.                 const modalElement = document.getElementById('deleteStockModal');
  646.                 if (modalElement) {
  647.                     const modal = new bootstrap.Modal(modalElement);
  648.                     modal.show();
  649.                 }
  650.             } else {
  651.                 // Ne peut pas supprimer
  652.                 showStockAlert('error', 'Suppression impossible', data.message);
  653.             }
  654.         } catch (error) {
  655.             console.error('Erreur détaillée:', error);
  656.             showStockAlert('error', 'Erreur', 'Erreur lors de la vérification: ' + error.message);
  657.         }
  658.     };
  659.     // Fonction d'alerte unifiée avec SweetAlert2
  660.     function showStockAlert(icon, title, text, reload = false) {
  661.         if (typeof Swal !== 'undefined') {
  662.             Swal.fire({
  663.                 icon: icon,
  664.                 title: title,
  665.                 text: text,
  666.                 timer: reload ? 2000 : undefined,
  667.                 showConfirmButton: !reload,
  668.                 showCancelButton: false,
  669.                 confirmButtonColor: icon === 'success' ? '#28a745' : '#dc3545',
  670.                 confirmButtonText: icon === 'success' ? 'OK' : 'Fermer'
  671.             }).then((result) => {
  672.                 if (reload) {
  673.                     window.location.reload();
  674.                 }
  675.             });
  676.         } else {
  677.             alert(`\${icon === 'success' ? '✅' : '❌'} \${title}\\n\${text}`);
  678.             if (reload) {
  679.                 window.location.reload();
  680.             }
  681.         }
  682.     }
  683.     // Initialisation après chargement DOM
  684.     document.addEventListener('DOMContentLoaded', function() {
  685.         console.log('✅ Script suppression stock chargé');
  686.         // Recherche instantanée : code-barre, nom de pièce ou référence
  687.         const searchInput = document.getElementById('stockSearchInput');
  688.         const searchEmpty = document.getElementById('stockSearchEmpty');
  689.         const stockRows = document.querySelectorAll('.stock-row');
  690.         if (searchInput) {
  691.             searchInput.addEventListener('input', function () {
  692.                 const term = this.value.trim().toLowerCase();
  693.                 let visibleCount = 0;
  694.                 stockRows.forEach(function (row) {
  695.                     const match = !term || (row.dataset.search || '').includes(term);
  696.                     row.classList.toggle('d-none', !match);
  697.                     if (match) visibleCount++;
  698.                 });
  699.                 if (searchEmpty) {
  700.                     searchEmpty.classList.toggle('d-none', visibleCount !== 0 || stockRows.length === 0);
  701.                 }
  702.             });
  703.         }
  704.         // Bouton confirmer suppression stock
  705.         const confirmBtn = document.getElementById('confirmDeleteStockBtn');
  706.         if (confirmBtn) {
  707.             confirmBtn.addEventListener('click', async function(e) {
  708.                 e.preventDefault();
  709.                 
  710.                 const codeInput = document.getElementById('deleteStockCode');
  711.                 const code = codeInput ? codeInput.value.trim() : '';
  712.                 const stockId = currentStockId;
  713.                 
  714.                 if (!stockId) {
  715.                     showStockAlert('error', 'Erreur', 'ID stock manquant');
  716.                     return;
  717.                 }
  718.                 
  719.                 if (code !== '123123') {
  720.                     showStockAlert('error', 'Code incorrect', 'Le code requis est : 123123');
  721.                     
  722.                     // Animation shake
  723.                     if (codeInput) {
  724.                         codeInput.classList.add('shake-animation');
  725.                         setTimeout(() => codeInput.classList.remove('shake-animation'), 500);
  726.                         codeInput.value = '';
  727.                         codeInput.focus();
  728.                     }
  729.                     return;
  730.                 }
  731.                 // Désactiver bouton + spinner
  732.                 const btn = this;
  733.                 const spinner = btn.querySelector('.spinner-border');
  734.                 const btnHtml = btn.innerHTML;
  735.                 
  736.                 btn.disabled = true;
  737.                 if (spinner) spinner.classList.remove('d-none');
  738.                 btn.innerHTML = '<span class=\"spinner-border spinner-border-sm me-2\" role=\"status\" aria-hidden=\"true\"></span>Suppression en cours...';
  739.                 try {
  740.                     const tokenInput = document.querySelector('#deleteStockForm input[name=\"_token\"]');
  741.                     const token = tokenInput ? tokenInput.value : '';
  742.                     
  743.                     const formData = new FormData();
  744.                     formData.append('_token', token);
  745.                     
  746.                     const response = await fetch(`/stock/\${stockId}/delete`, {
  747.                         method: 'POST',
  748.                         body: formData,
  749.                         headers: {
  750.                             'X-Requested-With': 'XMLHttpRequest'
  751.                         }
  752.                     });
  753.                     if (!response.ok) {
  754.                         throw new Error(`HTTP error! status: \${response.status}`);
  755.                     }
  756.                     
  757.                     const data = await response.json();
  758.                     if (data.success) {
  759.                         // Fermer la modal
  760.                         const modalElement = document.getElementById('deleteStockModal');
  761.                         if (modalElement) {
  762.                             const modal = bootstrap.Modal.getInstance(modalElement);
  763.                             if (modal) modal.hide();
  764.                         }
  765.                         
  766.                         // Afficher succès et recharger
  767.                         showStockAlert('success', 'Supprimé !', data.message, true);
  768.                     } else {
  769.                         showStockAlert('error', 'Erreur', data.message);
  770.                         
  771.                         // Réactiver le bouton
  772.                         btn.innerHTML = btnHtml;
  773.                         btn.disabled = false;
  774.                         if (spinner) spinner.classList.add('d-none');
  775.                         
  776.                         // Reset du code
  777.                         if (codeInput) {
  778.                             codeInput.value = '';
  779.                             codeInput.focus();
  780.                         }
  781.                     }
  782.                 } catch (error) {
  783.                     console.error('Erreur détaillée:', error);
  784.                     showStockAlert('error', 'Erreur', 'Erreur lors de la suppression: ' + error.message);
  785.                     
  786.                     // Réactiver le bouton
  787.                     btn.innerHTML = btnHtml;
  788.                     btn.disabled = false;
  789.                     if (spinner) spinner.classList.add('d-none');
  790.                     
  791.                     // Reset du code
  792.                     if (codeInput) {
  793.                         codeInput.value = '';
  794.                         codeInput.focus();
  795.                     }
  796.                 }
  797.             });
  798.         } else {
  799.             console.error('❌ Bouton confirmDeleteStockBtn non trouvé');
  800.         }
  801.         // Reset modal à la fermeture
  802.         const modalElement = document.getElementById('deleteStockModal');
  803.         if (modalElement) {
  804.             modalElement.addEventListener('hidden.bs.modal', function() {
  805.                 console.log('Modal fermée - nettoyage');
  806.                 const form = document.getElementById('deleteStockForm');
  807.                 const confirmBtn = document.getElementById('confirmDeleteStockBtn');
  808.                 const deleteMessage = document.getElementById('deleteStockMessage');
  809.                 const codeInput = document.getElementById('deleteStockCode');
  810.                 
  811.                 if (form) form.reset();
  812.                 if (confirmBtn) {
  813.                     confirmBtn.disabled = false;
  814.                     confirmBtn.innerHTML = 
  815.                         '<span class=\"spinner-border spinner-border-sm d-none me-2\" role=\"status\" aria-hidden=\"true\"></span><i class=\"bi bi-trash me-1\"></i>Supprimer le stock';
  816.                 }
  817.                 if (deleteMessage) deleteMessage.innerHTML = '';
  818.                 if (codeInput) codeInput.value = '';
  819.                 currentStockId = null;
  820.             });
  821.         }
  822.     });
  823. })();
  824. </script>
  825. ";
  826.         
  827.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  828.         
  829.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  830.         return; yield '';
  831.     }
  832.     /**
  833.      * @codeCoverageIgnore
  834.      */
  835.     public function getTemplateName()
  836.     {
  837.         return "stock/index.html.twig";
  838.     }
  839.     /**
  840.      * @codeCoverageIgnore
  841.      */
  842.     public function isTraitable()
  843.     {
  844.         return false;
  845.     }
  846.     /**
  847.      * @codeCoverageIgnore
  848.      */
  849.     public function getDebugInfo()
  850.     {
  851.         return array (  628 => 400,  618 => 399,  597 => 388,  587 => 381,  561 => 358,  523 => 322,  509 => 313,  486 => 297,  470 => 284,  456 => 273,  438 => 258,  432 => 255,  426 => 252,  421 => 250,  415 => 247,  408 => 246,  405 => 245,  402 => 244,  399 => 243,  396 => 242,  393 => 241,  391 => 240,  382 => 234,  363 => 219,  360 => 218,  355 => 217,  333 => 197,  327 => 196,  309 => 184,  303 => 182,  298 => 181,  294 => 180,  270 => 159,  264 => 156,  250 => 145,  240 => 144,  92 => 6,  82 => 5,  62 => 3,  39 => 1,);
  852.     }
  853.     public function getSourceContext()
  854.     {
  855.         return new Source("{% extends 'backoffice.base.html.twig' %}
  856. {% block title %}Gestion du Stock{% endblock %}
  857. {% block stylesheets %}
  858. {{ parent() }}
  859. <style>
  860.     /* Styles personnalisés */
  861.     .card {
  862.         border-radius: 12px;
  863.         box-shadow: 0 4px 20px rgba(0,0,0,0.05);
  864.         border: none;
  865.     }
  866.     
  867.     .card-header {
  868.         background-color: #f8f9fa;
  869.         border-bottom: 1px solid #eee;
  870.         padding: 1.5rem 1.5rem;
  871.     }
  872.     
  873.     .table {
  874.         font-size: 0.95rem;
  875.     }
  876.     
  877.     .table thead th {
  878.         border-bottom-width: 1px;
  879.         font-weight: 600;
  880.         color: #6c757d;
  881.         text-transform: uppercase;
  882.         letter-spacing: 0.5px;
  883.         font-size: 0.75rem;
  884.     }
  885.     
  886.     .table > :not(:last-child) > :last-child > * {
  887.         border-bottom-color: #f1f1f1;
  888.     }
  889.     
  890.     .btn-outline-primary {
  891.         border-width: 2px;
  892.         font-weight: 500;
  893.     }
  894.     
  895.     .btn-sm {
  896.         padding: 0.35rem 0.75rem;
  897.         font-size: 0.85rem;
  898.     }
  899.     
  900.     .menu-sub {
  901.         box-shadow: 0 5px 25px rgba(0,0,0,0.1);
  902.         border: none;
  903.         border-radius: 8px;
  904.     }
  905.     
  906.     .menu-link {
  907.         transition: all 0.2s;
  908.         font-weight: 500;
  909.     }
  910.     
  911.     .menu-link:hover {
  912.         background-color: #f3f6f9;
  913.         color: #009ef7;
  914.     }
  915.     
  916.     tr {
  917.         transition: all 0.2s;
  918.     }
  919.     
  920.     tr:hover {
  921.         background-color: #fbfbfb;
  922.     }
  923.     
  924.     .quantity-badge {
  925.         display: inline-block;
  926.         padding: 0.25rem 0.5rem;
  927.         border-radius: 50px;
  928.         font-weight: 600;
  929.         font-size: 0.8rem;
  930.         min-width: 30px;
  931.         text-align: center;
  932.     }
  933.     
  934.     .export-btn {
  935.         border-radius: 8px;
  936.         font-weight: 600;
  937.         padding: 0.5rem 1.25rem;
  938.     }
  939.     
  940.     /* Modal styles */
  941.     #deleteStockModal .modal-header {
  942.         background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  943.         border-bottom: 2px solid #dee2e6;
  944.     }
  945.     
  946.     #deleteStockModal .modal-title {
  947.         font-weight: 600;
  948.         color: #dc3545;
  949.     }
  950.     
  951.     #deleteStockModal .btn-danger {
  952.         background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
  953.         border: none;
  954.         transition: all 0.3s ease;
  955.     }
  956.     
  957.     #deleteStockModal .btn-danger:hover {
  958.         transform: translateY(-2px);
  959.         box-shadow: 0 4px 8px rgba(220, 53, 69, 0.3);
  960.     }
  961.     
  962.     #deleteStockModal .input-group-text {
  963.         background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  964.         border-right: none;
  965.     }
  966.     
  967.     #deleteStockModal .form-control:focus {
  968.         border-color: #dc3545;
  969.         box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
  970.     }
  971.     
  972.     .menu-link.text-muted {
  973.         opacity: 0.6;
  974.         cursor: not-allowed;
  975.         pointer-events: none;
  976.         background-color: #f8f9fa;
  977.     }
  978.     
  979.     .menu-link.text-muted:hover {
  980.         background-color: #f8f9fa !important;
  981.         color: #6c757d !important;
  982.     }
  983.     
  984.     @keyframes shake {
  985.         0%, 100% { transform: translateX(0); }
  986.         10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
  987.         20%, 40%, 60%, 80% { transform: translateX(5px); }
  988.     }
  989.     
  990.     .shake-animation {
  991.         animation: shake 0.5s ease-in-out;
  992.     }
  993. </style>
  994. {% endblock %}
  995. {% block body %}
  996. {{ include('Base/_sidebar_admin.html.twig') }}
  997. <div class=\"post d-flex flex-column-fluid\" id=\"kt_post\">
  998.     <div id=\"kt_content_container\" class=\"container-xxl\">
  999.         <div class=\"card shadow-sm\">
  1000.             <div class=\"card-header border-0 pt-6\">
  1001.                 <div class=\"card-title\">
  1002.                     <h2 class=\"fw-bolder mb-0\">Gestion du Stock</h2>
  1003.                 </div>
  1004.                 <div class=\"card-toolbar\">
  1005.                     <div class=\"d-flex justify-content-end\" data-kt-customer-table-toolbar=\"base\">
  1006.                         <a class=\"btn btn-light-primary btn-hover-rise me-2\" href=\"{{ path('inventaire_index') }}\">
  1007.                             <i class=\"fas fa-clipboard-list me-2\"></i>Rapports d'inventaire
  1008.                         </a>
  1009.                         <a class=\"btn btn-light-primary btn-hover-rise export-btn\" href=\"{{ path('export_donnees_csv_stock') }}\">
  1010.                             <i class=\"fas fa-file-export me-2\"></i>Exporter en CSV
  1011.                         </a>
  1012.                     </div>
  1013.                 </div>
  1014.             </div>
  1015.             <div class=\"card-body pt-0\">
  1016.                 <div class=\"mb-5\">
  1017.                     <div class=\"position-relative\">
  1018.                         <i class=\"fas fa-search position-absolute ms-4 fs-4\" style=\"top:50%;transform:translateY(-50%);color:#a1a5b7;\"></i>
  1019.                         <input type=\"text\" id=\"stockSearchInput\" class=\"form-control form-control-solid ps-13\"
  1020.                                style=\"height:48px;font-size:1rem;\"
  1021.                                placeholder=\"Rechercher par code-barre, nom de pièce ou référence...\">
  1022.                     </div>
  1023.                     <div id=\"stockSearchEmpty\" class=\"text-center py-10 d-none\">
  1024.                         <i class=\"fas fa-search fs-4x text-muted mb-4\"></i>
  1025.                         <div class=\"text-muted fw-bold fs-5\">Aucun résultat pour cette recherche</div>
  1026.                     </div>
  1027.                 </div>
  1028.                 <!-- Message flash -->
  1029.                 {% for label, messages in app.flashes %}
  1030.                     {% for message in messages %}
  1031.                         <div class=\"alert alert-dismissible bg-light-{{ label == 'error' ? 'danger' : label == 'success' ? 'success' : 'info' }} d-flex flex-column flex-sm-row p-5 mb-10\">
  1032.                             <div class=\"d-flex flex-column pe-0 pe-sm-10\">
  1033.                                 <span>{{ message }}</span>
  1034.                             </div>
  1035.                             <button type=\"button\" class=\"position-absolute position-sm-relative m-2 m-sm-0 top-0 end-0 btn btn-icon ms-sm-auto\" data-bs-dismiss=\"alert\">
  1036.                                 <span class=\"svg-icon svg-icon-1\">
  1037.                                     <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">
  1038.                                         <rect opacity=\"0.5\" x=\"6\" y=\"17.3137\" width=\"16\" height=\"2\" rx=\"1\" transform=\"rotate(-45 6 17.3137)\" fill=\"currentColor\"/>
  1039.                                         <rect x=\"7.41422\" y=\"6\" width=\"16\" height=\"2\" rx=\"1\" transform=\"rotate(45 7.41422 6)\" fill=\"currentColor\"/>
  1040.                                     </svg>
  1041.                                 </span>
  1042.                             </button>
  1043.                         </div>
  1044.                     {% endfor %}
  1045.                 {% endfor %}
  1046.                 
  1047.                 <div class=\"table-responsive\">
  1048.                     <table class=\"table align-middle table-row-dashed fs-6 gy-5\" id=\"kt_customers_table\">
  1049.                         <thead>
  1050.                             <tr class=\"text-start text-gray-600 fw-bolder fs-7 text-uppercase gs-0\">
  1051.                                 <th class=\"min-w-25px\">
  1052.                                     <div class=\"form-check form-check-sm form-check-custom form-check-solid\">
  1053.                                         <input class=\"form-check-input\" type=\"checkbox\" value=\"1\" data-kt-check=\"true\" data-kt-check-target=\".widget-9-check\"/>
  1054.                                     </div>
  1055.                                 </th>
  1056.                                 <th class=\"min-w-100px\">Pièce</th>
  1057.                                 <th class=\"text-center min-w-80px\">Quantité</th>
  1058.                                 <th class=\"min-w-100px\">Montant HTVA</th>
  1059.                                 <th class=\"min-w-100px\">Num. BL</th>
  1060.                                 <th class=\"min-w-120px\">Référence</th>
  1061.                                 <th class=\"min-w-150px\">Code-barres</th>
  1062.                                 <th class=\"text-end min-w-100px\">Actions</th>
  1063.                             </tr>
  1064.                         </thead>
  1065.                         <tbody class=\"fw-semibold text-gray-700\">
  1066.                             {% for stock in stocks %}
  1067.                             {% set nomPiece = stock.piece ?: (stock.idProduit ? stock.idProduit.description : null) %}
  1068.                             <tr class=\"stock-row\" data-search=\"{{ (nomPiece ~ ' ' ~ stock.reference ~ ' ' ~ stock.codeBarre)|lower }}\">
  1069.                                 <td>
  1070.                                     <div class=\"form-check form-check-sm form-check-custom form-check-solid\">
  1071.                                         <input class=\"form-check-input widget-9-check\" type=\"checkbox\" value=\"1\"/>
  1072.                                     </div>
  1073.                                 </td>
  1074.                                 <td>
  1075.                                     <div class=\"d-flex align-items-center\">
  1076.                                         <div class=\"symbol symbol-40px me-3\">
  1077.                                             <span class=\"symbol-label bg-light-primary\">
  1078.                                                 <i class=\"fas fa-box-open text-primary\"></i>
  1079.                                             </span>
  1080.                                         </div>
  1081.                                         <div>
  1082.                                             <span class=\"text-dark fw-bold d-block\">
  1083.                                                 {{ stock.piece ?: (stock.idProduit ? stock.idProduit.description : null) ?: (stock.reference ?: 'N/A') }}
  1084.                                             </span>
  1085.                                         </div>
  1086.                                     </div>
  1087.                                 </td>
  1088.                                 <td class=\"text-center\">
  1089.                                     {% set stock_class = 'success' %}
  1090.                                     {% if stock.quantite <= 5 %}
  1091.                                         {% set stock_class = 'danger' %}
  1092.                                     {% elseif stock.quantite <= 10 %}
  1093.                                         {% set stock_class = 'warning' %}
  1094.                                     {% endif %}
  1095.                                     <span class=\"quantity-badge bg-light-{{ stock_class }} text-{{ stock_class }}\">
  1096.                                         {{ stock.quantite }}
  1097.                                     </span>
  1098.                                 </td>
  1099.                                 <td>{{ stock.montantHTVA|number_format(2, ',', ' ') }} TND</td>
  1100.                                 <td>
  1101.                                     <span class=\"badge badge-light-primary\">{{ stock.numBl ?: 'N/A' }}</span>
  1102.                                 </td>
  1103.                                 <td>
  1104.                                     <span class=\"text-dark fw-bold\">{{ stock.reference ?: 'N/A' }}</span>
  1105.                                 </td>
  1106.                                 <td>
  1107.                                     <span class=\"badge badge-light-dark\">{{ stock.codeBarre ?: 'N/A' }}</span>
  1108.                                 </td>
  1109.                                 <td class=\"text-end\">
  1110.                                     <div class=\"dropdown\">
  1111.                                         <button class=\"btn btn-sm btn-icon btn-color-gray-400 btn-active-light-primary\" data-bs-toggle=\"dropdown\">
  1112.                                             <span class=\"svg-icon svg-icon-2\">
  1113.                                                 <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">
  1114.                                                     <rect x=\"10\" y=\"10\" width=\"4\" height=\"4\" rx=\"2\" fill=\"currentColor\"/>
  1115.                                                     <rect x=\"10\" y=\"3\" width=\"4\" height=\"4\" rx=\"2\" fill=\"currentColor\"/>
  1116.                                                     <rect x=\"10\" y=\"17\" width=\"4\" height=\"4\" rx=\"2\" fill=\"currentColor\"/>
  1117.                                                 </svg>
  1118.                                             </span>
  1119.                                         </button>
  1120.                                         <div class=\"dropdown-menu menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-600 menu-state-bg-light-primary fw-bold fs-7 w-150px py-4\" data-kt-menu=\"true\">
  1121.                                             <div class=\"menu-item px-3\">
  1122.                                                 <a href=\"{{ path('app_stock_show', {'id': stock.id}) }}\" class=\"menu-link px-3\">
  1123.                                                     <span class=\"svg-icon svg-icon-3 me-2\">
  1124.                                                         <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">
  1125.                                                             <path d=\"M21.7 18.9L18.6 15.8C17.9 16.9 16.9 17.9 15.8 18.6L18.9 21.7C19.3 22.1 19.9 22.1 20.3 21.7L21.7 20.3C22.1 19.9 22.1 19.3 21.7 18.9Z\" fill=\"currentColor\"/>
  1126.                                                             <path opacity=\"0.3\" d=\"M11 20C6 20 2 16 2 11C2 6 6 2 11 2C16 2 20 6 20 11C20 16 16 20 11 20ZM11 4C7.1 4 4 7.1 4 11C4 14.9 7.1 18 11 18C14.9 18 18 14.9 18 11C18 7.1 14.9 4 11 4ZM8 11C8 9.3 9.3 8 11 8C11.6 8 12 7.6 12 7C12 6.4 11.6 6 11 6C8.2 6 6 8.2 6 11C6 11.6 6.4 12 7 12C7.6 12 8 11.6 8 11Z\" fill=\"currentColor\"/>
  1127.                                                         </svg>
  1128.                                                     </span>
  1129.                                                     Afficher
  1130.                                                 </a>
  1131.                                             </div>
  1132.                                             <div class=\"menu-item px-3\">
  1133.                                                 <a href=\"{{ path('app_stock_edit', {'id': stock.id}) }}\" class=\"menu-link px-3\">
  1134.                                                     <span class=\"svg-icon svg-icon-3 me-2\">
  1135.                                                         <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">
  1136.                                                             <path opacity=\"0.3\" d=\"M21.4 8.35303L19.241 10.511L13.485 4.755L15.643 2.59595C16.0248 2.21423 16.5426 1.99988 17.0825 1.99988C17.6224 1.99988 18.1402 2.21423 18.522 2.59595L21.4 5.474C21.7817 5.85581 21.9962 6.37355 21.9962 6.91345C21.9962 7.45335 21.7817 7.97122 21.4 8.35303ZM3.68699 21.932L9.88699 19.865L4.13099 14.109L2.06399 20.309C1.98815 20.5354 1.97703 20.7787 2.03189 21.0111C2.08674 21.2436 2.2054 21.4561 2.37449 21.6248C2.54359 21.7934 2.75641 21.9115 2.989 21.9658C3.22158 22.0201 3.4647 22.0084 3.69099 21.932H3.68699Z\" fill=\"currentColor\"/>
  1137.                                                             <path d=\"M5.574 21.3L3.692 21.928C3.46591 22.0032 3.22334 22.0141 2.99144 21.9594C2.75954 21.9046 2.54744 21.7864 2.3789 21.6179C2.21036 21.4495 2.09202 21.2375 2.03711 21.0056C1.9822 20.7737 1.99289 20.5312 2.06799 20.3051L2.696 18.422L5.574 21.3ZM4.13499 14.105L9.891 19.861L19.245 10.507L13.489 4.75098L4.13499 14.105Z\" fill=\"currentColor\"/>
  1138.                                                         </svg>
  1139.                                                     </span>
  1140.                                                     Modifier
  1141.                                                 </a>
  1142.                                             </div>
  1143.                                             <div class=\"menu-item px-3\">
  1144.                                                 <a href=\"javascript:void(0)\" 
  1145.                                                    class=\"menu-link px-3 text-danger\" 
  1146.                                                    onclick=\"if (typeof checkAndOpenDeleteStockModal === 'function') checkAndOpenDeleteStockModal({{ stock.id }}, '{{ (stock.reference ?? stock.piece ?? 'Stock')|replace({\"'\": \"\\\\'\", '\"': '&quot;'}) }}'); else alert('Fonction de suppression non chargée');\">
  1147.                                                     <span class=\"svg-icon svg-icon-3 me-2\">
  1148.                                                         <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">
  1149.                                                             <path d=\"M5 9C5 8.44772 5.44772 8 6 8H18C18.5523 8 19 8.44772 19 9V18C19 19.6569 17.6569 21 16 21H8C6.34315 21 5 19.6569 5 18V9Z\" fill=\"currentColor\"/>
  1150.                                                             <path opacity=\"0.5\" d=\"M5 5C5 4.44772 5.44772 4 6 4H18C18.5523 4 19 4.44772 19 5C19 5.55228 18.5523 6 18 6H6C5.44772 6 5 5.55228 5 5Z\" fill=\"currentColor\"/>
  1151.                                                             <path opacity=\"0.5\" d=\"M9 4C9 3.44772 9.44772 3 10 3H14C14.5523 3 15 3.44772 15 4C15 4.55228 14.5523 5 14 5H10C9.44772 5 9 4.55228 9 4Z\" fill=\"currentColor\"/>
  1152.                                                         </svg>
  1153.                                                     </span>
  1154.                                                     Supprimer
  1155.                                                 </a>
  1156.                                             </div>
  1157.                                         </div>
  1158.                                     </div>
  1159.                                 </td>
  1160.                             </tr>
  1161.                             {% else %}
  1162.                             <tr>
  1163.                                 <td colspan=\"8\" class=\"text-center py-10\">
  1164.                                     <div class=\"d-flex flex-column align-items-center\">
  1165.                                         <i class=\"fas fa-box-open fs-4x text-muted mb-4\"></i>
  1166.                                         <span class=\"text-muted fw-bold fs-5\">Aucun article en stock</span>
  1167.                                     </div>
  1168.                                 </td>
  1169.                             </tr>
  1170.                             {% endfor %}
  1171.                         </tbody>
  1172.                     </table>
  1173.                 </div>
  1174.             </div>
  1175.         </div>
  1176.         <!-- MODAL DE SUPPRESSION STOCK -->
  1177.         <div class=\"modal fade\" id=\"deleteStockModal\" tabindex=\"-1\" aria-labelledby=\"deleteStockModalLabel\" aria-hidden=\"true\">
  1178.             <div class=\"modal-dialog\">
  1179.                 <div class=\"modal-content\">
  1180.                     <div class=\"modal-header\">
  1181.                         <h5 class=\"modal-title\" id=\"deleteStockModalLabel\">
  1182.                             <i class=\"bi bi-exclamation-triangle-fill text-warning me-2\"></i>
  1183.                             Confirmer la suppression
  1184.                         </h5>
  1185.                         <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button>
  1186.                     </div>
  1187.                     <div class=\"modal-body\">
  1188.                         <div id=\"deleteStockMessage\"></div>
  1189.                         <form id=\"deleteStockForm\">
  1190.                             <input type=\"hidden\" name=\"stock_id\" id=\"stockIdInput\" value=\"\">
  1191.                             <div class=\"mb-3\">
  1192.                                 <label for=\"deleteStockCode\" class=\"form-label\">
  1193.                                     <strong>Code de confirmation</strong>
  1194.                                 </label>
  1195.                                 <div class=\"input-group\">
  1196.                                     <span class=\"input-group-text bg-light\">
  1197.                                         <i class=\"bi bi-shield-lock\"></i>
  1198.                                     </span>
  1199.                                     <input type=\"password\" class=\"form-control\" id=\"deleteStockCode\" 
  1200.                                            name=\"delete_code\" placeholder=\"Saisissez 123123\" required maxlength=\"6\">
  1201.                                 </div>
  1202.                                 <div class=\"form-text text-muted\">
  1203.                                     <i class=\"bi bi-info-circle\"></i> Entrez le code de sécurité 123123 pour confirmer
  1204.                                 </div>
  1205.                             </div>
  1206.                             <input type=\"hidden\" name=\"_token\" value=\"{{ csrf_token('delete_stock') }}\">
  1207.                         </form>
  1208.                     </div>
  1209.                     <div class=\"modal-footer\">
  1210.                         <button type=\"button\" class=\"btn btn-secondary\" data-bs-dismiss=\"modal\">
  1211.                             <i class=\"bi bi-x-circle me-1\"></i>
  1212.                             Annuler
  1213.                         </button>
  1214.                         <button type=\"button\" class=\"btn btn-danger\" id=\"confirmDeleteStockBtn\">
  1215.                             <span class=\"spinner-border spinner-border-sm d-none me-2\" role=\"status\" aria-hidden=\"true\"></span>
  1216.                             <i class=\"bi bi-trash me-1\"></i>
  1217.                             Supprimer le stock
  1218.                         </button>
  1219.                     </div>
  1220.                 </div>
  1221.             </div>
  1222.         </div>
  1223.     </div>
  1224. </div>
  1225. <div class=\"modal fade\" id=\"kt_modal_add_customer_ok\" tabindex=\"-1\" aria-hidden=\"true\">
  1226.     <div class=\"modal-dialog modal-dialog-centered mw-650px\">
  1227.         <div class=\"modal-content\">
  1228.             <form class=\"form\" method=\"post\" action=\"{{ path('app_stock_new') }}\"
  1229.                   id=\"kt_modal_add_customer_form\" data-kt-redirect=\"apps/customers/list.html\">
  1230.                 <div class=\"post d-flex flex-column-fluid\" id=\"kt_post\">
  1231.                     <div id=\"kt_content_container\" class=\"container\">
  1232.                         <div class=\"card\">
  1233.                             <div class=\"card-header border-0 pt-6\"></div>
  1234.                             <div class=\"card-body pt-0\">
  1235.                                 {{ render(path('app_stock_new')) }}
  1236.                             </div>
  1237.                         </div>
  1238.                     </div>
  1239.                 </div>
  1240.             </form>
  1241.         </div>
  1242.     </div>
  1243. </div>
  1244. {% endblock %}
  1245. {% block javascripts %}
  1246. {{ parent() }}
  1247. <script src=\"https://cdn.jsdelivr.net/npm/sweetalert2@11\"></script>
  1248. <script>
  1249. (function() {
  1250.     'use strict';
  1251.     
  1252.     let currentStockId = null;
  1253.     // ✅ FONCTION GLOBALE DISPONIBLE IMMÉDIATEMENT
  1254.     window.checkAndOpenDeleteStockModal = async function(stockId, stockName) {
  1255.         try {
  1256.             currentStockId = stockId;
  1257.             
  1258.             // Appel AJAX pour vérifier si le stock peut être supprimé
  1259.             const response = await fetch(`/stock/check-delete/\${stockId}`);
  1260.             
  1261.             if (!response.ok) {
  1262.                 throw new Error(`HTTP error! status: \${response.status}`);
  1263.             }
  1264.             
  1265.             const data = await response.json();
  1266.             if (data.success && data.canDelete) {
  1267.                 // Peut supprimer : ouvrir modal
  1268.                 const stockIdInput = document.getElementById('stockIdInput');
  1269.                 const deleteMessage = document.getElementById('deleteStockMessage');
  1270.                 const deleteCode = document.getElementById('deleteStockCode');
  1271.                 
  1272.                 if (stockIdInput) stockIdInput.value = stockId;
  1273.                 
  1274.                 if (deleteMessage) {
  1275.                     deleteMessage.innerHTML = 
  1276.                         `<div class=\"alert alert-warning d-flex align-items-center mb-3\">
  1277.                             <i class=\"bi bi-exclamation-triangle-fill fs-3 me-3\"></i>
  1278.                             <div>
  1279.                                 <strong>Attention !</strong>
  1280.                                 <p class=\"mb-0\">Voulez-vous vraiment supprimer cette ligne de stock <strong>\"\${stockName}\"</strong> ?</p>
  1281.                             </div>
  1282.                         </div>
  1283.                         <div class=\"alert alert-success d-flex align-items-center\">
  1284.                             <i class=\"bi bi-check-circle-fill me-2\"></i>
  1285.                             <span>Cette ligne de stock peut être supprimée</span>
  1286.                         </div>`;
  1287.                 }
  1288.                 
  1289.                 if (deleteCode) {
  1290.                     deleteCode.value = '';
  1291.                     setTimeout(() => deleteCode.focus(), 500);
  1292.                 }
  1293.                 
  1294.                 // Ouvrir modal
  1295.                 const modalElement = document.getElementById('deleteStockModal');
  1296.                 if (modalElement) {
  1297.                     const modal = new bootstrap.Modal(modalElement);
  1298.                     modal.show();
  1299.                 }
  1300.             } else {
  1301.                 // Ne peut pas supprimer
  1302.                 showStockAlert('error', 'Suppression impossible', data.message);
  1303.             }
  1304.         } catch (error) {
  1305.             console.error('Erreur détaillée:', error);
  1306.             showStockAlert('error', 'Erreur', 'Erreur lors de la vérification: ' + error.message);
  1307.         }
  1308.     };
  1309.     // Fonction d'alerte unifiée avec SweetAlert2
  1310.     function showStockAlert(icon, title, text, reload = false) {
  1311.         if (typeof Swal !== 'undefined') {
  1312.             Swal.fire({
  1313.                 icon: icon,
  1314.                 title: title,
  1315.                 text: text,
  1316.                 timer: reload ? 2000 : undefined,
  1317.                 showConfirmButton: !reload,
  1318.                 showCancelButton: false,
  1319.                 confirmButtonColor: icon === 'success' ? '#28a745' : '#dc3545',
  1320.                 confirmButtonText: icon === 'success' ? 'OK' : 'Fermer'
  1321.             }).then((result) => {
  1322.                 if (reload) {
  1323.                     window.location.reload();
  1324.                 }
  1325.             });
  1326.         } else {
  1327.             alert(`\${icon === 'success' ? '✅' : '❌'} \${title}\\n\${text}`);
  1328.             if (reload) {
  1329.                 window.location.reload();
  1330.             }
  1331.         }
  1332.     }
  1333.     // Initialisation après chargement DOM
  1334.     document.addEventListener('DOMContentLoaded', function() {
  1335.         console.log('✅ Script suppression stock chargé');
  1336.         // Recherche instantanée : code-barre, nom de pièce ou référence
  1337.         const searchInput = document.getElementById('stockSearchInput');
  1338.         const searchEmpty = document.getElementById('stockSearchEmpty');
  1339.         const stockRows = document.querySelectorAll('.stock-row');
  1340.         if (searchInput) {
  1341.             searchInput.addEventListener('input', function () {
  1342.                 const term = this.value.trim().toLowerCase();
  1343.                 let visibleCount = 0;
  1344.                 stockRows.forEach(function (row) {
  1345.                     const match = !term || (row.dataset.search || '').includes(term);
  1346.                     row.classList.toggle('d-none', !match);
  1347.                     if (match) visibleCount++;
  1348.                 });
  1349.                 if (searchEmpty) {
  1350.                     searchEmpty.classList.toggle('d-none', visibleCount !== 0 || stockRows.length === 0);
  1351.                 }
  1352.             });
  1353.         }
  1354.         // Bouton confirmer suppression stock
  1355.         const confirmBtn = document.getElementById('confirmDeleteStockBtn');
  1356.         if (confirmBtn) {
  1357.             confirmBtn.addEventListener('click', async function(e) {
  1358.                 e.preventDefault();
  1359.                 
  1360.                 const codeInput = document.getElementById('deleteStockCode');
  1361.                 const code = codeInput ? codeInput.value.trim() : '';
  1362.                 const stockId = currentStockId;
  1363.                 
  1364.                 if (!stockId) {
  1365.                     showStockAlert('error', 'Erreur', 'ID stock manquant');
  1366.                     return;
  1367.                 }
  1368.                 
  1369.                 if (code !== '123123') {
  1370.                     showStockAlert('error', 'Code incorrect', 'Le code requis est : 123123');
  1371.                     
  1372.                     // Animation shake
  1373.                     if (codeInput) {
  1374.                         codeInput.classList.add('shake-animation');
  1375.                         setTimeout(() => codeInput.classList.remove('shake-animation'), 500);
  1376.                         codeInput.value = '';
  1377.                         codeInput.focus();
  1378.                     }
  1379.                     return;
  1380.                 }
  1381.                 // Désactiver bouton + spinner
  1382.                 const btn = this;
  1383.                 const spinner = btn.querySelector('.spinner-border');
  1384.                 const btnHtml = btn.innerHTML;
  1385.                 
  1386.                 btn.disabled = true;
  1387.                 if (spinner) spinner.classList.remove('d-none');
  1388.                 btn.innerHTML = '<span class=\"spinner-border spinner-border-sm me-2\" role=\"status\" aria-hidden=\"true\"></span>Suppression en cours...';
  1389.                 try {
  1390.                     const tokenInput = document.querySelector('#deleteStockForm input[name=\"_token\"]');
  1391.                     const token = tokenInput ? tokenInput.value : '';
  1392.                     
  1393.                     const formData = new FormData();
  1394.                     formData.append('_token', token);
  1395.                     
  1396.                     const response = await fetch(`/stock/\${stockId}/delete`, {
  1397.                         method: 'POST',
  1398.                         body: formData,
  1399.                         headers: {
  1400.                             'X-Requested-With': 'XMLHttpRequest'
  1401.                         }
  1402.                     });
  1403.                     if (!response.ok) {
  1404.                         throw new Error(`HTTP error! status: \${response.status}`);
  1405.                     }
  1406.                     
  1407.                     const data = await response.json();
  1408.                     if (data.success) {
  1409.                         // Fermer la modal
  1410.                         const modalElement = document.getElementById('deleteStockModal');
  1411.                         if (modalElement) {
  1412.                             const modal = bootstrap.Modal.getInstance(modalElement);
  1413.                             if (modal) modal.hide();
  1414.                         }
  1415.                         
  1416.                         // Afficher succès et recharger
  1417.                         showStockAlert('success', 'Supprimé !', data.message, true);
  1418.                     } else {
  1419.                         showStockAlert('error', 'Erreur', data.message);
  1420.                         
  1421.                         // Réactiver le bouton
  1422.                         btn.innerHTML = btnHtml;
  1423.                         btn.disabled = false;
  1424.                         if (spinner) spinner.classList.add('d-none');
  1425.                         
  1426.                         // Reset du code
  1427.                         if (codeInput) {
  1428.                             codeInput.value = '';
  1429.                             codeInput.focus();
  1430.                         }
  1431.                     }
  1432.                 } catch (error) {
  1433.                     console.error('Erreur détaillée:', error);
  1434.                     showStockAlert('error', 'Erreur', 'Erreur lors de la suppression: ' + error.message);
  1435.                     
  1436.                     // Réactiver le bouton
  1437.                     btn.innerHTML = btnHtml;
  1438.                     btn.disabled = false;
  1439.                     if (spinner) spinner.classList.add('d-none');
  1440.                     
  1441.                     // Reset du code
  1442.                     if (codeInput) {
  1443.                         codeInput.value = '';
  1444.                         codeInput.focus();
  1445.                     }
  1446.                 }
  1447.             });
  1448.         } else {
  1449.             console.error('❌ Bouton confirmDeleteStockBtn non trouvé');
  1450.         }
  1451.         // Reset modal à la fermeture
  1452.         const modalElement = document.getElementById('deleteStockModal');
  1453.         if (modalElement) {
  1454.             modalElement.addEventListener('hidden.bs.modal', function() {
  1455.                 console.log('Modal fermée - nettoyage');
  1456.                 const form = document.getElementById('deleteStockForm');
  1457.                 const confirmBtn = document.getElementById('confirmDeleteStockBtn');
  1458.                 const deleteMessage = document.getElementById('deleteStockMessage');
  1459.                 const codeInput = document.getElementById('deleteStockCode');
  1460.                 
  1461.                 if (form) form.reset();
  1462.                 if (confirmBtn) {
  1463.                     confirmBtn.disabled = false;
  1464.                     confirmBtn.innerHTML = 
  1465.                         '<span class=\"spinner-border spinner-border-sm d-none me-2\" role=\"status\" aria-hidden=\"true\"></span><i class=\"bi bi-trash me-1\"></i>Supprimer le stock';
  1466.                 }
  1467.                 if (deleteMessage) deleteMessage.innerHTML = '';
  1468.                 if (codeInput) codeInput.value = '';
  1469.                 currentStockId = null;
  1470.             });
  1471.         }
  1472.     });
  1473. })();
  1474. </script>
  1475. {% endblock %}", "stock/index.html.twig", "/htdocs/templates/stock/index.html.twig");
  1476.     }
  1477. }