diff --git a/loko/interventions/static/interventions/detail/intervention_posts_editor.js b/loko/interventions/static/interventions/detail/intervention_posts_editor.js index dfd3db5..007a008 100644 --- a/loko/interventions/static/interventions/detail/intervention_posts_editor.js +++ b/loko/interventions/static/interventions/detail/intervention_posts_editor.js @@ -1382,14 +1382,66 @@ } // ==================== Affichage de tous les postes ==================== - async function showAllContractPosts() { + function updateShowAllButtonUI() { + const showAllBtn = document.querySelector(CONFIG.selectors.showAllBtn); + if (!showAllBtn) return; if (appState.isShowingAllPosts) { - // Revenir aux postes de l'intervention - appState.currentData = appState.originalData.map(item => ({...item})); - appState.isShowingAllPosts = false; - document.querySelector(CONFIG.selectors.showAllBtn).innerHTML = ` + showAllBtn.innerHTML = ` + ${gettext('Afficher uniquement les postes de l\'intervention')} + `; + } else { + showAllBtn.innerHTML = ` ${gettext('Afficher tous les postes du contrat')} `; + } + } + + function populateWithAllContractPosts() { + const currentPostIds = new Set((appState.currentData || []).map(item => String(item.contract_post_id))); + const allPosts = [...(appState.currentData || [])]; + + (appState.contractPosts || []).forEach(post => { + if (!currentPostIds.has(String(post.id))) { + allPosts.push({ + contract_post_id: post.id, + order_number: post.order_number, + code: post.code, + description: post.description_fr || post.description_nl, + quantity: '', + comment: '', + unit: post.unit || '', + unit_price: post.unit_price, + total: '', + control_status: '', + control_comment: '', + remaining_quantity: '', + post_type: post.post_type || '', + is_coefficient_multipliable: post.is_coefficient_multipliable || false, + is_amount_to_be_justified: post.is_amount_to_be_justified || false, + coeff_amount_to_be_justified: post.coeff_amount_to_be_justified || 1, + deleted: false, + }); + } + }); + + appState.currentData = allPosts; + appState.isShowingAllPosts = true; + updateShowAllButtonUI(); + } + + async function showAllContractPosts() { + if (appState.isShowingAllPosts) { + // Revenir aux postes de l'intervention (postes originaux + postes ayant une quantité > 0 ou un commentaire) + const originalPostIds = new Set((appState.originalData || []).map(item => String(item.contract_post_id))); + appState.currentData = (appState.currentData || []).filter(item => { + const isOriginal = originalPostIds.has(String(item.contract_post_id)); + const qty = parseFloat(String(item.quantity || '').replace(',', '.')); + const hasQty = !Number.isNaN(qty) && qty !== 0; + const hasComment = Boolean(item.comment && item.comment.trim()); + return isOriginal || hasQty || hasComment; + }); + appState.isShowingAllPosts = false; + updateShowAllButtonUI(); } else { // Vérifier qu'un contrat est disponible const currentContractId = window.contractId || contractId; @@ -1399,48 +1451,17 @@ } // Charger tous les postes - if (appState.contractPosts.length === 0) { + if (!appState.contractPosts || appState.contractPosts.length === 0) { appState.contractPosts = await loadContractPosts(); } // Vérifier que des postes ont été chargés - if (appState.contractPosts.length === 0) { + if (!appState.contractPosts || appState.contractPosts.length === 0) { showAlert(gettext('Aucun poste trouvé dans le contrat.'), 'info'); return; } - // Merger avec les données actuelles - const currentPostIds = new Set(appState.originalData.map(item => item.contract_post_id)); - const allPosts = [...appState.originalData]; - - appState.contractPosts.forEach(post => { - if (!currentPostIds.has(post.id.toString())) { - allPosts.push({ - contract_post_id: post.id, - order_number: post.order_number, - code: post.code, - description: post.description_fr || post.description_nl, - quantity: '', - comment: '', - unit_price: post.unit_price, - total: '', - control_status: '', - control_comment: '', - remaining_quantity: '', - post_type: post.post_type || '', - is_coefficient_multipliable: post.is_coefficient_multipliable || false, - is_amount_to_be_justified: post.is_amount_to_be_justified || false, - coeff_amount_to_be_justified: post.coeff_amount_to_be_justified || 1, - deleted: false, - }); - } - }); - - appState.currentData = allPosts; - appState.isShowingAllPosts = true; - document.querySelector(CONFIG.selectors.showAllBtn).innerHTML = ` - ${gettext('Afficher uniquement les postes de l\'intervention')} - `; + populateWithAllContractPosts(); } renderTable(); @@ -1482,12 +1503,7 @@ if (appState.isShowingAllPosts) { appState.isShowingAllPosts = false; - const showAllBtn = document.querySelector(CONFIG.selectors.showAllBtn); - if (showAllBtn) { - showAllBtn.innerHTML = ` - ${gettext('Afficher tous les postes du contrat')} - `; - } + updateShowAllButtonUI(); } }; @@ -2679,11 +2695,38 @@ appState.quoteItems = Array.isArray(data.quote_items) ? data.quote_items : []; // Mettre à jour le contractId global si fourni par le serveur + const previousContractId = window.contractId; if (data.contract_id) { window.contractId = data.contract_id; + window.contractPostsCount = data.contract_posts_count !== undefined ? data.contract_posts_count : 0; + if (previousContractId !== data.contract_id) { + appState.contractPosts = []; + } } else if (!orderId) { // Si on désélectionne la commande, réinitialiser contractId window.contractId = null; + window.contractPostsCount = 0; + appState.contractPosts = []; + } + + if (appState.originalData.length === 0) { + if (window.contractId && window.contractPostsCount > 0 && window.contractPostsCount < 1000) { + if (!appState.contractPosts || appState.contractPosts.length === 0) { + appState.contractPosts = await loadContractPosts(); + } + if (appState.contractPosts && appState.contractPosts.length > 0) { + appState.currentData = []; + populateWithAllContractPosts(); + } else { + appState.currentData = []; + appState.isShowingAllPosts = false; + updateShowAllButtonUI(); + } + } else { + appState.currentData = []; + appState.isShowingAllPosts = false; + updateShowAllButtonUI(); + } } // Mettre à jour l'affichage dans la vue consultation @@ -2831,6 +2874,11 @@ appState.modal = new bootstrap.Modal(modalEl, { backdrop: 'static', keyboard: false }); + // Initialiser contractPostsCount depuis le contexte serveur + if (typeof contractPostsCount !== 'undefined') { + window.contractPostsCount = contractPostsCount; + } + // Initialiser hasCoefficientPosts depuis le contexte serveur if (typeof hasCoefficientPostsInitial !== 'undefined') { appState.hasCoefficientPosts = hasCoefficientPostsInitial; @@ -2848,10 +2896,27 @@ appState.originalData = extractDataFromSourceTable(); appState.currentData = appState.originalData.map(item => ({...item})); normalizeStatusForPeriodValidation(); - appState.isShowingAllPosts = false; appState.hasUnsavedChanges = false; appState.statusChanges = {}; + const currentContractId = window.contractId || contractId; + const currentPostsCount = window.contractPostsCount !== undefined ? window.contractPostsCount : (typeof contractPostsCount !== 'undefined' ? contractPostsCount : 0); + + if (appState.originalData.length === 0 && currentContractId && currentPostsCount > 0 && currentPostsCount < 1000) { + if (!appState.contractPosts || appState.contractPosts.length === 0) { + appState.contractPosts = await loadContractPosts(); + } + if (appState.contractPosts && appState.contractPosts.length > 0) { + populateWithAllContractPosts(); + } else { + appState.isShowingAllPosts = false; + updateShowAllButtonUI(); + } + } else { + appState.isShowingAllPosts = false; + updateShowAllButtonUI(); + } + await fetchPeriodQuantities(); if (autoShowPeriods) { appState.showPeriods = true; diff --git a/loko/interventions/templates/interventions/detail/card_posts.html b/loko/interventions/templates/interventions/detail/card_posts.html index e3a8563..0dd4819 100644 --- a/loko/interventions/templates/interventions/detail/card_posts.html +++ b/loko/interventions/templates/interventions/detail/card_posts.html @@ -362,6 +362,7 @@ data-contract="{{ order.contract.contract_number }}" data-order-code="{{ order.order_code }}" data-has-quote="{% if order.quote %}true{% else %}false{% endif %}" + data-contract-posts-count="{{ order.contract.posts.count }}" {% if intervention.order and order.id == intervention.order.id %}selected{% endif %}> {{ order.contract.contract_number }} - {{ order.order_code }} diff --git a/loko/interventions/templates/interventions/detail/scripts.html b/loko/interventions/templates/interventions/detail/scripts.html index 481d35d..1f0721b 100644 --- a/loko/interventions/templates/interventions/detail/scripts.html +++ b/loko/interventions/templates/interventions/detail/scripts.html @@ -48,6 +48,7 @@ const photosRequiredSince = "{{ photos_required_since }}"; const contractWarnNoPrestationOnProcessed = {{ contract_warn_no_prestation_on_processed|yesno:"true,false" }}; const hasPrestationsEncoded = {{ has_prestations_encoded|yesno:"true,false" }}; + var contractPostsCount = {{ contract_posts_count|default:0 }};