98 lines
4.5 KiB
JavaScript
98 lines
4.5 KiB
JavaScript
import { DRAWERS, NICHE } from '../../shared/manufacturing.js';
|
||
|
||
export function validateConfig(config = {}, settings = {}) {
|
||
const errors = [];
|
||
const warnings = [];
|
||
|
||
const installationType = config.installationType || 'free';
|
||
const doorType = config.doorType || 'hinged';
|
||
const widthMm = Number(config.widthMm || 0);
|
||
const heightMm = Number(config.heightMm || 0);
|
||
const depthMm = Number(config.depthMm || 0);
|
||
const modules = Array.isArray(config.modules) ? config.modules : [];
|
||
const allowSliding = String(settings.allow_sliding_doors ?? '0') === '1';
|
||
const sanitaryGapMm = Number(settings.sanitary_gap_mm || NICHE.sanitaryGapAround);
|
||
|
||
if (doorType === 'sliding' && !allowSliding) {
|
||
errors.push({ field: 'doorType', message: 'Portes coulissantes désactivées.' });
|
||
}
|
||
|
||
if (installationType === 'niche') {
|
||
const nm = config.nicheMeasurements || {};
|
||
const minW = Math.min(nm.widthTopMm || widthMm, nm.widthMidMm || widthMm, nm.widthBottomMm || widthMm);
|
||
const minD = Math.min(nm.depthTopMm || depthMm, nm.depthMidMm || depthMm, nm.depthBottomMm || depthMm);
|
||
const minH = Math.min(nm.heightLeftMm || heightMm, nm.heightRightMm || heightMm);
|
||
const expectedW = Math.max(400, minW - sanitaryGapMm * 2);
|
||
const expectedD = Math.max(400, minD - sanitaryGapMm * 2);
|
||
const expectedH = Math.max(1800, minH - sanitaryGapMm * 2);
|
||
if (Math.abs(expectedW - widthMm) > 2 || Math.abs(expectedD - depthMm) > 2 || Math.abs(expectedH - heightMm) > 2) {
|
||
errors.push({ field: 'nicheMeasurements', message: 'Dimensions niche incohérentes avec les mesures mini et vide sanitaire.' });
|
||
}
|
||
}
|
||
|
||
const drawerDepthMin = Number(settings.drawer_depth_min_mm || DRAWERS.minDepth);
|
||
const drawerDepthMax = Number(settings.drawer_depth_max_mm || DRAWERS.maxDepth);
|
||
const drawerDepthStep = Number(settings.drawer_depth_step_mm || DRAWERS.depthStep);
|
||
|
||
/** Même logique que `useWardrobeConfig` : pas de 50 mm sur la profondeur utile, puis réserve tiroir caché. */
|
||
const inferredEffectiveDrawerDepthMm = () => {
|
||
const rawGap = depthMm - NICHE.drawerBackGap;
|
||
const clamped = Math.max(drawerDepthMin, Math.min(drawerDepthMax, rawGap));
|
||
const steppedMm = Math.round(clamped / drawerDepthStep) * drawerDepthStep;
|
||
const rawDt = config.hardware?.drawerType || 'visible';
|
||
const depthReductionMm =
|
||
rawDt === 'hidden' || rawDt === 'hidden_with_handle' ? DRAWERS.hiddenHandleDepthReduction : 0;
|
||
return Math.max(350, steppedMm - depthReductionMm);
|
||
};
|
||
|
||
for (const [index, m] of modules.entries()) {
|
||
const isDrawerCol = (m.drawers || 0) > 0 || m.type === 'tiroirs';
|
||
if (isDrawerCol && Number(m.widthMm || 0) > DRAWERS.maxColumnWidth) {
|
||
errors.push({ field: `modules[${index}]`, message: `Colonne tiroirs > ${DRAWERS.maxColumnWidth} mm.` });
|
||
}
|
||
if (m.hasRod && heightMm < 1200) {
|
||
errors.push({ field: `modules[${index}]`, message: 'Tringle autorisée à partir de 1200 mm de hauteur armoire.' });
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Profondeur utile tiroir — alignée sur useWardrobeConfig (pas de 50 sur prof. caisse puis −40 si caché).
|
||
* Ne pas exiger un multiple de 50 sur la valeur finale : ex. 550 − 40 = 510 mm est valide.
|
||
*/
|
||
const canonicalEffectiveDrawerDepthMm = inferredEffectiveDrawerDepthMm();
|
||
const effectiveDrawerMinMm = 350;
|
||
if (
|
||
canonicalEffectiveDrawerDepthMm < effectiveDrawerMinMm ||
|
||
canonicalEffectiveDrawerDepthMm > drawerDepthMax
|
||
) {
|
||
errors.push({
|
||
field: 'effectiveDrawerDepthMm',
|
||
message: `Profondeur tiroir utile hors bornes (${effectiveDrawerMinMm}-${drawerDepthMax} mm) pour cette profondeur caisse.`
|
||
});
|
||
}
|
||
|
||
const explicitEff = Number(config.effectiveDrawerDepthMm);
|
||
if (
|
||
Number.isFinite(explicitEff) &&
|
||
explicitEff > 0 &&
|
||
Math.abs(explicitEff - canonicalEffectiveDrawerDepthMm) > 2
|
||
) {
|
||
warnings.push({
|
||
field: 'effectiveDrawerDepthMm',
|
||
message:
|
||
`Valeur stockée (${explicitEff} mm) différente du calcul attendu (${canonicalEffectiveDrawerDepthMm} mm) — le serveur utilise le calcul canonique.`
|
||
});
|
||
}
|
||
|
||
const handleAxis = Number(config.hardware?.handleBoreHeightMm || 1000);
|
||
const stdAxis = Number(settings.standard_handle_axis_mm || 1000);
|
||
const tolerance = Number(settings.standard_handle_tolerance_mm || 200);
|
||
if (handleAxis < stdAxis - tolerance || handleAxis > stdAxis + tolerance) {
|
||
warnings.push({ field: 'handleBoreHeightMm', message: 'Perçage poignée hors plage standard.' });
|
||
}
|
||
|
||
return { errors, warnings };
|
||
}
|
||
|
||
export default { validateConfig };
|