← Tous les articles

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

Partager cet articleLinkedInFacebookCourriel

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.

La page Sous-traitants à risque : une licence RBQ introuvable, une attestation de Revenu Québec expirée, une lettre CNESST manquante, une attestation qui expire bientôt

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.

Animation : la vérification RBQ répond Introuvable, puis la libération du bon de commande est arrêtée avec Afficher les problèmes et Passer outre

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é.

Libération arrêtée parce que l'attestation de Revenu Québec au dossier est expirée, avec 31 500 $ d'achats cette année dans le FactBox

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.

Animation : le journal des paiements signale la lettre CNESST manquante, la lettre est ajoutée, le sous-traitant devient conforme et le paiement est reporté

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 : OnBeforeReleasePurchaseDoc
  • Purch.-Post : OnBeforePostPurchaseDoc
  • Gen. 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 * 1000 millisecondes. Ç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.
  • asserterror annule vos données de test. Un test qui attend une erreur et continue ensuite doit faire Commit() 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.

Partager cet articleLinkedInFacebookCourriel