{"id":22717,"date":"2026-06-01T09:30:00","date_gmt":"2026-06-01T07:30:00","guid":{"rendered":"https:\/\/visionsoft.tech\/replanifier-production-erp\/"},"modified":"2026-06-01T20:11:30","modified_gmt":"2026-06-01T18:11:30","slug":"replanifier-production-erp","status":"publish","type":"post","link":"https:\/\/visionsoft.tech\/en\/replanifier-production-erp\/","title":{"rendered":"Replanifier la production quand l&#8217;ERP ne le fait pas"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"22717\" class=\"elementor elementor-22717\" data-elementor-post-type=\"post\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-cf38fea elementor-section-boxed elementor-section-height-default elementor-section-height-default qodef-elementor-content-no\" data-id=\"cf38fea\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-aac71dd\" data-id=\"aac71dd\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-c87e9d2 elementor-widget elementor-widget-html\" data-id=\"c87e9d2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\r\n.vstuto{\r\n  --navy:#232048;--blue-night:#394170;--cyan:#2a5fff;\r\n  --grey-light:#E6EBF2;--grey-mid:#CCD6E0;--red-accent:#D6544C;\r\n  --white:#FFFFFF;--code-bg:#1a1830;--maxw:760px;\r\n  font-family:'Roboto',-apple-system,sans-serif;font-weight:400;\r\n  color:#2b2a3d;background:transparent;line-height:1.7;\r\n  -webkit-font-smoothing:antialiased;text-align:left;\r\n}\r\n.vstuto *{box-sizing:border-box;margin:0;padding:0;}\r\n.vstuto h1,.vstuto h2,.vstuto h3{font-family:'Roboto',sans-serif;font-weight:600;line-height:1.25;}\r\n.vstuto a{color:#2a5fff;}\r\n.vstuto .vst-wrap{max-width:var(--maxw);margin:0 auto;padding:0 20px;}\r\n \r\n\/* En-t\u00eate *\/\r\n.vstuto .vst-head{border-bottom:1px solid var(--grey-mid);padding:6px 0 22px;margin-bottom:30px;}\r\n.vstuto .vst-kicker{font-size:.74rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--cyan);}\r\n.vstuto .vst-head h1{font-size:2rem;color:var(--navy);margin:10px 0 12px;}\r\n.vstuto .vst-head .vst-sub{font-size:1.1rem;color:var(--blue-night);font-family:'Roboto Slab',serif;}\r\n.vstuto .vst-byline{font-size:.82rem;color:#7b8196;margin-top:14px;}\r\n.vstuto .vst-byline b{color:var(--blue-night);font-weight:500;}\r\n \r\n.vstuto article p{margin:0 0 18px;font-size:1.05rem;}\r\n.vstuto article h2{font-size:1.4rem;color:var(--navy);margin:38px 0 12px;}\r\n.vstuto article h2 .vst-n{color:var(--cyan);margin-right:8px;}\r\n.vstuto .vst-em{color:var(--navy);font-weight:600;}\r\n.vstuto strong{color:var(--navy);}\r\n \r\n\/* Note *\/\r\n.vstuto .vst-note{background:#fff;border-left:3px solid var(--cyan);border-radius:6px;\r\n  padding:14px 18px;margin:22px 0;font-size:.98rem;color:var(--blue-night);}\r\n.vstuto .vst-note b{color:var(--navy);}\r\n \r\n\/* Flow *\/\r\n.vstuto .vst-flow{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:14px 0 22px;font-size:.86rem;}\r\n.vstuto .vst-node{background:#fff;border:1px solid var(--grey-mid);border-bottom:2px solid var(--cyan);\r\n  border-radius:5px;padding:6px 12px;color:var(--navy);font-weight:500;}\r\n.vstuto .vst-arrow{color:var(--cyan);font-weight:600;}\r\n \r\n\/* Table *\/\r\n.vstuto .vst-tblwrap{overflow-x:auto;margin:18px 0;border:1px solid var(--grey-mid);border-radius:6px;}\r\n.vstuto table{width:100%;border-collapse:collapse;background:#fff;font-size:.88rem;}\r\n.vstuto th{background:var(--navy);color:#fff;text-align:left;padding:9px 14px;font-weight:600;font-size:.82rem;}\r\n.vstuto td{padding:9px 14px;border-top:1px solid var(--grey-mid);vertical-align:top;color:#2b2a3d;}\r\n.vstuto td code{font-family:'JetBrains Mono',monospace;font-size:.78rem;color:var(--blue-night);background:var(--grey-light);padding:1px 5px;border-radius:4px;}\r\n \r\n\/* Code *\/\r\n.vstuto .vst-codeblock{margin:18px 0;}\r\n.vstuto .vst-label{display:flex;justify-content:space-between;align-items:center;background:#13111f;\r\n  color:var(--grey-mid);font-size:.72rem;font-weight:500;padding:7px 14px;border-radius:7px 7px 0 0;}\r\n.vstuto .vst-label .vst-tag{color:var(--cyan);text-transform:uppercase;letter-spacing:.1em;}\r\n.vstuto .vst-copy{background:rgba(42,95,255,.15);color:var(--cyan);border:1px solid rgba(42,95,255,.35);\r\n  border-radius:5px;padding:3px 11px;font-size:.7rem;font-weight:500;cursor:pointer;font-family:'Roboto',sans-serif;}\r\n.vstuto .vst-copy:hover{background:rgba(42,95,255,.28);}\r\n.vstuto pre{background:var(--code-bg);color:#dfe6f0;border-radius:0 0 7px 7px;padding:16px;overflow-x:auto;\r\n  font-family:'JetBrains Mono',monospace;font-size:.8rem;line-height:1.65;}\r\n.vstuto .c-kw{color:#2a5fff;}.vstuto .c-fn{color:#7ee3ff;}.vstuto .c-str{color:#9ad7a0;}\r\n.vstuto .c-num{color:#e0a96d;}.vstuto .c-com{color:#6b7394;font-style:italic;}.vstuto .c-var{color:#cfd6e6;}\r\n \r\n\/* Liste *\/\r\n.vstuto .vst-list{list-style:none;margin:10px 0 18px;}\r\n.vstuto .vst-list li{position:relative;padding-left:22px;margin-bottom:10px;font-size:1.02rem;}\r\n.vstuto .vst-list li::before{content:\"\\25B8\";position:absolute;left:0;color:var(--cyan);font-weight:600;}\r\n \r\n\/* ACCORDEON *\/\r\n.vstuto .vst-accordion{margin:10px 0 22px;border:1px solid var(--grey-mid);border-radius:8px;overflow:hidden;}\r\n.vstuto .vst-acc-trigger{width:100%;background:#f5f7fa;border:none;cursor:pointer;padding:13px 18px;\r\n  display:flex;align-items:center;justify-content:space-between;\r\n  font-family:'Roboto',sans-serif;font-size:.88rem;font-weight:500;color:var(--blue-night);text-align:left;}\r\n.vstuto .vst-acc-trigger:hover{background:#edf0f5;}\r\n.vstuto .vst-acc-icon{font-size:1rem;color:var(--cyan);transition:transform .25s;line-height:1;display:inline-block;}\r\n.vstuto .vst-acc-trigger.open .vst-acc-icon{transform:rotate(90deg);}\r\n.vstuto .vst-acc-body{max-height:0;overflow:hidden;transition:max-height .35s ease;}\r\n.vstuto .vst-acc-body.open{max-height:900px;}\r\n.vstuto .vst-acc-body .vst-codeblock{margin:0;}\r\n.vstuto .vst-acc-body pre{border-radius:0;}\r\n.vstuto .vst-acc-body .vst-label{border-radius:0;}\r\n \r\n\/* ENCART PROMPT *\/\r\n.vstuto .vst-prompt-card{background:linear-gradient(180deg,#232048 0%,#2e2c57 100%);\r\n  border:1px solid rgba(42,95,255,.2);border-radius:10px;padding:22px 24px;margin:18px 0;color:#fff;}\r\n.vstuto .vst-prompt-title{font-size:.72rem;font-weight:600;letter-spacing:.12em;\r\n  text-transform:uppercase;color:var(--cyan);margin-bottom:14px;display:flex;align-items:center;gap:8px;}\r\n.vstuto .vst-prompt-title::before{content:\"\";display:inline-block;width:6px;height:6px;\r\n  background:var(--cyan);border-radius:50%;}\r\n.vstuto .vst-prompt-items{display:flex;flex-direction:column;gap:10px;}\r\n.vstuto .vst-prompt-item{display:flex;align-items:flex-start;gap:12px;}\r\n.vstuto .vst-prompt-pill{flex:none;background:rgba(42,95,255,.15);color:var(--cyan);\r\n  border:1px solid rgba(42,95,255,.3);border-radius:4px;padding:3px 10px;font-size:.74rem;font-weight:600;\r\n  white-space:nowrap;}\r\n.vstuto .vst-prompt-item p{font-size:.88rem;color:#c8d0e0;margin:0;line-height:1.5;}\r\n \r\n\/* STEPS VISUELS *\/\r\n.vstuto .vst-steps{margin:18px 0 22px;display:flex;flex-direction:column;gap:0;}\r\n.vstuto .vst-step{display:flex;align-items:flex-start;gap:16px;padding:14px 0;\r\n  border-bottom:1px solid var(--grey-mid);}\r\n.vstuto .vst-step:last-child{border-bottom:none;}\r\n.vstuto .vst-step-num{flex:none;width:32px;height:32px;border-radius:50%;background:var(--navy);\r\n  color:var(--cyan);font-size:.82rem;font-weight:700;display:flex;align-items:center;justify-content:center;}\r\n.vstuto .vst-step-body{flex:1;}\r\n.vstuto .vst-step-body strong{display:block;color:var(--navy);font-size:.95rem;margin-bottom:3px;}\r\n.vstuto .vst-step-body span{font-size:.88rem;color:#5a6070;}\r\n \r\n\/* MINI-GANTT *\/\r\n.vstuto .vsg{margin:0 0 8px;padding:20px 22px;\r\n  background:linear-gradient(180deg,#232048 0%,#2e2c57 100%);\r\n  border:1px solid rgba(42,95,255,.18);border-radius:10px;color:#fff;}\r\n.vstuto .vsg-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;}\r\n.vstuto .vsg-head .vsg-h{font-size:.98rem;font-weight:600;color:#fff;}\r\n.vstuto .vsg-head .vsg-h small{display:block;font-weight:400;font-size:.74rem;color:var(--grey-mid);margin-top:2px;}\r\n.vstuto .vsg-phase{font-size:.74rem;font-weight:500;color:var(--cyan);\r\n  background:rgba(42,95,255,.12);border:1px solid rgba(42,95,255,.35);\r\n  border-radius:20px;padding:5px 13px;white-space:nowrap;transition:color .3s,background .3s,border-color .3s;}\r\n.vstuto .vsg.vsg-done .vsg-phase{color:#8fe39a;background:rgba(143,227,154,.12);border-color:rgba(143,227,154,.4);}\r\n.vstuto .vsg-legend{display:flex;flex-wrap:wrap;gap:14px;margin:13px 0 16px;font-size:.73rem;color:var(--grey-mid);}\r\n.vstuto .vsg-legend span{display:inline-flex;align-items:center;gap:6px;}\r\n.vstuto .vsg-dot{width:14px;height:10px;border-radius:3px;display:inline-block;}\r\n.vstuto .vsg-dot.ok{background:var(--cyan);}\r\n.vstuto .vsg-dot.late{background:var(--red-accent);}\r\n.vstuto .vsg-dot.brk{background:repeating-linear-gradient(45deg,rgba(214,84,76,.55) 0 5px,transparent 5px 10px);border:1px solid rgba(214,84,76,.6);}\r\n.vstuto .vsg-board{display:flex;}\r\n.vstuto .vsg-labels{flex:none;width:100px;}\r\n.vstuto .vsg-corner{height:28px;}\r\n.vstuto .vsg-lab{height:44px;display:flex;align-items:center;font-size:.8rem;font-weight:500;color:var(--grey-mid);transition:color .3s;}\r\n.vstuto .vsg.vsg-alea-on .vsg-lab[data-row=\"1\"]{color:var(--red-accent);font-weight:600;}\r\n.vstuto .vsg-lab[data-row=\"1\"] .vsg-warn{opacity:0;margin-left:5px;transition:opacity .3s;}\r\n.vstuto .vsg.vsg-alea-on .vsg-lab[data-row=\"1\"] .vsg-warn{opacity:1;}\r\n.vstuto .vsg-plot{flex:1;min-width:0;position:relative;}\r\n.vstuto .vsg-days{display:flex;height:28px;}\r\n.vstuto .vsg-days span{flex:1;text-align:center;font-size:.7rem;color:var(--grey-mid);\r\n  border-left:1px solid rgba(255,255,255,.06);line-height:28px;}\r\n.vstuto .vsg-days span:first-child{border-left:none;}\r\n.vstuto .vsg-rows{position:relative;height:132px;}\r\n.vstuto .vsg-rowbg{position:absolute;left:0;right:0;height:38px;top:calc(var(--row) * 44px);\r\n  background:rgba(255,255,255,.035);border-radius:6px;}\r\n.vstuto .vsg-rows::before{content:\"\";position:absolute;inset:0;pointer-events:none;border-radius:6px;\r\n  background-image:repeating-linear-gradient(to right,transparent 0,transparent calc(100%\/6 - 1px),rgba(255,255,255,.06) calc(100%\/6 - 1px),rgba(255,255,255,.06) calc(100%\/6));}\r\n.vstuto .vsg-break{position:absolute;top:calc(var(--row) * 44px);height:38px;\r\n  left:calc(2\/6*100%);width:calc(2\/6*100%);border-radius:6px;\r\n  background:repeating-linear-gradient(45deg,rgba(214,84,76,.32) 0 7px,transparent 7px 14px);\r\n  border:1px dashed rgba(214,84,76,.6);opacity:0;transition:opacity .5s;z-index:1;}\r\n.vstuto .vsg.vsg-alea-on .vsg-break{opacity:1;}\r\n.vstuto .vsg-bar{position:absolute;height:34px;top:calc(var(--row)*44px + 2px);\r\n  left:calc(var(--start)\/6*100% + 2px);width:calc(var(--len)\/6*100% - 4px);\r\n  background:var(--cyan);color:var(--navy);border-radius:5px;\r\n  display:flex;align-items:center;gap:6px;padding:0 10px;\r\n  font-size:.75rem;font-weight:600;white-space:nowrap;overflow:hidden;z-index:2;\r\n  box-shadow:0 2px 8px rgba(0,0,0,.25);\r\n  transition:left .9s cubic-bezier(.45,0,.25,1),width .9s cubic-bezier(.45,0,.25,1),background .5s,color .5s;}\r\n.vstuto .vsg-tag{font-size:.6rem;font-weight:600;background:rgba(0,0,0,.18);border-radius:3px;padding:1px 5px;display:none;}\r\n.vstuto .vsg.vsg-after .vsg-bar[data-bar=\"102\"]{--start:4;background:var(--red-accent);color:#fff;}\r\n.vstuto .vsg.vsg-after .vsg-bar[data-bar=\"102\"] .vsg-tag{display:inline;}\r\n.vstuto .vsg-alea{margin-top:14px;display:flex;align-items:center;gap:9px;font-size:.82rem;\r\n  background:rgba(214,84,76,.12);border:1px solid rgba(214,84,76,.4);border-radius:7px;color:#f3b4b0;\r\n  padding:0 14px;max-height:0;opacity:0;overflow:hidden;transition:max-height .4s,opacity .4s,padding .4s;}\r\n.vstuto .vsg.vsg-alea-on .vsg-alea{max-height:70px;opacity:1;padding:10px 14px;}\r\n.vstuto .vsg.vsg-after .vsg-alea{background:rgba(143,227,154,.1);border-color:rgba(143,227,154,.4);color:#bfe9c5;}\r\n.vstuto .vsg-cap{font-size:.78rem;color:#7b8196;margin:0 0 24px;font-style:italic;}\r\n \r\n.vstuto .vst-end{font-size:.92rem;color:#7b8196;border-top:1px solid var(--grey-mid);margin-top:36px;padding-top:18px;}\r\n.vstuto .vst-end a{font-weight:500;}\r\n \r\n@media(max-width:600px){\r\n  .vstuto .vsg-labels{width:78px;}\r\n  .vstuto .vst-head h1{font-size:1.6rem;}\r\n  .vstuto .vst-bar{font-size:.66rem;padding:0 6px;}\r\n}\r\n<\/style>\r\n \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7f859c66 elementor-widget elementor-widget-text-editor\" data-id=\"7f859c66\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<section class=\"vstuto\">\n<div class=\"vst-wrap\"><header class=\"vst-head\"><span class=\"vst-kicker\">Retour d&#8217;experience<\/span>\n<p class=\"vst-sub\">Comment on a mont\u00e9 un planificateur en no-code avec Vision, avec juste ce qu&#8217;il faut de JavaScript l\u00e0 o\u00f9 \u00e7a compte.<\/p>\n<p class=\"vst-byline\">No-code industrie<\/p>\n\n<\/header><article>Un client industriel nous a pos\u00e9 une question simple : son ERP lui sort un planning d&#8217;OF, mais d\u00e8s qu&#8217;une machine tombe en panne ou qu&#8217;un composant manque, il est faux et son ERP ne permet pas de le recalculer ni de faire des simulations selon tel ou tel cas d&#8217;approvisionnement. On a construit l&#8217;outil. Voici comment, et ce qu&#8217;on en retient<\/article><article><\/article><article><\/article><article>.<\/article><article>\n<div class=\"vsg\">\n<div class=\"vsg-head\">\n<div class=\"vsg-h\">Replanification en direct<small>3 postes \u00b7 horizon 6 jours \u00b7 une panne<\/small><\/div>\n<span class=\"vsg-phase\" data-phase=\"\">1 \u00b7 Planning initial<\/span>\n\n<\/div>\n<div class=\"vsg-legend\"><i class=\"vsg-dot ok\"><\/i> OF planifi\u00e9\n<i class=\"vsg-dot late\"><\/i> OF decal\u00e9 \/ en retard\n<i class=\"vsg-dot brk\"><\/i> Poste indisponible<\/div>\n<div class=\"vsg-board\">\n<div class=\"vsg-labels\">\n<div class=\"vsg-corner\"><\/div>\n<div class=\"vsg-lab\" data-row=\"0\">Tour CN<\/div>\n<div class=\"vsg-lab\" data-row=\"1\">Fraiseuse <span class=\"vsg-warn\">\u26a0<\/span><\/div>\n<div class=\"vsg-lab\" data-row=\"2\">Assemblage<\/div>\n<\/div>\n<div class=\"vsg-plot\">\n<div class=\"vsg-days\">J1J2J3J4J5J6<\/div>\n<div class=\"vsg-rows\">\n<div class=\"vsg-rowbg\" style=\"--row: 0;\"><\/div>\n<div class=\"vsg-rowbg\" style=\"--row: 1;\"><\/div>\n<div class=\"vsg-rowbg\" style=\"--row: 2;\"><\/div>\n<div class=\"vsg-break\" style=\"--row: 1;\"><\/div>\n<div class=\"vsg-bar\" style=\"--row: 0; --start: 0; --len: 3;\" data-bar=\"101\">OF-101<\/div>\n<div class=\"vsg-bar\" style=\"--row: 1; --start: 2; --len: 2;\" data-bar=\"102\">OF-102 <span class=\"vsg-tag\">retard<\/span><\/div>\n<div class=\"vsg-bar\" style=\"--row: 2; --start: 1; --len: 3;\" data-bar=\"103\">OF-103<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"vsg-alea\" data-alea=\"\"><b>\u26a0 Panne :<\/b> la Fraiseuse est indisponible en J3-J4. L&#8217;OF-102 est decal\u00e9 apr\u00e8s la remise en route.<\/div>\n<\/div>\n<p class=\"vsg-cap\">La Fraiseuse tombe en panne ; l&#8217;OF-102 glisse en J5-J6 sur le m\u00eame poste, signale en retard. Le responsable valide la proposition.<\/p>\n\n<h2><span class=\"vst-n\">1.<\/span>Le probl\u00e8me<\/h2>\nL&#8217;ERP fait bien son travail : il transforme les commandes en <span class=\"vst-em\">ordres de fabrication<\/span> via le calcul des besoins. Mais ce calcul est fait \u00e0 capacit\u00e9 infinie, sur un horizon fig\u00e9. Il suppose que les machines tournent toujours et que la mati\u00e8re est l\u00e0. Le planning est juste le lundi matin ; d\u00e8s le premier alea, c&#8217;est une fiction.\n\nEt des al\u00e9as, il y en a tous les jours : une rupture de composants, un retard fournisseur, une panne machine, une absence, une urgence client, un lot au rebut. A chaque fois, le responsable reouvre Excel, passe des coups de fil, d\u00e9place des \u00e9tiquettes sur un planning mural &#8211; sans visibilit\u00e9 sur l&#8217;effet en cascade.\n<div class=\"vst-note\"><b>Le besoin reel :<\/b> repartir du planning de l&#8217;ERP, v\u00e9rifier en continu la mati\u00e8re et la capacit\u00e9 r\u00e9elle, et reproposer un ordonnancement en quelques secondes quand un al\u00e9a tombe &#8211; avec l&#8217;impact chiffr\u00e9 sur les dates.<\/div>\n<h2><span class=\"vst-n\">2.<\/span>Les \u00e9crans et les workflows, en no-code<\/h2>\nAvec Vision, on ne dessine pas des maquettes : on d\u00e9crit le besoin, la plateforme g\u00e9n\u00e8re l&#8217;application, et on l&#8217;ajuste en no-code. On commence toujours par le <span class=\"vst-em\">mod\u00e8le de donn\u00e9es<\/span> &#8211; c&#8217;est lui qui structure tout le reste.\n<div class=\"vst-tblwrap\">\n<table>\n<thead>\n<tr>\n<th>Entite<\/th>\n<th>Champs principaux<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>Ordre de fabrication<\/code><\/td>\n<td>article, quantite, date_due, priorite, statut, poste, debut \/ fin planifies<\/td>\n<\/tr>\n<tr>\n<td><code>Article<\/code> \/ <code>Nomenclature<\/code><\/td>\n<td>reference, type ; + composant (vers Article), quantite_par<\/td>\n<\/tr>\n<tr>\n<td><code>Stock<\/code><\/td>\n<td>article, quantite_dispo, quantite_reservee<\/td>\n<\/tr>\n<tr>\n<td><code>Poste de charge<\/code><\/td>\n<td>nom, capacite_jour (h), calendrier, statut<\/td>\n<\/tr>\n<tr>\n<td><code>Alea<\/code><\/td>\n<td>type, OF \/ poste \/ article concerne, impact, date<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\nCote ecrans, on a genere l&#8217;essentiel : le Gantt par poste (ci-dessus), la liste des OF filtrable, la fiche OF, le tableau de charge, le formulaire de d\u00e9claration d&#8217;alea et le dashboard des retards. Le cycle de vie d&#8217;un OF se d\u00e9crit comme une suite d&#8217;\u00e9tats :\n<div class=\"vst-flow\"><span class=\"vst-node\">Planifie<\/span><span class=\"vst-arrow\">\u2192<\/span>\n<span class=\"vst-node\">Lancable<\/span><span class=\"vst-arrow\">\u2192<\/span>\n<span class=\"vst-node\">Lance<\/span><span class=\"vst-arrow\">\u2192<\/span>\n<span class=\"vst-node\">En cours<\/span><span class=\"vst-arrow\">\u2192<\/span>\n<span class=\"vst-node\">Termine<\/span><\/div>\nLe passage en &#8220;Lan\u00e7able&#8221; n&#8217;est pas manuel : une r\u00e8gle v\u00e9rifie que tous les composants sont en stock. Et d\u00e9clarer un alea d\u00e9clenche la replanification, que le responsable valide. Tout \u00e7a se d\u00e9crit a Vision en quelques lignes :\n<div class=\"vst-prompt-card\">\n<div class=\"vst-prompt-title\">Ce qu&#8217;on a decrit \u00e0 Vision (Vibe-code)<\/div>\n<div class=\"vst-prompt-items\">\n<div class=\"vst-prompt-item\">\n\n<span class=\"vst-prompt-pill\">Donn\u00e9es<\/span>\n\nOF, Articles et Nomenclatures, Stock, Postes de charge, Aleas &#8211; avec leurs relations et champs m\u00e9tier\n\n<\/div>\n<div class=\"vst-prompt-item\">\n\n<span class=\"vst-prompt-pill\">Objectif<\/span>\n\nReplanifier les OF selon la mati\u00e8re disponible et la capacit\u00e9 r\u00e9elle, et r\u00e9ordonnancer sur chaque al\u00e9a d\u00e9clar\u00e9\n\n<\/div>\n<div class=\"vst-prompt-item\">\n\n<span class=\"vst-prompt-pill\">Ecrans<\/span>\n\nGantt par poste \u00b7 liste d&#8217;OF \u00b7 fiche OF \u00b7 tableau de charge \u00b7 d\u00e9claration d&#8217;al\u00e9a \u00b7 dashboard des retards\n\n<\/div>\n<div class=\"vst-prompt-item\">\n\n<span class=\"vst-prompt-pill\">R\u00e8gles<\/span>\n\nStatuts Planifi\u00e9 \u2192 Lan\u00e7able (si composants OK) \u2192 Lanc\u00e9 \u2192 Termin\u00e9 \u00b7 al\u00e9a = replanification \u00e0 valider\n\n<\/div>\n<\/div>\n<\/div>\n<div class=\"vst-accordion\">\n\n<button class=\"vst-acc-trigger\" type=\"button\">\nVoir le prompt complet envoye a Vision\n<span class=\"vst-acc-icon\">\u25ba<\/span>\n<\/button>\n<div class=\"vst-acc-body\">\n<div class=\"vst-codeblock\">\n<div class=\"vst-label\"><span class=\"vst-tag\">Prompt Vibe-code<\/span><button class=\"vst-copy\" type=\"button\">Copier<\/button><\/div>\n<pre><code><span class=\"c-com\">## Modele de donnees<\/span>\n<span class=\"c-kw\">Ordre de fabrication<\/span> : article, quantite, date_due,\n  priorite (normale \/ urgente), statut (planifie \/ lancable \/ lance \/ termine \/ suspendu),\n  poste, debut_planifie, fin_planifiee\n<span class=\"c-kw\">Article<\/span> : reference, designation, type (fabrique \/ achete), delai_jours\n<span class=\"c-kw\">Nomenclature<\/span> : article_parent, composant, quantite_par\n<span class=\"c-kw\">Stock<\/span> : article, quantite_dispo, quantite_reservee\n<span class=\"c-kw\">Poste de charge<\/span> : nom, capacite_jour_h, calendrier, statut (ouvert \/ maintenance)\n<span class=\"c-kw\">Alea<\/span> : type (rupture \/ retard \/ panne \/ absence \/ urgence \/ rebut),\n  of_concerne, poste_concerne, impact, date\n\n<span class=\"c-com\">## Objectif<\/span>\nReplanifier les OF issus de l'ERP selon la matiere disponible et la capacite\nreelle des postes, et reordonnancer quand un alea est declare.\n\n<span class=\"c-com\">## Ecrans<\/span>\nGantt par poste . liste d'OF filtrable . fiche OF . tableau de charge .\ndeclaration d'alea . dashboard des retards.\n\n<span class=\"c-com\">## Regles<\/span>\n- Statuts : Planifie -&gt; Lancable -&gt; Lance -&gt; En cours -&gt; Termine\n- \"Lancable\" seulement si tous les composants sont en stock\n- Un alea declenche une replanification a valider par le responsable<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<h2><span class=\"vst-n\">3.<\/span>Le cerveau : un peu de JavaScript<\/h2>\nLe no-code couvre les \u00e9crans, les donn\u00e9es et les enchainements. Mais ordonnancer a capacite finie sous contrainte mati\u00e8re, c&#8217;est un vrai probl\u00e8me d&#8217;optimisation &#8211; ca ne se configure pas dans un menu. On l&#8217;a \u00e9crit en JavaScript, dans un bloc appel\u00e9 par le workflow &#8220;D\u00e9clarer un alea&#8221;.\n\nPas d&#8217;usine a gaz : une <span class=\"vst-em\">heuristique de liste<\/span> en 4 \u00e9tapes, simple a expliquer au responsable.\n<div class=\"vst-steps\">\n<div class=\"vst-step\">\n<div class=\"vst-step-num\">1<\/div>\n<div class=\"vst-step-body\"><strong>Trier les OF par priorit\u00e9<\/strong>\nUrgences client d&#8217;abord, puis date due la plus proche, puis marge la plus faible.<\/div>\n<\/div>\n<div class=\"vst-step\">\n<div class=\"vst-step-num\">2<\/div>\n<div class=\"vst-step-body\"><strong>Verifier la matiere disponible<\/strong>\nPour chaque OF, comparer la nomenclature au stock disponible avant de planifier.<\/div>\n<\/div>\n<div class=\"vst-step\">\n<div class=\"vst-step-num\">3<\/div>\n<div class=\"vst-step-body\"><strong>Placer sur le premier cr\u00e9neau libre<\/strong>\nEn sautant jours non ouvr\u00e9s et postes en maintenance. Poste le moins charge en priorit\u00e9.<\/div>\n<\/div>\n<div class=\"vst-step\">\n<div class=\"vst-step-num\">4<\/div>\n<div class=\"vst-step-body\"><strong>Marquer les retards et alerter<\/strong>\nTout OF dont la fin d\u00e9passe la date due est signal\u00e9, avec l&#8217;\u00e9cart chiffre sur les commandes concern\u00e9es.<\/div>\n<\/div>\n<\/div>\n<div class=\"vst-accordion\">\n\n<button class=\"vst-acc-trigger\" type=\"button\">\nCode &#8211; la fonction de tri (EDD)\n<span class=\"vst-acc-icon\">\u25ba<\/span>\n<\/button>\n<div class=\"vst-acc-body\">\n<div class=\"vst-codeblock\">\n<div class=\"vst-label\"><span class=\"vst-tag\">JavaScript<\/span><button class=\"vst-copy\" type=\"button\">Copier<\/button><\/div>\n<pre><code><span class=\"c-kw\">const<\/span> <span class=\"c-fn\">trierOFs<\/span> = (ofs, <span class=\"c-var\">aujourdhui<\/span>) =&gt; [...ofs].<span class=\"c-fn\">sort<\/span>((a, b) =&gt; {\n  <span class=\"c-kw\">if<\/span> (a.priorite !== b.priorite)\n    <span class=\"c-kw\">return<\/span> a.priorite === <span class=\"c-str\">\"urgente\"<\/span> ? <span class=\"c-num\">-1<\/span> : <span class=\"c-num\">1<\/span>;  <span class=\"c-com\">\/\/ urgences devant<\/span>\n  <span class=\"c-kw\">if<\/span> (a.dateDue !== b.dateDue) <span class=\"c-kw\">return<\/span> a.dateDue - b.dateDue;  <span class=\"c-com\">\/\/ EDD<\/span>\n  <span class=\"c-kw\">const<\/span> <span class=\"c-fn\">marge<\/span> = o =&gt; (o.dateDue - <span class=\"c-var\">aujourdhui<\/span>) - o.dureeRequise;\n  <span class=\"c-kw\">return<\/span> <span class=\"c-fn\">marge<\/span>(a) - <span class=\"c-fn\">marge<\/span>(b);\n});<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\nLe coeur du sujet pour le responsable : quand un al\u00e9a tombe, on applique l&#8217;effet, on relance le moteur, et on lui pr\u00e9sente <span class=\"vst-em\">l&#8217;\u00e9cart chiffr\u00e9<\/span> entre l&#8217;ancien et le nouveau planning. La d\u00e9cision reste humaine.\n<div class=\"vst-codeblock\">\n<div class=\"vst-label\"><span class=\"vst-tag\">JavaScript &#8211; r\u00e9action a l&#8217;alea<\/span><button class=\"vst-copy\" type=\"button\">Copier<\/button><\/div>\n<pre><code><span class=\"c-kw\">const<\/span> <span class=\"c-fn\">replanifierSurAlea<\/span> = (alea, etat) =&gt; {\n  <span class=\"c-kw\">const<\/span> avant = etat.planning;\n  <span class=\"c-kw\">switch<\/span> (alea.type) {                         <span class=\"c-com\">\/\/ 1) appliquer l'alea<\/span>\n    <span class=\"c-kw\">case<\/span> <span class=\"c-str\">\"panne\"<\/span>:   etat.<span class=\"c-fn\">fermerPoste<\/span>(alea.poste, alea.duree);   <span class=\"c-kw\">break<\/span>;\n    <span class=\"c-kw\">case<\/span> <span class=\"c-str\">\"retard\"<\/span>:  etat.<span class=\"c-fn\">decalerReception<\/span>(alea.article, alea.jours); <span class=\"c-kw\">break<\/span>;\n    <span class=\"c-kw\">case<\/span> <span class=\"c-str\">\"rebut\"<\/span>:   etat.<span class=\"c-fn\">reinjecterOF<\/span>(alea.of, alea.quantite);   <span class=\"c-kw\">break<\/span>;\n    <span class=\"c-kw\">case<\/span> <span class=\"c-str\">\"urgence\"<\/span>: etat.<span class=\"c-fn\">forcerPriorite<\/span>(alea.of, <span class=\"c-str\">\"urgente\"<\/span>);    <span class=\"c-kw\">break<\/span>;\n  }\n  <span class=\"c-kw\">const<\/span> apres  = <span class=\"c-fn\">ordonnancer<\/span>(etat, alea.date);  <span class=\"c-com\">\/\/ 2) relancer le moteur<\/span>\n  <span class=\"c-kw\">const<\/span> impact = apres.ofs                       <span class=\"c-com\">\/\/ 3) chiffrer l'ecart<\/span>\n    .<span class=\"c-fn\">map<\/span>(o =&gt; ({ of: o.ref, ancienneFin: avant[o.ref]?.fin,\n                nouvelleFin: o.fin, retard: o.fin &gt; o.dateDue }))\n    .<span class=\"c-fn\">filter<\/span>(d =&gt; d.ancienneFin !== d.nouvelleFin);\n  <span class=\"c-kw\">return<\/span> { planning: apres, impact, aValider: <span class=\"c-kw\">true<\/span> };\n};<\/code><\/pre>\n<\/div>\nLe responsable voit alors une proposition claire &#8211; &#8220;3 OF d\u00e9cal\u00e9s, 1 nouveau retard sur la commande X&#8221; &#8211; qu&#8217;il valide, ajuste ou rejette.\n<h2><span class=\"vst-n\">4.<\/span>Ce qu&#8217;on en retient<\/h2>\n<ul class=\"vst-list\">\n \t<li>Le bon partage : <span class=\"vst-em\">le no-code pour l&#8217;application<\/span> (90 % du temps gagne), <span class=\"vst-em\">le JS pour le cerveau m\u00e9tier<\/span> (la logique d&#8217;ordonnancement).<\/li>\n \t<li>Une heuristique simple et explicable bat une optimisation parfaite que personne ne comprend : le responsable doit pouvoir suivre la d\u00e9cision.<\/li>\n \t<li>L&#8217;ERP reste la source des besoins et des donnees maitres ; on ajoute par-dessus la couche de replanification reactive qui lui manque.<\/li>\n \t<li>Du cadrage a une V1 utilisable : quelques jours, pas un projet de 18 mois &#8211; et les profils m\u00e9tier font \u00e9voluer l&#8217;app eux-memes ensuite.<\/li>\n<\/ul>\n<p class=\"vst-end\">Un cas d&#8217;ordonnancement, de planification ou de suivi atelier de votre cot\u00e9 ? On peut en discuter, et partager le code complet de l&#8217;algo sur demande &#8211; <a href=\"https:\/\/visionsoft.tech\">visionsoft.tech<\/a>.<\/p>\n\n<\/article><\/div>\n<\/section>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c6fd34a elementor-widget elementor-widget-html\" data-id=\"c6fd34a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<script>\r\n(function(){\r\n  var root = (document.currentScript && document.currentScript.parentNode.querySelector('.vstuto'))\r\n             || document.querySelector('.vstuto');\r\n  if(!root) return;\r\n \r\n  \/* Copier *\/\r\n  root.addEventListener('click', function(e){\r\n    var btn = e.target.closest ? e.target.closest('.vst-copy') : null;\r\n    if(!btn) return;\r\n    var pre = btn.closest('.vst-codeblock').querySelector('pre');\r\n    var done = function(){ var o=btn.textContent; btn.textContent='Copie \u2713'; setTimeout(function(){ btn.textContent=o; },1500); };\r\n    if(navigator.clipboard && navigator.clipboard.writeText){\r\n      navigator.clipboard.writeText(pre.innerText).then(done, function(){ btn.textContent='Ctrl+C'; });\r\n    } else { btn.textContent='Ctrl+C'; }\r\n  });\r\n \r\n  \/* Accordeons *\/\r\n  root.querySelectorAll('.vst-acc-trigger').forEach(function(btn){\r\n    btn.addEventListener('click', function(){\r\n      var body = btn.nextElementSibling;\r\n      var isOpen = body.classList.contains('open');\r\n      body.classList.toggle('open', !isOpen);\r\n      btn.classList.toggle('open', !isOpen);\r\n    });\r\n  });\r\n \r\n  \/* Gantt anime *\/\r\n  var gantt = root.querySelector('.vsg');\r\n  if(gantt){\r\n    var phaseEl = gantt.querySelector('[data-phase]');\r\n    var phases = [\r\n      { t:2800, label:'1 - Planning initial',                alea:false, after:false, done:false },\r\n      { t:2400, label:'2 - Panne Fraiseuse (J3-J4)',         alea:true,  after:false, done:false },\r\n      { t:2800, label:'3 - Replanification : OF-102 decale', alea:true,  after:true,  done:false },\r\n      { t:3200, label:'4 - Planning valide - retard signale',alea:true,  after:true,  done:true  }\r\n    ];\r\n    var i = 0;\r\n    (function tick(){\r\n      var p = phases[i];\r\n      if(phaseEl) phaseEl.textContent = p.label;\r\n      gantt.classList.toggle('vsg-alea-on', p.alea);\r\n      gantt.classList.toggle('vsg-after',   p.after);\r\n      gantt.classList.toggle('vsg-done',    p.done);\r\n      i = (i+1) % phases.length;\r\n      setTimeout(tick, p.t);\r\n    })();\r\n  }\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Votre ERP sort un planning le lundi, mais d\u00e8s le premier al\u00e9a il est obsol\u00e8te. D\u00e9couvrez comment construire un planificateur de production r\u00e9actif en no-code avec Vision \u2014 ordonnancement \u00e0 capacit\u00e9 finie, gestion des al\u00e9as en temps r\u00e9el.<\/p>\n","protected":false},"author":9,"featured_media":22332,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[1,93],"tags":[],"class_list":["post-22717","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-non-classifiee","category-use-cases"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/visionsoft.tech\/en\/wp-json\/wp\/v2\/posts\/22717","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/visionsoft.tech\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visionsoft.tech\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visionsoft.tech\/en\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/visionsoft.tech\/en\/wp-json\/wp\/v2\/comments?post=22717"}],"version-history":[{"count":5,"href":"https:\/\/visionsoft.tech\/en\/wp-json\/wp\/v2\/posts\/22717\/revisions"}],"predecessor-version":[{"id":22726,"href":"https:\/\/visionsoft.tech\/en\/wp-json\/wp\/v2\/posts\/22717\/revisions\/22726"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/visionsoft.tech\/en\/wp-json\/wp\/v2\/media\/22332"}],"wp:attachment":[{"href":"https:\/\/visionsoft.tech\/en\/wp-json\/wp\/v2\/media?parent=22717"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visionsoft.tech\/en\/wp-json\/wp\/v2\/categories?post=22717"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visionsoft.tech\/en\/wp-json\/wp\/v2\/tags?post=22717"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}