templates/base.html.twig line 1

Open in your IDE?
  1. <!DOCTYPE html>
  2. <html lang="fr">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6.     <meta http-equiv="Content-Language" content="fr">
  7.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  8.     <meta name="msapplication-tap-highlight" content="no">
  9.     <meta name="author" lang="fr" content="Cedric BERARD & Curtis MARTY JACKSON & Levon BAGHDASARYAN & Axel SOFONEA & Delfine SIKORA & Hamza BOURHAIL BENHADI">
  10.     {% block meta %}{% endblock %}
  11.     <title>{% block title %}Visio{% endblock %}</title>
  12.     <link rel="icon" href="{{ asset('images/logo_pm_sm.png') }}">
  13.     <link href="{{ asset('main.87c0748b313a1dda75f5.css') }}" rel="stylesheet">
  14.     <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  15.     <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
  16.     <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.7.0/css/buttons.dataTables.min.css">
  17.     <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css">
  18.     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
  19.     <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
  20.     <!-- Fichier JS helpers -->
  21.     <script type="text/javascript" src="{{ asset('assets/scripts/helpers.js') }}"></script>
  22.     <link href="{{ asset('css/loading.css') }}" rel="stylesheet">
  23.     <link href="{{ asset('css/main.css') }}" rel="stylesheet">
  24.     <link href="{{ asset('css/custom-style.css') }}" rel="stylesheet">
  25.     <style>
  26.     .card-header{
  27.           height:35px;
  28.     }
  29.     </style>
  30.     {% block stylesheets %}{% endblock %}
  31. </head>
  32. <body>
  33. {% block complete_body %}
  34.     <div class="app-container app-theme-white body-tabs-shadow fixed-header fixed-sidebar fixed-footer">
  35.         <div class="app-header header-shadow">
  36.             <div class="app-header__logo">
  37.                 <a href="{{ path('index') }}"><div class="logo-src"></div></a>
  38.                 <div class="header__pane ml-auto">
  39.                     <div>
  40.                         <button type="button" class="hamburger close-sidebar-btn hamburger--elastic is-active" data-class="closed-sidebar">
  41.                                                                 <span class="hamburger-box">
  42.                                                                         <span class="hamburger-inner"></span>
  43.                                                                  </span>
  44.                         </button>
  45.                     </div>
  46.                 </div>
  47.             </div>
  48.             <div class="app-header__mobile-menu">
  49.                 <div>
  50.                     <button type="button" class="hamburger hamburger--elastic mobile-toggle-nav">
  51.                                                         <span class="hamburger-box">
  52.                                                                 <span class="hamburger-inner"></span>
  53.                                                          </span>
  54.                     </button>
  55.                 </div>
  56.             </div>
  57.             <div class="app-header__menu">
  58.                                      <span>
  59.                                          <button type="button" class="btn-icon btn-icon-only btn btn-primary btn-sm mobile-toggle-header-nav">
  60.                                             <span class="btn-icon-wrapper">
  61.                                                 <i class="fa fa-ellipsis-v fa-w-6"></i>
  62.                                              </span>
  63.                                          </button>
  64.                                      </span>
  65.             </div>
  66.             <div class="app-header__content">
  67.                 <div class="app-header-left">
  68.                     <div class="search-wrapper">
  69.                         <div class="input-holder">
  70.                             <input id="search-input-id"
  71.                                    type="text"
  72.                                    class="search-input"
  73.                                    placeholder="{{ 'menu.search'|trans }}"
  74.                                    >
  75.                             <button id="search-icon-id"
  76.                                     class="search-icon"
  77.                                     data-container="body"
  78.                                     data-toggle="popover"
  79.                                     data-placement="bottom"
  80.                                     data-content=" "
  81.                                     data-original-title= ""
  82.                                     title= "">
  83.                                 <span></span>
  84.                             </button>
  85.                         </div>
  86.                         <button id="search-icon-close-id" class="close"></button>
  87.                     </div>
  88.                 </div>
  89.             </div>
  90.             <div class="app-header__content">
  91.                 <div class="app-header-left">
  92.                 </div>
  93.                 <div class="app-header-right">
  94.                     {% if app.session.get('accesElium') %}
  95.                         <a href="https://planet-monetic.elium.com/login/saml2/login" class="btn btn-gradient-success mr-2" target="_blank">{{ "administration.acces_elium"|trans }}</a>
  96.                     {% endif %}
  97.                     {% if app.session.get('accesMemo') %}
  98.                         <div class="mr-3">
  99.                             <form method="post" action="https://memo.planet-monetic.fr/login.php" target="_blank" id="acces_memo_form">
  100.                                 <input type="hidden" value="{{ app.user.mail }}" name="username">
  101.                                 {% set key = app.user.mail ~ ':' ~ "now"|date("DMY") ~ 'PM' %}
  102.                                 {% set key = key|md5 %}
  103.                                 {% set key = key|base64_encode %}
  104.                                 <input type="hidden" value="{{ key }}" name="key">
  105.                                 <button type="submit" name="acces_memo_btn" class="btn btn-info">{{ "administration.acces_memo"|trans }}</button>
  106.                             </form>
  107.                         </div>
  108.                     {% endif %}
  109.                     <div class="header-dots">
  110.                         <!-- News icon -->
  111.                         {{ render(controller('App\\Controller\\GlobalController::newsMenuRenderControllerTwig', {})) }}
  112.                         <div class="dropdown">
  113.                             <button type="button" data-toggle="dropdown" class="p-0 mr-2 btn btn-link">
  114.                             <span class="icon-wrapper icon-wrapper-alt rounded-circle">
  115.                                     <span class="icon-wrapper-bg bg-focus"></span>
  116.                                {% if app.request.locale == 'en' %}
  117.                                    <span class="language-icon opacity-8 flag large GB"></span>
  118.                                {% else %}
  119.                                    <span class="language-icon opacity-8 flag large {{ app.request.locale|upper }}"></span>
  120.                                {% endif %}
  121.                             </span>
  122.                             </button>
  123.                             <div tabindex="-1" role="menu" aria-hidden="true" class="rm-pointers dropdown-menu dropdown-menu-right">
  124.                                 <a href="{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale': 'fr'})) }}">
  125.                                     <button type="button" tabindex="0" class="dropdown-item">
  126.                                         <span class="mr-3 opacity-8 flag large FR"></span>
  127.                                         {{ "menu.francais"|trans }}
  128.                                     </button>
  129.                                 </a>
  130.                                 <a href="{{ path(app.request.get('_route'), app.request.attributes.get('_route_params')|merge({'_locale': 'en'})) }}">
  131.                                     <button type="button" tabindex="0" class="dropdown-item">
  132.                                         <span class="mr-3 opacity-8 flag large GB"></span>
  133.                                         {{ "menu.english"|trans }}
  134.                                     </button>
  135.                                 </a>
  136.                             </div>
  137.                         </div>
  138.                         <div class="header-btn-lg pr-0">
  139.                             <div class="widget-content p-0">
  140.                                 <div class="widget-content-wrapper">
  141.                                     <div class="widget-content-left">
  142.                                         <div class="btn-group">
  143.                                             <a data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="p-0 btn">
  144.                                                 <img width="32" class="rounded-circle" src="{{ asset('assets/images/avatars/user.png') }}" alt="">
  145.                                                 <i class="fa fa-angle-down ml-2 opacity-8"></i>
  146.                                             </a>
  147.                                             <div tabindex="-1" role="menu" aria-hidden="true" class="rm-pointers dropdown-menu-lg dropdown-menu dropdown-menu-right">
  148.                                                 <div class="dropdown-menu-header">
  149.                                                     <div class="dropdown-menu-header-inner profil_banner">
  150.                                                         <div class="menu-header-image opacity-2"></div>
  151.                                                         <div class="menu-header-content text-left">
  152.                                                             <div class="widget-content p-0">
  153.                                                                 <div class="widget-content-wrapper">
  154.                                                                     <div class="widget-content-left mr-3">
  155.                                                                         <img width="32" class="rounded-circle" src="{{ asset('assets/images/avatars/user.png') }}" alt="">
  156.                                                                     </div>
  157.                                                                     <div class="widget-content-left">
  158.                                                                         <div class="widget-heading">
  159.                                                                             {{ app.user }}
  160.                                                                         </div>
  161.                                                                         <div class="widget-subheading opacity-8">
  162.                                                                             {{ app.session.get('profil').libelle|lower }}
  163.                                                                         </div>
  164.                                                                     </div>
  165.                                                                     <div class="widget-content-right mr-2">
  166.                                                                         <a href="{{ path('app_logout') }}" class="btn-pill btn-shadow btn-shine btn btn-danger ">{{ "menu.deconnexion"|trans }}
  167.                                                                         </a>
  168.                                                                     </div>
  169.                                                                 </div>
  170.                                                             </div>
  171.                                                         </div>
  172.                                                     </div>
  173.                                                 </div>
  174.                                                 <div class="scroll-area-xs" style="height: 150px;">
  175.                                                     <div class="scrollbar-container ps">
  176.                                                         <ul class="nav flex-column">
  177.                                                             <li class="nav-item-header nav-item">{{ "menu.compte"|trans }}
  178.                                                             </li>
  179.                                                         </ul>
  180.                                                     </div>
  181.                                                 </div>
  182.                                             </div>
  183.                                         </div>
  184.                                     </div>
  185.                                     <div class="widget-content-left  ml-3 header-user-info">
  186.                                         <div class="widget-heading">
  187.                                             {{ app.user }}
  188.                                         </div>
  189.                                         <div class="widget-subheading">
  190.                                             {{ app.user.fonction }}
  191.                                         </div>
  192.                                     </div>
  193.                                 </div>
  194.                             </div>
  195.                         </div>
  196.                     </div>
  197.                 </div>
  198.             </div>
  199.         </div>
  200.         <div class="app-main">
  201.             <div class="loader">
  202.                 <div class="big-loader-PM">
  203.                     <span>{{ 'loading_progress' | trans }}</span>
  204.                     <div class="dot-loader" id="loader-2">
  205.                         <span></span>
  206.                         <span></span>
  207.                         <span></span>
  208.                     </div>
  209.                 </div>
  210.             </div>
  211.             <div class="app-sidebar sidebar-shadow">
  212.                 <div class="scrollbar-sidebar">
  213.                     <div class="app-sidebar__inner">
  214.                         <ul class="vertical-nav-menu">
  215.                             {% block sidebar %}
  216.                                 <li class="app-sidebar__heading">{{ "menu" | trans }}</li>
  217.                                 <li>
  218.                                     <a href="{{ path('index') }}"><i
  219.                                                 class="metismenu-icon pe-7s-home"></i>{{ "menuvertical.accueil"|trans }}
  220.                                     </a>
  221.                                 </li>
  222.                                 {% for key_menu, menu in app.session.get('menu') %}
  223.                                     {% if menu.menu.seul == true %}
  224.                                         {% set activeLi = 'mm-active'%}
  225.                                         {% if menu.menu.url in app.request.pathinfo %}
  226.                                         <li class="{{ activeLi }}">
  227.                                         {% else %}
  228.                                             <li>
  229.                                         {% endif %}
  230.                                         <a href="{{ '/' ~ app.request.locale ~ '/' ~ menu.menu.url }}"><i
  231.                                                     class="metismenu-icon {{ menu.menu.icone }}"></i>{{ menu.menu.libelle|trans }}
  232.                                         </a>
  233.                                     {% else %}
  234.                                         {% set activeLi = 'mm-active' %}
  235.                                         {% set activeLink = false %}
  236.                                         {% set activeUl = 'mm-collapse' %}
  237.                                         <li>
  238.                                         <a href="#" aria-expanded="{{ activeLink }}"><i
  239.                                                     class="metismenu-icon {{ menu.menu.icone }}"></i>{{ menu.menu.libelle|trans }}
  240.                                             <i class="metismenu-state-icon pe-7s-angle-down caret-left"></i></a>
  241.                                         <ul class="{{ activeUl }}">
  242.                                             {% for key_sous_menu, sous_menu in menu.sous_menu %}
  243.                                                 {% if sous_menu.libelle is not empty %}
  244.                                                     <li>
  245.                                                     <i class="metismenu-icon"></i>
  246.                                                     <a href="#">{{ sous_menu.libelle|trans }}
  247.                                                         <i class="metismenu-state-icon pe-7s-angle-down caret-left"></i>
  248.                                                     </a>
  249.                                                     <ul>
  250.                                                 {% endif %}
  251.                                                 {% for key_page, page in sous_menu.page %}
  252.                                                     {% if page.url is not null %}
  253.                                                         {% if page.url in app.request.pathinfo %}
  254.                                                             {% if page.url|length > 18 %}
  255.                                                                 <li class="{{ activeLi }} scrollable-line">
  256.                                                             {% else %}
  257.                                                                 <li class="{{ activeLi }}">
  258.                                                             {% endif %}
  259.                                                         {% else %}
  260.                                                             {% if page.url|length > 18 %}
  261.                                                                 <li class="scrollable-line">
  262.                                                             {% else %}
  263.                                                                 <li>
  264.                                                             {% endif %}
  265.                                                         {% endif %}
  266.                                                         {% set pathinfoSplit = app.request.pathinfo|split('/') %}
  267.                                                         {% set nbElement = pathinfoSplit|length-1 %}
  268.                                                         {% if page.url == pathinfoSplit[nbElement] %}
  269.                                                             <a href="{{ '/' ~ app.request.locale ~ '/' ~ menu.menu.url ~ '/' ~ page.url }}"
  270.                                                                class="mm-active" aria-expanded="{{ activeLink }}">
  271.                                                         {% else %}
  272.                                                             <a href="{{ '/' ~ app.request.locale ~ '/' ~ menu.menu.url ~ '/' ~ page.url }}">
  273.                                                         {% endif %}
  274.                                                         <i class="metismenu-icon"></i>
  275.                                                         <span>{{ page.page |trans }}</span>
  276.                                                         </a>
  277.                                                         </li>
  278.                                                     {% endif %}
  279.                                                 {% endfor %}
  280.                                                 {% if sous_menu.libelle is not empty %}
  281.                                                     </ul>
  282.                                                     </li>
  283.                                                 {% endif %}
  284.                                             {% endfor %}
  285.                                         </ul>
  286.                                     {% endif %}
  287.                                     </li>
  288.                                 {% endfor %}
  289.                             {% endblock %}
  290.                         </ul>
  291.                     </div>
  292.                 </div>
  293.             </div>
  294.             <div class="app-main__outer">
  295.                 <div class="app-main__inner">
  296.                     {% block title_page %}{% endblock %}
  297.                     {% block message_body %}
  298.                         {% for label, messages in app.flashes %}
  299.                             {% for message in messages %}
  300.                                 <div class="alert alert-{{ label }}">
  301.                                     {{ message | raw }}
  302.                                     <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  303.                                         <span aria-hidden="true">&times;</span>
  304.                                     </button>
  305.                                 </div>
  306.                             {% endfor %}
  307.                         {% endfor %}
  308.                     {% endblock %}
  309.                     {% block body %}<h1>{{ "welcome" | trans }} {{ app.user }}</h1>{% endblock %}
  310.                     {% block after_body %}{% endblock %}
  311.                 </div>
  312.                 {% block footer %}
  313.                     <div class="app-wrapper-footer">
  314.                         <div class="app-footer">
  315.                             <div class="app-footer__inner">
  316.                                 <div class="app-footer" >
  317.                                     <p style="text-align: center;">
  318.                                         Visio© 2009-{{ "now"|date("Y") }}
  319.                                         <br> <a href="https://www.planet-monetic.fr/politique-de-confidentialite/" target="_blank">{{'titre_info_politique_conficdentialite'|trans}}</a> - {{ 'menu.footer'|trans }} <a href="http://www.mozilla.org/firefox/" target="_blank">FIREFOX©</a> & <a href="http://www.google.com/chrome/" target="_blank">CHROME©</a>
  320.                                     </p>
  321.                                 </div>
  322.                             </div>
  323.                         </div>
  324.                     </div>
  325.                 {% endblock %}
  326.             </div>
  327.         </div>
  328.     </div>
  329. {% endblock %}
  330. <!-- Scripts DataTables & JQuery Classique -->
  331. <script type="text/javascript" charset="utf8" src=https://code.jquery.com/jquery-3.5.1.js></script>
  332. <script src=https://code.jquery.com/ui/1.12.1/jquery-ui.js integrity="sha256-T0Vest3yCU7pafRw9r+settMBX6JkKN06dqBnpQ8d30=" crossorigin="anonymous"></script>
  333. <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.2/moment.js"></script>
  334. <script type="text/javascript" charset="utf8" src=https://cdn.datatables.net/1.12.1/js/jquery.dataTables.js></script>
  335. <script src="https://cdn.datatables.net/buttons/2.0.1/js/dataTables.buttons.min.js"></script>
  336. <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
  337. <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
  338. <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
  339. <script src="https://cdn.datatables.net/buttons/2.0.1/js/buttons.html5.min.js"></script>
  340. <script src="https://cdn.datatables.net/buttons/2.0.1/js/buttons.print.min.js"></script>
  341. <script src="https://cdn.datatables.net/scroller/2.0.5/js/dataTables.scroller.min.js"></script>
  342. <script src="https://cdn.datatables.net/datetime/1.1.2/js/dataTables.dateTime.min.js"></script>
  343. <!-- Inclure Popper.js -->
  344. <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.9.2/umd/popper.min.js" integrity="sha512-2rNj2KJ+D8s1ceNasTIex6z4HWyOnEYLVC3FigGOmyQCZc2eBXKgOxQmo3oKLHyfcj53uz4QMsRCWNbLd32Q1g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  345. <!-- Scripts Date Range Picker -->
  346. <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
  347. <!-- Scripts -->
  348. <script type="text/javascript" charset="utf8" src=https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js></script>
  349. <script src=https://cdn.ckeditor.com/ckeditor5/23.1.0/classic/ckeditor.js></script>
  350. <script src=https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js></script>
  351. <!-- Scripts Template -->
  352. <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  353. <script type="text/javascript" src="{{ asset('assets/scripts/main.87c0748b313a1dda75f5.js') }}"></script>
  354. <script type="text/javascript" src="{{ asset('assets/scripts/jquery.maphilight.min.js') }}"></script>
  355. <script src="https://cdn.jsdelivr.net/npm/bootstrap-modal-js/dist/bootstrap-modal-js.min.js"></script>
  356. <!-- Scripts Perso -->
  357. <script type="text/javascript">
  358.     function stripTags(html) {
  359.         return html.replace(/<[^>]*>?/gm, '');
  360.     }
  361.     // alert('Branché sur PROD, ne pas faire un test.');
  362.     $(".loader").show();
  363.     $(window).on('load', function() { $(".loader").fadeOut("2000"); });
  364.     var clickedButtons = {};
  365.     var dotLoaderDiv = document.getElementById("loader-2");
  366.     function showDotLoader(buttonClass, isMini = true) {
  367.         let buttonElement = document.querySelector(buttonClass);
  368.         let parentElement = buttonElement.parentNode;
  369.         let loader = dotLoaderDiv.cloneNode(true);
  370.         loader.style.width = buttonElement.offsetWidth + 'px';
  371.         loader.style.height = buttonElement.offsetHeight + 'px';
  372.         let buttonComputedStyle = window.getComputedStyle(buttonElement);
  373.         let buttonMarginLeft = parseInt(buttonComputedStyle.marginLeft);
  374.         let buttonMarginRight = parseInt(buttonComputedStyle.marginRight);
  375.         let buttonMarginTop = parseInt(buttonComputedStyle.marginTop);
  376.         let buttonMarginBottom = parseInt(buttonComputedStyle.marginBottom);
  377.         loader.style.margin = buttonMarginTop + 'px ' + buttonMarginRight + 'px ' + buttonMarginBottom + 'px ' + buttonMarginLeft + 'px';
  378.         if (isMini) {
  379.             loader.classList.add("mini-loader");
  380.             parentElement.replaceChild(loader, buttonElement);
  381.             clickedButtons[buttonClass] = { buttonElement: buttonElement, loader: loader };
  382.         } else {
  383.             if($(".micro-loader").length == 0) {
  384.                 let microLoader = dotLoaderDiv.cloneNode(true);
  385.                 microLoader.classList.add("micro-loader");
  386.                 buttonElement.parentNode.appendChild(microLoader);
  387.                 buttonElement.classList.add("d-none");
  388.             } else {
  389.                 $(".micro-loader").removeClass("d-none");
  390.                 buttonElement.classList.add("d-none");
  391.             }
  392.         }
  393.     }
  394.     function hideDotLoader(buttonClass, isMini = true) {
  395.         if (isMini) {
  396.             let buttonInfo = clickedButtons[buttonClass];
  397.             let parentElement = buttonInfo.loader.parentNode;
  398.             parentElement.replaceChild(buttonInfo.buttonElement, buttonInfo.loader);
  399.             delete clickedButtons[buttonClass];
  400.         } else {
  401.             let buttonElement = document.querySelector(buttonClass);
  402.             let loader = document.querySelector(".micro-loader");
  403.             loader.classList.add("d-none");
  404.             buttonElement.classList.remove("d-none");
  405.         }
  406.     }
  407.     function ValidAjax(url,data,function_return){
  408.         if (typeof function_return == 'undefined') {
  409.             function_return = false;
  410.         }
  411.         $.ajax({
  412.             url: url,
  413.             type: 'POST',
  414.             dataType:'json',
  415.             async: true,
  416.             data: { 'post': data},
  417.             success: function(response) {
  418.                 var res = response.toString().split('|');
  419.                 if(res[0] == "valide"){
  420.                     $(function() {
  421.                         toastr.success('', res[1], {positionClass: "toast-bottom-right"});
  422.                     });
  423.                 }
  424.                 else if(res[0] == "html"){
  425.                     $('#'+res[1]).html(res[3]);
  426.                     if(res[2] == 'referentiel'){
  427.                         datatable_referentiel();
  428.                     }
  429.                     else if(res[2] == 'affichage_materiel_cc'){
  430.                         affichageMaterielCc();
  431.                     }
  432.                     else if (res[2] === 'recherche'){
  433.                         retourAjaxRecherche();
  434.                     }
  435.                     if(typeof res[4] != 'undefined' && res[4] == "html"){
  436.                         $('#'+res[5]).html(res[7]);
  437.                     }
  438.                 }
  439.                 else if(res[0] == "html_append"){
  440.                     // $('#'+res[5]).html($('#'+res[5]).html() + res[7]);
  441.                     $('#'+res[1]).html($('#'+res[1]).html() + res[3]);
  442.                 }
  443.                 else if(res[0] == "no_toastr") {
  444.                     $(".loader").hide();
  445.                 }
  446.                 else {
  447.                     $(function() {
  448.                         toastr.error('', res[1], {positionClass: "toast-bottom-right"});
  449.                     });
  450.                     $(".loader").hide();
  451.                 }
  452.                 if(function_return == true){
  453.                     RetourAjax(res[2]);
  454.                 }
  455.             },
  456.             error : function(xhr, textStatus, errorThrown) {
  457.                 $(function() {
  458.                     toastr.error (errorThrown, textStatus, {positionClass: "toast-bottom-right"});
  459.                     $(".loader").hide();
  460.                     console.log(errorThrown);
  461.                     console.log(textStatus);
  462.                 });
  463.             }
  464.         });
  465.     }
  466.     /* Empecher la Soumisson d'un formulaire sous rafraichissmeent de la page (que sur le click = Submit) */
  467.     function preventFormSubmitOnPageRefresh() {
  468.         if ( window.history.replaceState ) {
  469.             window.history.replaceState( null, null, window.location.href );
  470.         }
  471.     }
  472. </script>
  473. {% block javascripts %}{% endblock %}
  474. <script>
  475.     /* Partie popover et bouton recherche */
  476.     let ariaDescribedby = "";
  477.     $('#search-icon-id').click(()=>{
  478.         if($('#search-icon-id').hasClass("open")){
  479.             $(function(){removeAttributesSearchIcon();});
  480.         }else {
  481.             $('#search-icon-id').addClass("open");
  482.             $('#search-icon-id').addClass("bg-tempting-azure");
  483.             $('#search-icon-id').attr("style", "transform: rotate(-0.25turn);");
  484.             $('#search-input-id').attr("disabled" , true);
  485.             $(function(){
  486.                 ariaDescribedby = $('#search-icon-id').attr("aria-describedby");
  487.                 let identifierPopoverElement = ariaDescribedby + "-body";
  488.                 $('.popover-body').append("<div id='loader-popover-search' class='loader' style='background-size: 95%'></div><div class='popover-body-child'><div style='width: 50px; height: 50px'></div></div>");
  489.                 $('.popover-body-child').attr("id", identifierPopoverElement);
  490.                 afficherContenuPopoverRecherche(identifierPopoverElement);
  491.             });
  492.         }
  493.     });
  494.     function removeAttributesSearchIcon(){
  495.         $('#search-icon-id').removeClass("open");
  496.         $('#search-icon-id').removeClass("bg-tempting-azure");
  497.         $('#search-icon-id').removeAttr("style");
  498.     }
  499.     $('#search-icon-close-id').click(function() {
  500.         $('#link-search-button-popover').removeAttr('href');
  501.         $('#search-input-id').val("");
  502.         if($('#search-icon-id').hasClass("open")){
  503.             $('#search-icon-id').trigger("click");
  504.         }
  505.     });
  506.     function afficherContenuPopoverRecherche(identifierPopoverElement){
  507.         ValidAjax(
  508.             "https://{{ app.request.server.get('HTTP_HOST') }}/{{ app.request.getLocale() }}/recherche/formulaire",
  509.             identifierPopoverElement,
  510.             false
  511.         );
  512.     }
  513.     function toggleSearchButtonPopover(element){
  514.         if(((element.val().trim()).length > 3) && ($('[name = search-radio]:checked').attr("id") ===
  515.             "search-radio-serial")){
  516.             $('#search-button-popover').removeAttr("disabled");
  517.         }else if(((element.val().trim()).length > 7) && ($('[name = search-radio]:checked').attr("id") ===
  518.             "search-radio-tracking")){
  519.             $('#search-button-popover').removeAttr("disabled");
  520.         }else if(element.val().trim() !== "" && $('[name = search-radio]:checked').attr("id") !==
  521.             "search-radio-tracking" && $('[name = search-radio]:checked').attr("id") !==
  522.             "search-radio-serial"){
  523.             $('#search-button-popover').removeAttr("disabled");
  524.         }else{
  525.             $('#search-button-popover').attr("disabled", true);
  526.         }
  527.     }
  528.     function retourAjaxRecherche(){
  529.         $("#loader-popover-search").hide();
  530.         if($('#search-input-id').val() !== ""){
  531.             toggleSearchButtonPopover($('#search-input-id'));
  532.         }
  533.         $('#search-input-id').removeAttr("disabled");
  534.         $('#search-input-id').focus();
  535.         $('#search-input-id').keyup(function() {
  536.             toggleSearchButtonPopover($(this));
  537.         });
  538.         $('#search-button-popover').click(function() {
  539.             let type = $('[name = search-radio]:checked').attr("id").split("-")[2];
  540.             let search = $('#search-input-id').val();
  541.             let url = "https://{{ app.request.server.get('HTTP_HOST') }}/{{ app.request.getLocale()}}/recherche/"
  542.             $('#search-input-id').attr("disabled" , true);
  543.             $('#link-search-button-popover').attr('href', (url + encodeURIComponent(type) + "/" + encodeURIComponent(search.trim())));
  544.             $('#link-search-button-popover').trigger("click");
  545.             $('#loader-popover-search').show();
  546.         });
  547.         $('#liste-client-radio-button').click(function() {
  548.             $('#search-radio-client-2').trigger("click");
  549.         });
  550.         $('#liste-client-radio-button').change(function() {
  551.             $('#search-input-id').val("");
  552.             $('#search-input-id').val($(this).val())
  553.             toggleSearchButtonPopover($('#search-input-id'));
  554.         });
  555.         $('[name = search-radio]').click(function() {
  556.             if($(this).attr("id") === 'search-radio-client-2'){
  557.                 $('#search-input-id').attr("disabled" , true);
  558.                 $('#search-input-id').off("focus");
  559.                 $('#search-input-id').val("");
  560.                 $('#search-input-id').val($('#liste-client-radio-button').val())
  561.                 toggleSearchButtonPopover($('#search-input-id'));
  562.             }else{
  563.                 $('#search-input-id').removeAttr("disabled");
  564.                 $('#search-input-id').focus();
  565.                 $('#liste-client-radio-button #default').prop("selected", "selected");
  566.                 toggleSearchButtonPopover($('#search-input-id'));
  567.             }
  568.             let id = $(this).prop('id');
  569.             $('[name = search-radio]:not(#' + id + ')').removeAttr('checked');
  570.             $('#' + id).attr('checked', 'checked');
  571.         });
  572.         $('#search-input-id').keydown(function(e){
  573.             var key = e.which;
  574.             if(key === 9){
  575.                 $(function (){$('#search-input-id').focus()});
  576.             }
  577.             if(key === 13){
  578.                 if($('#search-button-popover').attr("disabled") !== true){
  579.                     $('#search-button-popover').trigger("click")
  580.                 }
  581.             }
  582.         })
  583.         $('#search-input-id').on('paste', function(){
  584.             let element = $(this);
  585.             setTimeout(function(){
  586.                 toggleSearchButtonPopover(element)
  587.             },0);
  588.         });
  589.     }
  590.     /* Fin de la partie recherche */
  591.     function datatable_referentiel(){
  592.         let currentPage = 1;
  593.         let nombreDeResultatsParPage = 12;
  594.         let $listeReferentiel = $('#liste_referentiel');
  595.         let $listeItems = $listeReferentiel.find('.item');
  596.         function afficherPage(items, page) {
  597.             let debut = (page - 1) * nombreDeResultatsParPage;
  598.             let fin = debut + nombreDeResultatsParPage;
  599.             $listeItems.hide(); // Ocultar todos los elementos primero
  600.             items.slice(debut, fin).show(); // Mostrar solo los elementos de la página actual
  601.         }
  602.         function updatePagination(items) {
  603.             let pagination = $('<div class="paginationCustom"></div>');
  604.             let maxDisplayedPages = 5; // Nombre de pages à afficher avant et après la page courante
  605.             let nombreTotalDeResultats = items.length;
  606.             let nombreTotalDePages = Math.ceil(nombreTotalDeResultats / nombreDeResultatsParPage);
  607.             function createPageLink(page, text, active) {
  608.                 let pageLink = $('<button type="button" class="page-link"></button>').text(text).attr('data-page', page);
  609.                 if (active) {
  610.                     pageLink.addClass('active_page');
  611.                 }
  612.                 pageLink.on('click', function() {
  613.                     var page = parseInt($(this).attr('data-page'));
  614.                     currentPage = page;
  615.                     afficherPage(items, page);
  616.                     updatePagination(items);
  617.                 });
  618.                 return pageLink;
  619.             }
  620.             pagination.empty();
  621.             // Previous page link
  622.             if (currentPage > 1) {
  623.                 pagination.append(createPageLink(currentPage - 1, '{{ "btn.previous" | trans }}', false));
  624.             }
  625.             // First page
  626.             if (currentPage > 1) {
  627.                 pagination.append(createPageLink(1, 1, currentPage === 1));
  628.             }
  629.             // Ellipsis before current page
  630.             if (currentPage > maxDisplayedPages) {
  631.                 pagination.append($('<span>').text('...'));
  632.             }
  633.             // Page links around the current page
  634.             let startPage = Math.max(2, currentPage - maxDisplayedPages + 1);
  635.             let endPage = Math.min(nombreTotalDePages - 1, currentPage + maxDisplayedPages - 1);
  636.             for (let i = startPage; i <= endPage; i++) {
  637.                 pagination.append(createPageLink(i, i, currentPage === i));
  638.             }
  639.             // Ellipsis after current page
  640.             if (currentPage < nombreTotalDePages - maxDisplayedPages) {
  641.                 pagination.append($('<span>').text('...'));
  642.             }
  643.             // Last page
  644.             if (currentPage < nombreTotalDePages) {
  645.                 pagination.append(createPageLink(nombreTotalDePages, nombreTotalDePages, currentPage === nombreTotalDePages));
  646.             }
  647.             // Next page link
  648.             if (currentPage < nombreTotalDePages) {
  649.                 pagination.append(createPageLink(currentPage + 1, '{{ "btn.next" | trans }}', false));
  650.             }
  651.             // Remplacer la pagination existante par celle mise à jour
  652.             $('.paginationCustom').replaceWith(pagination);
  653.         }
  654.         function FilterCards() {
  655.             clearTimeout(timeout);
  656.             timeout = setTimeout(function() {
  657.                 const searchTerm = $('#mySearch').val().toLowerCase();
  658.                 const filteredItemsByCode = $listeItems.filter(function() {
  659.                     const codeArticle = $(this).find('.refCodeVe').text().toLowerCase();
  660.                     return codeArticle.includes(searchTerm);
  661.                 });
  662.                 const filteredItemsByModele = $listeItems.filter(function() {
  663.                     const Modele = $(this).find('.refModele').text().toLowerCase();
  664.                     return Modele.includes(searchTerm);
  665.                 });
  666.                 if (filteredItemsByCode.text().length > filteredItemsByModele.text().length) {
  667.                     filteredItems = filteredItemsByCode;
  668.                 }
  669.                 else {
  670.                     filteredItems = filteredItemsByModele;
  671.                 }
  672.                 currentPage = 1; // Reset to the first page after a new search
  673.                 afficherPage(filteredItems, currentPage);
  674.                 updatePagination(filteredItems);
  675.             }, 300);
  676.         }
  677.         let timeout = null;
  678.         $('#mySearch').on('keyup', FilterCards);
  679.         afficherPage($listeItems, currentPage);
  680.         updatePagination($listeItems);
  681.     }
  682.     $(document).ready(function() {
  683.         datatable_referentiel();
  684.     });
  685.     function choixMateriel(id, typeRefCC) {
  686.         if (typeof typeRefCC == undefined) {
  687.             typeRefCC = null;
  688.         }
  689.         let idSplit = id.split('_')[1];
  690.         //Si c'est le popup CC materiel
  691.         if (typeRefCC != null && typeRefCC == true) {
  692.             let saveMatOld = $('#materiel_popup_choisi').val();
  693.             //Si c'est vide, on fait un reset
  694.             if (saveMatOld != '' && $('#materiel_popup_choisi').val() != idSplit) {
  695.                 $('#mat_' + saveMatOld).val('');
  696.                 $('#qty_mat_' + saveMatOld).val('');
  697.                 $('#qty_block_' + saveMatOld).hide();
  698.             }
  699.             //On sauvegarde l'element selectioné
  700.             $('#materiel_popup_choisi').val(idSplit);
  701.             //On affiche le block
  702.             $('#qty_block_' + idSplit).show();
  703.         }
  704.         $('#mat_selectionne').val(id.replace('td_', ''));
  705.         $('.td_referentiel').css({'background': 'none'});
  706.         $('#' + id).css({'background-color': '#96c574'});
  707.         let idRef = id.split('_')[1];
  708.         $('.refCodeVe').css({'color': '#ff9c5b'})
  709.         $('.refModele').css({'color': '#2385c3'})
  710.         $("#card-title-referentiel-" + idRef).css({'color': '#ffffff'})
  711.         $("#card-text-referentiel-" + idRef).css({'color': '#ffffff'})
  712.     }
  713.     function ValidechoixMateriel(){
  714.         var dest = $('#destination_selection').val();
  715.         var mat =  $('#mat_selectionne').val();
  716.         var nom_mat =  $('#nom_mat_'+mat).val();
  717.         if($('#inPopup').val() != '' && $('#inPopup').val() == 'true') {
  718.             choixMaterielStd(mat);
  719.         }
  720.         else {
  721.             $('#ref_mat_'+dest).val(mat).trigger('change');
  722.             $('#em_'+dest).html(nom_mat);
  723.             $('#em_'+dest).css('color','#5bc0de');
  724.         }
  725.     }
  726.     function InfoPanneModal(val){
  727.         $('#td_panne_16_autre').hide();
  728.         $('#td_panne_43_autre').hide();
  729.         $('#td_panne_16_autre').val("");
  730.         $('#td_panne_43_autre').val("");
  731.         $('.list_choix_panne').css({'background': 'none', 'color': '#0099ff'});
  732.         $('#destination_panne_selection').val(val);
  733.         var val_panne = $('#type_panne_'+val).val();
  734.         var liste_panne = "";
  735.         var pannes = val_panne.split('|');
  736.         for(var i=0;i<pannes.length;i++){
  737.             if(pannes[i] != ""){
  738.                 if(pannes[i].indexOf('*_*') > -1){
  739.                     var autrePb =  pannes[i].split('*_*');
  740.                     liste_panne += "td_panne_" + autrePb[0] + '|';
  741.                     $('#td_panne_' + autrePb[0]).css({'background-color': '#007bff', 'color': '#fff'});
  742.                     if($('#td_panne_' + autrePb[0] + '_autre').length){
  743.                         $('#td_panne_' + autrePb[0] + '_autre').val(autrePb[1]);
  744.                         $('#td_panne_' + autrePb[0] + '_autre').show();
  745.                     } else {
  746.                         $('#td_panne_' + autrePb[0]).html($('#td_panne_' + autrePb[0]).html() + '<input type="text" id="td_panne_' + autrePb[0]+'_autre" value="'+autrePb[1]+'"/>');
  747.                     }
  748.                 } else {
  749.                     liste_panne += "td_panne_" + pannes[i] + '|';
  750.                     $('#td_panne_' + pannes[i]).css({'background-color': '#007bff', 'color': '#fff'});
  751.                 }
  752.             }
  753.         }
  754.         $('#panne_selectionne').val(liste_panne);
  755.     }
  756.                     function choixPanne(id, draggable){
  757.                         if(typeof draggable == undefined) {
  758.                             draggable = null;
  759.                         }
  760.                         var panne =  $('#panne_selectionne').val();
  761.                         //Si on clique sur autre
  762.                         if(id == 'td_panne_16' || id == 'td_panne_43') {
  763.                             //Si on n'a pas encore cliqué sur autre, alors on insert le texte champ
  764.                             if(!$('#' + id).attr('data-clique')) {
  765.                                 if(id == 'td_panne_16'){
  766.                                     $('#' + id).attr('data-clique', 'td_16_changee');
  767.                                 } else {
  768.                                     $('#' + id).attr('data-clique', 'td_43_changee');
  769.                                 }
  770.                                 if($('#td_panne_' + id + '_autre').length == 0){
  771.                                     $('#' + id).html($('#' + id).html() + '<input type="text" id="'+ id +'_autre" />');
  772.                                 }
  773.                             }
  774.                         }
  775.                         //Si le draggable est true, alors on sort du fonction pour ne pas sélectionner les éléments
  776.                         if(draggable != null) {
  777.                             return true;
  778.                         }
  779.                         //Code qui va bloquer la cloque sur le champ autre problème (pour ne pas fermer)
  780.                         $('#'+id + '_autre').click(function (event) {
  781.                             return false;
  782.                         });
  783.                         if(panne.indexOf(id+'|') > -1){
  784.                             $('#panne_selectionne').val(panne.replace(id+'|',''));
  785.                             $('#'+id).css({'background': 'none', 'color': '#0099ff'});
  786.                             $('#'+id + '_autre').hide();
  787.                         }
  788.                         else {
  789.                             $('#panne_selectionne').val(panne+id+'|');
  790.                             $('#'+id).css({'background-color': '#007bff', 'color': '#fff'});
  791.                             $('#'+id + '_autre').show();
  792.                         }
  793.                     }
  794.                     function ValideChoixPanne(){
  795.                         var dest = $('#destination_panne_selection').val();
  796.                         var pannes =  $('#panne_selectionne').val().split('|');
  797.                         var pannes_value = "";
  798.                         var pannes_text = "";
  799.                         var text = "";
  800.                         for(var i=0;i<pannes.length;i++){
  801.                             if(pannes[i] != "") {
  802.                                 //Si on a sélectionné un autre problème, alors on récupère depuis ce champ
  803.                                 if(pannes[i] == "td_panne_16" || pannes[i] == "td_panne_43") {
  804.                                     text = $('#' + pannes[i] + '_autre').val()
  805.                                     pannes_text +=text + " ";
  806.                                     pannes_value += pannes[i].replace('td_panne_', '') + '*_*'+text+'|';
  807.                                 }
  808.                                 else {
  809.                                     pannes_value += pannes[i].replace('td_panne_', '') + '|';
  810.                                     pannes_text += $('#' + pannes[i]).text() + " ";
  811.                                 }
  812.                             }
  813.                         }
  814.                         if(pannes_text == ""){
  815.                             pannes_text = "{{ 'type_panne'|trans }}";
  816.                         }
  817.                         if(pannes_text == ' ') {
  818.                             pannes_text = "{{ 'pas_de_panne'|trans }}";
  819.                         }
  820.                         $('#type_panne_'+dest).val(pannes_value);
  821.                         $('#em_panne_'+dest).html(pannes_text);
  822.                         $('.list_choix_panne').css({'background': 'none', 'color': '#0099ff'});
  823.                         $('#destination_panne_selection').val('');
  824.                         $('#panne_selectionne').val('');
  825.                     }
  826.                     function UploadFile(name_input_file,destination,reference,name_progess,name_visu,name_del,name_link, fileDrop, mimeTypes, hiddenField, fileNameCustom, isCustomName, displayToast){
  827.                         if (typeof name_progess == 'undefined') {
  828.                             name_progess = null;
  829.                         }
  830.                         if (typeof name_visu == 'undefined') {
  831.                             name_visu = null;
  832.                         }
  833.                         if (typeof name_del == 'undefined') {
  834.                             name_del = null;
  835.                         }
  836.                         if (typeof name_link == 'undefined') {
  837.                             name_link = null;
  838.                         }
  839.                         if (typeof fileDrop == 'undefined') {
  840.                             fileDrop = null;
  841.                         }
  842.                         if (typeof mimeTypes == 'undefined' || mimeTypes == null) {
  843.                             mimeTypes = {
  844.                                 'image/jpeg': '.jpg, .jpeg',// Par défaut
  845.                             };
  846.                         }
  847.                         if (typeof hiddenField == 'undefined') {
  848.                             hiddenField = null;
  849.                         }
  850.                         if (typeof fileNameCustom == 'undefined' || fileNameCustom == '') {
  851.                             fileNameCustom = null;
  852.                         }
  853.                         if (typeof isCustomName == 'undefined' || isCustomName == '') {
  854.                             isCustomName = false;
  855.                         }
  856.                         if (typeof displayToast == 'undefined' || displayToast == '') {
  857.                             displayToast = true;
  858.                         }
  859.                         // Si fileDrop ne pas null, ça veut dire qu'on utilise le drag and drop
  860.                         let files = null;
  861.                         if(fileDrop !== null) {
  862.                             files = fileDrop;
  863.                         }else {
  864.                             files = document.querySelector('#'+name_input_file).files;
  865.                         }
  866.                         //On fait une boucle pour parcourire les fichiers (si multiple)
  867.                         let filesData = {};
  868.                         $.each(files, (key, file) => {
  869.                             if(Object.keys(mimeTypes).indexOf(file.type) != -1) {
  870.                                 //Nommage fichier
  871.                                 let time = Date.now(); // Unique time
  872.                                 let fileName = file.name.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~ ]/g, "_");
  873.                                 let nomDuFichier = fileName.replace(/_([^_]*)$/, ".$1"); // Pour avoir un point avant l'extension
  874.                                 let nomDuFichierWithoutExt = nomDuFichier.split('.')[0] + '_' + time;
  875.                                 let fileExtension = nomDuFichier.split('.')[1];
  876.                                 nomDuFichierWithoutExt = nomDuFichierWithoutExt.toLowerCase();
  877.                                 nomDuFichier = nomDuFichierWithoutExt + '.' + fileExtension;
  878.                                 let nomDuFichier_ = nomDuFichier.replace(/\./g, '_');
  879.                                 //Si hiddenField existe, par la suite possibilité de faire dynamiquement
  880.                                 if(hiddenField != null) {
  881.                                     filesData[nomDuFichier] = nomDuFichier;
  882.                                     $('#'+ hiddenField).html($('#'+ hiddenField).html() + '<span id="item_img_'+ nomDuFichier_ +'"><a a href="/uploads/'+ destination +'/'+ nomDuFichier +'" class="mr-2" target="_blank">'+ nomDuFichier +'</a><a href="#step-5" id="pieceJointeSuppBtn" onclick="pieceJointeSuppBtn(\''+nomDuFichier_+'\')"><i class="pe-7s-trash"> </i></a></span>');
  883.                                 }
  884.                                 // upload file now
  885.                                 let data = new FormData();
  886.                                 //If we use a custom filename
  887.                                 if(fileNameCustom != null) {
  888.                                     nomDuFichierWithoutExt = fileNameCustom;
  889.                                 }
  890.                                 // file selected by the user
  891.                                 data.append('file', file);
  892.                                 data.append('dst',destination);
  893.                                 if(isCustomName) {
  894.                                     data.append('ref',fileName.replace(/_[^_]+$/, ''));
  895.                                 } else {
  896.                                     data.append('ref',nomDuFichierWithoutExt);
  897.                                 }
  898.                                 let request = new XMLHttpRequest();
  899.                                 request.open('POST', '/{{ app.request.locale }}/upload');
  900.                                 if(name_progess !== null) {
  901.                                     $('#'+ name_progess +'progress-box').css('display', 'block');
  902.                                     $('#'+ name_progess +'progress_bar_percent').attr('class', "progress-bar progress-bar-animated bg-info progress-bar-striped");
  903.                                     // upload progress event
  904.                                     request.upload.addEventListener('progress', function(e) {
  905.                                         let percent_complete = Math.round((e.loaded / e.total)*100);
  906.                                         // percentage of upload completed
  907.                                         $('#'+ name_progess +'progress_bar_percent').attr('aria-valuenow', percent_complete).css('width', percent_complete+'%');
  908.                                         if(percent_complete === 100){
  909.                                             $('#'+ name_progess +'progress_bar_percent').attr('class', "progress-bar progress-bar-animated bg-success progress-bar-striped");
  910.                                             $('#'+ name_progess +'progress-box').fadeOut( 3000, function() {
  911.                                                 $(this).css('display', 'none');
  912.                                                 $('#'+ name_progess +'progress_bar_percent').attr('aria-valuenow', 0).css('width', '0%');
  913.                                             });
  914.                                         }
  915.                                     });
  916.                                 }
  917.                                 // AJAX request finished event
  918.                                 request.addEventListener('load', function(e) {
  919.                                     // HTTP status message
  920.                                     const response = JSON.parse(request.response);
  921.                                     if(request.status === 200){
  922.                                         if(displayToast == false) {
  923.                                             toastr.success ('',response[0], {positionClass: "toast-bottom-right"});
  924.                                         }
  925.                                         //Reactivate the Save button CC
  926.                                         $('#facturation_form_btn_update').prop('disabled', false);
  927.                                         if(name_visu !== null) {
  928.                                             $("#"+name_visu).css('display', 'block');
  929.                                         }
  930.                                         if(name_del !== null) {
  931.                                             $("#"+name_del).css('display', 'block');
  932.                                         }
  933.                                         if(name_link !== null) {
  934.                                             $("#"+name_link).attr('href', response[1]);
  935.                                         }
  936.                                     } else {
  937.                                         toastr.error ('',response[0], {positionClass: "toast-bottom-right"});
  938.                                     }
  939.                                 });
  940.                                 // send POST request to server side script
  941.                                 request.send(data);
  942.                             }
  943.                             else {
  944.                                 $('#param-livraison-upload-error').html('{{ "message.format_fichier_non_valide"|trans }}<br>{{ "message.format_fichier_non_valide_format_accepte"|trans }} ' + Object.values(mimeTypes).join(', '));
  945.                                 $("#param-livraison-upload-file h5").html('{{ "cc_param_livraison_fichier_drag_and_drop1"|trans }}<br>{{ "ou"|trans }}<br>{{ "cc_param_livraison_fichier_drag_and_drop2"|trans }}');
  946.                                 setTimeout(function(){
  947.                                     $('#param-livraison-upload-error').hide();
  948.                                 }, 10000);
  949.                             }
  950.                         });
  951.                         return filesData;
  952.                     }
  953.                     function DeleteUploadFile(dst,ref,name_visu,name_del,name_link){
  954.                         // user has not chosen any file
  955.                         if(!confirm("{{ "message.confirmationsuppression"|trans }}")) {
  956.                             return false;
  957.                         } else {
  958.                             let data = new FormData();
  959.                             data.append('dst',dst);
  960.                             data.append('ref',ref);
  961.                             let request = new XMLHttpRequest();
  962.                             request.open('POST', '/{{ app.request.locale }}/delupload');
  963.                             // AJAX request finished event
  964.                             request.addEventListener('load', function(e) {
  965.                                 // HTTP status message
  966.                                 const response = JSON.parse(request.response);
  967.                                 if(request.status === 200){
  968.                                     toastr.success ('',response[0], {positionClass: "toast-bottom-right"});
  969.                                     $("#"+name_visu).css('display', 'none');
  970.                                     $("#"+name_del).css('display', 'none');
  971.                                     $("#"+name_link).attr('href', "");
  972.                                 } else {
  973.                                     toastr.error ('',response[0], {positionClass: "toast-bottom-right"});
  974.                                 }
  975.                             });
  976.                             // send POST request to server side script
  977.                             request.send(data);
  978.                             return true;
  979.                         }
  980.                     }
  981.                     /*
  982.                         Code JS pour e commande client matériel
  983.                     */
  984.                     function affichageMaterielCc()
  985.                     {
  986.                         //Revendeur
  987.                         $('#table_produits_revendeur').DataTable({
  988.                             "bLengthChange" : false,
  989.                             "bInfo": false,
  990.                             "pageLength": 10,
  991.                             "ordering": false,
  992.                             "drawCallback": function() {
  993.                                 $("#table_produits_revendeur thead").remove();
  994.                             }
  995.                         });
  996.                         $('#table_produits_revendeur_filter input[type=search]').addClass('form-control mt-2').attr('style', 'width: 500px;');
  997.                         $('#table_produits_revendeur_filter label').addClass('produit_recherche');
  998.                         //Planet
  999.                         $('#table_produits_planet').DataTable({
  1000.                             "bLengthChange" : false,
  1001.                             "bInfo": false,
  1002.                             "pageLength": 10,
  1003.                             "ordering": false,
  1004.                             "drawCallback": function() {
  1005.                                 $("#table_produits_planet thead").remove();
  1006.                             }
  1007.                         });
  1008.                         $('#table_produits_planet_filter input[type=search]').addClass('form-control mt-2').attr('style', 'width: 500px;');
  1009.                         $('#table_produits_planet_filter label').addClass('produit_recherche');
  1010.                     }
  1011.                     function desactiveEntrer(e){
  1012.                         if (e.keyCode == 13) {
  1013.                             return false;
  1014.                         }
  1015.                     }
  1016.                     function getDateDifference(){
  1017.                         let d1 = $('#cc_update_status_form_dateDebut').val();
  1018.                         let splitDate1 = d1.split('-');
  1019.                         let day1 = splitDate1[2];
  1020.                         let month1 = splitDate1[1];
  1021.                         let year1 = splitDate1[0];
  1022.                         let d2 = $('#cc_update_status_form_dateFin').val();
  1023.                         let splitDate2 = d2.split('-');
  1024.                         let day2 = splitDate2[2];
  1025.                         let month2 = splitDate2[1];
  1026.                         let year2 = splitDate2[0];
  1027.                         let calculateDayDifference = (day2 - day1);
  1028.                         let calculateMonthDifference = (month2 - month1);
  1029.                         let calculateYearDifference = (year2 - year1);
  1030.                         if(calculateMonthDifference > 3 && calculateDayDifference === 0) {
  1031.                             alert("La période de recherche ne doit pas dépasser 3 mois");
  1032.                             return false;
  1033.                         } else if (calculateYearDifference == 1 && calculateMonthDifference > 3) {
  1034.                             alert("La période de recherche ne doit pas dépasser 3 mois");
  1035.                             return false;
  1036.                         } else if (calculateYearDifference > 2) {
  1037.                             alert("La période de recherche ne doit pas dépasser 3 mois");
  1038.                             return false;
  1039.                         } else if (calculateMonthDifference >= 3 && calculateDayDifference >= 1) {
  1040.                             alert("La période de recherche ne doit pas dépasser 3 mois");
  1041.                             return false;
  1042.                         } else {
  1043.                             $('#cc_update_status_form').submit();
  1044.                         }
  1045.                     }
  1046.                     /*
  1047.                         Code pour afficher/masquer le tableau type panne
  1048.                      */
  1049.                     function checkboxPasDePanne()
  1050.                     {
  1051.                         $('#choix_mat_table').hide();
  1052.                         $("#type_panne_pas_de_panne").change(function() {
  1053.                             if(this.checked) {
  1054.                                 $('#choix_mat_table').hide();
  1055.                                 $('#panne_selectionne').val('td_panne_44');
  1056.                             }
  1057.                             else {
  1058.                                 $('#choix_mat_table').show();
  1059.                                 $('#panne_selectionne').val('');
  1060.                             }
  1061.                         });
  1062.                     }
  1063.                     function imprimer(event){
  1064.                         if($('#print_authorisation').html() == "false") {
  1065.                             alert("Vous n'avez pas le droit d'imprimer cette étiquette");
  1066.                             event.preventDefault();
  1067.                         } else {
  1068.                             var stock = $("#stock").html();
  1069.                             var modele = $("#material").html();
  1070.                             var serial = $("#serial").html();
  1071.                             var etat = $("#state").html();
  1072.                             let post = "type=btn_print";
  1073.                             post += "&stock="+stock;
  1074.                             post += "&modele="+modele;
  1075.                             post += "&serial="+serial;
  1076.                             post += "&etat="+etat;
  1077.                             ValidAjax('{{ app.request.uri }}', post, true);
  1078.                             event.preventDefault();
  1079.                         }
  1080.                     }
  1081.                     function datatableExportBtn(type, customizeOptions)
  1082.                     {
  1083.                         if (typeof type == 'undefined') {
  1084.                             type = 'csv';
  1085.                         }
  1086.                         let baseOptions = {
  1087.                             "extend": type,
  1088.                             "text": '<img src="/images/excel.png" alt="Logo" />',
  1089.                             "fieldSeparator": ';',
  1090.                             "className": 'btn_export_datatable',
  1091.                             "exportOptions": {
  1092.                                 "format": {
  1093.                                     "header": function (data) {
  1094.                                         data = data.replace(/<[^>]+>/g, '');
  1095.                                         data = data.trim().replace(/\s+/g, ' ');
  1096.                                         return data;
  1097.                                     },
  1098.                                     "body": function (data) {
  1099.                                         data = data.replace(/<[^>]+>/g, '');
  1100.                                         data = data.trim().replace(/\s+/g, ' ');
  1101.                                         return data;
  1102.                                     }
  1103.                                 }
  1104.                             }
  1105.                         };
  1106.                         if (typeof customizeOptions === 'function') {
  1107.                             var additionalOptions = customizeOptions();
  1108.                             $.extend(true, baseOptions, additionalOptions);
  1109.                         }
  1110.                         return [baseOptions];
  1111.                     }
  1112.                     function togglePasswordVisibility(inputId) {
  1113.                         var inputField = $('#' + inputId);
  1114.                         if (inputField.attr('type') === 'password') {
  1115.                             inputField.attr('type', 'text');
  1116.                             $('#toggle-visibility-span').attr('title', '{{ 'hide_password'|trans }}');
  1117.                             $('#login-form-password-icon').removeClass('fa-eye').addClass('fa-eye-slash');
  1118.                         } else {
  1119.                             inputField.attr('type', 'password');
  1120.                             $('#toggle-visibility-span').attr('title', '{{ 'show_password'|trans }}');
  1121.                             $('#login-form-password-icon').removeClass('fa-eye-slash').addClass('fa-eye');
  1122.                         }
  1123.                     }
  1124.                     function toggleConfirmPasswordVisibility(inputId2) {
  1125.                         var inputField2 = $('#' + inputId2);
  1126.                         if(inputField2.attr('type') === 'password') {
  1127.                             inputField2.attr('type', 'text');
  1128.                             $('#toggle-visibility-span-2').attr('title', '{{ 'hide_password'|trans }}');
  1129.                             $('#login-form-password-icon-2').removeClass('fa-eye').addClass('fa-eye-slash');
  1130.                         } else {
  1131.                             inputField2.attr('type', 'password');
  1132.                             $('#toggle-visibility-span-2').attr('title', '{{ 'show_password'|trans }}');
  1133.                             $('#login-form-password-icon-2').removeClass('fa-eye-slash').addClass('fa-eye');
  1134.                         }
  1135.                     }
  1136.                 </script>
  1137.                 <style>
  1138.                     .scrollable-line {
  1139.                         display: inline-block;
  1140.                         white-space: nowrap;
  1141.                         overflow: hidden;
  1142.                         text-overflow: ellipsis;
  1143.                     }
  1144.                     .scrollable-line:hover > a > span, .one-line:focus > a > span {
  1145.                         display: inline-block;
  1146.                         animation-name: scroll-text;
  1147.                         animation-duration: 7s;
  1148.                         animation-timing-function: linear;
  1149.                         animation-delay: 0s;
  1150.                         animation-iteration-count: infinite;
  1151.                         animation-direction: normal;
  1152.                     }
  1153.                     @keyframes scroll-text {
  1154.                         0% {
  1155.                             transform: translateX(0%);
  1156.                         }
  1157.                         90% {
  1158.                             transform: translateX(-50%);
  1159.                         }
  1160.                         95% {
  1161.                             transform: translateX(0%);
  1162.                         }
  1163.                         100% {
  1164.                             transform: translateX(0%);
  1165.                         }
  1166.                     }
  1167.                     .client-data:hover{
  1168.                         cursor: pointer;
  1169.                     }
  1170.                     .choix_liste_td td{
  1171.                         color: #0099ff;
  1172.                         text-align:center;
  1173.                         font-size:9pt;
  1174.                     }
  1175.                     .choix_liste_td td:hover{
  1176.                         background-color: #007bff;
  1177.                         color: #fff;
  1178.                         cursor: pointer;
  1179.                     }
  1180.                     /* Table des installations Clients */
  1181.                     .tableFixHead{
  1182.                         overflow: auto;
  1183.                         height: 100px;
  1184.                     }
  1185.                     .tableFixHead thead th {
  1186.                         position: sticky; top: 0;
  1187.                         z-index: 1;
  1188.                         background: white;
  1189.                         font-size: 12px;
  1190.                     }
  1191.                     #no_install{
  1192.                         font-weight: bolder;
  1193.                         color: red;
  1194.                     }
  1195.                     /* HIDE RADIO */
  1196.                     .contact_choix {
  1197.                         position: absolute;
  1198.                         opacity: 0;
  1199.                         width: 0;
  1200.                         height: 0;
  1201.                     }
  1202.                     /* IMAGE STYLES */
  1203.                     .contact_choix + img {
  1204.                         cursor: pointer;
  1205.                     }
  1206.                     /* CHECKED STYLES */
  1207.                     .selected + img {
  1208.                         border: 2px solid #73AD21;
  1209.                         border-radius: 25px;
  1210.                     }
  1211.                     .btn-etat:hover {
  1212.                         background: #3ac47d;
  1213.                         color:white;
  1214.                     }
  1215.                     /* Faire Apparaitre le commentaire du Tech sur Hover de la ligne ATT_HISTORIQUE */
  1216.                     .tooltip .tooltiptext {
  1217.                         visibility: hidden;
  1218.                     }
  1219.                     .tooltip:hover .tooltiptext {
  1220.                         visibility: visible;
  1221.                     }
  1222.                     /* Etat Btn Cloture ATT */
  1223.                     .selected-cloture-att{
  1224.                         background-color: #3ac47d;
  1225.                         color:white;
  1226.                     }
  1227.                     /* Style de la Table ATT HISTORIQUE */
  1228.                     .table_att_historique th, .table_att_historique td {
  1229.                         font-size: 12px;
  1230.                     }
  1231.                     .table_att_liste th, .table_att_liste td {
  1232.                         font-size: 12px;
  1233.                     }
  1234.                     .table_att_historique{
  1235.                         border-left: 6px solid #2d87c3;
  1236.                     }
  1237.                     .table_att_liste{
  1238.                         border-left: 6px solid #009800;
  1239.                     }
  1240.                     /* Style de la Table ETAT CLOTURE */
  1241.                     .table_etat_att th, .table_etat_att td {
  1242.                         font-size: 14px;
  1243.                     }
  1244.                     /* Style de la Table Retour SEARCH_CLIENT */
  1245.                     #table_result_search_client th, #table_result_search_client td{
  1246.                         font-size: 12px;
  1247.                     }
  1248.                 </style>
  1249.         {% block modal %}
  1250.         {% endblock %}
  1251.         </body>
  1252. </html>