feat: refactor post filtering logic and automate contract post population based on context counts

This commit is contained in:
kdeterme 2026-08-19 12:19:00 +02:00
parent e2eb20536d
commit cde2c7e52f
4 changed files with 115 additions and 46 deletions

View file

@ -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 = `
<i class="bi bi-list-check"></i> ${gettext('Afficher uniquement les postes de l\'intervention')}
`;
} else {
showAllBtn.innerHTML = `
<i class="bi bi-list-ul"></i> ${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 = `
<i class="bi bi-list-check"></i> ${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 = `
<i class="bi bi-list-ul"></i> ${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;

View file

@ -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 }}
</option>

View file

@ -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 }};
</script>
<script>

View file

@ -632,6 +632,7 @@ def intervention_detail(request, intervention_id):
'operations_asset_groups': asset_operations_groups,
'orders': orders,
'contract_id': contract_id,
'contract_posts_count': contract.posts.count() if contract else 0,
'can_control': can_control,
'is_draft': is_draft,
'providers': providers,
@ -2226,6 +2227,7 @@ def intervention_link_order(request, intervention_id):
return JsonResponse({
'success': True,
'contract_id': intervention.order.contract.id if intervention.order else None,
'contract_posts_count': intervention.order.contract.posts.count() if intervention.order and intervention.order.contract else 0,
'quote_items': quote_items,
'quote_total': quote_total,
'can_manage_posts': 'posts' in allowed_update_fields,