Vérifier les sous-traitants du Québec dans Business Central : licence RBQ, Revenu Québec, CNESST, CCQ
Par Fred Morin ·
Aussi en anglais : Checking Quebec subcontractors in Business Central: RBQ licence, Revenu Québec, CNESST, CCQ
Au Québec, l'entreprise qui engage un sous-traitant porte une partie du risque quand ce sous-traitant n'est pas en règle. Quatre documents comptent, et dans la plupart des entreprises ils vivent dans des fils de courriels et des chiffriers, loin de l'ERP qui envoie pourtant les bons de commande et les paiements.
J'ai donc construit une extension Business Central qui les vérifie là où l'argent bouge : à la libération et au report des achats, et au report des paiements. Cet article couvre ce qu'elle fait et comment elle est montée, avec assez de détails pour lancer un développeur AL.
Il s'agit d'aider à la conformité, pas d'un avis juridique. Les règles plus bas sont résumées à partir de la RBQ, de Revenu Québec, de la CNESST et de la CCQ, et de l'Autorité des marchés publics pour le RENA.
Mis à jour le 7 octobre 2026 : l'extension vérifie maintenant aussi le RENA sur les contrats publics. Voyez la dernière ligne du tableau, et les étapes 8 et 9.
Les quatre documents, et un registre
| Document | Règle | Quand l'ERP doit s'en occuper |
|---|---|---|
| Licence RBQ | L'entrepreneur doit avoir une licence active dans la bonne sous-catégorie. Faire affaire avec un entrepreneur sans licence expose une entreprise à des amendes de 32 267 $ à 161 334 $ | Libération et report des achats |
| Attestation de Revenu Québec (ARQ) | Exigée dès que les contrats de construction avec un même sous-traitant atteignent 25 000 $ avant taxes dans une année civile. Copie au plus tard le 7e jour des travaux, authenticité vérifiée au plus tard le 10e. Valide jusqu'à la fin du mois de délivrance plus 3 mois | Achats, une fois le seuil atteint |
| Lettre d'état de situation de la CNESST | Sans elle à la fin du contrat, la CNESST peut vous réclamer les cotisations impayées de l'entrepreneur | Paiements |
| Lettre d'état de situation de la CCQ | L'entrepreneur général est solidairement responsable des salaires dus aux travailleurs d'un sous-traitant | Paiements |
| RENA (contrats publics seulement) | Une entreprise inscrite au registre des entreprises non admissibles aux contrats publics, tenu par l'Autorité des marchés publics, ne peut pas être sous-traitante sur un contrat public, et l'entrepreneur doit vérifier avant de sous-traiter (Loi sur les contrats des organismes publics, art. 21.5.5 et 21.11). Amendes de 7 500 $ à 40 000 $ pour une entreprise, pour les deux parties (art. 27.8) | Achats et paiements marqués comme contrat public |
Ce qu'elle fait
Une page Sous-traitants à risque liste chaque sous-traitant visé qui demande de l'attention, le plus urgent en premier.

Un sous-traitant par situation. La démo roule en français du Québec ; chaque texte est traduit.
La licence RBQ est vérifiée dans les données de la RBQ elle-même, en direct, et de nouveau chaque nuit. Quand elle n'est pas dans la liste des licences actives, le bon de commande ne part pas.

L'extension additionne les achats de l'année par sous-traitant, y compris le document qu'on libère, et exige l'attestation de Revenu Québec une fois le seuil dépassé.

Au journal des paiements, les lettres de la CNESST et de la CCQ sont vérifiées avant le report. On ajoute le document manquant, et le paiement passe.

Sur un contrat public, le sous-traitant est aussi vérifié dans le RENA. L'extension télécharge le registre chaque semaine et associe les fournisseurs par NEQ, le numéro d'entreprise du Québec. Un bon de commande marqué comme contrat public est arrêté quand le sous-traitant est inscrit ; sans la marque, l'inscription est montrée à titre d'information, puisqu'une entreprise inscrite peut encore faire des travaux privés.
Comment je l'ai construite
Environ 60 objets AL. Voici la recette.
1. Mettre les règles dans les données
Une table Type de document contient chaque document : sa sorte (RBQ, ARQ, CNESST, CCQ ou la vôtre, comme un certificat d'assurance), quand il est exigé (sur les achats, une fois le seuil ARQ atteint, ou avant le paiement), l'application (Aucune, Avertir, Bloquer) et une validité par défaut sous forme de DateFormula (<CM+3M> pour l'ARQ : fin du mois de délivrance plus trois mois).
Une table Document fournisseur contient ce que chaque sous-traitant vous a remis : numéro, date de délivrance, date d'expiration, date de réception, et qui l'a vérifié et quand. Deux profils de configuration (une entreprise de construction, ou une entreprise qui engage des entrepreneurs pour ses propres bâtiments) filtrent les types qui s'appliquent.
2. Lire les données ouvertes de la RBQ
La RBQ publie ses licences actives chaque jour sur Données Québec, derrière une API CKAN publique datastore_search. Pas de clé nécessaire :
Url := StrSubstNo('%1?resource_id=%2&filters=%3', ApiUrl, ResourceId,
Uri.EscapeDataString(StrSubstNo('{"Numero de licence":"%1"}', LicenceNo)));
HttpClient.Get(Url, Response);
La réponse a un enregistrement par sous-catégorie. Une licence inconnue ou suspendue ne renvoie aucun enregistrement : c'est votre « introuvable ». Je garde en cache sur le fournisseur le statut, la restriction, le nom du titulaire, le NEQ et les sous-catégories, avec l'heure de la lecture. Une écriture de file d'attente des travaux les rafraîchit chaque nuit, et chaque recherche roule dans son propre Codeunit.Run, pour qu'un échec n'arrête pas le lot. Dans un sandbox, pensez à activer Allow HttpClient Requests pour l'extension.
Une petite vérification compare le nom du titulaire à la RBQ et le nom du fournisseur. Un numéro de licence avec un chiffre de travers peut pointer vers une vraie compagnie active, complètement différente.
3. Calculer le seuil à partir des écritures
Le seuil ARQ est une somme de Purchase (LCY) sur les écritures fournisseur de l'année civile, plus le montant du document qu'on libère. Dès qu'une année depuis l'entrée en vigueur de la règle l'a dépassé, l'attestation est exigée pour tous les contrats suivants : la vérification regarde en arrière, pas juste l'année en cours.
4. Une fonction de vérification, plusieurs appelants
Comme pour l'extension Loi 96, un seul codeunit prend un fournisseur, un contexte (achat, paiement, revue), une date et un montant, et remplit une table temporaire de problèmes. Il n'écrit rien. La même fonction sert à la vérification à la libération, à celle du paiement, au FactBox, à la notification et à la feuille des sous-traitants à risque.
5. Se brancher sur les achats et les paiements
Release Purchase Document:OnBeforeReleasePurchaseDocPurch.-Post:OnBeforePostPurchaseDocGen. Jnl.-Post Batch:OnBeforeProcessLines, filtré sur les lignes de paiement à un fournisseur
Les erreurs sont un ErrorInfo avec les actions Afficher les problèmes et Passer outre..., et les dérogations vont dans un journal identifié par une empreinte SHA-256 du fournisseur, du document et des problèmes exacts. Si les problèmes changent, la dérogation ne s'applique plus.
6. Le piège : les journaux avalent vos actions d'erreur
La libération et le report montrent l'ErrorInfo avec ses boutons. Le report d'un journal, non. Gen. Jnl.-Post Batch ramasse les erreurs dans la page Messages d'erreur, et les actions disparaissent : l'utilisateur voit pourquoi le paiement est arrêté, sans moyen de corriger ou de passer outre.
La solution : donner au journal des paiements ses propres actions Vérifier et Passer outre... qui appellent le même code, pour que l'utilisateur règle le problème avant le report. Testez vos chemins d'erreur dans un journal, pas juste sur des documents.
7. Les traductions, ce n'est pas juste des libellés
Les descriptions des types de document sont des données, enregistrées dans la langue de la personne qui a configuré la compagnie. Mon premier essai en français affichait « Aucune CCQ status letter au dossier ». Les messages sur les documents officiels utilisent maintenant des libellés par sorte de document, et seuls les types personnalisés reprennent la description enregistrée.
8. Un registre qui est un fichier, pas une API
Le RENA est un fichier JSON mensuel sur Données Québec, environ 1 800 inscriptions, sans datastore à interroger. Trois choses valent la peine d'être copiées.
Trouver l'adresse du fichier au moment de rouler. La page du jeu de données liste ses fichiers, et leurs adresses peuvent changer d'une publication à l'autre. Demandez le jeu de données à package_show de CKAN et prenez la ressource dont le format est JSON :
foreach ResourceToken in Resources do
if UpperCase(GetText(ResourceToken.AsObject(), 'format')) = 'JSON' then
exit(GetText(ResourceToken.AsObject(), 'url'));
Valider avant de remplacer. Lisez d'abord le fichier dans une table temporaire. Un fichier illisible, vide, ou qui a moins de la moitié des lignes déjà au dossier est refusé : la copie précédente reste, et la raison est affichée sur la page de configuration. Une vérification de conformité qui vide en silence ses propres données de référence est pire que pas de vérification du tout.
Garder moins. Le fichier nomme des personnes : personnes liées, actionnaires majoritaires, la municipalité où elles habitent. L'association n'a besoin que du NEQ, donc ces champs ne sont jamais lus. C'est une question de Loi 25 réglée en n'ayant pas les données.
Une surprise dans les données : les inscriptions provisoires n'ont aucun indicateur. Le seul signe, ce sont les mots « Inscription provisoire » dans le texte de la décision, et l'absence de date de fin, exactement ce que prévoit l'article 21.7 de la Loi.
9. Ce que les tests ont attrapé
La vérification du RENA est arrivée avec une application de test, et son premier passage a valu la peine :
- 45 jours ne rentrent pas dans un Integer. « Périmé après 45 jours » était écrit comme une différence de DateTime comparée à
45 * 24 * 60 * 60 * 1000millisecondes. Ça fait 3,9 milliards, plus que les 2 147 483 647 qu'un Integer peut contenir. Le compilateur a refusé la constante dans le test ; dans l'application, où le 45 venait d'un champ de configuration, ça n'aurait échoué qu'à l'exécution. Comparez plutôt des dates. asserterrorannule vos données de test. Un test qui attend une erreur et continue ensuite doit faireCommit()de sa préparation avant.- Un champ NEQ de 10 caractères est exactement trop court. Un NEQ a 10 chiffres, mais les gens tapent « 1172 411 358 ». Ignorer les espaces et les tirets n'aide que si le champ peut les contenir.
La suite possible
Le suivi par projet des dates de début et de fin des travaux (la lettre CNESST est par contrat), des rappels envoyés par courriel aux sous-traitants avant que leurs documents expirent, et la lecture des dates dans un PDF téléversé plutôt que de les taper.
Vous utilisez Business Central avec des sous-traitants au Québec et voulez ça dans votre compagnie, adapté à vos règles et à vos documents? Parlons-en.