Codifarticle AJAX with fetch

frontend.js.utils.js

  1// utils.js
  2// Fonctions utilitaires Javascript
  3//
  4// - https://flaviocopes.com/javascript-let-const/
  5// - https://gdevops.gitlab.io/tuto_javascript/reference/instructions/const/const.html
  6// - https://gdevops.gitlab.io/tuto_javascript/reference/promise/flaviocopes.com/flaviocopes.com.html
  7// - https://gdevops.gitlab.io/tuto_web/html/apis/document/methods/getElementById/getElementById.html
  8// - https://gdevops.gitlab.io/tuto_web/html/apis/fetch/fetch.html
  9//
 10export function id3_toggle_classes(element) {
 11  if (element.title === "Write") {
 12    element.title = "Preview";
 13    element.classList.remove("fa-pencil");
 14    element.classList.add("fa-eye");
 15  } else {
 16    element.title = "Write";
 17    element.classList.remove("fa-eye");
 18    element.classList.add("fa-pencil");
 19  }
 20}
 21
 22export function increment_update() {
 23  const id_ajax_call = document.getElementById("id_nb_ajax_call");
 24  if (id_ajax_call === null) {
 25      return;
 26  }
 27
 28  let a = Number(id_ajax_call.innerText);
 29  a = a + 1;
 30  id_ajax_call.innerText = a;
 31}
 32
 33export function build_url_with_parameters(i_url, parameters) {
 34  //
 35  // let parameters = {'id': codifnomenclature_id,'demande_codification': demande_codification};
 36  //
 37  // Exemple d'url: "/articles/ajax/codif_nomenclature_update?id=398&besoin_reel=51";
 38  //
 39  let base_url = new URL("http://bidon");
 40  Object.keys(parameters).forEach((key) =>
 41    base_url.searchParams.append(key, parameters[key])
 42  );
 43
 44  let url = i_url + base_url.search;
 45  return url;
 46}
 47
 48export function display_parameters(parameters) {
 49  //
 50  // let parameters = {'id': 6,'demande_codification': 78};
 51  //
 52  Object.keys(parameters).forEach((key) =>
 53    console.log(`key=${key} parameter=${parameters[key]}`)
 54  );
 55}
 56
 57
 58export function update_demande(url) {
 59    const etat_demande = document.getElementById('id_etat_demande').value;
 60    const id_demande_article = document.getElementById('id_demande_article').textContent;
 61    const widget = document.getElementById('id_send_email');
 62    const send_email = widget.checked;
 63    const parameters = { 'id_demande_article': id_demande_article,  'etat_demande': etat_demande, 'send_email': send_email};
 64    const url_param = build_url_with_parameters(url, parameters);
 65    try {
 66        fetch(url_param);
 67        increment_update();
 68    } catch (error) {
 69        console.error(error);
 70    }
 71}
 72
 73export function update_iframe_description_demande(url, libelles_description)
 74{
 75    const iframe_description_demande = document.getElementById('id_description_iframe');
 76    // Le texte HTML issu du iframe id_description_iframe
 77    const editables = iframe_description_demande.contentDocument.getElementsByClassName('note-editable');
 78    if (editables.length > 0) {
 79        const editable = editables[0];
 80        const description = editable.innerHTML;
 81        const id_demande_article = document.getElementById('id_demande_article').textContent;
 82        console.log(`id_demande_article=${id_demande_article} description=${description}`);
 83        const widget = document.getElementById('id_send_email');
 84        const send_email = widget.checked;
 85
 86        const parameters = {'id_demande_article': id_demande_article,'description': description,'send_email': send_email};
 87        const url_param = build_url_with_parameters(url, parameters);
 88        fetch(url_param).then(response => response.json()).then(json => {
 89            increment_update();
 90            libelles_description.forEach(function(libelle, index, array) {
 91                libelle.textContent = json.libelle_description;
 92            });
 93        });
 94    }
 95}
 96
 97export function update_summernote(url, editables, map_parameters, key_data) {
 98    if (editables.length > 0) {
 99        const editable = editables[0];
100        const new_data = editable.innerHTML;
101        map_parameters.set(key_data, new_data);
102        const parameters =  Object.fromEntries(map_parameters);
103        const url_param = build_url_with_parameters(url, parameters);
104        fetch(url_param).then(response => response.json()).then(json => {
105            increment_update();
106        });
107    };
108}
109
110
111export function id3_fetch(url, parameters) {
112    // https://gdevops.gitlab.io/tuto_javascript/reference/promise/flaviocopes.com/flaviocopes.com.html
113    // chaining of promises
114    const url_param = build_url_with_parameters(url, parameters);
115    const promise = fetch(url_param)
116    .then(response => response.json())
117    .then(json => {
118        increment_update();
119        return Promise.resolve(json);
120    });
121    return promise;
122}
123
124export function get_temps_impute(temps_impute) {
125    //  Par defaut un intervalle est de type HH:MM:SS => on concatene ':00'
126    let nb_tokens = temps_impute.split(':').length;
127    if (nb_tokens === 1) {
128      temps_impute = temps_impute.concat(':00:00');
129    }
130    if (nb_tokens === 2) {
131      temps_impute = temps_impute.concat(':00');
132    }
133    // Cas de l'emploi de la virgule
134    nb_tokens = temps_impute.split(',').length
135    if (nb_tokens === 2) {
136      //  de cette façon on a le meme comportement qu'avec le "." ce qui est très bien
137      temps_impute = tokens[0] + '.' + tokens[1];
138    }
139
140    console.log(`temps_impute=${temps_impute}`);
141    return temps_impute;
142}

articles.templates.articles.demande.achat_service.articles_update.html

  1{% extends "base.html" %}
  2{% load static %}
  3{% load article %}
  4{% load markdown_extras %}
  5
  6{% block stylesheet %}
  7    <link rel="stylesheet" href="{% static 'css/couleurs_demande_article.css' %}">
  8    <!-- CSS pour datetime picker -->
  9    <link rel="stylesheet" href="{% static 'js/jquery.datetimepicker.min.css' %}">
 10
 11    <!-- CSS pour autocomplete_light -->
 12    <link rel="stylesheet" href="{% static 'select2/css/select2.css' %}">
 13    <link rel="stylesheet" href="{% static 'autocomplete_light/select2.css' %}">
 14
 15    <!-- Bordure des tables -->
 16    <link rel="stylesheet" href="{% static 'css/table.css' %}">
 17{% endblock  %}
 18
 19
 20{% block javascript %}
 21    {# a employer dans les templates fils->{{ block.super }} #}
 22    {{ block.super }}
 23
 24    <!-- datetime picker jQuery script -->
 25    <script src="{% static 'js/jquery.datetimepicker.full.js' %}"></script>
 26
 27    <!-- Javascript for autocomplete_light -->
 28    <script src="{% static 'autocomplete_light/jquery.init.js' %}"></script>
 29    <script src="{% static 'autocomplete_light/autocomplete.init.js' %}"></script>
 30    <script src="{% static 'select2/js/select2.full.js' %}"></script>
 31    <script src="{% static 'autocomplete_light/forward.js' %}"></script>
 32    <script src="{% static 'autocomplete_light/select2.js' %}"></script>
 33
 34    <script type="module">
 35        import { increment_update, build_url_with_parameters, update_demande } from '{% static 'js/utils.js' %}';
 36        import { update_iframe_description_demande, update_summernote, id3_fetch } from '{% static 'js/utils.js' %}';
 37
 38        window.increment_update = increment_update;
 39        window.build_url_with_parameters = build_url_with_parameters;
 40        window.update_demande = update_demande;
 41        window.update_iframe_description_demande = update_iframe_description_demande;
 42        window.update_summernote = update_summernote;
 43        window.id3_fetch = id3_fetch;
 44    </script>
 45
 46{% endblock javascript %}
 47
 48{% block extra_js %}
 49{# Code composé de Javascript et de Django Template Language #}
 50{# ========================================================= #}
 51
 52<script type="module">
 53
 54function trt_date_butoir() {
 55    // langue française
 56    $.datetimepicker.setLocale('fr');
 57
 58    {% for form_codif_article in formset_codif_articles %}
 59        {# Choix de la livraison souhaitée #}
 60        $('#id_codifarticle_related-{{ forloop.counter0 }}-date_butoir').datetimepicker(
 61            {
 62                // http://marcocecchetti.it/Post/Articolo/608
 63                weeks: true,
 64                rtl: false,
 65                // formatTime:'H:i',
 66                // formatDate:'d/m/Y',
 67                format: 'd/m/Y H:i',
 68                // date
 69                datepicker: true,
 70                opened: false,
 71                todayButton: true,     // Show button "Go To Today"
 72                defaultSelect:  true,  // Highlight the current date even if the input is empty
 73                dayOfWeekStart : 1, // Start week DatePicker. Default Sunday=0.
 74                defaultDate: false,
 75                // https://secure.php.net/manual/fr/function.date.php
 76                minDate:0,    // today
 77                weekends : [],
 78                disabledDates : [],
 79                // time
 80                timepicker:true,
 81                timepickerScrollbar:true,
 82                step: 60,
 83                defaultTime:'10:00',
 84                allowTimes:[
 85                  '8:00', '9:00', '10:00', '11:00', '12:00',
 86                  '13:00', '14:00', '15:00', '16:00', '17:00',
 87                  '18:00', '19:00'
 88                ]
 89            }
 90        );
 91
 92    {% endfor %}
 93
 94}
 95
 96document.addEventListener('DOMContentLoaded', (event) => {
 97    // https://gdevops.gitlab.io/tuto_web/html/apis/document/events/DOMContentLoaded_event/DOMContentLoaded_event.html
 98    console.log('DOM is loaded');
 99    console.log(`document.readyState = ${document.readyState}`);
100
101    trt_date_butoir();
102});
103
104function trt_widgets() {
105    console.log(`trt_widgets() document.readyState = ${document.readyState}`);
106    document.getElementById('id_etat_demande').onchange = function() {
107        const url = '{% url "articles:ajax_update_demande_article" %}';
108        update_demande(url);
109    }
110    const url = '{% url "articles:ajax_update_codif_article" %}';
111    let codifarticle_id = 0;
112    {% for form_codif_article in formset_codif_articles %}
113        codifarticle_id = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-id').value;
114        const parameters_{{ forloop.counter0 }} = {'id': codifarticle_id};
115        try {
116            document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-etat_poste').onchange = function() {
117                parameters_{{ forloop.counter0 }}.etat_poste = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-etat_poste').value;
118                id3_fetch(url, parameters_{{ forloop.counter0 }});
119            }
120        } catch (error) {
121            ;
122        }
123        try {
124            document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-ofda').onchange = function() {
125                parameters_{{ forloop.counter0 }}.ofda = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-ofda').value;
126                id3_fetch(url, parameters_{{ forloop.counter0 }});
127            }
128        } catch (error) {
129            ;
130        }
131        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-article').onchange = function() {
132            parameters_{{ forloop.counter0 }}.article_id =document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-article').value;
133            id3_fetch(url, parameters_{{ forloop.counter0 }}).then(json => { document.getElementById('libelle_article_{{ forloop.counter0 }}').textContent = json.libelle_article;});
134        }
135        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-projet').onchange = function() {
136            parameters_{{ forloop.counter0 }}.projet_id = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-projet').value;
137            id3_fetch(url, parameters_{{ forloop.counter0 }}).then(json => { document.getElementById('libelle_projet_{{ forloop.counter0 }}').textContent = json.libelle_projet});
138        }
139        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-fabricant').onchange = function() {
140            parameters_{{ forloop.counter0 }}.fabricant_id = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-fabricant').value;
141            id3_fetch(url, parameters_{{ forloop.counter0 }});            ;
142        }
143        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-ref_fabricant').onchange = function() {
144            parameters_{{ forloop.counter0 }}.ref_fabricant = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-ref_fabricant').value;
145            id3_fetch(url, parameters_{{ forloop.counter0 }});
146        }
147        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-fournisseur').onchange = function() {
148            parameters_{{ forloop.counter0 }}.fournisseur_id = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-fournisseur').value;
149            id3_fetch(url, parameters_{{ forloop.counter0 }});
150        }
151        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-ref_fournisseur').onchange = function() {
152            parameters_{{ forloop.counter0 }}.ref_fournisseur = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-ref_fournisseur').value;
153            id3_fetch(url, parameters_{{ forloop.counter0 }});
154        }
155        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-date_butoir').onchange = function() {
156            parameters_{{ forloop.counter0 }}.date_butoir = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-date_butoir').value;
157            id3_fetch(url, parameters_{{ forloop.counter0 }});
158        }
159        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-demande_codification').onchange = function() {
160            parameters_{{ forloop.counter0 }}.demande_codification = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-demande_codification').checked;
161            id3_fetch(url, parameters_{{ forloop.counter0 }});
162        }
163        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-besoin_reel').onchange = function() {
164            parameters_{{ forloop.counter0 }}.besoin_reel = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-besoin_reel').value;
165            id3_fetch(url, parameters_{{ forloop.counter0 }});
166        }
167        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-besoin_potentiel').onchange = function() {
168            parameters_{{ forloop.counter0 }}.besoin_potentiel = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-besoin_potentiel').value;
169            id3_fetch(url, parameters_{{ forloop.counter0 }});
170        }
171        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-sortie_stock').onchange = function() {
172            parameters_{{ forloop.counter0 }}.sortie_stock = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-sortie_stock').value;
173            id3_fetch(url, parameters_{{ forloop.counter0 }});
174        }
175        document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-cotation_par').onchange = function() {
176            parameters_{{ forloop.counter0 }}.cotation_par = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-cotation_par').value;
177            id3_fetch(url, parameters_{{ forloop.counter0 }});
178        }
179
180    {% endfor %}
181}
182
183
184function trt_iframe_description_demande()
185{
186    console.log(`trt_description_demande() document.readyState = ${document.readyState}`);
187
188    const url = '{% url "articles:ajax_update_demande_article" %}';
189    const iframe_description_demande = document.getElementById('id_description_iframe');
190    iframe_description_demande.contentDocument.activeElement.onblur = function() {
191        try {
192            let libelles_description = [];
193            let libelle_description = "";
194            {% for form_codif_article in formset_codif_articles %}
195                {% if forloop.counter >= 2 %}
196                    libelle_description = document.getElementById('libelle_description_{{ forloop.counter0 }}');
197                    libelles_description.push(libelle_description);
198                {% endif %}
199            {% endfor %}
200            update_iframe_description_demande(url, libelles_description);
201        } catch (error) {
202            console.error(error);
203        }
204    }
205}
206
207
208function trt_iframes_responses()
209{
210    console.log(`trt_iframes_reponses() document.readyState = ${document.readyState}`);
211    const url = '{% url "articles:ajax_update_codif_article" %}';
212    {% for form_codif_article in formset_codif_articles %}
213        try
214        {
215            {# le champ reponse n'est pas toujours present #}
216            const iframe_reponse_{{ forloop.counter0 }} = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-reponse_iframe');
217            iframe_reponse_{{ forloop.counter0 }}.contentDocument.activeElement.onblur = function() {
218                const editables = iframe_reponse_{{ forloop.counter0 }}.contentDocument.getElementsByClassName('note-editable');
219                const codifarticle_id = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-id').value;
220                const map_parameters = new Map([['id',codifarticle_id],['reponse', ""]]);
221                update_summernote(url, editables, map_parameters, 'reponse');
222            }
223        } catch (error) {
224            ; // console.error(error);
225        }
226
227    {% endfor %}
228}
229
230function trt_iframes_designations()
231{
232    console.log(`trt_iframes_designations() document.readyState = ${document.readyState}`);
233
234    const url = '{% url "articles:ajax_update_codif_article" %}';
235    {% for form_codif_article in formset_codif_articles %}
236        const iframe_designation_{{ forloop.counter0 }} = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-designation_iframe');
237        iframe_designation_{{ forloop.counter0 }}.contentDocument.activeElement.onblur = function() {
238            const editables = iframe_designation_{{ forloop.counter0 }}.contentDocument.getElementsByClassName('note-editable');
239            const codifarticle_id = document.getElementById('id_codifarticle_related-{{ forloop.counter0 }}-id').value;
240            const map_parameters = new Map([['id',codifarticle_id],['designation', ""]]);
241            update_summernote(url, editables, map_parameters, 'designation');
242       }
243    {% endfor %}
244}
245
246window.addEventListener('load', (event) => {
247    console.log('window page is fully loaded');
248
249    {% comment %}
250    On ne traite les iframes que lorsque tout est chargé
251    voir:
252    - https://javascript.info/onload-ondomcontentloaded#readystate
253    - https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
254    {% endcomment %}
255
256    trt_widgets();
257    trt_iframe_description_demande();
258    trt_iframes_responses();
259    trt_iframes_designations();
260});
261
262
263
264</script>
265{% endblock extra_js %}
266
267
268{% block content %}
269
270
271<a class="btn btn-success" href="{% url 'articles:demande_article_non_cloturee_list' %}">Liste des demandes non clôturées</a>
272<a class="btn btn-success" href="{% url 'articles:demande_article_list' %}">Liste de toutes les demandes</a>
273
274
275{% url 'articles:demande_codif_article_update' demande_article.pk  as url_demande_codif_article_update %}
276
277
278{# https://getbootstrap.com/components/#labels #}
279
280{% if demande_article.demande_non_transmise %}
281<h4 class="couleur_demande_non_transmise">
282{% elif demande_article.demande_transmise %}
283<h4 class="couleur_demande_transmise">
284{% elif demande_article.demande_en_cours %}
285<h4 class="couleur_demande_en_cours">
286{% elif demande_article.demande_traitee %}
287<h4 class="couleur_demande_traitee">
288{% elif demande_article.demande_cloturee %}
289<h4 class="couleur_demande_cloturee">
290{% endif %}
291    Demande N° <span id="id_demande_article"> {{ demande_article.id }}</span> Update:<span id="id_nb_ajax_call"> 0</span>
292</h4>
293
294
295{% if messages %}
296    <ul class="messages">
297        {% comment %} https://getbootstrap.com/components/#alerts {% endcomment %}
298        {% for message in messages %}
299        <!--li{% if message.tags %} class="{{ message.tags }}"{% endif %} -->
300            {% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}
301                <div class="alert alert-danger" role="alert">{{ message }}</div>
302            {% elif message.level == DEFAULT_MESSAGE_LEVELS.SUCCESS %}
303                <div class="alert alert-success" role="alert">{{ message }}</div>
304            {% else %}
305                <div class="alert alert-info" role="alert">{{ message }}</div>
306            {% endif %}
307        <!-- /li -->
308        {% endfor %}
309    </ul>
310{% endif %}
311
312{{ form.description }}
313{{ form.etat_demande }}
314<tr>
315    <th><label for="id_send_email">Envoi courriel :</label></th>
316    <td><input type="checkbox" name="send_email" id="id_send_email"></td>
317</tr>
318
319{% url 'tiers:create'  as url_tiers_create %}
320
321<form id="codif_articles" method="post" action=".">
322    {% csrf_token %}
323    <input type="hidden" name="demande_article" value="{{ demande_article }}">
324    <div class="table-responsive">
325        <table id="id_list_table" class="table table-condensed">
326            <tbody>
327                {{ formset_codif_articles.management_form }}
328                {# rajout des erreurs #}
329                {% if formset_codif_articles.errors %}
330                    {% for error in formset_codif_articles.non_field_errors %}
331                        <div class="alert alert-error">
332                            <strong>{{ error|escape }}</strong>
333                        </div>
334                    {% endfor %}
335                {% endif %}
336                {# Parcours des formulaires et des instances initiales associées #}
337                {% for form_codif_article, codif_article in formset_instances %}
338                    {{ form_codif_article.id }}
339                    <tr>
340                       <td>
341                           <table id="id_table_in_table" class="table table-hover table-bordered table-condensed
342                                {% if forloop.counter|divisibleby:"2" %}
343                                   table-pair
344                                {% else %}
345                                    table-impair
346                                {% endif %}
347                                ">
348                               {# un element de formulaire => un tableau dans un tableau #}
349                                <tbody>
350                                    <tr>
351                                       {% url 'articles:codif_article_delete' form_codif_article.id.value  as url_codif_article_delete %}
352                                       {% url 'articles:codif_article_clone'  form_codif_article.id.value  as url_codif_article_clone %}
353                                       {% if forloop.counter <= nb_articles %}
354                                            <td colspan=2 id={{ forloop.counter }}>
355                                               {% comment %}
356                                                   Mise en place des liens internes à une page HTML (href)
357                                                   https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_a_href_anchor
358                                               {% endcomment %}
359                                               {% for num_article in list_articles %}
360                                                  {% if num_article != forloop.parentloop.counter  %}
361                                                      <a href="#{{ num_article }}">Codif {{ num_article }}</a>
362                                                  {% else %}
363                                                      Codif  {{ forloop.parentloop.counter }}{{codif_article.id }}
364                                                  {% endif %}
365                                               {% endfor %}
366                                               {% if demande_article.demande_non_cloturee %}
367                                                   <a href="{{ url_codif_article_clone }}"> | Ajouter un article</a>
368                                                   <a href="{{ url_codif_article_delete }}">| Supprimer un article</a>
369                                                   {% if forloop.counter >= 2 %}
370                                                       <ul class=list-group>
371                                                          <li class="alert alert-success list-group-item">
372                                                            <a href="#id_demande_article">Demande article N°{{ demande_article.id }}</a>
373                                                             <span id="libelle_description_{{ forloop.counter0 }}"> {{ demande_article.description | markdown | safe }}</span>
374                                                          </li>
375                                                       </ul>
376                                                   {% endif %}
377                                               {% endif %}
378                                            </td>
379                                        {% else %}
380                                            <td colspan=2>
381                                            </td>
382                                        {% endif %}
383                                    </tr>
384                                    {% if demande_article.reponse_affichable %}
385                                        <tr>
386                                            {% comment %} Affichage en vert quand l'état du poste est dans l'état "Traité" {% endcomment %}
387                                            <td {% if codif_article.is_poste_traite %} class="text-right poste_traite" {% else %} class="text-right" {% endif %}>
388                                                Etat du poste {{ form_codif_article.etat_poste }}
389                                            </td>
390                                            <td {% if codif_article.is_poste_traite %} {% else %} class="info" {% endif %}>
391                                                Réponse {{ form_codif_article.reponse }}
392                                            </td>
393                                        </tr>
394                                        <tr>
395                                            <td class="text-right">N°OFDA</td>
396                                            <td class="info">{{ form_codif_article.ofda }}
397                                            </td>
398                                        </tr>
399                                    {% endif %}
400                                    <tr>
401                                        <td class="text-right">Code article</td>
402                                        <td class="danger">
403                                            {% if demande_article.demande_non_cloturee %}
404                                                {{ form_codif_article.article }}
405                                            {% endif %}
406                                            <span id="libelle_article_{{ forloop.counter0 }}"> {{ codif_article.get_libelle_article }}</span>
407                                        </td>
408                                    </tr>
409                                    <tr>
410                                        <td class="text-right">Projet</td>
411                                        <td>
412                                            {% if demande_article.demande_non_cloturee %}
413                                                {{ form_codif_article.projet }}
414                                            {% endif %}
415                                            <span id="libelle_projet_{{ forloop.counter0 }}"> {{ codif_article.get_libelle_projet }}</span>
416                                       </td>
417                                    </tr>
418                                    <tr>
419                                        <td class="text-right">Désignation</td>
420                                        <td>{{ form_codif_article.designation }}</td>
421                                    </tr>
422                                    {% if codif_article.demande_cloturee_and_no_documents %}
423                                    {% else %}
424                                        <tr>
425                                            {% url 'articles:codif_article_doc_list'  codif_article.id  as url_list_documents %}
426                                            <td class="text-right">
427                                                {% if demande_article.demande_non_cloturee %}
428                                                    {% if forloop.counter <= nb_articles %}
429                                                        <a href="{{ url_list_documents }}">Documents associés</a>
430                                                    {% endif %}
431                                                {% else %}
432                                                    Documents associés
433                                                {% endif %}
434                                            </td>
435                                            <td>
436                                                {% if forloop.counter <= nb_articles %}
437                                                    {% for document in codif_article.contents.all %}
438                                                        {% with media=document.item %}
439                                                           <p> {{ media.render }} </p>
440                                                        {% endwith %}
441                                                    {% endfor %}
442                                                {% endif %}
443                                            </td>
444                                        </tr>
445                                    {% endif %}
446                                    <tr>
447                                        <td class="text-right">Fabricant</td>
448                                        <td>
449                                                {{ form_codif_article.fabricant }}
450                                                Réf Fab {{ form_codif_article.ref_fabricant }}
451                                        </td>
452                                    </tr>
453                                    <tr>
454                                        <td class="text-right">Fournisseur</td>
455                                        <td>
456                                              {{ form_codif_article.fournisseur }}
457                                              Réf Fourn {{ form_codif_article.ref_fournisseur }}
458                                        </td>
459                                    </tr>
460                                    <tr>
461                                        <td class="text-right">Livraison souhaitée</td>
462                                        <td class="danger">{{ form_codif_article.date_butoir }}</td>
463                                    </tr>
464                                    <tr>
465                                        <td class="text-right">Demande de codification: {{ form_codif_article.demande_codification }} </td>
466                                        <td></td>
467                                    </tr>
468                                    <tr>
469                                        <td class="text-right">Demande d'approvisionnement <input id="id_codifarticle_related-{{ forloop.counter0 }}-demande_approvisionnement"
470                                                   name="codifarticle_set-{{ forloop.counter0 }}-demande_approvisionnement"
471                                                   {% if form_codif_article.demande_approvisionnement.value %}
472                                                       checked="checked"
473                                                   {% else %}
474                                                   {% endif %}
475                                                   data-toggle="collapse"
476                                                   data-target="#demande_approvisionnement_{{ forloop.counter0 }}"
477                                                   type="checkbox"
478                                            />
479                                        <td>
480                                            <div id="demande_approvisionnement_{{ forloop.counter0 }}"
481                                                   {% if form_codif_article.demande_approvisionnement.value %}
482                                                   class="collapse in"
483                                                   {% else %}
484                                                   class="collapse"
485                                                   {% endif %}
486                                                   >
487                                                <p>Besoin réel:  {{ form_codif_article.besoin_reel }}  Besoin potentiel: {{ form_codif_article.besoin_potentiel }}</p>
488                                            </div>
489                                        </td>
490                                    </tr>
491                                    <tr>
492                                        <td class="text-right">Demande de sortie du stock  <input  id="id_codifarticle_related-{{ forloop.counter0 }}-demande_sortie_stock"
493                                                    name="codifarticle_set-{{ forloop.counter0 }}-demande_sortie_stock"
494                                                    {% if form_codif_article.demande_sortie_stock.value %}
495                                                        checked="checked"
496                                                    {% else %}
497                                                    {% endif %}
498                                                    data-toggle="collapse"
499                                                    data-target="#demande_sortie_stock_{{ forloop.counter0 }}"
500                                                    type="checkbox"
501                                            />
502                                        </td>
503                                        <td>
504                                            <div id="demande_sortie_stock_{{ forloop.counter0 }}"
505                                                 {% if form_codif_article.demande_sortie_stock.value %}
506                                                 class="collapse in"
507                                                 {% else %}
508                                                 class="collapse"
509                                                 {% endif %}
510                                                 >
511                                                Quantité à sortir: {{ form_codif_article.sortie_stock }}
512                                            </div>
513                                        </td>
514                                    </tr>
515                                    <tr>
516                                        <td class="text-right">Demande de cotation <input id="id_codifarticle_related-{{ forloop.counter0 }}-demande_cotation"
517                                                    name="codifarticle_set-{{ forloop.counter0 }}-demande_cotation"
518                                                    {% if form_codif_article.demande_cotation.value %}
519                                                    checked="checked"
520                                                    {% else %}
521                                                    {% endif %}
522                                                    data-toggle="collapse"
523                                                    data-target="#demande_cotation_{{ forloop.counter0 }}"
524                                                    type="checkbox"
525                                            />
526                                        </td>
527                                        <td>
528
529                                            <div id="demande_cotation_{{ forloop.counter0 }}"
530                                                 {% if form_codif_article.demande_cotation.value %}
531                                                 class="collapse in"
532                                                 {% else %}
533                                                 class="collapse"
534                                                 {% endif %}
535                                                 >
536                                                Cotation par: {{ form_codif_article.cotation_par }}
537                                            </div>
538                                        </td>
539                                    </tr>
540                                    <tr>
541                                        <td colspan=2>
542                                        {% if demande_article.demande_non_cloturee %}
543                                        {% endif %}
544                                        </td>
545                                    </tr>
546                                </tbody>
547                            {# table imbriquee = 1 enregistrement #}
548                            </table>
549                        </td>
550                    </tr>
551                {% endfor %}
552            </tbody>
553        </table>
554    </div>
555</form>
556
557
558
559{% endblock %}
560
561
562{% block footer %}
563
564{% endblock footer %}