RC: stabilise projet validation and reorganize product scripts
This commit is contained in:
parent
349c379dc7
commit
7b484f34c9
|
|
@ -37,7 +37,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
|
||||||
const parcours = JSON.parse(sessionStorage.getItem('parcours'));
|
const parcours = JSON.parse(sessionStorage.getItem('parcours'));
|
||||||
const contrat = JSON.parse(sessionStorage.getItem('contrat'));
|
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;
|
const produitObj = contrat?.["@expand"]?.enCours || null;
|
||||||
|
|
||||||
|
|
@ -60,10 +60,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
|
||||||
if (submenu === "projet") {
|
if (submenu === "projet") {
|
||||||
fetchUrl = `/navParcours/${submenu}${produit}?numParcours=${numParcours}`;
|
fetchUrl = `/navParcours/${submenu}${produit}?numParcours=${numParcours}`;
|
||||||
scriptSrc = `/js/projet-form-${produit}.js`;
|
scriptSrc = `/js/${produit}/projet-form-${produit}.js`;
|
||||||
} else if (submenu === "tarif") {
|
} else if (submenu === "tarif") {
|
||||||
fetchUrl = `/navParcours/${submenu}${produit}?numParcours=${numParcours}`;
|
fetchUrl = `/navParcours/${submenu}${produit}?numParcours=${numParcours}`;
|
||||||
scriptSrc = `/js/tarif-form-${produit}.js`;
|
scriptSrc = `/js/${produit}/tarif-form-${produit}.js`;
|
||||||
} else {
|
} else {
|
||||||
fetchUrl = `/navParcours/${submenu}?numParcours=${numParcours}`;
|
fetchUrl = `/navParcours/${submenu}?numParcours=${numParcours}`;
|
||||||
scriptSrc = `/js/${submenu}-form.js`;
|
scriptSrc = `/js/${submenu}-form.js`;
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,9 +1,15 @@
|
||||||
(function () {
|
(function () {
|
||||||
|
/**
|
||||||
|
* Normalise numeric input.
|
||||||
|
*/
|
||||||
function normalizeNumericInput(raw) {
|
function normalizeNumericInput(raw) {
|
||||||
if (raw == null) return '';
|
if (raw == null) return '';
|
||||||
return String(raw).trim().replace(/\s+/g, '');
|
return String(raw).trim().replace(/\s+/g, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse loose number.
|
||||||
|
*/
|
||||||
function parseLooseNumber(raw) {
|
function parseLooseNumber(raw) {
|
||||||
const normalized = normalizeNumericInput(raw).replace(',', '.');
|
const normalized = normalizeNumericInput(raw).replace(',', '.');
|
||||||
if (!normalized) return NaN;
|
if (!normalized) return NaN;
|
||||||
|
|
@ -11,6 +17,9 @@
|
||||||
return Number.isFinite(parsed) ? parsed : NaN;
|
return Number.isFinite(parsed) ? parsed : NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formate french amount.
|
||||||
|
*/
|
||||||
function formatFrenchAmount(value, digits) {
|
function formatFrenchAmount(value, digits) {
|
||||||
const number = Number(value);
|
const number = Number(value);
|
||||||
if (!Number.isFinite(number)) return '0.00';
|
if (!Number.isFinite(number)) return '0.00';
|
||||||
|
|
@ -20,6 +29,9 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronise floating labels.
|
||||||
|
*/
|
||||||
function syncFloatingLabels(root) {
|
function syncFloatingLabels(root) {
|
||||||
const scope = root && root.querySelectorAll ? root : document;
|
const scope = root && root.querySelectorAll ? root : document;
|
||||||
const labels = scope.querySelectorAll('.rc-field-label[for]');
|
const labels = scope.querySelectorAll('.rc-field-label[for]');
|
||||||
|
|
@ -64,6 +76,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Securise error slot.
|
||||||
|
*/
|
||||||
function ensureErrorSlot(field, customErrorId) {
|
function ensureErrorSlot(field, customErrorId) {
|
||||||
if (!field) return null;
|
if (!field) return null;
|
||||||
|
|
||||||
|
|
@ -92,6 +107,9 @@
|
||||||
return sibling;
|
return sibling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere pick field label.
|
||||||
|
*/
|
||||||
function pickFieldLabel(field, fallbackLabel) {
|
function pickFieldLabel(field, fallbackLabel) {
|
||||||
if (fallbackLabel) return fallbackLabel;
|
if (fallbackLabel) return fallbackLabel;
|
||||||
if (!field) return 'Champ';
|
if (!field) return 'Champ';
|
||||||
|
|
@ -110,6 +128,9 @@
|
||||||
return field.name || field.id || 'Champ';
|
return field.name || field.id || 'Champ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Met a jour field error.
|
||||||
|
*/
|
||||||
function setFieldError(field, errorSlot, message) {
|
function setFieldError(field, errorSlot, message) {
|
||||||
if (!errorSlot) return;
|
if (!errorSlot) return;
|
||||||
errorSlot.textContent = message || '';
|
errorSlot.textContent = message || '';
|
||||||
|
|
@ -124,10 +145,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifie forbidden numeric chars.
|
||||||
|
*/
|
||||||
function hasForbiddenNumericChars(value) {
|
function hasForbiddenNumericChars(value) {
|
||||||
return /[A-Za-z€$£¥]/.test(value);
|
return /[A-Za-z€$£¥]/.test(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere validate numeric.
|
||||||
|
*/
|
||||||
function validateNumeric(value, options) {
|
function validateNumeric(value, options) {
|
||||||
const raw = normalizeNumericInput(value);
|
const raw = normalizeNumericInput(value);
|
||||||
const decimals = Number.isInteger(options.decimals) ? options.decimals : 2;
|
const decimals = Number.isInteger(options.decimals) ? options.decimals : 2;
|
||||||
|
|
@ -182,6 +209,9 @@
|
||||||
return { valid: true, normalized: raw.replace(',', '.') };
|
return { valid: true, normalized: raw.replace(',', '.') };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere validate integer.
|
||||||
|
*/
|
||||||
function validateInteger(value, options) {
|
function validateInteger(value, options) {
|
||||||
const raw = normalizeNumericInput(value);
|
const raw = normalizeNumericInput(value);
|
||||||
const label = options.label || 'Champ';
|
const label = options.label || 'Champ';
|
||||||
|
|
@ -209,6 +239,9 @@
|
||||||
return { valid: true };
|
return { valid: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere validate immat.
|
||||||
|
*/
|
||||||
function validateImmat(value, options) {
|
function validateImmat(value, options) {
|
||||||
const raw = String(value || '').trim().toUpperCase();
|
const raw = String(value || '').trim().toUpperCase();
|
||||||
const label = options.label || 'Immatriculation';
|
const label = options.label || 'Immatriculation';
|
||||||
|
|
@ -227,6 +260,9 @@
|
||||||
return { valid: true, normalized: raw };
|
return { valid: true, normalized: raw };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere validate text safe.
|
||||||
|
*/
|
||||||
function validateTextSafe(value, options) {
|
function validateTextSafe(value, options) {
|
||||||
const raw = String(value || '').trim();
|
const raw = String(value || '').trim();
|
||||||
const label = options.label || 'Champ';
|
const label = options.label || 'Champ';
|
||||||
|
|
@ -250,6 +286,9 @@
|
||||||
return { valid: true };
|
return { valid: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere validate number or consult.
|
||||||
|
*/
|
||||||
function validateNumberOrConsult(raw, options) {
|
function validateNumberOrConsult(raw, options) {
|
||||||
const value = String(raw || '').trim();
|
const value = String(raw || '').trim();
|
||||||
const lower = value.toLowerCase();
|
const lower = value.toLowerCase();
|
||||||
|
|
@ -268,6 +307,9 @@
|
||||||
return validateNumeric(value, options);
|
return validateNumeric(value, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere evaluate rule.
|
||||||
|
*/
|
||||||
function evaluateRule(field, config) {
|
function evaluateRule(field, config) {
|
||||||
const profile = config.profile;
|
const profile = config.profile;
|
||||||
const label = pickFieldLabel(field, config.label);
|
const label = pickFieldLabel(field, config.label);
|
||||||
|
|
@ -331,11 +373,17 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere create summary element.
|
||||||
|
*/
|
||||||
function createSummaryElement(summaryId) {
|
function createSummaryElement(summaryId) {
|
||||||
if (!summaryId) return null;
|
if (!summaryId) return null;
|
||||||
return document.getElementById(summaryId);
|
return document.getElementById(summaryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere create guard.
|
||||||
|
*/
|
||||||
function createGuard(options) {
|
function createGuard(options) {
|
||||||
const summary = createSummaryElement(options.summaryId);
|
const summary = createSummaryElement(options.summaryId);
|
||||||
const summaryTitle = String(options.summaryTitle || 'Impossible de continuer car :');
|
const summaryTitle = String(options.summaryTitle || 'Impossible de continuer car :');
|
||||||
|
|
@ -357,6 +405,9 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere apply summary.
|
||||||
|
*/
|
||||||
function applySummary(messages) {
|
function applySummary(messages) {
|
||||||
if (!summary) return;
|
if (!summary) return;
|
||||||
if (!messages.length) {
|
if (!messages.length) {
|
||||||
|
|
@ -379,6 +430,9 @@
|
||||||
summary.style.display = 'block';
|
summary.style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere apply blocking.
|
||||||
|
*/
|
||||||
function applyBlocking(hasErrors) {
|
function applyBlocking(hasErrors) {
|
||||||
state.targetButtons.forEach(function (button) {
|
state.targetButtons.forEach(function (button) {
|
||||||
if (!button) return;
|
if (!button) return;
|
||||||
|
|
@ -395,6 +449,9 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere recompute.
|
||||||
|
*/
|
||||||
function recompute() {
|
function recompute() {
|
||||||
const messages = [];
|
const messages = [];
|
||||||
|
|
||||||
|
|
@ -405,10 +462,15 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
state.externalChecks.forEach(function (entry, key) {
|
state.externalChecks.forEach(function (entry, key) {
|
||||||
const checkResult = typeof entry.fn === 'function' ? entry.fn() : { valid: true };
|
try {
|
||||||
if (!checkResult || checkResult.valid === false) {
|
const checkResult = typeof entry.fn === 'function' ? entry.fn() : { valid: true };
|
||||||
const message = checkResult && checkResult.message ? checkResult.message : entry.message || key;
|
if (!checkResult || checkResult.valid === false) {
|
||||||
messages.push(message);
|
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;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere validate field.
|
||||||
|
*/
|
||||||
function validateField(field) {
|
function validateField(field) {
|
||||||
const config = state.fieldRules.get(field);
|
try {
|
||||||
if (!config) return;
|
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();
|
recompute();
|
||||||
return;
|
} catch (error) {
|
||||||
}
|
const config = state.fieldRules.get(field);
|
||||||
|
const key = config && config.key ? config.key : 'champ-inconnu';
|
||||||
if (typeof config.activeWhen === 'function' && !config.activeWhen(field)) {
|
console.warn('[RC guard] Validation en erreur:', key, error);
|
||||||
setFieldError(field, config.errorSlot, '');
|
if (config && config.errorSlot) {
|
||||||
state.fieldErrors.delete(config.key);
|
setFieldError(field, config.errorSlot, 'Erreur de validation, rechargez la page.');
|
||||||
recompute();
|
}
|
||||||
return;
|
state.fieldErrors.set(key, {
|
||||||
}
|
message: 'Erreur de validation sur un champ du formulaire.'
|
||||||
|
|
||||||
// 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
|
|
||||||
});
|
});
|
||||||
|
recompute();
|
||||||
}
|
}
|
||||||
|
|
||||||
recompute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere attach field.
|
||||||
|
*/
|
||||||
function attachField(field, config) {
|
function attachField(field, config) {
|
||||||
if (!field) return;
|
if (!field) return;
|
||||||
|
|
||||||
|
|
@ -489,6 +570,9 @@
|
||||||
validateField(field);
|
validateField(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enregistre field.
|
||||||
|
*/
|
||||||
function registerField(selectorOrElement, config) {
|
function registerField(selectorOrElement, config) {
|
||||||
if (!selectorOrElement || !config || !config.profile) return;
|
if (!selectorOrElement || !config || !config.profile) return;
|
||||||
if (typeof selectorOrElement === 'string') {
|
if (typeof selectorOrElement === 'string') {
|
||||||
|
|
@ -500,6 +584,9 @@
|
||||||
attachField(selectorOrElement, config);
|
attachField(selectorOrElement, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere observe.
|
||||||
|
*/
|
||||||
function observe(selector, config) {
|
function observe(selector, config) {
|
||||||
if (!selector || !config || !config.profile) return;
|
if (!selector || !config || !config.profile) return;
|
||||||
|
|
||||||
|
|
@ -517,6 +604,9 @@
|
||||||
return observer;
|
return observer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enregistre external.
|
||||||
|
*/
|
||||||
function registerExternal(key, fn, fallbackMessage) {
|
function registerExternal(key, fn, fallbackMessage) {
|
||||||
if (!key || typeof fn !== 'function') return;
|
if (!key || typeof fn !== 'function') return;
|
||||||
state.externalChecks.set(key, {
|
state.externalChecks.set(key, {
|
||||||
|
|
@ -526,6 +616,9 @@
|
||||||
recompute();
|
recompute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere refresh.
|
||||||
|
*/
|
||||||
function refresh() {
|
function refresh() {
|
||||||
state.fieldRules.forEach(function (_cfg, field) {
|
state.fieldRules.forEach(function (_cfg, field) {
|
||||||
validateField(field);
|
validateField(field);
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
|
/**
|
||||||
|
* Initialise submenu form.
|
||||||
|
*/
|
||||||
function initSubmenuForm() {
|
function initSubmenuForm() {
|
||||||
// Accéder aux informations stockées du parcours
|
// Accéder aux informations stockées du parcours
|
||||||
const parcours = JSON.parse(sessionStorage.getItem('parcours'));
|
const parcours = JSON.parse(sessionStorage.getItem('parcours'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convertit number.
|
||||||
|
*/
|
||||||
function toNumber(x) {
|
function toNumber(x) {
|
||||||
if (x == null) return 0;
|
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)
|
// Fonction pour formater un nombre avec X décimales max (sans décimales si entier)
|
||||||
|
/**
|
||||||
|
* Formate number.
|
||||||
|
*/
|
||||||
function formatNumber(num, decimals = 2) {
|
function formatNumber(num, decimals = 2) {
|
||||||
if (!num || isNaN(num)) return '0.' + '0'.repeat(decimals);
|
if (!num || isNaN(num)) return '0.' + '0'.repeat(decimals);
|
||||||
const factor = Math.pow(10, decimals);
|
const factor = Math.pow(10, decimals);
|
||||||
|
|
@ -56,6 +65,9 @@ function formatNumber(num, decimals = 2) {
|
||||||
return rounded.toFixed(decimals);
|
return rounded.toFixed(decimals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupere element by id flexible.
|
||||||
|
*/
|
||||||
function getElementByIdFlexible(id) {
|
function getElementByIdFlexible(id) {
|
||||||
if (!id) return null;
|
if (!id) return null;
|
||||||
const direct = document.getElementById(id);
|
const direct = document.getElementById(id);
|
||||||
|
|
@ -78,12 +90,18 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
let rcTarifGuard = null;
|
let rcTarifGuard = null;
|
||||||
let rcTarifHasErrors = false;
|
let rcTarifHasErrors = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronise rcfloating labels.
|
||||||
|
*/
|
||||||
function syncRCFloatingLabels() {
|
function syncRCFloatingLabels() {
|
||||||
if (window.RCValidationUtils && typeof window.RCValidationUtils.syncFloatingLabels === 'function') {
|
if (window.RCValidationUtils && typeof window.RCValidationUtils.syncFloatingLabels === 'function') {
|
||||||
window.RCValidationUtils.syncFloatingLabels(document);
|
window.RCValidationUtils.syncFloatingLabels(document);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Met a jour tarifettes visibility.
|
||||||
|
*/
|
||||||
function updateTarifettesVisibility() {
|
function updateTarifettesVisibility() {
|
||||||
const tarifettesContainer = document.getElementById('tarifettesContainer');
|
const tarifettesContainer = document.getElementById('tarifettesContainer');
|
||||||
if (!tarifettesContainer) return;
|
if (!tarifettesContainer) return;
|
||||||
|
|
@ -95,6 +113,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
// ═══════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
// Fonction helper : trouver la tranche la plus proche
|
// Fonction helper : trouver la tranche la plus proche
|
||||||
|
/**
|
||||||
|
* Trouve closest tranche.
|
||||||
|
*/
|
||||||
function findClosestTranche(val, tranches) {
|
function findClosestTranche(val, tranches) {
|
||||||
if (val <= tranches[0]) return tranches[0];
|
if (val <= tranches[0]) return tranches[0];
|
||||||
if (val >= tranches[tranches.length - 1]) return tranches[tranches.length - 1];
|
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];
|
return tranches[tranches.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Met a jour tarif choice buttons state.
|
||||||
|
*/
|
||||||
function updateTarifChoiceButtonsState() {
|
function updateTarifChoiceButtonsState() {
|
||||||
const buttons = document.querySelectorAll('.franchise-card button[name]');
|
const buttons = document.querySelectorAll('.franchise-card button[name]');
|
||||||
buttons.forEach((button) => {
|
buttons.forEach((button) => {
|
||||||
|
|
@ -122,6 +146,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
updateTarifettesVisibility();
|
updateTarifettesVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure rcsafe validation.
|
||||||
|
*/
|
||||||
function setupRCSafeValidation() {
|
function setupRCSafeValidation() {
|
||||||
if (!window.RCValidationUtils || typeof window.RCValidationUtils.createGuard !== 'function') {
|
if (!window.RCValidationUtils || typeof window.RCValidationUtils.createGuard !== 'function') {
|
||||||
return;
|
return;
|
||||||
|
|
@ -130,7 +157,7 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
rcTarifGuard = window.RCValidationUtils.createGuard({
|
rcTarifGuard = window.RCValidationUtils.createGuard({
|
||||||
summaryId: 'rcTarifBlockingSummary',
|
summaryId: 'rcTarifBlockingSummary',
|
||||||
summaryTitle: 'Impossible de choisir un tarif ou de continuer car :',
|
summaryTitle: 'Impossible de choisir un tarif ou de continuer car :',
|
||||||
blockTargets: ['#generateDeclinaison', '#generateProject', '#comm-OK'],
|
blockTargets: ['#generateDeclinaison', '#generateProject'],
|
||||||
onChange: function (messages) {
|
onChange: function (messages) {
|
||||||
rcTarifHasErrors = messages.length > 0;
|
rcTarifHasErrors = messages.length > 0;
|
||||||
updateTarifChoiceButtonsState();
|
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"]', {
|
rcTarifGuard.observe('#tabAdvaloTerrestre input[type="text"], #tabAdvaloMultimodal input[type="text"], #tabAdvaloAerien input[type="text"]', {
|
||||||
profile: 'number_or_consulter',
|
profile: 'number_or_consulter',
|
||||||
label: 'Valeur ad valorem',
|
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 %
|
// Fonction pour afficher un avertissement visuel de dépassement %
|
||||||
|
/**
|
||||||
|
* Affiche percentage warning.
|
||||||
|
*/
|
||||||
function showPercentageWarning(excess) {
|
function showPercentageWarning(excess) {
|
||||||
let warningDiv = document.getElementById('percentageWarning');
|
let warningDiv = document.getElementById('percentageWarning');
|
||||||
if (!warningDiv) {
|
if (!warningDiv) {
|
||||||
|
|
@ -357,6 +363,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fonction pour masquer toutes les primes (quand % invalide)
|
// Fonction pour masquer toutes les primes (quand % invalide)
|
||||||
|
/**
|
||||||
|
* Masque all primes.
|
||||||
|
*/
|
||||||
function hideAllPrimes() {
|
function hideAllPrimes() {
|
||||||
const primeElements = [
|
const primeElements = [
|
||||||
'primeChapActRCC', 'primeChapActRCE',
|
'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
|
// Fonction pour mettre à jour l'indicateur visuel du total des pourcentages
|
||||||
|
/**
|
||||||
|
* Met a jour percentage indicator.
|
||||||
|
*/
|
||||||
function updatePercentageIndicator(total) {
|
function updatePercentageIndicator(total) {
|
||||||
const indicator = document.getElementById('pourcentageTotal');
|
const indicator = document.getElementById('pourcentageTotal');
|
||||||
if (!indicator) return;
|
if (!indicator) return;
|
||||||
|
|
@ -405,6 +417,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
// ═══════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
// Initialisation du formulaire et des données
|
// Initialisation du formulaire et des données
|
||||||
|
/**
|
||||||
|
* Initialise la logique de cette fonction.
|
||||||
|
*/
|
||||||
function init() {
|
function init() {
|
||||||
// Materialize init select
|
// Materialize init select
|
||||||
var select = document.querySelectorAll('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
|
// Configuration des listeners d'événements
|
||||||
|
/**
|
||||||
|
* Configure event listeners.
|
||||||
|
*/
|
||||||
function setupEventListeners() {
|
function setupEventListeners() {
|
||||||
// Empêcher la soumission du formulaire avec la touche Enter
|
// Empêcher la soumission du formulaire avec la touche Enter
|
||||||
const form = document.getElementById('projetForm');
|
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"
|
// Le bouton Annuler ferme automatiquement le modal grâce à la classe "modal-close"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse prefill array.
|
||||||
|
*/
|
||||||
function parsePrefillArray(value) {
|
function parsePrefillArray(value) {
|
||||||
if (Array.isArray(value)) return value;
|
if (Array.isArray(value)) return value;
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
|
|
@ -1194,6 +1215,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalise prefill value.
|
||||||
|
*/
|
||||||
function normalizePrefillValue(value) {
|
function normalizePrefillValue(value) {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
return value
|
return value
|
||||||
|
|
@ -1223,6 +1247,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere build projet prefill delta.
|
||||||
|
*/
|
||||||
function buildProjetPrefillDelta(snapshot, baseline) {
|
function buildProjetPrefillDelta(snapshot, baseline) {
|
||||||
if (!snapshot || typeof snapshot !== 'object') return null;
|
if (!snapshot || typeof snapshot !== 'object') return null;
|
||||||
if (!baseline || typeof baseline !== 'object') return snapshot;
|
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;
|
return Object.keys(delta).length > 0 ? delta : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere apply projet data to tarif.
|
||||||
|
*/
|
||||||
function applyProjetDataToTarif(projetSource) {
|
function applyProjetDataToTarif(projetSource) {
|
||||||
if (!projetSource || typeof projetSource !== 'object') return;
|
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
|
// Peupler le formulaire avec les données
|
||||||
|
/**
|
||||||
|
* Gere populate form data.
|
||||||
|
*/
|
||||||
function populateFormData() {
|
function populateFormData() {
|
||||||
//Poupulate select historique
|
//Poupulate select historique
|
||||||
if (!contrat.historique) {
|
if (!contrat.historique) {
|
||||||
|
|
@ -1877,6 +1910,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule mod ca.
|
||||||
|
*/
|
||||||
function calcModCA(caRaw){
|
function calcModCA(caRaw){
|
||||||
const ca = Number(String(caRaw || '').replace(/\s/g,'').replace(',','.')) || 0;
|
const ca = Number(String(caRaw || '').replace(/\s/g,'').replace(',','.')) || 0;
|
||||||
const thresholds = Object.keys(modRCCA).map(n => Number(n)).sort((a,b)=>a-b);
|
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;
|
return modRCCA[thresholds.at(-1)] ?? 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule mod marchandises.
|
||||||
|
*/
|
||||||
function calcModMarchandises(data, activityName, type, cot) {
|
function calcModMarchandises(data, activityName, type, cot) {
|
||||||
let m = 1;
|
let m = 1;
|
||||||
|
|
||||||
|
|
@ -1927,6 +1966,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupere zone mods.
|
||||||
|
*/
|
||||||
function getZoneMods(data) {
|
function getZoneMods(data) {
|
||||||
let mRCC = 1;
|
let mRCC = 1;
|
||||||
let mRCE = 1;
|
let mRCE = 1;
|
||||||
|
|
@ -1958,6 +2000,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
return { mRCC, mRCE };
|
return { mRCC, mRCE };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule mod act compl.
|
||||||
|
*/
|
||||||
function calcModActCompl(data, activityName, type, cot) {
|
function calcModActCompl(data, activityName, type, cot) {
|
||||||
let m = 1;
|
let m = 1;
|
||||||
const current = getSelectedActivities().find(a => a.typeActivite === activityName);
|
const current = getSelectedActivities().find(a => a.typeActivite === activityName);
|
||||||
|
|
@ -1970,12 +2015,18 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule engag compl.
|
||||||
|
*/
|
||||||
function calcEngagCompl(data, primeRCC) {
|
function calcEngagCompl(data, primeRCC) {
|
||||||
let prime = primeRCC;
|
let prime = primeRCC;
|
||||||
let surPrime = 0;
|
let surPrime = 0;
|
||||||
let modDommImmat = 1;
|
let modDommImmat = 1;
|
||||||
let infos = [];
|
let infos = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere write to card.
|
||||||
|
*/
|
||||||
function writeToCard(inputId, message) {
|
function writeToCard(inputId, message) {
|
||||||
const inputEl = document.getElementById(inputId);
|
const inputEl = document.getElementById(inputId);
|
||||||
if (!inputEl) return;
|
if (!inputEl) return;
|
||||||
|
|
@ -2078,6 +2129,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fonction helper : trouver la tranche la plus proche
|
// Fonction helper : trouver la tranche la plus proche
|
||||||
|
/**
|
||||||
|
* Trouve closest tranche.
|
||||||
|
*/
|
||||||
function findClosestTranche(val, tranches) {
|
function findClosestTranche(val, tranches) {
|
||||||
if (val <= tranches[0]) return tranches[0];
|
if (val <= tranches[0]) return tranches[0];
|
||||||
if (val >= tranches[tranches.length - 1]) return tranches[tranches.length - 1];
|
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 %
|
// Fonction pour afficher un avertissement visuel de dépassement %
|
||||||
|
/**
|
||||||
|
* Affiche percentage warning.
|
||||||
|
*/
|
||||||
function showPercentageWarning(excess) {
|
function showPercentageWarning(excess) {
|
||||||
// Créer ou récupérer le div d'avertissement
|
// Créer ou récupérer le div d'avertissement
|
||||||
let warningDiv = document.getElementById('percentageWarning');
|
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)
|
// Fonction pour masquer toutes les primes (quand % invalide)
|
||||||
|
/**
|
||||||
|
* Masque all primes.
|
||||||
|
*/
|
||||||
function hideAllPrimes() {
|
function hideAllPrimes() {
|
||||||
const primeElements = [
|
const primeElements = [
|
||||||
'primeChapActRCC', 'primeChapActRCE',
|
'primeChapActRCC', 'primeChapActRCE',
|
||||||
|
|
@ -2143,10 +2203,16 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fonction pour afficher toutes les primes (quand % valide)
|
// Fonction pour afficher toutes les primes (quand % valide)
|
||||||
|
/**
|
||||||
|
* Affiche all primes.
|
||||||
|
*/
|
||||||
function showAllPrimes() {
|
function showAllPrimes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fonction pour mettre à jour l'indicateur visuel du total des pourcentages
|
// Fonction pour mettre à jour l'indicateur visuel du total des pourcentages
|
||||||
|
/**
|
||||||
|
* Met a jour percentage indicator.
|
||||||
|
*/
|
||||||
function updatePercentageIndicator(total) {
|
function updatePercentageIndicator(total) {
|
||||||
const indicator = document.getElementById('pourcentageTotal');
|
const indicator = document.getElementById('pourcentageTotal');
|
||||||
if (!indicator) return;
|
if (!indicator) return;
|
||||||
|
|
@ -2182,6 +2248,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule gar add.
|
||||||
|
*/
|
||||||
function calcGarAdd(data, primeRCC, primeRCE) {
|
function calcGarAdd(data, primeRCC, primeRCE) {
|
||||||
let primeRCCres = Number(primeRCC) || 0;
|
let primeRCCres = Number(primeRCC) || 0;
|
||||||
let primeRCEres = Number(primeRCE) || 0;
|
let primeRCEres = Number(primeRCE) || 0;
|
||||||
|
|
@ -2189,6 +2258,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
const infosRCC = [];
|
const infosRCC = [];
|
||||||
const infosRCE = [];
|
const infosRCE = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere write to card.
|
||||||
|
*/
|
||||||
function writeToCard(inputId, message) {
|
function writeToCard(inputId, message) {
|
||||||
const inputEl = document.getElementById(inputId);
|
const inputEl = document.getElementById(inputId);
|
||||||
if (!inputEl) return;
|
if (!inputEl) return;
|
||||||
|
|
@ -2276,6 +2348,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule sinistre.
|
||||||
|
*/
|
||||||
function calcSinistre(data, primeRCC, primeRCE) {
|
function calcSinistre(data, primeRCC, primeRCE) {
|
||||||
console.log('[calcSinistre] start', { primeRCC, primeRCE });
|
console.log('[calcSinistre] start', { primeRCC, primeRCE });
|
||||||
|
|
||||||
|
|
@ -2327,6 +2402,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
|
|
||||||
// --- Fonctions utilitaires ---
|
// --- Fonctions utilitaires ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupere max mini rcc.
|
||||||
|
*/
|
||||||
function getMaxMiniRCC(activites, cot) {
|
function getMaxMiniRCC(activites, cot) {
|
||||||
let maxMini = 0;
|
let maxMini = 0;
|
||||||
activites.forEach(act => {
|
activites.forEach(act => {
|
||||||
|
|
@ -2355,6 +2433,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
return maxMini;
|
return maxMini;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupere max mini rce.
|
||||||
|
*/
|
||||||
function getMaxMiniRCE(activites, cot) {
|
function getMaxMiniRCE(activites, cot) {
|
||||||
let maxMini = 0;
|
let maxMini = 0;
|
||||||
activites.forEach(act => {
|
activites.forEach(act => {
|
||||||
|
|
@ -2384,6 +2465,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule tarif rcc.
|
||||||
|
*/
|
||||||
function calcTarifRCC({
|
function calcTarifRCC({
|
||||||
CA,
|
CA,
|
||||||
primeRCCbase,
|
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) {
|
function calcTarifettes(primePJ, CA, activites, capitalTPPC, nbVehicules, coefTPPC, primeRCCbase, primeRCEbase) {
|
||||||
const cards = [
|
const cards = [
|
||||||
{ key: "250", priceId: "priceFr250", rccId: "rccFr250", rceId: "rceFr250", pjId: "pjFr250", txRccId: "tauxRccFr250", txRceId: "tauxRceFr250", txGlobId: "tauxGlobalFr250" },
|
{ 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
|
// Fonction pour calculer la PJ selon la prime totale
|
||||||
|
/**
|
||||||
|
* Calcule pj.
|
||||||
|
*/
|
||||||
function calcPJ(primeTotale) {
|
function calcPJ(primeTotale) {
|
||||||
let primePJ = 0;
|
let primePJ = 0;
|
||||||
const tablePJ = modRCGarAdd?.modRCC?.["Protection juridique"];
|
const tablePJ = modRCGarAdd?.modRCC?.["Protection juridique"];
|
||||||
|
|
@ -2592,6 +2682,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule global.
|
||||||
|
*/
|
||||||
function calcGlobal() {
|
function calcGlobal() {
|
||||||
// Vérification des pourcentages AVANT calcul
|
// Vérification des pourcentages AVANT calcul
|
||||||
const allPourcentInputs = Array.from(document.querySelectorAll('.input-pourcent')).filter(p => p.offsetParent != null);
|
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();
|
updateTarifChoiceButtonsState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule revisable.
|
||||||
|
*/
|
||||||
function calcRevisable() {
|
function calcRevisable() {
|
||||||
// ========= Variables centrales (déclarées au début) =========
|
// ========= Variables centrales (déclarées au début) =========
|
||||||
const capitalTPPCEl = document.getElementById("capital_TPPC");
|
const capitalTPPCEl = document.getElementById("capital_TPPC");
|
||||||
|
|
@ -2856,6 +2952,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
"Autres activites": "Autres activites"
|
"Autres activites": "Autres activites"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupere selected activites.
|
||||||
|
*/
|
||||||
function getSelectedActivites() {
|
function getSelectedActivites() {
|
||||||
const activites = [];
|
const activites = [];
|
||||||
document.querySelectorAll('label input[type="checkbox"]:checked').forEach(cb => {
|
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() {
|
function calcForfaitaire() {
|
||||||
// ========= Variables centrales =========
|
// ========= Variables centrales =========
|
||||||
let primeBaseRCC = 0;
|
let primeBaseRCC = 0;
|
||||||
|
|
@ -3139,6 +3241,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
"Autres activites": "Autres activites"
|
"Autres activites": "Autres activites"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupere selected activites.
|
||||||
|
*/
|
||||||
function getSelectedActivites() {
|
function getSelectedActivites() {
|
||||||
const activites = [];
|
const activites = [];
|
||||||
document.querySelectorAll('label input[type="checkbox"]:checked').forEach(cb => {
|
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) {
|
function getZoneMods(modRCZone) {
|
||||||
const zones = [
|
const zones = [
|
||||||
{ id: 'zone1', label: 'France Métropolitaine et pays limitrophes' },
|
{ 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() {
|
function handleLoadHistoriqueBtn() {
|
||||||
var selectedId = document.getElementById('idSelect').value;
|
var selectedId = document.getElementById('idSelect').value;
|
||||||
|
|
||||||
|
|
@ -3213,6 +3324,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
}
|
}
|
||||||
|
|
||||||
//Appel pour recevoir les constantes
|
//Appel pour recevoir les constantes
|
||||||
|
/**
|
||||||
|
* Gere constants json.
|
||||||
|
*/
|
||||||
async function constantsJSON() {
|
async function constantsJSON() {
|
||||||
try {
|
try {
|
||||||
const responsesJSON = await Promise.all([
|
const responsesJSON = await Promise.all([
|
||||||
|
|
@ -3249,6 +3363,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gere reset inputs.
|
||||||
|
*/
|
||||||
function resetInputs() {
|
function resetInputs() {
|
||||||
// Sélection des éléments input pourcentage
|
// Sélection des éléments input pourcentage
|
||||||
const pourcentInputs = document.querySelectorAll('.input-pourcent');
|
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) {
|
function get_taux_base_RCC(grille_mod_RCC, cot) {
|
||||||
const tauxOptimaux = [];
|
const tauxOptimaux = [];
|
||||||
const selections = getSelectedActivities();
|
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) {
|
function get_taux_base_RCE(grille_mod_RCE, cot) {
|
||||||
const tauxOptimaux = [];
|
const tauxOptimaux = [];
|
||||||
const selections = getSelectedActivities();
|
const selections = getSelectedActivities();
|
||||||
|
|
@ -3372,6 +3495,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
return tauxOptimaux;
|
return tauxOptimaux;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupere selected activities.
|
||||||
|
*/
|
||||||
function getSelectedActivities() {
|
function getSelectedActivities() {
|
||||||
const selections = [];
|
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
|
// Fonction pour sauvegarder les données tarifRC dans la base
|
||||||
|
/**
|
||||||
|
* Sauvegarde tarif rc.
|
||||||
|
*/
|
||||||
async function saveTarifRC() {
|
async function saveTarifRC() {
|
||||||
if (!rc || !contrat) {
|
if (!rc || !contrat) {
|
||||||
console.error('Données manquantes pour sauvegarder le tarif RC');
|
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
|
// Fonction helper pour collecter les activités complémentaires
|
||||||
|
/**
|
||||||
|
* Collecte activites compl json.
|
||||||
|
*/
|
||||||
function collectActivitesComplJSON(typeActivite) {
|
function collectActivitesComplJSON(typeActivite) {
|
||||||
let name;
|
let name;
|
||||||
switch(typeActivite.toLowerCase()) {
|
switch(typeActivite.toLowerCase()) {
|
||||||
|
|
@ -3770,6 +3902,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fonction helper pour collecter les marchandises
|
// Fonction helper pour collecter les marchandises
|
||||||
|
/**
|
||||||
|
* Collecte marchandises json.
|
||||||
|
*/
|
||||||
function collectMarchandisesJSON(typeActivite) {
|
function collectMarchandisesJSON(typeActivite) {
|
||||||
let name;
|
let name;
|
||||||
switch(typeActivite.toLowerCase()) {
|
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
|
// Fonction pour gérer les clics sur les boutons de tariffettes
|
||||||
|
/**
|
||||||
|
* Configure tarifette buttons.
|
||||||
|
*/
|
||||||
function setupTarifetteButtons() {
|
function setupTarifetteButtons() {
|
||||||
const tarifetteButtons = document.querySelectorAll('.franchise-card button[name]');
|
const tarifetteButtons = document.querySelectorAll('.franchise-card button[name]');
|
||||||
tarifetteButtons.forEach(button => {
|
tarifetteButtons.forEach(button => {
|
||||||
|
|
@ -3827,6 +3965,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fonction pour configurer les alertes de marchandises
|
// Fonction pour configurer les alertes de marchandises
|
||||||
|
/**
|
||||||
|
* Configure marchandise alerts.
|
||||||
|
*/
|
||||||
function setupMarchandiseAlerts() {
|
function setupMarchandiseAlerts() {
|
||||||
// Alerte pour Animaux Vivants
|
// Alerte pour Animaux Vivants
|
||||||
document.querySelectorAll('[name^="mar"] input[type="checkbox"]').forEach(cb => {
|
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
|
// Fonction pour configurer les alertes d'activités
|
||||||
|
/**
|
||||||
|
* Configure activite alerts.
|
||||||
|
*/
|
||||||
function setupActiviteAlerts() {
|
function setupActiviteAlerts() {
|
||||||
// Alerte pour Autocariste + RCE
|
// Alerte pour Autocariste + RCE
|
||||||
const checkAutocariste = document.getElementById('checkAutocariste');
|
const checkAutocariste = document.getElementById('checkAutocariste');
|
||||||
|
|
@ -3862,6 +4006,9 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
const seuil = 5;
|
const seuil = 5;
|
||||||
|
|
||||||
// Fonction pour ouvrir le modal de tarif commercial
|
// Fonction pour ouvrir le modal de tarif commercial
|
||||||
|
/**
|
||||||
|
* Ouvre modal tarif com.
|
||||||
|
*/
|
||||||
function openModalTarifCom(franchiseValue) {
|
function openModalTarifCom(franchiseValue) {
|
||||||
// Récupérer le tarif de référence selon la franchise
|
// Récupérer le tarif de référence selon la franchise
|
||||||
let tarifRef = 0;
|
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('tarifRefText').innerText = `Tarif de Référence : ${formatNumber(tarifRef, 2)} €`;
|
||||||
document.getElementById('tarifCom').value = '';
|
document.getElementById('tarifCom').value = '';
|
||||||
document.getElementById('commentaire').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('tarifCom-error').style.display = 'none';
|
||||||
document.getElementById('col-commentaire').style.display = 'none';
|
document.getElementById('col-commentaire').style.display = 'none';
|
||||||
document.getElementById('qualiteDiv').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
|
// Ouvrir le modal
|
||||||
window.modalTarifCom.open();
|
window.modalTarifCom.open();
|
||||||
|
if (rcTarifGuard) rcTarifGuard.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fonction pour gérer l'input du tarif commercial
|
// Fonction pour gérer l'input du tarif commercial
|
||||||
|
/**
|
||||||
|
* Gere tarif com input.
|
||||||
|
*/
|
||||||
function handleTarifComInput(e) {
|
function handleTarifComInput(e) {
|
||||||
const tarifCom = parseFloat(e.target.value);
|
const tarifCom = parseFloat(e.target.value);
|
||||||
const tarifRef = parseFloat(document.getElementById('comm-OK').getAttribute('data-tarif-ref'));
|
const tarifRef = parseFloat(document.getElementById('comm-OK').getAttribute('data-tarif-ref'));
|
||||||
|
|
||||||
if (!tarifCom || tarifCom <= 0) {
|
if (!tarifCom || tarifCom <= 0) {
|
||||||
document.getElementById('qualiteDiv').style.display = 'none';
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3952,19 +4107,32 @@ window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollutio
|
||||||
document.getElementById('tarifCom-error').style.display = 'none';
|
document.getElementById('tarifCom-error').style.display = 'none';
|
||||||
document.getElementById('col-commentaire').style.display = 'none';
|
document.getElementById('col-commentaire').style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rcTarifGuard) rcTarifGuard.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fonction pour gérer l'input du commentaire
|
// Fonction pour gérer l'input du commentaire
|
||||||
|
/**
|
||||||
|
* Gere commentaire input.
|
||||||
|
*/
|
||||||
function handleCommentaireInput(e) {
|
function handleCommentaireInput(e) {
|
||||||
const commentaire = e.target.value.trim();
|
const commentaire = e.target.value.trim();
|
||||||
|
const tarifCom = parseFloat(document.getElementById('tarifCom').value);
|
||||||
const tarifComError = document.getElementById('tarifCom-error').style.display !== 'none';
|
const tarifComError = document.getElementById('tarifCom-error').style.display !== 'none';
|
||||||
|
|
||||||
if (tarifComError) {
|
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
|
// Fonction pour gérer la validation du tarif commercial
|
||||||
|
/**
|
||||||
|
* Gere validate tarif com.
|
||||||
|
*/
|
||||||
async function handleValidateTarifCom() {
|
async function handleValidateTarifCom() {
|
||||||
const tarifCom = parseFloat(document.getElementById('tarifCom').value);
|
const tarifCom = parseFloat(document.getElementById('tarifCom').value);
|
||||||
const commentaire = document.getElementById('commentaire').value.trim();
|
const commentaire = document.getElementById('commentaire').value.trim();
|
||||||
|
|
@ -4,161 +4,187 @@ function isValidEmail(email) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateField(fieldId, showErrors = true) {
|
function validateField(fieldId, showErrors = true) {
|
||||||
const inputElement = document.getElementById(fieldId);
|
try {
|
||||||
|
const inputElement = document.getElementById(fieldId);
|
||||||
|
|
||||||
if (!inputElement) {
|
if (!inputElement) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const value = document.getElementById(fieldId).value.trim();
|
const rawValue = inputElement.value;
|
||||||
const rule = validationRules[fieldId]; // Importé de js/json/json-verif-form.js
|
const value = typeof rawValue === 'string' ? rawValue.trim() : String(rawValue ?? '').trim();
|
||||||
const errorElement = document.getElementById(`${fieldId}-error`);
|
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;
|
if (!rule) {
|
||||||
let errorMessage = "";
|
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 == '')) {
|
// Vérifie si le champ est requis et vide
|
||||||
errorMessage = "Ce champ est obligatoire.";
|
if (rule.required && (!value || value == '')) {
|
||||||
isValid = false;
|
errorMessage = "Ce champ est obligatoire.";
|
||||||
}
|
|
||||||
|
|
||||||
// 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'";
|
|
||||||
isValid = false;
|
isValid = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Vérifie si la saisie est un taux sans décimale ou avec un maximum de trois chiffres après la virgule
|
// Vérifie la longueur de la saisie si spécifié et nécessaire
|
||||||
if (isValid && value && rule.tauxFormat) {
|
if (isValid && value && rule.length && value.length !== rule.length) {
|
||||||
const isTauxFormatValid = /^(?:\d+|\d+\.\d{1,3})$/.test(value);
|
errorMessage = `Veuillez saisir ${rule.length} caractères, il y en a actuellement ${value.length}.`;
|
||||||
|
|
||||||
if (!isTauxFormatValid) {
|
|
||||||
errorMessage = "Le champ doit être un nombre avec un maximum de trois décimales '00.000' ou entier '00'";
|
|
||||||
isValid = false;
|
isValid = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Vérifie si le champ doit être compris dans un certain intervalle
|
// 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.range) {
|
if (isValid && value && rule.numberFormat) {
|
||||||
const numberValue = parseFloat(value);
|
const isNumberFormatValid = /^(?:\d+|\d+\.\d{1,2})$/.test(value);
|
||||||
|
|
||||||
if (isNaN(numberValue) || numberValue < rule.range.min || numberValue > rule.range.max) {
|
if (!isNumberFormatValid) {
|
||||||
errorMessage = rule.errorMsg;
|
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;
|
isValid = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Valide l'adresse e-mail seulement si le champ n'est pas vide
|
// Vérifie si le champ commence par le caractère spécifié
|
||||||
if (isValid && value && rule.email) {
|
if (isValid && value && rule.startsWith && !value.startsWith(rule.startsWith)) {
|
||||||
if (!isValidEmail(value)) {
|
errorMessage = `Le champ doit commencer par '${rule.startsWith}' majuscule.`;
|
||||||
errorMessage = rule.errorMsg;
|
|
||||||
isValid = false;
|
isValid = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Vérifie la présence de caractères potentiellement problématiques
|
// Vérifie si le champ date est correct
|
||||||
const specialCharsPattern = /[;">&<]/g;
|
if (isValid && value && rule.dateFormat) {
|
||||||
let invalidChars = value.match(specialCharsPattern);
|
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) {
|
if (!isDateFormatValid) {
|
||||||
invalidChars = [...new Set(invalidChars)];
|
errorMessage = "Le champ doit être au format JJ//MM/AAAA ou 00/00/0000.";
|
||||||
errorMessage = `Caractère(s) invalide(s) détecté(s) [ ${invalidChars.join(" ")} ].`;
|
isValid = false;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Vérifie si la saisie ne contient pas d'espace
|
// Vérifie si la saisie ne contient pas d'espace
|
||||||
if (isValid && value && rule.noSpace) {
|
if (isValid && value && rule.noSpace) {
|
||||||
const isNoSpaceValid = /^\S*$/.test(value);
|
const isNoSpaceValid = /^\S*$/.test(value);
|
||||||
|
|
||||||
if (!isNoSpaceValid) {
|
if (!isNoSpaceValid) {
|
||||||
errorMessage = "La saisie ne doit pas contenir d'espaces.";
|
errorMessage = "La saisie ne doit pas contenir d'espaces.";
|
||||||
isValid = false;
|
isValid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Vérifie si le champ date est correct au format JJ/MM
|
// Vérifie si le champ date est correct au format JJ/MM
|
||||||
if (isValid && value && rule.dateFormatShort) {
|
if (isValid && value && rule.dateFormatShort) {
|
||||||
const isDateFormatShortValid = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[012])$|^00\/00$/.test(value);
|
const isDateFormatShortValid = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[012])$|^00\/00$/.test(value);
|
||||||
|
|
||||||
if (!isDateFormatShortValid) {
|
if (!isDateFormatShortValid) {
|
||||||
errorMessage = "Le champ doit être au format JJ/MM ou 00/00.";
|
errorMessage = "Le champ doit être au format JJ/MM ou 00/00.";
|
||||||
isValid = false;
|
isValid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Vérifie la casse des caractères si spécifié
|
// Vérifie la casse des caractères si spécifié
|
||||||
if (isValid && value && rule.case) {
|
if (isValid && value && rule.case) {
|
||||||
if (rule.case === "upper" && value !== value.toUpperCase()) {
|
if (rule.case === "upper" && value !== value.toUpperCase()) {
|
||||||
errorMessage = "Le champ doit être en majuscules.";
|
errorMessage = "Le champ doit être en majuscules.";
|
||||||
isValid = false;
|
isValid = false;
|
||||||
} else if (rule.case === "lower" && value !== value.toLowerCase()) {
|
} else if (rule.case === "lower" && value !== value.toLowerCase()) {
|
||||||
errorMessage = "Le champ doit être en minuscules.";
|
errorMessage = "Le champ doit être en minuscules.";
|
||||||
isValid = false;
|
isValid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Vérifie si le champ doit être numérique
|
// Vérifie si le champ doit être numérique
|
||||||
if (isValid && value && rule.digit) {
|
if (isValid && value && rule.digit) {
|
||||||
const isNumeric = /^\d+$/.test(value); // Vérifie si la chaîne est un nombre entier
|
const isNumeric = /^\d+$/.test(value); // Vérifie si la chaîne est un nombre entier
|
||||||
|
|
||||||
if (!isNumeric) {
|
if (!isNumeric) {
|
||||||
errorMessage = "Le champ doit contenir uniquement des chiffres.";
|
errorMessage = "Le champ doit contenir uniquement des chiffres.";
|
||||||
isValid = false;
|
isValid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Affiche ou cache le message d'erreur selon la validité du champ
|
// Affiche ou cache le message d'erreur selon la validité du champ
|
||||||
if (showErrors) {
|
if (showErrors && errorElement) {
|
||||||
errorElement.textContent = errorMessage;
|
errorElement.textContent = errorMessage;
|
||||||
errorElement.style.display = isValid ? 'none' : 'block';
|
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) {
|
function updateSubmitButtonState(formId) {
|
||||||
|
|
||||||
let allFieldsValid = true;
|
let allFieldsValid = true;
|
||||||
const form = document.querySelector(`#${formId}`);
|
const form = document.querySelector(`#${formId}`);
|
||||||
|
const hasValidationRules = typeof validationRules !== 'undefined' && validationRules;
|
||||||
|
|
||||||
if (!form) {
|
if (!form) {
|
||||||
console.error('Formulaire non trouvé:', formId);
|
console.error('Formulaire non trouvé:', formId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const fieldId in validationRules) {
|
if (!hasValidationRules) {
|
||||||
const inputElement = form.querySelector(`#${fieldId}`);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (inputElement && !validateField(fieldId, false)) {
|
for (const fieldId in validationRules) {
|
||||||
allFieldsValid = false;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -60,17 +60,17 @@
|
||||||
<!-- Feuille de script pour les donnée static JSON de saisie formulaire -->
|
<!-- Feuille de script pour les donnée static JSON de saisie formulaire -->
|
||||||
<script src="/js/json/json-verif-form.js"></script>
|
<script src="/js/json/json-verif-form.js"></script>
|
||||||
<!-- Utilitaires de validation et blocage RC -->
|
<!-- Utilitaires de validation et blocage RC -->
|
||||||
<script src="/js/rc-validation-utils.js"></script>
|
<script src="/js/rc/rc-validation-utils.js"></script>
|
||||||
<!-- Feuille de script pour le bon fonctionnement du loader -->
|
<!-- Feuille de script pour le bon fonctionnement du loader -->
|
||||||
<script src="/js/loader.js"></script>
|
<script src="/js/loader.js"></script>
|
||||||
<!-- Script pour la navigation AJAX -->
|
<!-- Script pour la navigation AJAX -->
|
||||||
<script src="/js/navigation.js"></script>
|
<script src="/js/navigation.js"></script>
|
||||||
<!-- Utilitaires de synchronisation RC -->
|
<!-- Utilitaires de synchronisation RC -->
|
||||||
<script src="/js/rc-sync-utils.js"></script>
|
<script src="/js/rc/rc-sync-utils.js"></script>
|
||||||
<!-- Gestionnaire de données RC -->
|
<!-- Gestionnaire de données RC -->
|
||||||
<script src="/js/rc-data-manager.js"></script>
|
<script src="/js/rc/rc-data-manager.js"></script>
|
||||||
<!-- Orchestrateur de synchronisation RC -->
|
<!-- Orchestrateur de synchronisation RC -->
|
||||||
<script src="/js/rc-orchestrator.js"></script>
|
<script src="/js/rc/rc-orchestrator.js"></script>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
<form id="projetForm">
|
<form id="projetForm">
|
||||||
<div id="rcProjetBlockingSummary" class="rc-blocking-summary"></div>
|
|
||||||
<!-- Historique de projet -->
|
<!-- Historique de projet -->
|
||||||
<div class="row" id="historiqueDiv">
|
<div class="row" id="historiqueDiv">
|
||||||
<div class="col s12">
|
<div class="col s12">
|
||||||
|
|
@ -777,8 +776,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<i class="material-icons prefix">trending_up</i>
|
<i class="material-icons prefix">trending_up</i>
|
||||||
<label class="rc-field-label" for="CA">Montant en euros</label>
|
<input id="CA" type="text" placeholder="100000">
|
||||||
<input id="CA" type="text" placeholder="Ex: 1234567">
|
|
||||||
<span class="helper-text">Chiffre d'affaires</span>
|
<span class="helper-text">Chiffre d'affaires</span>
|
||||||
<span id="CA-error" class="helper-text red-text"></span>
|
<span id="CA-error" class="helper-text red-text"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -792,8 +790,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<i class="material-icons prefix">euro_symbol</i>
|
<i class="material-icons prefix">euro_symbol</i>
|
||||||
<label class="rc-field-label" for="cotisationIrreductible">Montant en euros</label>
|
<input id="cotisationIrreductible" type="text" placeholder="200">
|
||||||
<input id="cotisationIrreductible" type="text" placeholder="Ex: 1200">
|
|
||||||
<span class="helper-text">Cotisation minimale irréductible</span>
|
<span class="helper-text">Cotisation minimale irréductible</span>
|
||||||
<span id="cotisationIrreductible-error" class="helper-text red-text"></span>
|
<span id="cotisationIrreductible-error" class="helper-text red-text"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -959,20 +956,20 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>Frais de répertoire</td>
|
<td>Frais de répertoire</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="cotFraisHT" id="cotFraisHT" value="36.00" />
|
<input type="text" name="cotFraisHT" id="cotFraisHT" placeholder="Ex: 36.00" />
|
||||||
<span id="cotFraisHT-error" class="helper-text red-text"></span>
|
<span id="cotFraisHT-error" class="helper-text red-text"></span>
|
||||||
</td>
|
</td>
|
||||||
<td><input type="text" name="cotFraisTaux" id="cotFraisTaux" value="Sans taxe" disabled />
|
<td><input type="text" name="cotFraisTaux" id="cotFraisTaux" value="Sans taxe" disabled />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="cotFraisTTC" id="cotFraisTTC" value="36.00" />
|
<input type="text" name="cotFraisTTC" id="cotFraisTTC" placeholder="Ex: 36.00" />
|
||||||
<span id="cotFraisTTC-error" class="helper-text red-text"></span>
|
<span id="cotFraisTTC-error" class="helper-text red-text"></span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr id="primeRefRow">
|
<tr id="primeRefRow">
|
||||||
<td>Prime HT de référence (tarif choisi)</td>
|
<td>Prime HT de référence (tarif choisi)</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="primeRefHT" id="primeRefHT" readonly />
|
<input type="text" name="primeRefHT" id="primeRefHT" disabled />
|
||||||
<span id="primeRefHT-error" class="helper-text red-text"></span>
|
<span id="primeRefHT-error" class="helper-text red-text"></span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -982,8 +979,20 @@
|
||||||
<input type="text" name="primeRefTTC" id="primeRefTTC" value="//" disabled />
|
<input type="text" name="primeRefTTC" id="primeRefTTC" value="//" disabled />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr id="tarifCommercialRow">
|
||||||
|
<td>Tarif commercial saisi (étape Tarif)</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="tarifComSaisiHT" id="tarifComSaisiHT" disabled />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="tarifComSaisiTaxe" id="tarifComSaisiTaxe" value="Tarif saisi" disabled />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="tarifComSaisiTTC" id="tarifComSaisiTTC" value="//" disabled />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Total</td>
|
<td>Total (retenu)</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="cotTotalHT" id="cotTotalHT" />
|
<input type="text" name="cotTotalHT" id="cotTotalHT" />
|
||||||
<span id="cotTotalHT-error" class="helper-text red-text"></span>
|
<span id="cotTotalHT-error" class="helper-text red-text"></span>
|
||||||
|
|
@ -1016,6 +1025,7 @@
|
||||||
<h6 class="red-text text-darken-4">Veuillez enregistrer toutes modifications sur le formulaire :</h6>
|
<h6 class="red-text text-darken-4">Veuillez enregistrer toutes modifications sur le formulaire :</h6>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="rcProjetBlockingSummary" class="rc-blocking-summary"></div>
|
||||||
<button class="btn" type="submit" id="projetFormBtn">Enregistrer et poursuivre le parcours</button>
|
<button class="btn" type="submit" id="projetFormBtn">Enregistrer et poursuivre le parcours</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1248,7 +1248,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button id="comm-OK" class="waves-effect waves-light btn indigo darken-4">Valider</button>
|
<button id="comm-OK" type="button" class="waves-effect waves-light btn indigo darken-4">Valider</button>
|
||||||
<button id="comm-cancel" class="modal-close waves-effect waves-light btn red darken-1">Annuler</button>
|
<button id="comm-cancel" type="button" class="modal-close waves-effect waves-light btn red darken-1">Annuler</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue