Documentation technique
Pour faciliter la compréhension du code source de l’exemple, des commentaires dans le code source sont préfixés par un tag sous la forme [APInn].
Ci-dessous, les explications d’appel à l’API Sage Business Cloud Comptabilité sont toutes associées à un tag, il suffira de rechercher ce tag dans l’ensemble du projet pour retrouver le code source concerné par l’explication.
Onglet Requêtes
Interface pour se familiariser avec l’écriture des requêtes OData et interroger les ressources de l’API Sage Business Cloud Comptabilité.
Liens code source
request.cs
RequestController.cs
Index.cshtml
[API01]
- Affichage du formulaire
- Récupération de la liste des sociétés - RequestController.cs -
Index()
. - Cette récupération a pour objectif d’approvisionner une liste déroulante dans la page Index.cshtml.
- La variable
companies
, de type JObject, contient la liste des sociétés. Si la récupération dc la liste a échouée, un message d’erreur sera affiché. - La variable
ViewBag.Companies
est la variable passée à la page Index.cshtml.
[API02]
- Affichage du formulaire
- Récupération des ressources d’une société - RequestController.cs -
Index()
- Cette récupération a pour objectif d’approvisionner une liste déroulante dans la page Views/Request/Index.cshtml.
- La variable
message
, de type HttpResponseMessage, est la réponse d’une requête API. Ici la réponse concernera la récupération des ressources d’une société. - La variable
endpoints
, de type JObject, contient la liste des ressources d’une société. - La variable
ViewBag.Endpoints
est la variable passée à la page Views/Request/Index.cshtml.
[API03]
- Envoi du formulaire - RequestController.cs -
DoRequest(…)
. - L’objectif de cette partie est dans un premier temps de trier les paramètres OData à envoyer lors de notre appel API et dans un second temps de faire cet appel API.
- La méthode
DoRequest(…)
est appelée seulement quand le formulaire Views/Request/Index.cshtml a été envoyé. A l’envoi, cela renseigne l’objet Request model (par défaut à valeur nul) dans la méthode Index(…). - Le dictionnaire
parameters
a pour clés les paramètres OData possibles, ces clés se verront affecter les données envoyées dans le formulaire. Les clés qui peuvent être renseignés depuis le formulaire sont$expand
,$filter
,$select
,$orderby
,$top
,$skip
et$count
. - Le dictionnaire
options
aura pour paires clé-valeur les clé-valeur du dictionnaireparameters
dont les valeurs ne seront pas nulles ou vides. Le dictionnaire options sera utilisé comme paramètre lorsqu’il faudra faire un appel API au travers de la méthodeGet(…)
où sera assemblé l’URI. - Si par exemple dans la vue, on a renseigné
$count
à true, le traitement écrira lors de la construction de la requête OData$count=true
. Il n’y a donc pas besoin de mettre le = dans le formulaire. - La variable
message
, de type HttpResponseMessage, est la réponse d’une requête API. Cette variable sert de réceptacle aux données de l’appel API réalisé par la méthodeGet(…)
de la classe APIRepository.cs.
Onglet Clients
Afficher les tiers clients (avec recherche et pagination), consulter, ajouter et modifier des fiches clients.
Liens code source
CustomersController.cs
Index.cshtml
Resp.cshtml
Get.cshtml
Add.cshtml
Edit.cshtml
AddEdit.cshtml
[API04]
- Récupération des clients selon le champ de recherche - CustomersController.cs -
Index()
- L’objectif est d’afficher une liste de clients et de pouvoir rechercher ces clients par leur intitulé ou leur numéro. Cette liste affichera les champs : numéro, intitulé, l’adresse et le numéro de téléphone.
- La valeur de la variable
searchTerm
est mise en minuscules côté application. - Le dictionnaire
options
contient les paramètres nécessaires à la recherche des clients. Pour de meilleurs performances, il y a deux requêtes dans cette partie : la première récupère le nombre total de clients, la seconde récupère les clients. (les paramètres OData n’autorisent pas les valeurs vides) :qryCount
, initialisé àtrue
permet d’obtenir le nombre total de résultats obtenus dans la liste. Cette variable est uniquement utilisé lors de la première requête.qrySkip
, initialisé à 0, correspond au nombre de résultats ignorés. On se sert de cette valeur pour déterminer la page actuelle.qryTop
est le nombre de résultats, initialisé par défaut à 10, par page. Lors de la première requête concernant le nombre de résultats, la variable est initialisée à 0.qryOrderby
détermine les champs selon lesquels les résultats seront ordonnés. Il s’agit ici de l’intitulé et du numéro.qrySelect
permet de sélectionner certains champs afin de réduire le temps de réponse de la requête : id, numéro, intitulé, adresse et le numéro de téléphone.qryFilter
où on définit le filtre pour récupérer uniquement les clients dont l’intitulé ou le numéro contiennent la valeur saisie dans le champ de recherche. Les filtres étant sensibles à la casse, on utilise la fonction ODatatolower(…)
pour mettre en minuscules l’intitulé ou le numéro. IciqryFilter
n’est ajouté que si il possède une valeur.
- La variable
messageCount
, de type HttpResponseMessage, est la réponse d’une requête API concernant le nombre total de clients. - La variable
count
récupère le nombre total de résultats obtenus dans la liste des clients. - La variable
message
, de type HttpResponseMessage, est la réponse d’une requête API concernant la récupération des clients. La requête utilise tous les paramètres saufqryCount
. - Les variables
ViewBag.Results
,ViewBag.ResultsByPage
etViewBag.Clients
contiennent respectivement le nombre de résultats total de clients, le nombre de résultats par page et les clients récupérées. Ces données sont affichées dans le formulaire Resp.cshtml. - La pagination est effectivement faite dans le formulaire Resp.cshtml.
C’est en réalité un formulaire où les numéros de pages font office de bouton d’envoi. Le nombre de résultatsnumber
dépend deViewBag.Clients
et nécessite queqryCount
ait été renseigné àtrue
.
[API05]
- Consultation d’une fiche client - CustomersController.cs -
Get(id)
- L’objectif est d’afficher une liste de clients et de pouvoir rechercher ces clients par leur intitulé ou leur numéro. Cette liste affichera les champs : numéro, intitulé, l’adresse et le numéro de téléphone.
- Dans la variable
customer
, de type Customer, on détermine selon l’id en paramètre l’identité complète du client dans la base. - La vue affichée se situe dans le fichier Get.cshtml.
[API06]
- Ajout des données du client - CustomersController.cs -
Add(...)
- Récupération des comptes généraux dans le formulaire d’ajout
- L’affichage et le traitement du formulaire sont séparées. La fonction Add() affiche la vue tandis que la fonction Add(Customer customer, Address address, Telecom telecom) ajoute, si possible, les données dans la base.
- Dans les formulaires d’ajout et d’édition, on ne liste que les comptes actifs dont le numéro commence par 41 grâce à la fonction
GetActiveAccountsStartingWith(…)
- Le numéro, l’intitulé et le type sont des champs obligatoires.
- La variable
model
permet de conserver les données s’il y a une erreur lors de l’envoi du formulaire. - Les vues concernées sont Add.cshtml et AddEdit.cshtml.
[API07]
- Ajout des données du client - CustomersController.cs -
Add(...)
- Envoi des données
- L’affichage et le traitement du formulaire sont séparées. La fonction Add() affiche la vue tandis que la fonction Add(Customer customer, Address address, Telecom telecom) ajoute, si possible, les données dans la base.
- Le numéro, l’intitulé et le type sont des champs obligatoires.
- Le champ
customer.comptePrincipal
doit se voir affecter une valeur au format{API URL}/comptes('{id compte}')
, ce champ ne peut être vide et le formulaire ne le prévoit pas. Il évolue plusieurs fois, d’abord c’est juste le numéro de compte (ex: 411000), d’après ce numéro on retrouve l’id ensuite on affecte au champ l’url complète. - La variable
data
, de type chaîne de caractères, reçoit la sérialisation de l’objetCustomer
pour envoyer une chaîne de caractères. Les propriétés de l’objetCustomer
sont forcés au format camelCase. - La variable
result
, de type HttpResponseMessage, envoie les données du formulaire dans la ressource clients. - En cas d’erreur sur un champ lors de l’envoi du fichier, l’erreur retournée proviendra directement de ce que renvoie l’API.
[API08]
- Édition des données du client - CustomersController.cs -
Edit(...)
- Récupération des comptes généraux dans le formulaire d’édition
- L’affichage et le traitement du formulaire sont séparées. La fonction Edit(string id) affiche la vue tandis que la fonction Edit(Customer customer, Address address, Telecom telecom) ajoute, si possible, les données dans la base.
- Le comportement de cette partie concernant la récupération des comptes et l’affection des comptes à
ViewBag.Accounts
est ici similaire à [API06]. - Les vues concernées sont Edit.cshtml et AddEdit.cshtml.
[API09]
- Édition des données du client
- Affichage des anciennes valeurs
- Les anciennes valeurs sont obtenues dans la variable de type Customer
model
. - Dans le cas où les champs numéro, intitulé, type et [email protected] sont vides ou nulles, on retourne la vue avec le nouvel objet
model
avec les champs saisies.
[API10]
- Édition des données du client
- Envoi des données
- L’affichage et le traitement du formulaire sont séparées. La fonction Edit(string id) affiche la vue tandis que la fonction Edit(Customer customer, Address address, Telecom telecom) ajoute, si possible, les données dans la base.
- On détecte l’envoi du formulaire lorsque les valeurs sont vides (par défaut).
- Le numéro, l’intitulé et le type sont des champs obligatoires.
- Le champ
customer.comptePrincipal
doit se voir affecter une valeur au format{API URL}/comptes('{id compte}')
, ce champ ne peut être vide et le formulaire ne le prévoit pas. Il évolue plusieurs fois, d’abord c’est juste le numéro de compte (ex: 411000), d’après ce numéro on retrouve l’id ensuite on affecte au champ l’adresse complète. - La variable
data
, de type chaîne de caractères, dans lequel on sérialise l’objet Customer pour envoyer une chaîne de caractères. Les propriétés de l’objetCustomer
sont forcés au format camelCase sans quoi la chaîne ne pourrait être envoyée (sensibilité à la casse). - La variable
result
, de type HttpResponseMessage, envoie les données du formulaire dans la ressource clients. - En cas d’erreur sur un champ lors de l’envoi du fichier, l’erreur retournée proviendra de l’API.
Onglet Import
Exemple d’import d’écritures avec contrôle de cohérence.
Liens code source
ImportController.cs
Index.cshtml
[API11]
- Récupération des données du fichier d’import
- Lecture préalable des codes journaux, modes de règlement, dates exercice.
- Après avoir “chargé” puis importé le fichier d’import, le contenu se trouve dans l’objet
file
, de type IFormFile. - Dans l’ordre, grâce à des appels API, des données seront chargés dans des variables :
- Les codes journaux existants sont stockés dans le dictionnaire
codes
ayant pour clé le code et pour valeur l’identifiant. De sorte qu’on puisse accéder directement à leur id lorsqu’on devra lier (odata.bind) les journaux plus tard. Ce dictionnaire ne peut être nul ou vide. - Les modes de règlement existants dans le dictionnaire
intitulesModesReglement
ayant pour clé l’intitulé du mode de règlement et pour valeur son identifiant. Ce dictionnaire ne peut être nul. - Les dates de début et de fin du plus récent exercice actif dans les variables
exerciceStartDate
etexerciceEndDate
. Ces valeurs ne peuvent être nulles ou vides.
- Les codes journaux existants sont stockés dans le dictionnaire
- Ces données seront ajoutées dans un objet de type Import et seront passées à la fonction d’import Add(…).
[API12]
- Contrôles avant import
- Import des écritures valides
- L’affichage et le traitement sont séparées dans Index(…) et Add(…).
- Le dictionnaire
pieces
contient en clé la concaténation des champs obligatoires et permettant d’identifier la pièce d’une écriture : le code journal, le numéro de pièce et la date. Cet id ne sera pas envoyé dans l’API et ne sert que dans le traitement. - Le dictionnaire
errors
contient toutes les erreurs relevés par pièce. En clé, la concaténation code journal, numéro de pièce et date. - La variable
existing
contient les données chargées dans [API11]. - Dans la méthode ReadFile(…), nous allons recenser les pièces ainsi erreurs des écritures de pièces dans les variables
pieces
eterrors
.- On lit le fichier ligne par ligne en effectuant à chaque fois ces vérifications :
- On crée un objet
Writing
dans la variable eponyme correspondant à une ligne du fichier. - Cet objet
Writing
créé, on détecte toutes les erreurs possibles dewriting
danserrorLogs
par l’utilisation de la fonctionControlWriting(…)
.
- On crée un objet
- Les éléments à vérifier pour chaque ligne d’écriture d’une pièce sont :
- Respect des longueurs maximales pour les propriétés string de l’écriture.
- Le code journal doit exister dans la ressource
Journaux
, propriétécode
. - Date de pièce doit être dans l’intervalle
dateDebut
etdateFin
d’un exercice non clôturé (cloture=false
) de la sous ressourceExercice
de la ressourceInformations Société
. - La date de la pièce doit être identique pour toutes les lignes d’un même numéro de pièce.
- Le numéro de pièce doit être identique pour toutes les écritures constituant une pièce comptable.
- Le numéro de compte général doit exister dans la ressource
Comptes
, propriéténuméro
. - Le numéro de compte tiers, si renseigné, doit exister dans la ressource
Tiers
, propriéténuméro
. - Mode de règlement, si renseigné, doit exister dans la ressource
modeReglement
, propriétéintitulé
. - L’ensemble des écritures d’une pièce doit être équilibré (Total montant débit = Total montant crédit).
- Si cette écriture appartient à une pièce non recensée dans le dictionnaire
pieces
:- On crée une liste d’écritures pour cette pièce dans laquelle on ajoutera les écritures.
- On crée une clé
id
dans le dictionnaireerrors
.
- A l’emplacement
id
deerrors
, on ajoute les erreurs de l’écriture courantewriting
trouvées danserrorLogs
. - Enfin, on ajoute l’écriture dans le dictionnaire
pieces
à l’emplacementid
qui existera forcément. - On répète ces actions tant qu’on n’est pas à arrivé au bout du fichier.
- On lit le fichier ligne par ligne en effectuant à chaque fois ces vérifications :
[API13]
- Contrôles avant import
- Import des écritures valides
- A ce stade, on a seulement recensé les erreurs par ligne. Il reste plusieurs contrôles à effectuer : vérifier l’équilibre de la pièce et éviter les doublons. On va donc tenter d’ajouter les éléments du dictionnaire
pieces
dans la méthode AddPieces(…). - Par rapport à la vérification par pièce des doublons, on vérifie le numéro de pièce, le code journal, le mois et l’année de la date de l’écriture. Si un doublon est détecté, ses écritures ne seront pas ajoutées dans la base.
- Lorsqu’une pièce possède des erreurs dont une écriture déséquilibrée, ses écritures ne seront pas ajoutées dans la base.
- Lorsqu’on est certain qu’une pièce est valide:
- Il va falloir d’abord lier l’id du compte, l’id correspondant au numéro de tiers, l’id du code journal et l’id du mode de règlement à l’écriture au format
{API URL}/{datasetId}/tiers('{tiersId}')
. Si les valeurs de ces champs liés sont vides, on est obligé de les retirer de la chaîne (c’est le cas pour mode de règlement et tiers) de donnéesdata
à envoyer à l’API. - On va envoyer chaque écriture de la pièce dans la base.
- Il va falloir d’abord lier l’id du compte, l’id correspondant au numéro de tiers, l’id du code journal et l’id du mode de règlement à l’écriture au format
- On affiche les erreurs relevés des pièces à corriger. Ces mêmes pièces qui ne seront pas envoyés dans l’API.
- Les erreurs affichées seront celles contenues dans
errorsList
.
[API14]
- Authentification - Configuration.
- le mécanisme d’authentification est implémenté en s’appuyant sur un gestionnaire de cookie (permettant de stocker les informations de session de l’utilisateur) et d’un gestionnaire d’authentification OpenID Connect.
- Dans cet exemple, le paramétrage a été adapté afin de spécifier les paramètres propres à l’authentification SageID dont l’api publique à besoin pour autoriser l’exécution des différentes requêtes (bearer token passé en header de chaque appel http).
- Tous ces paramètres de connexion/déconnexion sont définis dans la méthode
ConfigureServices(...)
du fichier Startup.cs. - Url d’autorisation dans
options.Authority
. - ClientId et Secret dans
options.ClientId
etoptions.ClientSecret
. - Url de redirection dans
options.CallbackPath
. - Scopes autorisés dans la liste
options.Scope
. - Audience dans la variable
options.Event
, de type OpenIdConnectEvents. L’audience et l’url de déconnexion sont définies dans des évènements OpenIdConnect. Ces évènements sont respectivement appelés par les méthodes de connexion et déconnexion au compte SageID. - Ces méthodes Login() et Logout() et se déclenchent lors d’un clic sur le bouton Connexion/Déconnexion sont définies dans le contrôleur AuthentificationController.cs
- Afin que le bouton Connexion/Déconnexion soit visible, il faut renseigner le
client_id
, leclient_secret
, lecallback_url
et lecompany_name
un fichier client_application.json