{
  "name": "Relances OPCO et suivi des dossiers de financement",
  "nodes": [
    {
      "id": "4fc9be38-d75b-4898-a739-54927d5bb4d6",
      "name": "Note dossiers opco",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -460,
        -340
      ],
      "parameters": {
        "color": 4,
        "width": 520,
        "height": 280,
        "content": "## 1. Onglet Financements (Google Sheets)\n\n`id_dossier` | `client` | `apprenant` | `titre_formation` | `opco` | `email_opco` | `numero_dossier` | `montant_demande` | `date_depot` | `statut` | `nb_relances` | `derniere_relance`\n\n`statut` : `depose`, `en_instruction`, `accord`, `refus`, `paye`. Seuls les dossiers non soldes sont relances."
      },
      "typeVersion": 1
    },
    {
      "id": "e6543fba-61d3-45a3-a584-c7224bdf81f1",
      "name": "Note escalade",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        200,
        -340
      ],
      "parameters": {
        "color": 3,
        "width": 520,
        "height": 280,
        "content": "## 2. Escalade progressive\n\n| Anciennete | Action |\n| --- | --- |\n| J+7 | relance courtoise |\n| J+15 | relance ferme avec rappel des pieces |\n| J+30 | escalade : demande de point telephonique |\n\nAu-dela de 45 jours, une alerte interne part vers le responsable administratif."
      },
      "typeVersion": 1
    },
    {
      "id": "958a929b-c74c-483c-a051-036191a74f29",
      "name": "Chaque lundi a 9h",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -420,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 * * 1"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "2ff341b8-5782-4181-ac29-cd66f8a0b6e7",
      "name": "Lire les dossiers de financement",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -200,
        0
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Financements"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "REMPLACER_PAR_ID_DU_GOOGLE_SHEET"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "5d751a32-ab62-465d-a4b3-a25a1c971f78",
      "name": "Calculer anciennete et niveau de relance",
      "type": "n8n-nodes-base.code",
      "position": [
        20,
        0
      ],
      "parameters": {
        "jsCode": "// Determine quels dossiers OPCO doivent etre relances cette semaine.\nconst STATUTS_CLOS = ['accord', 'paye', 'refus', 'annule'];\nconst PALIERS = [7, 15, 30];   // jours depuis le depot\nconst SEUIL_ALERTE = 45;\nconst ESPACEMENT_JOURS = 6;    // pas plus d une relance par semaine\n\nconst maintenant = new Date();\nconst sortie = [];\n\nfor (const item of $input.all()) {\n  const l = item.json;\n  const statut = String(l.statut || '').trim().toLowerCase();\n\n  if (STATUTS_CLOS.includes(statut)) continue;\n  if (!l.email_opco) continue;\n\n  const depot = new Date(l.date_depot);\n  if (isNaN(depot.getTime())) continue;\n\n  const anciennete = Math.floor((maintenant - depot) / 86400000);\n  if (anciennete < PALIERS[0]) continue;\n\n  if (l.derniere_relance) {\n    const derniere = new Date(l.derniere_relance);\n    if (!isNaN(derniere.getTime()) && (maintenant - derniere) / 86400000 < ESPACEMENT_JOURS) continue;\n  }\n\n  let niveau = 1;\n  if (anciennete >= PALIERS[2]) niveau = 3;\n  else if (anciennete >= PALIERS[1]) niveau = 2;\n\n  sortie.push({\n    json: {\n      ...l,\n      anciennete_jours: anciennete,\n      niveau,\n      dossier_bloque: anciennete >= SEUIL_ALERTE,\n      nb_relances: Number(l.nb_relances || 0) + 1,\n      relance_le: maintenant.toISOString(),\n    },\n  });\n}\n\nreturn sortie;"
      },
      "typeVersion": 2
    },
    {
      "id": "6a77e1f7-0d65-4973-a96d-27ccb322a061",
      "name": "Router selon le niveau",
      "type": "n8n-nodes-base.switch",
      "position": [
        240,
        0
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "9a2a106d-0153-44dc-af7e-05b6806f8a26",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.niveau }}",
                    "rightValue": 1
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "Relance J+7"
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "a52623f3-2687-4b1e-afe8-6294bcc07d72",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.niveau }}",
                    "rightValue": 2
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "Relance J+15"
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "98560200-b45d-4bc5-a0c5-666a13d48c39",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.niveau }}",
                    "rightValue": 3
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "Escalade J+30"
            }
          ]
        },
        "options": {
          "looseTypeValidation": true
        }
      },
      "typeVersion": 3.2
    },
    {
      "id": "d24bf181-54c8-40c3-a437-daa1ab3bbf50",
      "name": "Message relance 1",
      "type": "n8n-nodes-base.set",
      "position": [
        460,
        -200
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "924780c0-3bf4-4c36-a1de-b4fc81c102cf",
              "name": "objet_relance",
              "type": "string",
              "value": "=Suivi dossier {{ $json.numero_dossier }} - {{ $json.client }}"
            },
            {
              "id": "03edb4d5-3d5b-4f6a-ae6e-79a263adbda2",
              "name": "corps_relance",
              "type": "string",
              "value": "=<p>Bonjour,</p><p>Nous revenons vers vous concernant le dossier de prise en charge suivant, d&eacute;pos&eacute; il y a {{ $json.anciennete_jours }} jours :</p><ul><li><strong>Dossier :</strong> {{ $json.numero_dossier }}</li><li><strong>Entreprise :</strong> {{ $json.client }}</li><li><strong>Stagiaire :</strong> {{ $json.apprenant }}</li><li><strong>Formation :</strong> {{ $json.titre_formation }}</li><li><strong>Montant demand&eacute; :</strong> {{ $json.montant_demande }} EUR</li><li><strong>D&eacute;pos&eacute; le :</strong> {{ $json.date_depot }} ({{ $json.anciennete_jours }} jours)</li></ul><p>Pourriez-vous nous confirmer sa bonne r&eacute;ception et l'&eacute;tat d'avancement de son instruction ?</p><p>Bien cordialement,<br/>Le service administratif</p>"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "cd030fa7-e4ff-4506-a3fa-f3a0f4978fa9",
      "name": "Message relance 2",
      "type": "n8n-nodes-base.set",
      "position": [
        460,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "17e63db3-e3ea-4652-a2ec-51afb4aefdc8",
              "name": "objet_relance",
              "type": "string",
              "value": "=RELANCE 2 - dossier {{ $json.numero_dossier }} en attente depuis {{ $json.anciennete_jours }} jours"
            },
            {
              "id": "c9b3c9e5-c09a-4e88-aa6a-22654bb8f384",
              "name": "corps_relance",
              "type": "string",
              "value": "=<p>Bonjour,</p><p>Sauf erreur de notre part, ce dossier reste sans r&eacute;ponse malgr&eacute; notre premi&egrave;re relance :</p><ul><li><strong>Dossier :</strong> {{ $json.numero_dossier }}</li><li><strong>Entreprise :</strong> {{ $json.client }}</li><li><strong>Stagiaire :</strong> {{ $json.apprenant }}</li><li><strong>Formation :</strong> {{ $json.titre_formation }}</li><li><strong>Montant demand&eacute; :</strong> {{ $json.montant_demande }} EUR</li><li><strong>D&eacute;pos&eacute; le :</strong> {{ $json.date_depot }} ({{ $json.anciennete_jours }} jours)</li></ul><p>Merci de nous indiquer sous 5 jours ouvr&eacute;s si des pi&egrave;ces compl&eacute;mentaires sont attendues (convention sign&eacute;e, programme, devis, attestation d'assiduit&eacute;).</p><p>Bien cordialement,<br/>Le service administratif</p>"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "9163db24-3812-4438-a83f-6b3c16df23bd",
      "name": "Message escalade",
      "type": "n8n-nodes-base.set",
      "position": [
        460,
        200
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1311b398-74ac-4946-a735-50a735094105",
              "name": "objet_relance",
              "type": "string",
              "value": "=ESCALADE - dossier {{ $json.numero_dossier }} bloque depuis {{ $json.anciennete_jours }} jours"
            },
            {
              "id": "d9b11e2d-e458-4a67-a102-eb8c09b731fe",
              "name": "corps_relance",
              "type": "string",
              "value": "=<p>Bonjour,</p><p>Ce dossier de financement est en attente depuis plus de 30 jours et bloque notre facturation :</p><ul><li><strong>Dossier :</strong> {{ $json.numero_dossier }}</li><li><strong>Entreprise :</strong> {{ $json.client }}</li><li><strong>Stagiaire :</strong> {{ $json.apprenant }}</li><li><strong>Formation :</strong> {{ $json.titre_formation }}</li><li><strong>Montant demand&eacute; :</strong> {{ $json.montant_demande }} EUR</li><li><strong>D&eacute;pos&eacute; le :</strong> {{ $json.date_depot }} ({{ $json.anciennete_jours }} jours)</li></ul><p>Nous sollicitons un point t&eacute;l&eacute;phonique cette semaine avec le gestionnaire en charge du dossier. Merci de nous communiquer un cr&eacute;neau ou le contact direct concern&eacute;.</p><p>Bien cordialement,<br/>Le service administratif</p>"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "841df533-a446-4325-a9ad-bf181869040e",
      "name": "Fusionner les relances",
      "type": "n8n-nodes-base.merge",
      "position": [
        680,
        0
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3
    },
    {
      "id": "0ba219e6-cb36-49d9-a267-9bacd70e3334",
      "name": "Envoyer la relance a l'OPCO",
      "type": "n8n-nodes-base.gmail",
      "position": [
        900,
        0
      ],
      "parameters": {
        "sendTo": "={{ $json.email_opco }}",
        "subject": "={{ $json.objet_relance }}",
        "message": "={{ $json.corps_relance }}",
        "options": {
          "appendAttribution": false
        },
        "emailType": "html",
        "resource": "message",
        "operation": "send"
      },
      "typeVersion": 2.1,
      "webhookId": "459261b5-4513-40cd-a2a0-70b5692989a9"
    },
    {
      "id": "ffe4c1e3-0b73-4002-a981-9a4a2fa9b67a",
      "name": "Historiser la relance",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1120,
        0
      ],
      "parameters": {
        "columns": {
          "value": {
            "id_dossier": "={{ $json.id_dossier }}",
            "nb_relances": "={{ $json.nb_relances }}",
            "derniere_relance": "={{ $json.relance_le }}",
            "niveau_relance": "={{ $json.niveau }}",
            "anciennete_jours": "={{ $json.anciennete_jours }}"
          },
          "schema": [
            {
              "id": "id_dossier",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "id_dossier",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "nb_relances",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "nb_relances",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "derniere_relance",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "derniere_relance",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "niveau_relance",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "niveau_relance",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "anciennete_jours",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "anciennete_jours",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id_dossier"
          ]
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Financements"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "REMPLACER_PAR_ID_DU_GOOGLE_SHEET"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "a0670299-aab2-49f6-ae4f-c7613d104e78",
      "name": "Dossier bloque ?",
      "type": "n8n-nodes-base.if",
      "position": [
        1340,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e50a1b48-a5d8-4dd4-a8d1-49014b22fe82",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.dossier_bloque }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "c6ec90b2-99e2-4267-af2e-1872654cb994",
      "name": "Alerter le responsable administratif",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1560,
        -120
      ],
      "parameters": {
        "sendTo": "administratif@votre-of.fr",
        "subject": "=Dossier OPCO bloque - {{ $json.numero_dossier }} ({{ $json.anciennete_jours }} j)",
        "message": "=<p>Le dossier <strong>{{ $json.numero_dossier }}</strong> ({{ $json.client }} - {{ $json.titre_formation }}) est sans r&eacute;ponse depuis {{ $json.anciennete_jours }} jours pour un montant de {{ $json.montant_demande }} EUR.</p><p>{{ $json.nb_relances }} relance(s) automatique(s) envoy&eacute;e(s) a {{ $json.email_opco }}. Une action manuelle est n&eacute;cessaire.</p>",
        "options": {
          "appendAttribution": false
        },
        "emailType": "html",
        "resource": "message",
        "operation": "send"
      },
      "typeVersion": 2.1,
      "webhookId": "228574a5-b2dd-48de-acd7-fff8509fbdd2"
    },
    {
      "id": "9ec0cbc2-ac27-4c07-a826-6da0fc03b4c9",
      "name": "Suivi normal",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1560,
        120
      ],
      "parameters": {},
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "Chaque lundi a 9h": {
      "main": [
        [
          {
            "node": "Lire les dossiers de financement",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lire les dossiers de financement": {
      "main": [
        [
          {
            "node": "Calculer anciennete et niveau de relance",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculer anciennete et niveau de relance": {
      "main": [
        [
          {
            "node": "Router selon le niveau",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Router selon le niveau": {
      "main": [
        [
          {
            "node": "Message relance 1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Message relance 2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Message escalade",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message relance 1": {
      "main": [
        [
          {
            "node": "Fusionner les relances",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message relance 2": {
      "main": [
        [
          {
            "node": "Fusionner les relances",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Message escalade": {
      "main": [
        [
          {
            "node": "Fusionner les relances",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Fusionner les relances": {
      "main": [
        [
          {
            "node": "Envoyer la relance a l'OPCO",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Envoyer la relance a l'OPCO": {
      "main": [
        [
          {
            "node": "Historiser la relance",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Historiser la relance": {
      "main": [
        [
          {
            "node": "Dossier bloque ?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Dossier bloque ?": {
      "main": [
        [
          {
            "node": "Alerter le responsable administratif",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Suivi normal",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "b1e37a67-ac6f-4fae-ae77-38933f6c3d9f",
  "meta": {
    "instanceId": "5f7c1a2b9d3e4f60a8b7c6d5e4f3021998af77bc12de34ff56aa7788bb99ccdd",
    "templateCredsSetupCompleted": true
  },
  "tags": []
}
