diff --git a/ecole/public/js/projet-form-fac.js b/ecole/public/js/fac/projet-form-fac.js similarity index 100% rename from ecole/public/js/projet-form-fac.js rename to ecole/public/js/fac/projet-form-fac.js diff --git a/ecole/public/js/nav-parcours.js b/ecole/public/js/nav-parcours.js index 560449df..ea8d676f 100644 --- a/ecole/public/js/nav-parcours.js +++ b/ecole/public/js/nav-parcours.js @@ -37,7 +37,7 @@ document.addEventListener('DOMContentLoaded', function() { const parcours = JSON.parse(sessionStorage.getItem('parcours')); const contrat = JSON.parse(sessionStorage.getItem('contrat')); - let produit = parcours["@expand"].contrat.produit + let produit = String(parcours?.["@expand"]?.contrat?.produit || '').toLowerCase(); const produitObj = contrat?.["@expand"]?.enCours || null; @@ -60,10 +60,10 @@ document.addEventListener('DOMContentLoaded', function() { if (submenu === "projet") { fetchUrl = `/navParcours/${submenu}${produit}?numParcours=${numParcours}`; - scriptSrc = `/js/projet-form-${produit}.js`; + scriptSrc = `/js/${produit}/projet-form-${produit}.js`; } else if (submenu === "tarif") { fetchUrl = `/navParcours/${submenu}${produit}?numParcours=${numParcours}`; - scriptSrc = `/js/tarif-form-${produit}.js`; + scriptSrc = `/js/${produit}/tarif-form-${produit}.js`; } else { fetchUrl = `/navParcours/${submenu}?numParcours=${numParcours}`; scriptSrc = `/js/${submenu}-form.js`; diff --git a/ecole/public/js/projet-form-rc.js b/ecole/public/js/rc/projet-form-rc.js similarity index 89% rename from ecole/public/js/projet-form-rc.js rename to ecole/public/js/rc/projet-form-rc.js index 43dcc59e..d6b08efa 100644 --- a/ecole/public/js/projet-form-rc.js +++ b/ecole/public/js/rc/projet-form-rc.js @@ -1,3 +1,6 @@ +/** + * Initialise submenu form. + */ function initSubmenuForm() { // Accéder aux informations stockées du parcours const parcours = JSON.parse(sessionStorage.getItem('parcours')); @@ -13,6 +16,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio let hasSavedGrilleData = false; // évite d'écraser une grille déjà enregistrée let rcProjetGuard = null; + /** + * Synchronise rcfloating labels. + */ function syncRCFloatingLabels() { if (window.RCValidationUtils && typeof window.RCValidationUtils.syncFloatingLabels === 'function') { window.RCValidationUtils.syncFloatingLabels(document); @@ -31,6 +37,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio var tagDemenageurEntrInter = false; // Initialisation du formulaire et des données + /** + * Initialise la logique de cette fonction. + */ function init() { // Materialize init select var select = document.querySelectorAll('select'); @@ -95,19 +104,27 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }, 700); } updatePrimeReferenceRow(); + updateTarifCommercialRows(); + syncTotalWithTarifCommercial(); setupRCSafeValidation(); syncRCFloatingLabels(); updateSubmitButtonState('projetForm'); setTimeout(() => { updatePrimeReferenceRow(); + updateTarifCommercialRows(); + syncTotalWithTarifCommercial(); if (rcProjetGuard) rcProjetGuard.refresh(); syncRCFloatingLabels(); + refreshTarifReferenceFromApi(); }, 350); } let tarifOriginalData = null; + /** + * Recupere linked tarif id. + */ function getLinkedTarifId() { if (tarif && typeof tarif === 'object' && tarif.id) return tarif.id; if (typeof tarif === 'string' && tarif.trim()) return tarif; @@ -118,10 +135,16 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return null; } + /** + * Verifie tarif reference. + */ function hasTarifReference() { return Boolean(getLinkedTarifId()); } + /** + * Gere refresh tarif context from session. + */ function refreshTarifContextFromSession() { try { const sessionContrat = JSON.parse(sessionStorage.getItem('contrat') || 'null'); @@ -136,6 +159,8 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio window.projet = projet; window.tarif = tarif; updatePrimeReferenceRow(); + updateTarifCommercialRows(); + syncTotalWithTarifCommercial(); return true; } catch (error) { console.warn('Impossible de recharger le contexte RC depuis la session:', error); @@ -143,6 +168,64 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Gere refresh tarif reference from api. + */ + async function refreshTarifReferenceFromApi() { + const tarifId = getLinkedTarifId(); + if (!tarifId) return false; + + try { + const response = await fetch(`/rc/tarif/${tarifId}`); + const data = await response.json(); + if (!data?.valid || !data?.tarifRc) { + return false; + } + + tarif = data.tarifRc; + + if (rc && typeof rc === 'object') { + rc.tarifRC = tarif; + if (!rc["@expand"] || typeof rc["@expand"] !== 'object') { + rc["@expand"] = {}; + } + rc["@expand"].tarifRC = tarif; + } + + window.rc = rc; + window.tarif = tarif; + try { + const sessionContrat = JSON.parse(sessionStorage.getItem('contrat') || 'null'); + const sessionRC = sessionContrat?.["@expand"]?.enCours; + if (sessionRC && typeof sessionRC === 'object') { + sessionRC.tarifRC = tarif?.id || tarif; + if (!sessionRC["@expand"] || typeof sessionRC["@expand"] !== 'object') { + sessionRC["@expand"] = {}; + } + sessionRC["@expand"].tarifRC = tarif; + sessionStorage.setItem('contrat', JSON.stringify(sessionContrat)); + } + } catch (error) { + console.warn('Impossible de synchroniser tarifRC en sessionStorage:', error); + } + + tarifOriginalData = null; + ensureTarifImpactContext(); + updatePrimeReferenceRow(); + updateTarifCommercialRows(); + syncTotalWithTarifCommercial(); + calcCotTotal(); + if (rcProjetGuard) rcProjetGuard.refresh(); + return true; + } catch (error) { + console.warn('Impossible de recharger le tarif RC depuis l\'API:', error); + return false; + } + } + + /** + * Securise tarif impact context. + */ function ensureTarifImpactContext() { if (hasTarifReference() && tarifOriginalData) return true; @@ -156,6 +239,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return Boolean(tarifOriginalData); } + /** + * Parse validation number. + */ function parseValidationNumber(rawValue) { if (window.RCValidationUtils && typeof window.RCValidationUtils.parseLooseNumber === 'function') { return window.RCValidationUtils.parseLooseNumber(rawValue); @@ -169,6 +255,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return Number.isFinite(parsed) ? parsed : NaN; } + /** + * Formate reference amount. + */ function formatReferenceAmount(value) { const number = Number(value); if (!Number.isFinite(number)) return '0,00 €'; @@ -178,6 +267,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }) + ' €'; } + /** + * Normalise franchise choice. + */ function normalizeFranchiseChoice(rawChoice) { const choice = String(rawChoice || '').trim().toLowerCase(); if (!choice) return null; @@ -187,6 +279,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return null; } + /** + * Resout tarif source for reference. + */ function resolveTarifSourceForReference() { if (tarif && typeof tarif === 'object') return tarif; if (rc?.["@expand"]?.tarifRC && typeof rc["@expand"].tarifRC === 'object') return rc["@expand"].tarifRC; @@ -194,6 +289,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return null; } + /** + * Recupere prime reference state. + */ function getPrimeReferenceState() { const tarifSource = resolveTarifSourceForReference(); if (!tarifSource) { @@ -233,6 +331,35 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }; } + /** + * Recupere tarif commercial state. + */ + function getTarifCommercialState() { + const tarifSource = resolveTarifSourceForReference(); + if (!tarifSource) { + return { + valid: false, + reason: 'Aucun tarif RC sélectionné n\'est rattaché à ce dossier.' + }; + } + + const tarifCommercialValue = parseValidationNumber(tarifSource.tarifcommercial); + if (!Number.isFinite(tarifCommercialValue) || tarifCommercialValue <= 0) { + return { + valid: false, + reason: 'Aucun tarif commercial saisi n\'est disponible sur le tarif RC.' + }; + } + + return { + valid: true, + tarifCommercialValue + }; + } + + /** + * Met a jour prime reference row. + */ function updatePrimeReferenceRow() { const primeInput = document.getElementById('primeRefHT'); const primeError = document.getElementById('primeRefHT-error'); @@ -251,6 +378,48 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio primeError.style.display = 'block'; } + /** + * Met a jour tarif commercial rows. + */ + function updateTarifCommercialRows() { + const tarifComInput = document.getElementById('tarifComSaisiHT'); + const tarifComTtcInput = document.getElementById('tarifComSaisiTTC'); + if (!tarifComInput || !tarifComTtcInput) return; + + const state = getTarifCommercialState(); + if (state.valid) { + const formatted = formatReferenceAmount(state.tarifCommercialValue); + tarifComInput.value = formatted; + tarifComTtcInput.value = formatted; + return; + } + + tarifComInput.value = 'Non renseigné'; + tarifComTtcInput.value = '//'; + } + + /** + * Synchronise total with tarif commercial. + */ + function syncTotalWithTarifCommercial(options = {}) { + const totalHTInput = document.getElementById('cotTotalHT'); + if (!totalHTInput) return; + + const state = getTarifCommercialState(); + if (!state.valid) return; + + const force = Boolean(options.force); + const currentTotal = parseValidationNumber(totalHTInput.value); + if (!force && Number.isFinite(currentTotal) && currentTotal > 0) { + return; + } + + totalHTInput.value = state.tarifCommercialValue.toFixed(2); + } + + /** + * Configure rcsafe validation. + */ function setupRCSafeValidation() { if (!window.RCValidationUtils || typeof window.RCValidationUtils.createGuard !== 'function') { return; @@ -259,13 +428,7 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio rcProjetGuard = window.RCValidationUtils.createGuard({ summaryId: 'rcProjetBlockingSummary', summaryTitle: 'Impossible d\'enregistrer ou de continuer car :', - blockTargets: ['#projetFormBtn', '#generateDeclinaison', '#generateProject'], - onChange: function (messages) { - const actionsRow = document.getElementById('projetActionsRow'); - if (actionsRow) { - actionsRow.classList.toggle('rc-tarifettes-hidden', messages.length > 0); - } - } + blockTargets: ['#projetFormBtn', '#generateDeclinaison', '#generateProject'] }); rcProjetGuard.registerField('#CA', { @@ -307,6 +470,22 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); }); + rcProjetGuard.registerExternal('legacy-field-errors', function () { + const visibleFieldError = Array.from( + document.querySelectorAll('#projetForm [id$="-error"].red-text') + ).find((node) => { + const text = String(node?.textContent || '').trim(); + const style = window.getComputedStyle(node); + return Boolean(text) && style.display !== 'none' && style.visibility !== 'hidden'; + }); + + if (visibleFieldError) { + return { valid: false, message: visibleFieldError.textContent.trim() }; + } + + return { valid: true }; + }); + rcProjetGuard.registerField('#nomAdditionnel', { profile: 'text', label: 'Nom assuré additionnel' @@ -422,6 +601,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio rcProjetGuard.refresh(); } + /** + * Charge modulateurs. + */ async function loadModulateurs() { try { const response = await fetch('/rc/modulo/activiteRCC'); @@ -464,6 +646,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Sauvegarde original tarif data. + */ function saveOriginalTarifData() { if (!hasTarifReference()) return; @@ -544,6 +729,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }; } + /** + * Controle activity impact. + */ function checkActivityImpact(activityData) { const activities = ['checkVoiturier', 'checkCommissionnaire', 'checkDemenageur', 'checkLogistique', 'checkAutocariste', 'checkAutres']; for (let act of activities) { @@ -556,6 +744,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return false; } + /** + * Controle marchandise impact. + */ function checkMarchandiseImpact(marchandiseData) { const normalizeArray = (arr) => { if (!arr) return []; @@ -573,6 +764,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return false; } + /** + * Recupere max zone coefficient. + */ function getMaxZoneCoefficient(zones) { let maxRCC = 1; let maxRCE = 1; @@ -611,12 +805,18 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return { maxRCC, maxRCE }; } + /** + * Controle zone impact. + */ function checkZoneImpact(zoneData) { const originalMax = getMaxZoneCoefficient(tarifOriginalData); const currentMax = getMaxZoneCoefficient(zoneData); return originalMax.maxRCC !== currentMax.maxRCC || originalMax.maxRCE !== currentMax.maxRCE; } + /** + * Controle activite compl impact. + */ function checkActiviteComplImpact(activiteComplData) { const activiteKeys = ['activitesVoiturier', 'activitesCommissionnaire', 'activitesDemenageur', 'activitesLogistique']; for (let key of activiteKeys) { @@ -627,6 +827,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return false; } + /** + * Recupere current activite compl data. + */ function getCurrentActiviteComplData() { const activitesCompl = { activitesVoiturier: getActivitesComplFromForm('actComplVoiturier/Loueur'), @@ -637,6 +840,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return activitesCompl; } + /** + * Recupere activites compl from form. + */ function getActivitesComplFromForm(containerName) { const container = document.querySelector(`[name="${containerName}"]`); if (!container) return []; @@ -649,11 +855,17 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return activites; } + /** + * Recupere current type ext confies. + */ function getCurrentTypeExtConfies() { if (document.getElementById('AdValorem')?.checked) return 'ADVALOREM'; return 'VALEUR DECLAREE'; } + /** + * Capture zone state. + */ function captureZoneState() { const state = {}; for (let i = 1; i <= 6; i++) { @@ -666,6 +878,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return state; } + /** + * Restaure zone state. + */ function restoreZoneState(state) { if (!state) return; isRestoringValue = true; @@ -685,6 +900,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Normalise impact value. + */ function normalizeImpactValue(value) { if (Array.isArray(value)) { return value.map((item) => normalizeImpactValue(item)).sort((a, b) => String(a).localeCompare(String(b), 'fr')); @@ -708,6 +926,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return value; } + /** + * Collecte effective advalorem grid. + */ function collectEffectiveAdvaloremGrid(zoneData) { const activeZones = []; for (let i = 1; i <= 6; i++) { @@ -734,27 +955,42 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }; } + /** + * Controle cotisation impact. + */ function checkCotisationImpact() { const currentCotisation = document.querySelector('input[name="cotisation"]:checked')?.value || null; return currentCotisation !== (tarifOriginalData?.typeCotisation || null); } + /** + * Controle caimpact. + */ function checkCAImpact() { const currentCA = normalizeImpactValue(document.getElementById('CA')?.value || ''); const originalCA = normalizeImpactValue(tarifOriginalData?.ca || ''); return currentCA !== originalCA; } + /** + * Controle pjimpact. + */ function checkPJImpact() { const currentPJ = Boolean(document.getElementById('switchPJ')?.checked); return currentPJ !== Boolean(tarifOriginalData?.pj); } + /** + * Controle rceimpact. + */ function checkRCEImpact() { const currentRCE = Boolean(document.getElementById('choixRCE')?.checked); return currentRCE !== Boolean(tarifOriginalData?.checkRCE); } + /** + * Controle type ext confies impact. + */ function checkTypeExtConfiesImpact() { const currentGaranties = getCurrentGarantieRCCData(); const originalGaranties = Array.isArray(tarifOriginalData?.garantiesRCC) ? tarifOriginalData.garantiesRCC : []; @@ -765,6 +1001,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return getCurrentTypeExtConfies() !== (tarifOriginalData?.typeExtConfies || null); } + /** + * Parse capital number. + */ function parseCapitalNumber(value) { const normalized = String(value ?? '') .trim() @@ -774,6 +1013,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return Number.isFinite(parsed) ? parsed : 0; } + /** + * Controle capital impact by field. + */ function checkCapitalImpactByField(fieldId, fieldValue) { if (!fieldId || !tarifOriginalData) return false; @@ -812,6 +1054,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return Math.abs(currentValue - expected) > 0.01; } + /** + * Collecte projet data for tarif prefill. + */ function collectProjetDataForTarifPrefill() { const getNumberValue = (id) => { const element = document.getElementById(id); @@ -893,6 +1138,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return payload; } + /** + * Gere store projet data for tarif prefill. + */ function storeProjetDataForTarifPrefill() { try { const payload = collectProjetDataForTarifPrefill(); @@ -906,6 +1154,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio let isTarifImpactModalOpen = false; const tarifImpactDebugReasons = new Set(); + /** + * Gere log tarif impact skip. + */ function logTarifImpactSkip(reason, details = null) { if (tarifImpactDebugReasons.has(reason)) return; tarifImpactDebugReasons.add(reason); @@ -916,6 +1167,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio console.warn(`[RC modal impact] ${reason}`); } + /** + * Execute with restore guard. + */ function runWithRestoreGuard(callback) { isRestoringValue = true; try { @@ -927,11 +1181,17 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Recupere displayed style. + */ function getDisplayedStyle(id) { const element = document.getElementById(id); return element ? element.style.display : ''; } + /** + * Met a jour displayed style. + */ function setDisplayedStyle(id, value) { const element = document.getElementById(id); if (element) { @@ -939,11 +1199,17 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Gere read input value. + */ function readInputValue(id) { const element = document.getElementById(id); return element ? element.value : ''; } + /** + * Gere write input value. + */ function writeInputValue(id, value) { const element = document.getElementById(id); if (element) { @@ -951,6 +1217,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Gere apply cotisation layout. + */ function applyCotisationLayout(value) { if (value === "forfaitaire") { document.getElementById("checkVehicules").style.display = 'block'; @@ -977,6 +1246,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Gere recalculate after cachange. + */ function recalculateAfterCAChange() { validateField('CA', true); updateSubmitButtonState('projetForm'); @@ -989,6 +1261,68 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio if (rcProjetGuard) rcProjetGuard.refresh(); } + /** + * Vérifie si une saisie numérique contient un format interdit. + */ + function hasInvalidNumericValue(value, maxDecimals = null) { + const normalized = String(value ?? '') + .trim() + .replace(/\s/g, ''); + + if (!normalized) return false; + if (/[A-Za-z€$£¥]/.test(normalized)) return true; + if (/[^0-9.,-]/.test(normalized)) return true; + + if ((normalized.match(/,/g) || []).length > 1) return true; + if ((normalized.match(/\./g) || []).length > 1) return true; + if (normalized.includes('-') && normalized.indexOf('-') !== 0) return true; + if (!/^-?\d+(?:[.,]\d+)?$/.test(normalized)) return true; + + if (Number.isInteger(maxDecimals)) { + const decimalPart = normalized.split(/[.,]/)[1]; + if (decimalPart && decimalPart.length > maxDecimals) return true; + } + + return false; + } + + /** + * Coupe un recalcul si la valeur courante n'est pas un nombre valide. + */ + function skipRecomputeIfInvalid(fieldId, maxDecimals = null) { + const field = document.getElementById(fieldId); + if (!field) return false; + if (!hasInvalidNumericValue(field.value, maxDecimals)) return false; + + if (rcProjetGuard) rcProjetGuard.refresh(); + return true; + } + + /** + * Exécute un handler de champ sans laisser remonter une erreur JS bloquante. + */ + function runSafeFieldHandler(fieldId, handler) { + try { + handler(); + } catch (error) { + console.error(`[RC Projet] Erreur sur le champ "${fieldId}"`, error); + try { + validateField(fieldId, true); + } catch (_) { + // no-op + } + try { + updateSubmitButtonState('projetForm'); + } catch (_) { + // no-op + } + if (rcProjetGuard) rcProjetGuard.refresh(); + } + } + + /** + * Capture rcestate. + */ function captureRCEState() { return { checked: Boolean(document.getElementById('choixRCE')?.checked), @@ -1002,6 +1336,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }; } + /** + * Restaure rcestate. + */ function restoreRCEState(state) { if (!state) return; runWithRestoreGuard(() => { @@ -1021,6 +1358,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); } + /** + * Capture pjstate. + */ function capturePJState() { return { checked: Boolean(document.getElementById('switchPJ')?.checked), @@ -1031,6 +1371,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }; } + /** + * Restaure pjstate. + */ function restorePJState(state) { if (!state) return; runWithRestoreGuard(() => { @@ -1047,12 +1390,18 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); } + /** + * Capture cotisation state. + */ function captureCotisationState() { return { value: document.querySelector('input[name="cotisation"]:checked')?.value || null }; } + /** + * Restaure cotisation state. + */ function restoreCotisationState(state) { if (!state) return; runWithRestoreGuard(() => { @@ -1066,12 +1415,18 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); } + /** + * Capture castate. + */ function captureCAState() { return { value: document.getElementById('CA')?.value || '' }; } + /** + * Restaure castate. + */ function restoreCAState(state) { if (!state) return; runWithRestoreGuard(() => { @@ -1083,6 +1438,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); } + /** + * Restaure changed field value. + */ function restoreChangedFieldValue(changedElement, previousValue) { if (!changedElement) return; @@ -1144,12 +1502,18 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); } + /** + * Redirige to tarif from modal. + */ function redirectToTarifFromModal() { storeProjetDataForTarifPrefill(); const target = `/navParcours?numParcours=${getNumParcoursFromURL()}&submenu=tarif`; window.location.href = target; } + /** + * Affiche tarif impact modal. + */ function showTarifImpactModal(options = {}) { const modal = document.getElementById('modalModif'); if (!modal) { @@ -1198,6 +1562,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return true; } + /** + * Gere prompt tarif impact if needed. + */ function promptTarifImpactIfNeeded(context = {}) { if (isRestoringValue) { logTarifImpactSkip('ignore pendant restauration'); @@ -1245,6 +1612,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); } + /** + * Configure tarif impact listeners. + */ function setupTarifImpactListeners() { ensureTarifImpactContext(); setTimeout(() => { @@ -1609,6 +1979,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio // Décision produit: pas de modal sur les zones textuelles de grille ad valorem. } + /** + * Controle garantie rccimpact. + */ function checkGarantieRCCImpact(garantieData) { const garantiesImpactantes = ['contenant-confie', 'tppc']; const originalGaranties = tarifOriginalData?.garantiesRCC || []; @@ -1623,6 +1996,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return false; } + /** + * Recupere current activity data. + */ function getCurrentActivityData() { const activitySelector = document.getElementById('activity-selector'); const selectedActivities = Array.from(activitySelector.selectedOptions).map(opt => opt.value); @@ -1641,6 +2017,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }; } + /** + * Recupere current marchandise data. + */ function getCurrentMarchandiseData() { const selectedMarchandises = getSelectedMarchandises(); const marchandiseTexts = selectedMarchandises.map(val => { @@ -1658,6 +2037,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }; } + /** + * Recupere current zone data. + */ function getCurrentZoneData() { const zone1 = document.getElementById("zone1"); const zone2 = document.getElementById("zone2"); @@ -1671,17 +2053,26 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }; } + /** + * Recupere current garantie rccdata. + */ function getCurrentGarantieRCCData() { const selector = document.getElementById('garantieRCC-selector'); if (!selector) return []; return Array.from(selector.selectedOptions).map(opt => opt.value); } + /** + * Recupere selected marchandises. + */ function getSelectedMarchandises() { const selector = document.getElementById('marchandise-selector'); return Array.from(selector.selectedOptions).map(opt => opt.value); } + /** + * Pre-remplit from tarif. + */ function prefillFromTarif() { if (!tarif || !rc) { console.log('Pas de donnees tarif/rc pour pre-remplir'); @@ -1693,6 +2084,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio console.log('Pre-remplissage depuis tarif...', { rc, tarif }); + /** + * Parse array. + */ function parseArray(value) { if (Array.isArray(value)) return value; if (typeof value === 'string') { @@ -2139,6 +2533,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Configuration des écouteurs d'événements + /** + * Configure event listeners. + */ function setupEventListeners() { document.getElementById('projetFormBtn').addEventListener('click', handleSubmitForm); @@ -2369,6 +2766,18 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio var radioButtonsFract = document.getElementsByName('fractionnement'); for (var i = 0; i < radioButtonsFract.length; i++) { radioButtonsFract[i].addEventListener('change', function () { + const cotFraisHTEl = document.getElementById("cotFraisHT"); + const cotFraisTTCEl = document.getElementById("cotFraisTTC"); + const hasExistingFraisValue = Boolean( + String(cotFraisHTEl?.value || '').trim() || + String(cotFraisTTCEl?.value || '').trim() + ); + + if (!hasExistingFraisValue) { + calcCotTotal(); + return; + } + if (this.value == "mensuel") { document.getElementById("cotFraisHT").value = 36.00; document.getElementById("cotFraisTTC").value = 36.00; @@ -2462,23 +2871,35 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } document.getElementById('CA').addEventListener('input', function (e) { - if (isRestoringValue) { - recalculateAfterCAChange(); - return; - } - - if (promptTarifImpactIfNeeded({ - isImpacting: () => checkCAImpact(), - restore: () => restoreCAState(previousCAState), - onNoImpact: () => { - previousCAState = captureCAState(); - recalculateAfterCAChange(); + runSafeFieldHandler('CA', () => { + if (isRestoringValue) { + if (!skipRecomputeIfInvalid('CA', 2)) { + recalculateAfterCAChange(); + } else { + validateField('CA', true); + updateSubmitButtonState('projetForm'); + } + return; } - })) { - e.stopImmediatePropagation(); - e.preventDefault(); - return; - } + + if (promptTarifImpactIfNeeded({ + isImpacting: () => checkCAImpact(), + restore: () => restoreCAState(previousCAState), + onNoImpact: () => { + previousCAState = captureCAState(); + if (!skipRecomputeIfInvalid('CA', 2)) { + recalculateAfterCAChange(); + } else { + validateField('CA', true); + updateSubmitButtonState('projetForm'); + } + } + })) { + e.stopImmediatePropagation(); + e.preventDefault(); + return; + } + }); }); document.getElementById('cotisationIrreductible').addEventListener('input', function () { @@ -2487,47 +2908,59 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); document.getElementById('tauxRCCHT').addEventListener('input', function () { - validateField('tauxRCCHT', true); - updateSubmitButtonState('projetForm'); - calcAddTaxe('tauxRCCHT', 0, 'tauxRCCTTC'); - calcTauxTotal(); - calcCotFromTauxCA('tauxRCCHT', 'cotRCCHT'); - calcAddTaxe('cotRCCHT', 0, 'cotRCCTTC'); - calcCotIrreductible(); - calcCotTotal(); + runSafeFieldHandler('tauxRCCHT', () => { + validateField('tauxRCCHT', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('tauxRCCHT', 3)) return; + calcAddTaxe('tauxRCCHT', 0, 'tauxRCCTTC'); + calcTauxTotal(); + calcCotFromTauxCA('tauxRCCHT', 'cotRCCHT'); + calcAddTaxe('cotRCCHT', 0, 'cotRCCTTC'); + calcCotIrreductible(); + calcCotTotal(); + }); }); document.getElementById('tauxRCCTTC').addEventListener('input', function () { - validateField('tauxRCCTTC', true); - updateSubmitButtonState('projetForm'); - calcSubTaxe('tauxRCCHT', 0, 'tauxRCCTTC'); - calcTauxTotal(); - calcCotFromTauxCA('tauxRCCHT', 'cotRCCHT'); - calcAddTaxe('cotRCCHT', 0, 'cotRCCTTC'); - calcCotIrreductible(); - calcCotTotal(); + runSafeFieldHandler('tauxRCCTTC', () => { + validateField('tauxRCCTTC', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('tauxRCCTTC', 3)) return; + calcSubTaxe('tauxRCCHT', 0, 'tauxRCCTTC'); + calcTauxTotal(); + calcCotFromTauxCA('tauxRCCHT', 'cotRCCHT'); + calcAddTaxe('cotRCCHT', 0, 'cotRCCTTC'); + calcCotIrreductible(); + calcCotTotal(); + }); }); document.getElementById('tauxRCEHT').addEventListener('input', function () { - validateField('tauxRCEHT', true); - updateSubmitButtonState('projetForm'); - calcAddTaxe('tauxRCEHT', 0.09, 'tauxRCETTC'); - calcTauxTotal(); - calcCotFromTauxCA('tauxRCEHT', 'cotRCEHT'); - calcAddTaxe('cotRCEHT', 0.09, 'cotRCETTC'); - calcCotIrreductible(); - calcCotTotal(); + runSafeFieldHandler('tauxRCEHT', () => { + validateField('tauxRCEHT', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('tauxRCEHT', 3)) return; + calcAddTaxe('tauxRCEHT', 0.09, 'tauxRCETTC'); + calcTauxTotal(); + calcCotFromTauxCA('tauxRCEHT', 'cotRCEHT'); + calcAddTaxe('cotRCEHT', 0.09, 'cotRCETTC'); + calcCotIrreductible(); + calcCotTotal(); + }); }); document.getElementById('tauxRCETTC').addEventListener('input', function () { - validateField('tauxRCETTC', true); - updateSubmitButtonState('projetForm'); - calcSubTaxe('tauxRCEHT', 0.09, 'tauxRCETTC'); - calcTauxTotal(); - calcCotFromTauxCA('tauxRCEHT', 'cotRCEHT'); - calcAddTaxe('cotRCEHT', 0.09, 'cotRCETTC'); - calcCotIrreductible(); - calcCotTotal(); + runSafeFieldHandler('tauxRCETTC', () => { + validateField('tauxRCETTC', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('tauxRCETTC', 3)) return; + calcSubTaxe('tauxRCEHT', 0.09, 'tauxRCETTC'); + calcTauxTotal(); + calcCotFromTauxCA('tauxRCEHT', 'cotRCEHT'); + calcAddTaxe('cotRCEHT', 0.09, 'cotRCETTC'); + calcCotIrreductible(); + calcCotTotal(); + }); }); document.getElementById('tauxTotalHT').addEventListener('input', function () { @@ -2541,59 +2974,83 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); document.getElementById('cotRCCHT').addEventListener('input', function () { - validateField('cotRCCHT', true); - updateSubmitButtonState('projetForm'); - calcAddTaxe('cotRCCHT', 0, 'cotRCCTTC'); - calcCotTotal(); + runSafeFieldHandler('cotRCCHT', () => { + validateField('cotRCCHT', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('cotRCCHT', 2)) return; + calcAddTaxe('cotRCCHT', 0, 'cotRCCTTC'); + calcCotTotal(); + }); }); document.getElementById('cotRCCTTC').addEventListener('input', function () { - validateField('cotRCCTTC', true); - updateSubmitButtonState('projetForm'); - calcSubTaxe('cotRCCHT', 0, 'cotRCCTTC'); - calcCotTotal(); + runSafeFieldHandler('cotRCCTTC', () => { + validateField('cotRCCTTC', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('cotRCCTTC', 2)) return; + calcSubTaxe('cotRCCHT', 0, 'cotRCCTTC'); + calcCotTotal(); + }); }); document.getElementById('cotRCEHT').addEventListener('input', function () { - validateField('cotRCEHT', true); - updateSubmitButtonState('projetForm'); - calcAddTaxe('cotRCEHT', 0.09, 'cotRCETTC'); - calcCotTotal(); + runSafeFieldHandler('cotRCEHT', () => { + validateField('cotRCEHT', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('cotRCEHT', 2)) return; + calcAddTaxe('cotRCEHT', 0.09, 'cotRCETTC'); + calcCotTotal(); + }); }); document.getElementById('cotRCETTC').addEventListener('input', function () { - validateField('cotRCETTC', true); - updateSubmitButtonState('projetForm'); - calcSubTaxe('cotRCEHT', 0.09, 'cotRCETTC'); - calcCotTotal(); + runSafeFieldHandler('cotRCETTC', () => { + validateField('cotRCETTC', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('cotRCETTC', 2)) return; + calcSubTaxe('cotRCEHT', 0.09, 'cotRCETTC'); + calcCotTotal(); + }); }); document.getElementById('cotPJHT').addEventListener('input', function () { - validateField('cotPJHT', true); - updateSubmitButtonState('projetForm'); - calcAddTaxe('cotPJHT', 0.134, 'cotPJTTC'); - calcCotTotal(); + runSafeFieldHandler('cotPJHT', () => { + validateField('cotPJHT', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('cotPJHT', 2)) return; + calcAddTaxe('cotPJHT', 0.134, 'cotPJTTC'); + calcCotTotal(); + }); }); document.getElementById('cotPJTTC').addEventListener('input', function () { - validateField('cotPJTTC', true); - updateSubmitButtonState('projetForm'); - calcSubTaxe('cotPJHT', 0.134, 'cotPJTTC'); - calcCotTotal(); + runSafeFieldHandler('cotPJTTC', () => { + validateField('cotPJTTC', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('cotPJTTC', 2)) return; + calcSubTaxe('cotPJHT', 0.134, 'cotPJTTC'); + calcCotTotal(); + }); }); document.getElementById('cotFraisHT').addEventListener('input', function () { - validateField('cotFraisHT', true); - updateSubmitButtonState('projetForm'); - calcAddTaxe('cotFraisHT', 0, 'cotFraisTTC'); - calcCotTotal(); + runSafeFieldHandler('cotFraisHT', () => { + validateField('cotFraisHT', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('cotFraisHT', 2)) return; + calcAddTaxe('cotFraisHT', 0, 'cotFraisTTC'); + calcCotTotal(); + }); }); document.getElementById('cotFraisTTC').addEventListener('input', function () { - validateField('cotFraisTTC', true); - updateSubmitButtonState('projetForm'); - calcSubTaxe('cotFraisHT', 0, 'cotFraisTTC'); - calcCotTotal(); + runSafeFieldHandler('cotFraisTTC', () => { + validateField('cotFraisTTC', true); + updateSubmitButtonState('projetForm'); + if (skipRecomputeIfInvalid('cotFraisTTC', 2)) return; + calcSubTaxe('cotFraisHT', 0, 'cotFraisTTC'); + calcCotTotal(); + }); }); document.getElementById('cotTotalHT').addEventListener('input', function () { @@ -2806,6 +3263,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }; // Peupler le formulaire avec les données + /** + * Gere populate form data. + */ function populateFormData() { //Poupulate select historique : n'afficher que si des entrées existent const historiqueDiv = document.getElementById('historiqueDiv'); @@ -3233,6 +3693,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio syncRCFloatingLabels(); } + /** + * Gere populate gr advalo. + */ function populateGrAdvalo(jsonData, tableID) { var table = document.getElementById(tableID); if (!table) { @@ -3305,6 +3768,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } }; + /** + * Gere gr advalo. + */ function handleGrAdvalo() { for (let i = 1; i <= 6; i++) { const checkZone = document.getElementById("zone" + i).checked; @@ -3322,6 +3788,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Met a jour category values. + */ function updateCategoryValues(mode, zone, index, checkZone) { for (let k = 1; k <= 8; k++) { const element = document.getElementById(`${mode}Cat${k}Zone${zone}`); @@ -3364,6 +3833,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Gere load historique btn. + */ function handleLoadHistoriqueBtn() { var selectedId = document.getElementById('idSelect').value; @@ -3385,6 +3857,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Gere activity selection. + */ function handleActivitySelection() { const select = document.getElementById('activity-selector'); const activityFormsContainer = document.getElementById('selected-activities'); @@ -3436,6 +3911,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); } + /** + * Gere garantie rccselection. + */ function handleGarantieRCCSelection() { const select = document.getElementById('garantieRCC-selector'); const garantieRccFormsContainer = document.getElementById('selected-garantieRCC'); @@ -3460,6 +3938,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); } + /** + * Gere garantie rceselection. + */ function handleGarantieRCESelection() { const select = document.getElementById('garantieRCE-selector'); const garantieRceFormsContainer = document.getElementById('selected-garantieRCE'); @@ -3487,6 +3968,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }); } + /** + * Gere marchandise selection. + */ function handleMarchandiseSelection() { const select = document.getElementById('marchandise-selector'); const marchandiseFormsContainer = document.getElementById('selected-marchandises'); @@ -3524,6 +4008,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Ajouter une ligne au tableau + /** + * Gere add row additionnel. + */ function addRowAdditionnel(nomValue, adresseValue, siretValue) { const table = document.getElementById('empTableAdditionnel'); @@ -3552,6 +4039,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Ajouter une ligne au tableau Vehicule + /** + * Gere add row vehicule. + */ function addRowVehicule(marqueValue, genreValue, typeValue, immatValue, capitalValue) { const table = document.getElementById('empTableVehicules'); @@ -3584,12 +4074,18 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Supprimer une ligne du tableau + /** + * Gere delete row. + */ function deleteRow(btn) { const row = btn.parentElement.parentElement; row.parentElement.removeChild(row); } // Contruit la structure Assuré additionnel à envoyer à la BDD + /** + * Gere extract assure additionnel. + */ function extractAssureAdditionnel(tableId) { const jsonArr = []; const table = document.getElementById(tableId); @@ -3622,6 +4118,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Contruit la structure Designation à envoyer à la BDD + /** + * Gere extract designation vehicule. + */ function extractDesignationVehicule(tableId) { const jsonArr = []; const table = document.getElementById(tableId); @@ -3653,6 +4152,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return "[]"; // Retourne un tableau JSON vide si aucune saisie n'est trouvée dans le tableau } + /** + * Gere extract grille advalo. + */ function extractGrilleAdvalo(tableID) { var jsonData = []; var table = document.getElementById(tableID); @@ -3736,6 +4238,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return jsonData; } + /** + * Gere extract tempo. + */ function extractTempo() { let tempo = ""; @@ -3747,6 +4252,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return tempo; } + /** + * Gere extract type cot. + */ function extractTypeCot() { let cot = ""; @@ -3756,70 +4264,152 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return cot; } + /** + * Calcule cot total. + */ function calcCotTotal() { - const cotRCCHT = parseFloat(document.getElementById("cotRCCHT").value) || 0 - const cotRCCTTC = parseFloat(document.getElementById("cotRCCTTC").value) || 0 - const cotRCEHT = parseFloat(document.getElementById("cotRCEHT").value) || 0 - const cotRCETTC = parseFloat(document.getElementById("cotRCETTC").value) || 0 - const cotPJHT = parseFloat(document.getElementById("cotPJHT").value) || 0 - const cotPJTTC = parseFloat(document.getElementById("cotPJTTC").value) || 0 - const cotFraisHT = parseFloat(document.getElementById("cotFraisHT").value) || 0 - const cotFraisTTC = parseFloat(document.getElementById("cotFraisTTC").value) || 0 + const readValue = (id) => { + const field = document.getElementById(id); + if (!field) return 0; + const parsed = parseValidationNumber(field.value); + return Number.isFinite(parsed) ? parsed : 0; + }; - document.getElementById("cotTotalHT").value = (cotRCCHT + cotRCEHT + cotPJHT + cotFraisHT).toFixed(2); - document.getElementById("cotTotalTTC").value = (cotRCCTTC + cotRCETTC + cotPJTTC + cotFraisTTC).toFixed(2); + const cotRCCHT = readValue("cotRCCHT"); + const cotRCCTTC = readValue("cotRCCTTC"); + const cotRCEHT = readValue("cotRCEHT"); + const cotRCETTC = readValue("cotRCETTC"); + const cotPJHT = readValue("cotPJHT"); + const cotPJTTC = readValue("cotPJTTC"); + const cotFraisHT = readValue("cotFraisHT"); + const cotFraisTTC = readValue("cotFraisTTC"); + + const totalCalcHT = cotRCCHT + cotRCEHT + cotPJHT + cotFraisHT; + const totalCalcTTC = cotRCCTTC + cotRCETTC + cotPJTTC + cotFraisTTC; + + const totalHTInput = document.getElementById("cotTotalHT"); + if (!totalHTInput) return; + const currentTotalHT = parseValidationNumber(totalHTInput?.value); + if (!Number.isFinite(currentTotalHT) || currentTotalHT <= 0) { + const tarifCommercialState = getTarifCommercialState(); + if (tarifCommercialState.valid) { + totalHTInput.value = tarifCommercialState.tarifCommercialValue.toFixed(2); + } else { + totalHTInput.value = totalCalcHT.toFixed(2); + } + } + const totalTTCInput = document.getElementById("cotTotalTTC"); + if (totalTTCInput) { + const currentTotalTTC = parseValidationNumber(totalTTCInput.value); + if (!Number.isFinite(currentTotalTTC) || currentTotalTTC <= 0) { + if (totalCalcTTC > 0) { + totalTTCInput.value = totalCalcTTC.toFixed(2); + } + } + } + updateTarifCommercialRows(); if (rcProjetGuard) rcProjetGuard.refresh(); } + /** + * Calcule taux total. + */ function calcTauxTotal() { - const tauxRCCHT = parseFloat(document.getElementById("tauxRCCHT").value) || 0 - const tauxRCCTTC = parseFloat(document.getElementById("tauxRCCTTC").value) || 0 - const tauxRCEHT = parseFloat(document.getElementById("tauxRCEHT").value) || 0 - const tauxRCETTC = parseFloat(document.getElementById("tauxRCETTC").value) || 0 + const tauxRCCHTEl = document.getElementById("tauxRCCHT"); + const tauxRCCTTCEl = document.getElementById("tauxRCCTTC"); + const tauxRCEHTEl = document.getElementById("tauxRCEHT"); + const tauxRCETTCEl = document.getElementById("tauxRCETTC"); + const tauxTotalHTEl = document.getElementById("tauxTotalHT"); + const tauxTotalTTCEl = document.getElementById("tauxTotalTTC"); + if (!tauxRCCHTEl || !tauxRCCTTCEl || !tauxRCEHTEl || !tauxRCETTCEl || !tauxTotalHTEl || !tauxTotalTTCEl) return; - document.getElementById("tauxTotalHT").value = (tauxRCCHT + tauxRCEHT).toFixed(3); - document.getElementById("tauxTotalTTC").value = (tauxRCCTTC + tauxRCETTC).toFixed(3); + const tauxRCCHT = parseValidationNumber(tauxRCCHTEl.value); + const tauxRCCTTC = parseValidationNumber(tauxRCCTTCEl.value); + const tauxRCEHT = parseValidationNumber(tauxRCEHTEl.value); + const tauxRCETTC = parseValidationNumber(tauxRCETTCEl.value); + + tauxTotalHTEl.value = ((Number.isFinite(tauxRCCHT) ? tauxRCCHT : 0) + (Number.isFinite(tauxRCEHT) ? tauxRCEHT : 0)).toFixed(3); + tauxTotalTTCEl.value = ((Number.isFinite(tauxRCCTTC) ? tauxRCCTTC : 0) + (Number.isFinite(tauxRCETTC) ? tauxRCETTC : 0)).toFixed(3); if (rcProjetGuard) rcProjetGuard.refresh(); } + /** + * Calcule cot from taux ca. + */ function calcCotFromTauxCA(idTaux, idCot) { - const valueCA = parseFloat(document.getElementById("CA").value) || 0 - const valueTaux = parseFloat(document.getElementById(idTaux).value) || 0 + const caEl = document.getElementById("CA"); + const tauxEl = document.getElementById(idTaux); + const cotEl = document.getElementById(idCot); + if (!caEl || !tauxEl || !cotEl) return; - document.getElementById(idCot).value = (valueCA * valueTaux / 100).toFixed(2); + const valueCA = parseValidationNumber(caEl.value); + const valueTaux = parseValidationNumber(tauxEl.value); + if (!Number.isFinite(valueCA) || !Number.isFinite(valueTaux)) return; + + cotEl.value = (valueCA * valueTaux / 100).toFixed(2); } + /** + * Calcule cot irreductible. + */ function calcCotIrreductible() { - const cotRCCHT = parseFloat(document.getElementById("cotRCCHT").value) || 0 - const cotRCEHT = parseFloat(document.getElementById("cotRCEHT").value) || 0 + const cotRCCHTEl = document.getElementById("cotRCCHT"); + const cotRCEHTEl = document.getElementById("cotRCEHT"); + const cotIrreductibleEl = document.getElementById("cotisationIrreductible"); + if (!cotRCCHTEl || !cotRCEHTEl || !cotIrreductibleEl) return; - document.getElementById("cotisationIrreductible").value = ((cotRCCHT + cotRCEHT) * 0.8).toFixed(2); + const cotRCCHT = parseValidationNumber(cotRCCHTEl.value); + const cotRCEHT = parseValidationNumber(cotRCEHTEl.value); + if (!Number.isFinite(cotRCCHT) || !Number.isFinite(cotRCEHT)) return; + + cotIrreductibleEl.value = ((cotRCCHT + cotRCEHT) * 0.8).toFixed(2); } + /** + * Calcule add taxe. + */ function calcAddTaxe(idHT, valueTaxe, idTTC) { - const valueHT = parseFloat(document.getElementById(idHT).value) || 0 + const htEl = document.getElementById(idHT); + const ttcEl = document.getElementById(idTTC); + if (!htEl || !ttcEl) return; + + const valueHT = parseValidationNumber(htEl.value); + if (!Number.isFinite(valueHT)) return; if (idTTC != "tauxRCCTTC" && idTTC != "tauxRCETTC") { - document.getElementById(idTTC).value = (valueHT * (1 + valueTaxe)).toFixed(2); + ttcEl.value = (valueHT * (1 + valueTaxe)).toFixed(2); } else { - document.getElementById(idTTC).value = (valueHT * (1 + valueTaxe)).toFixed(3); + ttcEl.value = (valueHT * (1 + valueTaxe)).toFixed(3); } } + /** + * Calcule sub taxe. + */ function calcSubTaxe(idHT, valueTaxe, idTTC) { - const valueTTC = parseFloat(document.getElementById(idTTC).value) || 0 + const htEl = document.getElementById(idHT); + const ttcEl = document.getElementById(idTTC); + if (!htEl || !ttcEl) return; + + const valueTTC = parseValidationNumber(ttcEl.value); + if (!Number.isFinite(valueTTC)) return; if (idHT != "tauxRCCHT" && idHT != "tauxRCEHT") { - document.getElementById(idHT).value = (valueTTC / (1 + valueTaxe)).toFixed(2); + htEl.value = (valueTTC / (1 + valueTaxe)).toFixed(2); } else { - document.getElementById(idHT).value = (valueTTC / (1 + valueTaxe)).toFixed(3); + htEl.value = (valueTTC / (1 + valueTaxe)).toFixed(3); } } // Gérer la soumission du formulaire + /** + * Gere submit form. + */ async function handleSubmitForm(event) { event.preventDefault(); + await refreshTarifReferenceFromApi(); updatePrimeReferenceRow(); + updateTarifCommercialRows(); if (rcProjetGuard && rcProjetGuard.refresh().length > 0) { M.toast({ html: 'Corrigez les erreurs du formulaire avant de continuer.', classes: 'red' }); @@ -4129,6 +4719,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction helper pour récupérer valeur ou "Nous consulter" + /** + * Recupere value or consulter. + */ function getValueOrConsulter(id) { const element = document.getElementById(id); if (!element) return 'Nous consulter'; @@ -4137,6 +4730,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction exposée pour sauvegarder le projet sans générer le document + /** + * Sauvegarde projet rc. + */ async function saveProjetRC() { try { updatePrimeReferenceRow(); diff --git a/ecole/public/js/rc-data-manager.js b/ecole/public/js/rc/rc-data-manager.js similarity index 100% rename from ecole/public/js/rc-data-manager.js rename to ecole/public/js/rc/rc-data-manager.js diff --git a/ecole/public/js/rc-orchestrator.js b/ecole/public/js/rc/rc-orchestrator.js similarity index 100% rename from ecole/public/js/rc-orchestrator.js rename to ecole/public/js/rc/rc-orchestrator.js diff --git a/ecole/public/js/rc-sync-utils.js b/ecole/public/js/rc/rc-sync-utils.js similarity index 100% rename from ecole/public/js/rc-sync-utils.js rename to ecole/public/js/rc/rc-sync-utils.js diff --git a/ecole/public/js/rc-validation-utils.js b/ecole/public/js/rc/rc-validation-utils.js similarity index 82% rename from ecole/public/js/rc-validation-utils.js rename to ecole/public/js/rc/rc-validation-utils.js index 380d05ff..45b09901 100644 --- a/ecole/public/js/rc-validation-utils.js +++ b/ecole/public/js/rc/rc-validation-utils.js @@ -1,9 +1,15 @@ (function () { + /** + * Normalise numeric input. + */ function normalizeNumericInput(raw) { if (raw == null) return ''; return String(raw).trim().replace(/\s+/g, ''); } + /** + * Parse loose number. + */ function parseLooseNumber(raw) { const normalized = normalizeNumericInput(raw).replace(',', '.'); if (!normalized) return NaN; @@ -11,6 +17,9 @@ return Number.isFinite(parsed) ? parsed : NaN; } + /** + * Formate french amount. + */ function formatFrenchAmount(value, digits) { const number = Number(value); if (!Number.isFinite(number)) return '0.00'; @@ -20,6 +29,9 @@ }); } + /** + * Synchronise floating labels. + */ function syncFloatingLabels(root) { const scope = root && root.querySelectorAll ? root : document; const labels = scope.querySelectorAll('.rc-field-label[for]'); @@ -64,6 +76,9 @@ } } + /** + * Securise error slot. + */ function ensureErrorSlot(field, customErrorId) { if (!field) return null; @@ -92,6 +107,9 @@ return sibling; } + /** + * Gere pick field label. + */ function pickFieldLabel(field, fallbackLabel) { if (fallbackLabel) return fallbackLabel; if (!field) return 'Champ'; @@ -110,6 +128,9 @@ return field.name || field.id || 'Champ'; } + /** + * Met a jour field error. + */ function setFieldError(field, errorSlot, message) { if (!errorSlot) return; errorSlot.textContent = message || ''; @@ -124,10 +145,16 @@ } } + /** + * Verifie forbidden numeric chars. + */ function hasForbiddenNumericChars(value) { return /[A-Za-z€$£¥]/.test(value); } + /** + * Gere validate numeric. + */ function validateNumeric(value, options) { const raw = normalizeNumericInput(value); const decimals = Number.isInteger(options.decimals) ? options.decimals : 2; @@ -182,6 +209,9 @@ return { valid: true, normalized: raw.replace(',', '.') }; } + /** + * Gere validate integer. + */ function validateInteger(value, options) { const raw = normalizeNumericInput(value); const label = options.label || 'Champ'; @@ -209,6 +239,9 @@ return { valid: true }; } + /** + * Gere validate immat. + */ function validateImmat(value, options) { const raw = String(value || '').trim().toUpperCase(); const label = options.label || 'Immatriculation'; @@ -227,6 +260,9 @@ return { valid: true, normalized: raw }; } + /** + * Gere validate text safe. + */ function validateTextSafe(value, options) { const raw = String(value || '').trim(); const label = options.label || 'Champ'; @@ -250,6 +286,9 @@ return { valid: true }; } + /** + * Gere validate number or consult. + */ function validateNumberOrConsult(raw, options) { const value = String(raw || '').trim(); const lower = value.toLowerCase(); @@ -268,6 +307,9 @@ return validateNumeric(value, options); } + /** + * Gere evaluate rule. + */ function evaluateRule(field, config) { const profile = config.profile; const label = pickFieldLabel(field, config.label); @@ -331,11 +373,17 @@ }; } + /** + * Gere create summary element. + */ function createSummaryElement(summaryId) { if (!summaryId) return null; return document.getElementById(summaryId); } + /** + * Gere create guard. + */ function createGuard(options) { const summary = createSummaryElement(options.summaryId); const summaryTitle = String(options.summaryTitle || 'Impossible de continuer car :'); @@ -357,6 +405,9 @@ }); }); + /** + * Gere apply summary. + */ function applySummary(messages) { if (!summary) return; if (!messages.length) { @@ -379,6 +430,9 @@ summary.style.display = 'block'; } + /** + * Gere apply blocking. + */ function applyBlocking(hasErrors) { state.targetButtons.forEach(function (button) { if (!button) return; @@ -395,6 +449,9 @@ }); } + /** + * Gere recompute. + */ function recompute() { const messages = []; @@ -405,10 +462,15 @@ }); state.externalChecks.forEach(function (entry, key) { - const checkResult = typeof entry.fn === 'function' ? entry.fn() : { valid: true }; - if (!checkResult || checkResult.valid === false) { - const message = checkResult && checkResult.message ? checkResult.message : entry.message || key; - messages.push(message); + try { + const checkResult = typeof entry.fn === 'function' ? entry.fn() : { valid: true }; + if (!checkResult || checkResult.valid === false) { + const message = checkResult && checkResult.message ? checkResult.message : entry.message || key; + messages.push(message); + } + } catch (error) { + console.warn('[RC guard] Check externe en erreur:', key, error); + messages.push(entry.message || ('Validation en erreur: ' + key)); } }); @@ -422,46 +484,65 @@ return messages; } + /** + * Gere validate field. + */ function validateField(field) { - const config = state.fieldRules.get(field); - if (!config) return; + try { + const config = state.fieldRules.get(field); + if (!config) return; + + if (!field || !field.isConnected || field.disabled) { + if (config.errorSlot) setFieldError(field, config.errorSlot, ''); + state.fieldErrors.delete(config.key); + recompute(); + return; + } + + if (typeof config.activeWhen === 'function' && !config.activeWhen(field)) { + setFieldError(field, config.errorSlot, ''); + state.fieldErrors.delete(config.key); + recompute(); + return; + } + + // Sécurité défaut: sans activeWhen explicite, on ignore un champ masqué. + if (typeof config.activeWhen !== 'function' && field.type !== 'hidden' && field.offsetParent === null) { + setFieldError(field, config.errorSlot, ''); + state.fieldErrors.delete(config.key); + recompute(); + return; + } + + const result = evaluateRule(field, config); + setFieldError(field, config.errorSlot, result.valid ? '' : result.message); + + if (result.valid) { + state.fieldErrors.delete(config.key); + } else { + state.fieldErrors.set(config.key, { + message: result.message + }); + } - if (!field || !field.isConnected || field.disabled) { - if (config.errorSlot) setFieldError(field, config.errorSlot, ''); - state.fieldErrors.delete(config.key); recompute(); - return; - } - - if (typeof config.activeWhen === 'function' && !config.activeWhen(field)) { - setFieldError(field, config.errorSlot, ''); - state.fieldErrors.delete(config.key); - recompute(); - return; - } - - // Sécurité défaut: sans activeWhen explicite, on ignore un champ masqué. - if (typeof config.activeWhen !== 'function' && field.type !== 'hidden' && field.offsetParent === null) { - setFieldError(field, config.errorSlot, ''); - state.fieldErrors.delete(config.key); - recompute(); - return; - } - - const result = evaluateRule(field, config); - setFieldError(field, config.errorSlot, result.valid ? '' : result.message); - - if (result.valid) { - state.fieldErrors.delete(config.key); - } else { - state.fieldErrors.set(config.key, { - message: result.message + } catch (error) { + const config = state.fieldRules.get(field); + const key = config && config.key ? config.key : 'champ-inconnu'; + console.warn('[RC guard] Validation en erreur:', key, error); + if (config && config.errorSlot) { + setFieldError(field, config.errorSlot, 'Erreur de validation, rechargez la page.'); + } + state.fieldErrors.set(key, { + message: 'Erreur de validation sur un champ du formulaire.' }); + recompute(); } - - recompute(); } + /** + * Gere attach field. + */ function attachField(field, config) { if (!field) return; @@ -489,6 +570,9 @@ validateField(field); } + /** + * Enregistre field. + */ function registerField(selectorOrElement, config) { if (!selectorOrElement || !config || !config.profile) return; if (typeof selectorOrElement === 'string') { @@ -500,6 +584,9 @@ attachField(selectorOrElement, config); } + /** + * Gere observe. + */ function observe(selector, config) { if (!selector || !config || !config.profile) return; @@ -517,6 +604,9 @@ return observer; } + /** + * Enregistre external. + */ function registerExternal(key, fn, fallbackMessage) { if (!key || typeof fn !== 'function') return; state.externalChecks.set(key, { @@ -526,6 +616,9 @@ recompute(); } + /** + * Gere refresh. + */ function refresh() { state.fieldRules.forEach(function (_cfg, field) { validateField(field); diff --git a/ecole/public/js/tarif-form-rc.js b/ecole/public/js/rc/tarif-form-rc.js similarity index 98% rename from ecole/public/js/tarif-form-rc.js rename to ecole/public/js/rc/tarif-form-rc.js index b739855c..541f30c8 100644 --- a/ecole/public/js/tarif-form-rc.js +++ b/ecole/public/js/rc/tarif-form-rc.js @@ -1,8 +1,14 @@ +/** + * Initialise submenu form. + */ function initSubmenuForm() { // Accéder aux informations stockées du parcours const parcours = JSON.parse(sessionStorage.getItem('parcours')); } +/** + * Convertit number. + */ function toNumber(x) { if (x == null) return 0; @@ -45,6 +51,9 @@ function toNumber(x) { } // Fonction pour formater un nombre avec X décimales max (sans décimales si entier) +/** + * Formate number. + */ function formatNumber(num, decimals = 2) { if (!num || isNaN(num)) return '0.' + '0'.repeat(decimals); const factor = Math.pow(10, decimals); @@ -56,6 +65,9 @@ function formatNumber(num, decimals = 2) { return rounded.toFixed(decimals); } +/** + * Recupere element by id flexible. + */ function getElementByIdFlexible(id) { if (!id) return null; const direct = document.getElementById(id); @@ -78,12 +90,18 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio let rcTarifGuard = null; let rcTarifHasErrors = false; + /** + * Synchronise rcfloating labels. + */ function syncRCFloatingLabels() { if (window.RCValidationUtils && typeof window.RCValidationUtils.syncFloatingLabels === 'function') { window.RCValidationUtils.syncFloatingLabels(document); } } + /** + * Met a jour tarifettes visibility. + */ function updateTarifettesVisibility() { const tarifettesContainer = document.getElementById('tarifettesContainer'); if (!tarifettesContainer) return; @@ -95,6 +113,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio // ═══════════════════════════════════════════════════════════════ // Fonction helper : trouver la tranche la plus proche + /** + * Trouve closest tranche. + */ function findClosestTranche(val, tranches) { if (val <= tranches[0]) return tranches[0]; if (val >= tranches[tranches.length - 1]) return tranches[tranches.length - 1]; @@ -107,6 +128,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return tranches[tranches.length - 1]; } + /** + * Met a jour tarif choice buttons state. + */ function updateTarifChoiceButtonsState() { const buttons = document.querySelectorAll('.franchise-card button[name]'); buttons.forEach((button) => { @@ -122,6 +146,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio updateTarifettesVisibility(); } + /** + * Configure rcsafe validation. + */ function setupRCSafeValidation() { if (!window.RCValidationUtils || typeof window.RCValidationUtils.createGuard !== 'function') { return; @@ -130,7 +157,7 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio rcTarifGuard = window.RCValidationUtils.createGuard({ summaryId: 'rcTarifBlockingSummary', summaryTitle: 'Impossible de choisir un tarif ou de continuer car :', - blockTargets: ['#generateDeclinaison', '#generateProject', '#comm-OK'], + blockTargets: ['#generateDeclinaison', '#generateProject'], onChange: function (messages) { rcTarifHasErrors = messages.length > 0; updateTarifChoiceButtonsState(); @@ -267,30 +294,6 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } }); - rcTarifGuard.registerField('#tarifCom', { - profile: 'numeric', - label: 'Tarif commercial', - min: 0, - positive: true, - requiredWhen: function () { - return Boolean(document.getElementById('modalTarifCom')?.classList.contains('open')); - }, - activeWhen: function () { - return Boolean(document.getElementById('modalTarifCom')?.classList.contains('open')); - } - }); - - rcTarifGuard.registerField('#commentaire', { - profile: 'text', - label: 'Commentaire explicatif', - requiredWhen: function () { - return document.getElementById('tarifCom-error')?.style.display !== 'none'; - }, - activeWhen: function () { - return document.getElementById('col-commentaire')?.style.display !== 'none'; - } - }); - rcTarifGuard.observe('#tabAdvaloTerrestre input[type="text"], #tabAdvaloMultimodal input[type="text"], #tabAdvaloAerien input[type="text"]', { profile: 'number_or_consulter', label: 'Valeur ad valorem', @@ -328,6 +331,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction pour afficher un avertissement visuel de dépassement % + /** + * Affiche percentage warning. + */ function showPercentageWarning(excess) { let warningDiv = document.getElementById('percentageWarning'); if (!warningDiv) { @@ -357,6 +363,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction pour masquer toutes les primes (quand % invalide) + /** + * Masque all primes. + */ function hideAllPrimes() { const primeElements = [ 'primeChapActRCC', 'primeChapActRCE', @@ -376,6 +385,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction pour mettre à jour l'indicateur visuel du total des pourcentages + /** + * Met a jour percentage indicator. + */ function updatePercentageIndicator(total) { const indicator = document.getElementById('pourcentageTotal'); if (!indicator) return; @@ -405,6 +417,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio // ═══════════════════════════════════════════════════════════════ // Initialisation du formulaire et des données + /** + * Initialise la logique de cette fonction. + */ function init() { // Materialize init select var select = document.querySelectorAll('select'); @@ -467,6 +482,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Configuration des listeners d'événements + /** + * Configure event listeners. + */ function setupEventListeners() { // Empêcher la soumission du formulaire avec la touche Enter const form = document.getElementById('projetForm'); @@ -1181,6 +1199,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio // Le bouton Annuler ferme automatiquement le modal grâce à la classe "modal-close" } + /** + * Parse prefill array. + */ function parsePrefillArray(value) { if (Array.isArray(value)) return value; if (typeof value === 'string') { @@ -1194,6 +1215,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return []; } + /** + * Normalise prefill value. + */ function normalizePrefillValue(value) { if (Array.isArray(value)) { return value @@ -1223,6 +1247,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return value; } + /** + * Gere build projet prefill delta. + */ function buildProjetPrefillDelta(snapshot, baseline) { if (!snapshot || typeof snapshot !== 'object') return null; if (!baseline || typeof baseline !== 'object') return snapshot; @@ -1240,6 +1267,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return Object.keys(delta).length > 0 ? delta : null; } + /** + * Gere apply projet data to tarif. + */ function applyProjetDataToTarif(projetSource) { if (!projetSource || typeof projetSource !== 'object') return; @@ -1503,6 +1533,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Peupler le formulaire avec les données + /** + * Gere populate form data. + */ function populateFormData() { //Poupulate select historique if (!contrat.historique) { @@ -1877,6 +1910,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }, 500); } + /** + * Calcule mod ca. + */ function calcModCA(caRaw){ const ca = Number(String(caRaw || '').replace(/\s/g,'').replace(',','.')) || 0; const thresholds = Object.keys(modRCCA).map(n => Number(n)).sort((a,b)=>a-b); @@ -1884,6 +1920,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return modRCCA[thresholds.at(-1)] ?? 1; } + /** + * Calcule mod marchandises. + */ function calcModMarchandises(data, activityName, type, cot) { let m = 1; @@ -1927,6 +1966,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return m; } + /** + * Recupere zone mods. + */ function getZoneMods(data) { let mRCC = 1; let mRCE = 1; @@ -1958,6 +2000,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return { mRCC, mRCE }; } + /** + * Calcule mod act compl. + */ function calcModActCompl(data, activityName, type, cot) { let m = 1; const current = getSelectedActivities().find(a => a.typeActivite === activityName); @@ -1970,12 +2015,18 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return m; } + /** + * Calcule engag compl. + */ function calcEngagCompl(data, primeRCC) { let prime = primeRCC; let surPrime = 0; let modDommImmat = 1; let infos = []; + /** + * Gere write to card. + */ function writeToCard(inputId, message) { const inputEl = document.getElementById(inputId); if (!inputEl) return; @@ -2078,6 +2129,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction helper : trouver la tranche la plus proche + /** + * Trouve closest tranche. + */ function findClosestTranche(val, tranches) { if (val <= tranches[0]) return tranches[0]; if (val >= tranches[tranches.length - 1]) return tranches[tranches.length - 1]; @@ -2092,6 +2146,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction pour afficher un avertissement visuel de dépassement % + /** + * Affiche percentage warning. + */ function showPercentageWarning(excess) { // Créer ou récupérer le div d'avertissement let warningDiv = document.getElementById('percentageWarning'); @@ -2124,6 +2181,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction pour masquer toutes les primes (quand % invalide) + /** + * Masque all primes. + */ function hideAllPrimes() { const primeElements = [ 'primeChapActRCC', 'primeChapActRCE', @@ -2143,10 +2203,16 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction pour afficher toutes les primes (quand % valide) + /** + * Affiche all primes. + */ function showAllPrimes() { } // Fonction pour mettre à jour l'indicateur visuel du total des pourcentages + /** + * Met a jour percentage indicator. + */ function updatePercentageIndicator(total) { const indicator = document.getElementById('pourcentageTotal'); if (!indicator) return; @@ -2182,6 +2248,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Calcule gar add. + */ function calcGarAdd(data, primeRCC, primeRCE) { let primeRCCres = Number(primeRCC) || 0; let primeRCEres = Number(primeRCE) || 0; @@ -2189,6 +2258,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio const infosRCC = []; const infosRCE = []; + /** + * Gere write to card. + */ function writeToCard(inputId, message) { const inputEl = document.getElementById(inputId); if (!inputEl) return; @@ -2276,6 +2348,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio + /** + * Calcule sinistre. + */ function calcSinistre(data, primeRCC, primeRCE) { console.log('[calcSinistre] start', { primeRCC, primeRCE }); @@ -2327,6 +2402,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio // --- Fonctions utilitaires --- + /** + * Recupere max mini rcc. + */ function getMaxMiniRCC(activites, cot) { let maxMini = 0; activites.forEach(act => { @@ -2355,6 +2433,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return maxMini; } + /** + * Recupere max mini rce. + */ function getMaxMiniRCE(activites, cot) { let maxMini = 0; activites.forEach(act => { @@ -2384,6 +2465,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } + /** + * Calcule tarif rcc. + */ function calcTarifRCC({ CA, primeRCCbase, @@ -2449,6 +2533,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } + /** + * Calcule tarifettes. + */ function calcTarifettes(primePJ, CA, activites, capitalTPPC, nbVehicules, coefTPPC, primeRCCbase, primeRCEbase) { const cards = [ { key: "250", priceId: "priceFr250", rccId: "rccFr250", rceId: "rceFr250", pjId: "pjFr250", txRccId: "tauxRccFr250", txRceId: "tauxRceFr250", txGlobId: "tauxGlobalFr250" }, @@ -2573,6 +2660,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction pour calculer la PJ selon la prime totale + /** + * Calcule pj. + */ function calcPJ(primeTotale) { let primePJ = 0; const tablePJ = modRCGarAdd?.modRCC?.["Protection juridique"]; @@ -2592,6 +2682,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio + /** + * Calcule global. + */ function calcGlobal() { // Vérification des pourcentages AVANT calcul const allPourcentInputs = Array.from(document.querySelectorAll('.input-pourcent')).filter(p => p.offsetParent != null); @@ -2631,6 +2724,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio updateTarifChoiceButtonsState(); } + /** + * Calcule revisable. + */ function calcRevisable() { // ========= Variables centrales (déclarées au début) ========= const capitalTPPCEl = document.getElementById("capital_TPPC"); @@ -2856,6 +2952,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio "Autres activites": "Autres activites" }; + /** + * Recupere selected activites. + */ function getSelectedActivites() { const activites = []; document.querySelectorAll('label input[type="checkbox"]:checked').forEach(cb => { @@ -2885,6 +2984,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }; } + /** + * Calcule forfaitaire. + */ function calcForfaitaire() { // ========= Variables centrales ========= let primeBaseRCC = 0; @@ -3139,6 +3241,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio "Autres activites": "Autres activites" }; + /** + * Recupere selected activites. + */ function getSelectedActivites() { const activites = []; document.querySelectorAll('label input[type="checkbox"]:checked').forEach(cb => { @@ -3167,6 +3272,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio }; } + /** + * Recupere zone mods. + */ function getZoneMods(modRCZone) { const zones = [ { id: 'zone1', label: 'France Métropolitaine et pays limitrophes' }, @@ -3191,6 +3299,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } + /** + * Gere load historique btn. + */ function handleLoadHistoriqueBtn() { var selectedId = document.getElementById('idSelect').value; @@ -3213,6 +3324,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } //Appel pour recevoir les constantes + /** + * Gere constants json. + */ async function constantsJSON() { try { const responsesJSON = await Promise.all([ @@ -3249,6 +3363,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Gere reset inputs. + */ function resetInputs() { // Sélection des éléments input pourcentage const pourcentInputs = document.querySelectorAll('.input-pourcent'); @@ -3280,6 +3397,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } } + /** + * Recupere taux base rcc. + */ function get_taux_base_RCC(grille_mod_RCC, cot) { const tauxOptimaux = []; const selections = getSelectedActivities(); @@ -3340,6 +3460,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } + /** + * Recupere taux base rce. + */ function get_taux_base_RCE(grille_mod_RCE, cot) { const tauxOptimaux = []; const selections = getSelectedActivities(); @@ -3372,6 +3495,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio return tauxOptimaux; } + /** + * Recupere selected activities. + */ function getSelectedActivities() { const selections = []; @@ -3503,6 +3629,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction pour sauvegarder les données tarifRC dans la base + /** + * Sauvegarde tarif rc. + */ async function saveTarifRC() { if (!rc || !contrat) { console.error('Données manquantes pour sauvegarder le tarif RC'); @@ -3741,6 +3870,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction helper pour collecter les activités complémentaires + /** + * Collecte activites compl json. + */ function collectActivitesComplJSON(typeActivite) { let name; switch(typeActivite.toLowerCase()) { @@ -3770,6 +3902,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction helper pour collecter les marchandises + /** + * Collecte marchandises json. + */ function collectMarchandisesJSON(typeActivite) { let name; switch(typeActivite.toLowerCase()) { @@ -3805,6 +3940,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction pour gérer les clics sur les boutons de tariffettes + /** + * Configure tarifette buttons. + */ function setupTarifetteButtons() { const tarifetteButtons = document.querySelectorAll('.franchise-card button[name]'); tarifetteButtons.forEach(button => { @@ -3827,6 +3965,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction pour configurer les alertes de marchandises + /** + * Configure marchandise alerts. + */ function setupMarchandiseAlerts() { // Alerte pour Animaux Vivants document.querySelectorAll('[name^="mar"] input[type="checkbox"]').forEach(cb => { @@ -3843,6 +3984,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio } // Fonction pour configurer les alertes d'activités + /** + * Configure activite alerts. + */ function setupActiviteAlerts() { // Alerte pour Autocariste + RCE const checkAutocariste = document.getElementById('checkAutocariste'); @@ -3862,6 +4006,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio const seuil = 5; // Fonction pour ouvrir le modal de tarif commercial + /** + * Ouvre modal tarif com. + */ function openModalTarifCom(franchiseValue) { // Récupérer le tarif de référence selon la franchise let tarifRef = 0; @@ -3877,7 +4024,7 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio document.getElementById('tarifRefText').innerText = `Tarif de Référence : ${formatNumber(tarifRef, 2)} €`; document.getElementById('tarifCom').value = ''; document.getElementById('commentaire').value = ''; - document.getElementById('comm-OK').disabled = false; + document.getElementById('comm-OK').disabled = true; document.getElementById('tarifCom-error').style.display = 'none'; document.getElementById('col-commentaire').style.display = 'none'; document.getElementById('qualiteDiv').style.display = 'none'; @@ -3896,15 +4043,23 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio // Ouvrir le modal window.modalTarifCom.open(); + if (rcTarifGuard) rcTarifGuard.refresh(); } // Fonction pour gérer l'input du tarif commercial + /** + * Gere tarif com input. + */ function handleTarifComInput(e) { const tarifCom = parseFloat(e.target.value); const tarifRef = parseFloat(document.getElementById('comm-OK').getAttribute('data-tarif-ref')); if (!tarifCom || tarifCom <= 0) { document.getElementById('qualiteDiv').style.display = 'none'; + document.getElementById('tarifCom-error').style.display = 'none'; + document.getElementById('col-commentaire').style.display = 'none'; + document.getElementById('comm-OK').disabled = true; + if (rcTarifGuard) rcTarifGuard.refresh(); return; } @@ -3952,19 +4107,32 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio document.getElementById('tarifCom-error').style.display = 'none'; document.getElementById('col-commentaire').style.display = 'none'; } + + if (rcTarifGuard) rcTarifGuard.refresh(); } // Fonction pour gérer l'input du commentaire + /** + * Gere commentaire input. + */ function handleCommentaireInput(e) { const commentaire = e.target.value.trim(); + const tarifCom = parseFloat(document.getElementById('tarifCom').value); const tarifComError = document.getElementById('tarifCom-error').style.display !== 'none'; if (tarifComError) { - document.getElementById('comm-OK').disabled = !commentaire; + document.getElementById('comm-OK').disabled = !commentaire || !tarifCom || tarifCom <= 0; + } else { + document.getElementById('comm-OK').disabled = !tarifCom || tarifCom <= 0; } + + if (rcTarifGuard) rcTarifGuard.refresh(); } // Fonction pour gérer la validation du tarif commercial + /** + * Gere validate tarif com. + */ async function handleValidateTarifCom() { const tarifCom = parseFloat(document.getElementById('tarifCom').value); const commentaire = document.getElementById('commentaire').value.trim(); diff --git a/ecole/public/js/projet-form-tppc.js b/ecole/public/js/tppc/projet-form-tppc.js similarity index 100% rename from ecole/public/js/projet-form-tppc.js rename to ecole/public/js/tppc/projet-form-tppc.js diff --git a/ecole/public/js/tarif-form-tppc.js b/ecole/public/js/tppc/tarif-form-tppc.js similarity index 100% rename from ecole/public/js/tarif-form-tppc.js rename to ecole/public/js/tppc/tarif-form-tppc.js diff --git a/ecole/public/js/verif-form.js b/ecole/public/js/verif-form.js index ceb025b1..2d5ec4af 100644 --- a/ecole/public/js/verif-form.js +++ b/ecole/public/js/verif-form.js @@ -4,161 +4,187 @@ function isValidEmail(email) { } function validateField(fieldId, showErrors = true) { - const inputElement = document.getElementById(fieldId); + try { + const inputElement = document.getElementById(fieldId); - if (!inputElement) { - return true; - } + if (!inputElement) { + return true; + } - const value = document.getElementById(fieldId).value.trim(); - const rule = validationRules[fieldId]; // Importé de js/json/json-verif-form.js - const errorElement = document.getElementById(`${fieldId}-error`); + const rawValue = inputElement.value; + const value = typeof rawValue === 'string' ? rawValue.trim() : String(rawValue ?? '').trim(); + const hasValidationRules = typeof validationRules !== 'undefined' && validationRules; + const rule = hasValidationRules ? validationRules[fieldId] : null; // Importé de js/json/json-verif-form.js + const errorElement = document.getElementById(`${fieldId}-error`); - let isValid = true; - let errorMessage = ""; + if (!rule) { + if (showErrors && errorElement) { + errorElement.textContent = ""; + errorElement.style.display = 'none'; + } + return true; + } - // Vérifie si le champ est requis et vide + let isValid = true; + let errorMessage = ""; - if (rule.required && (!value || value == '')) { - errorMessage = "Ce champ est obligatoire."; - isValid = false; - } - - // Vérifie la longueur de la saisie si spécifié et nécessaire - if (isValid && value && rule.length && value.length !== rule.length) { - errorMessage = `Veuillez saisir ${rule.length} caractères, il y en a actuellement ${value.length}.`; - isValid = false; - } - - // Vérifie si la saisie est un nombre sans décimale ou avec un maximum de deux chiffres après la virgule - if (isValid && value && rule.numberFormat) { - const isNumberFormatValid = /^(?:\d+|\d+\.\d{1,2})$/.test(value); - - if (!isNumberFormatValid) { - errorMessage = "Le champ doit être nombre de deux décimal maximum '00.00' ou entier '00'"; + // Vérifie si le champ est requis et vide + if (rule.required && (!value || value == '')) { + errorMessage = "Ce champ est obligatoire."; isValid = false; } - } - // Vérifie si la saisie est un taux sans décimale ou avec un maximum de trois chiffres après la virgule - if (isValid && value && rule.tauxFormat) { - const isTauxFormatValid = /^(?:\d+|\d+\.\d{1,3})$/.test(value); - - if (!isTauxFormatValid) { - errorMessage = "Le champ doit être un nombre avec un maximum de trois décimales '00.000' ou entier '00'"; + // Vérifie la longueur de la saisie si spécifié et nécessaire + if (isValid && value && rule.length && value.length !== rule.length) { + errorMessage = `Veuillez saisir ${rule.length} caractères, il y en a actuellement ${value.length}.`; isValid = false; } - } - // Vérifie si le champ doit être compris dans un certain intervalle - if (isValid && value && rule.range) { - const numberValue = parseFloat(value); + // Vérifie si la saisie est un nombre sans décimale ou avec un maximum de deux chiffres après la virgule + if (isValid && value && rule.numberFormat) { + const isNumberFormatValid = /^(?:\d+|\d+\.\d{1,2})$/.test(value); - if (isNaN(numberValue) || numberValue < rule.range.min || numberValue > rule.range.max) { - errorMessage = rule.errorMsg; + if (!isNumberFormatValid) { + errorMessage = "Le champ doit être nombre de deux décimal maximum '00.00' ou entier '00'"; + isValid = false; + } + } + + // Vérifie si la saisie est un taux sans décimale ou avec un maximum de trois chiffres après la virgule + if (isValid && value && rule.tauxFormat) { + const isTauxFormatValid = /^(?:\d+|\d+\.\d{1,3})$/.test(value); + + if (!isTauxFormatValid) { + errorMessage = "Le champ doit être un nombre avec un maximum de trois décimales '00.000' ou entier '00'"; + isValid = false; + } + } + + // Vérifie si le champ doit être compris dans un certain intervalle + if (isValid && value && rule.range) { + const numberValue = parseFloat(value); + + if (isNaN(numberValue) || numberValue < rule.range.min || numberValue > rule.range.max) { + errorMessage = rule.errorMsg; + isValid = false; + } + } + + // Valide l'adresse e-mail seulement si le champ n'est pas vide + if (isValid && value && rule.email) { + if (!isValidEmail(value)) { + errorMessage = rule.errorMsg; + isValid = false; + } + } + + // Vérifie la présence de caractères potentiellement problématiques + const specialCharsPattern = /[;">&<]/g; + let invalidChars = value.match(specialCharsPattern); + + if (isValid && value && invalidChars) { + invalidChars = [...new Set(invalidChars)]; + errorMessage = `Caractère(s) invalide(s) détecté(s) [ ${invalidChars.join(" ")} ].`; isValid = false; } - } - // Valide l'adresse e-mail seulement si le champ n'est pas vide - if (isValid && value && rule.email) { - if (!isValidEmail(value)) { - errorMessage = rule.errorMsg; + // Vérifie si le champ commence par le caractère spécifié + if (isValid && value && rule.startsWith && !value.startsWith(rule.startsWith)) { + errorMessage = `Le champ doit commencer par '${rule.startsWith}' majuscule.`; isValid = false; } - } - // Vérifie la présence de caractères potentiellement problématiques - const specialCharsPattern = /[;">&<]/g; - let invalidChars = value.match(specialCharsPattern); + // Vérifie si le champ date est correct + if (isValid && value && rule.dateFormat) { + const isDateFormatValid = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[012])\/\d{4}$|^00\/00\/0000$/.test(value); - if (isValid && value && invalidChars) { - invalidChars = [...new Set(invalidChars)]; - errorMessage = `Caractère(s) invalide(s) détecté(s) [ ${invalidChars.join(" ")} ].`; - isValid = false; - } - - // Vérifie si le champ commence par le caractère spécifié - if (isValid && value && rule.startsWith && !value.startsWith(rule.startsWith)) { - errorMessage = `Le champ doit commencer par '${rule.startsWith}' majuscule.`; - isValid = false; - } - - // Vérifie si le champ date est correct - if (isValid && value && rule.dateFormat) { - const isDateFormatValid = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[012])\/\d{4}$|^00\/00\/0000$/.test(value); - - if (!isDateFormatValid) { - errorMessage = "Le champ doit être au format JJ//MM/AAAA ou 00/00/0000."; - isValid = false; + if (!isDateFormatValid) { + errorMessage = "Le champ doit être au format JJ//MM/AAAA ou 00/00/0000."; + isValid = false; + } } - } - // Vérifie si la saisie ne contient pas d'espace - if (isValid && value && rule.noSpace) { - const isNoSpaceValid = /^\S*$/.test(value); + // Vérifie si la saisie ne contient pas d'espace + if (isValid && value && rule.noSpace) { + const isNoSpaceValid = /^\S*$/.test(value); - if (!isNoSpaceValid) { - errorMessage = "La saisie ne doit pas contenir d'espaces."; - isValid = false; + if (!isNoSpaceValid) { + errorMessage = "La saisie ne doit pas contenir d'espaces."; + isValid = false; + } } - } - // Vérifie si le champ date est correct au format JJ/MM - if (isValid && value && rule.dateFormatShort) { - const isDateFormatShortValid = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[012])$|^00\/00$/.test(value); + // Vérifie si le champ date est correct au format JJ/MM + if (isValid && value && rule.dateFormatShort) { + const isDateFormatShortValid = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[012])$|^00\/00$/.test(value); - if (!isDateFormatShortValid) { - errorMessage = "Le champ doit être au format JJ/MM ou 00/00."; - isValid = false; + if (!isDateFormatShortValid) { + errorMessage = "Le champ doit être au format JJ/MM ou 00/00."; + isValid = false; + } } - } - // Vérifie la casse des caractères si spécifié - if (isValid && value && rule.case) { - if (rule.case === "upper" && value !== value.toUpperCase()) { - errorMessage = "Le champ doit être en majuscules."; - isValid = false; - } else if (rule.case === "lower" && value !== value.toLowerCase()) { - errorMessage = "Le champ doit être en minuscules."; - isValid = false; + // Vérifie la casse des caractères si spécifié + if (isValid && value && rule.case) { + if (rule.case === "upper" && value !== value.toUpperCase()) { + errorMessage = "Le champ doit être en majuscules."; + isValid = false; + } else if (rule.case === "lower" && value !== value.toLowerCase()) { + errorMessage = "Le champ doit être en minuscules."; + isValid = false; + } } - } - // Vérifie si le champ doit être numérique - if (isValid && value && rule.digit) { - const isNumeric = /^\d+$/.test(value); // Vérifie si la chaîne est un nombre entier + // Vérifie si le champ doit être numérique + if (isValid && value && rule.digit) { + const isNumeric = /^\d+$/.test(value); // Vérifie si la chaîne est un nombre entier - if (!isNumeric) { - errorMessage = "Le champ doit contenir uniquement des chiffres."; - isValid = false; + if (!isNumeric) { + errorMessage = "Le champ doit contenir uniquement des chiffres."; + isValid = false; + } } - } - // Affiche ou cache le message d'erreur selon la validité du champ - if (showErrors) { - errorElement.textContent = errorMessage; - errorElement.style.display = isValid ? 'none' : 'block'; - } + // Affiche ou cache le message d'erreur selon la validité du champ + if (showErrors && errorElement) { + errorElement.textContent = errorMessage; + errorElement.style.display = isValid ? 'none' : 'block'; + } - return isValid; + return isValid; + } catch (error) { + console.warn('Validation interrompue pour le champ:', fieldId, error); + return false; + } } function updateSubmitButtonState(formId) { let allFieldsValid = true; const form = document.querySelector(`#${formId}`); + const hasValidationRules = typeof validationRules !== 'undefined' && validationRules; if (!form) { console.error('Formulaire non trouvé:', formId); return; } - for (const fieldId in validationRules) { - const inputElement = form.querySelector(`#${fieldId}`); + if (!hasValidationRules) { + return; + } - if (inputElement && !validateField(fieldId, false)) { - allFieldsValid = false; + for (const fieldId in validationRules) { + const inputElement = document.getElementById(fieldId); + + if (inputElement && form.contains(inputElement)) { + try { + if (!validateField(fieldId, false)) { + allFieldsValid = false; + } + } catch (error) { + console.warn('Erreur pendant la validation du champ:', fieldId, error); + allFieldsValid = false; + } } } @@ -169,4 +195,4 @@ function updateSubmitButtonState(formId) { button.disabled = !allFieldsValid; }) } -} \ No newline at end of file +} diff --git a/ecole/src/db/pb_data/data.db b/ecole/src/db/pb_data/data.db index 7a47c5a3..44ff364e 100644 Binary files a/ecole/src/db/pb_data/data.db and b/ecole/src/db/pb_data/data.db differ diff --git a/ecole/src/db/pb_data/data.db-shm b/ecole/src/db/pb_data/data.db-shm index f18b1bf9..b03ca011 100644 Binary files a/ecole/src/db/pb_data/data.db-shm and b/ecole/src/db/pb_data/data.db-shm differ diff --git a/ecole/src/db/pb_data/data.db-wal b/ecole/src/db/pb_data/data.db-wal index 8d72c40e..e70acba8 100644 Binary files a/ecole/src/db/pb_data/data.db-wal and b/ecole/src/db/pb_data/data.db-wal differ diff --git a/ecole/src/db/pb_data/logs.db b/ecole/src/db/pb_data/logs.db index d098229f..b4d2350f 100644 Binary files a/ecole/src/db/pb_data/logs.db and b/ecole/src/db/pb_data/logs.db differ diff --git a/ecole/src/db/pb_data/logs.db-shm b/ecole/src/db/pb_data/logs.db-shm index e803f2b7..9125f7bd 100644 Binary files a/ecole/src/db/pb_data/logs.db-shm and b/ecole/src/db/pb_data/logs.db-shm differ diff --git a/ecole/src/db/pb_data/logs.db-wal b/ecole/src/db/pb_data/logs.db-wal index 9dcabf37..0ff2a2c2 100644 Binary files a/ecole/src/db/pb_data/logs.db-wal and b/ecole/src/db/pb_data/logs.db-wal differ diff --git a/ecole/views/layout.ejs b/ecole/views/layout.ejs index b906368b..47bb1280 100644 --- a/ecole/views/layout.ejs +++ b/ecole/views/layout.ejs @@ -60,17 +60,17 @@ - + - + - + - + diff --git a/ecole/views/projetformrc.ejs b/ecole/views/projetformrc.ejs index 1f13f397..12f78766 100644 --- a/ecole/views/projetformrc.ejs +++ b/ecole/views/projetformrc.ejs @@ -1,5 +1,4 @@
-
@@ -777,8 +776,7 @@
trending_up - - + Chiffre d'affaires
@@ -792,8 +790,7 @@
euro_symbol - - + Cotisation minimale irréductible
@@ -959,20 +956,20 @@ Frais de répertoire - + - + Prime HT de référence (tarif choisi) - + @@ -982,8 +979,20 @@ + + Tarif commercial saisi (étape Tarif) + + + + + + + + + + - Total + Total (retenu) @@ -1016,6 +1025,7 @@
Veuillez enregistrer toutes modifications sur le formulaire :
+
diff --git a/ecole/views/tarifformrc.ejs b/ecole/views/tarifformrc.ejs index 1780a536..d1bef496 100644 --- a/ecole/views/tarifformrc.ejs +++ b/ecole/views/tarifformrc.ejs @@ -1248,7 +1248,7 @@