ArchitectureLe logiciel CRISALID client-serveur modulaire qui s’appuie sur un Serveur de Bases de Données Relationnelles Firebird.Le stockage des données est réalisé par deux bases de données :
La numérotation des tickets suit les règles suivantes: Chaque type de document possède sa propre séquence continue qui est composée de:
ex: Ticket (VTE) 3-1.1 Les types de tickets 1 TCK TICKET 2 DUP DUPLICATA 3 FCT FACTURE 4 NTE NOTE 5 JSP JUSTIFICATIF DE PAIEMENT 6 IVT INVENTAIRE 7 EST ENTREE STOCK 8 SST SORTIE STOCK 9 IVD INVENDUS 10 RUP RUPTURE 11 ALT ALERTE 12 RAZ RAZ STOCK 13 FAB FABRIQUES 14 TRS TRANSFORMABLES 15 REI REINTEGRABLES 16 CDC COMMANDE CENTRAL 17 LVC LIVRAISON CENTRAL 18 TRM TRANSFERT MAGASINS 19 BCD BON DE COMMANDE 20 DEV DEVIS 21 CFR COMMANDE FOURNISSEUR 22 RCD RECAPITULATIF DE COMMANDES 23 BLV BON DE LIVRAISON 24 RGF REGROUPEMENT DE FACTURES 25 REG REGLEMENT COMPTE CLIENT Les types d'opération 1 VTE VENTE (+) 2 ANN ANNULATION (-) 3 GES GESTION-TRESORERIE(0) Le logiciel peut être étendu par un système de plugins. Les plugins sont des librairies de code exécutable (DLL). Le cœur de l'application gère le ticket de caisse et les fonctionnalités associées au ticket de caisse (annulations, encaissements, manipulations sur le ticket), le pilotage de l’interface graphique et des périphériques. Les tickets sont des documents XML et sont stockés comme tels dans des champs d’objet de la base de données. Ce logiciel est plus précisément un progiciel destiné à être personnalisé en fonction de l’activité de chaque client. CRISALID propose plusieurs adaptations standard commercialisées sous des noms de marques déposées:
Le progiciel intègre un moteur de fidélité modulaire. Les données de chaque carte de fidélité sont gérées par la base de données mais le moteur de décision propre à chaque client est externe à l’application et peut ainsi être adapté aux besoins de chaque client.
|
J | Journalière |
H | Hebdomadaire |
M | Mensuelle |
T | Trimestrielle |
S | Semestrielle |
E | Exercice |
L'application créée automatiquement les GT et archives rattachées à chaque période
Gestion des archives
Gestion des archives
L'application génère automatiquement les archives fiscales liés aux clôture automatiques. Ces archives sont créés sous forme de fichier 7zip dans le répertoire /Archives du serveur de caisse:
Les fichiers sont identifiés de la manière suivante:
ARC[num d'archive][type d'archive][date-heure de début][date-heure de fin][Uid-caisse]
Le contenu des archives est décrit dans le fichier Doc_archive.txt:
archive.json | descriptif et signature du fichier d'archive | |
bilans.csv | Totaux des tickets | ID;NUMERO_DOCUMENT;NUMERO_LIGNE;TOTAL_HT;CODE_TVA;TAUX_TVA;MONTANT_TVA;TOTAL_REMISE;TAUX_SERVICE;CALCUL_SERVICE;MONTANT_SERVICE;TOTAL_TTC |
comptes-clients.csv | Totaux comptes clients | ID;NUMERO_DOCUMENT;NUMERO_LIGNE;MONTANT_TTC;NUMERO_CLIENT;SOLDE;CUMUL_POINTS;SOLDE_POINTS;PART_SUBVENTION;PART_PATRONALE; PART_SALARIALE;ADMIN_PATRONALE;ADMIN_SALARIALE;POINTS_PATRONALE;POINTS_SALARIALE |
detail.csv | Détail des lignes articles | ID;NUMERO_DOCUMENT;NUMERO_LIGNE;RGPT;CODE_PRODUIT;ORIGINE;LIBELLE;QUANTITE;CODE_TVA;TAUX_TVA;CODE_TARIF;PRIX_TARIF;PU_HT;PU_TTC;CODE_REMISE;TAUX_REMISE;MONTANT_REMISE; MONTANT_HT;MONTANT_TTC;QUANTITE_MESURE;UNITE_MESURE;TYPE_OPERATION;CODE_UTILISATEUR;HORODATAGE;CODE_MAGASIN;CODE_CAISSE;CODE_VENDEUR;CODE_OPERATION; CODE_COMPTABLE;TAUX_SERVICE;CALCUL_SERVICE;MONTANT_SERVICE |
duplicatas.csv | Historique des duplicatas | ID;NUMERO_DOCUMENT;NUMERO_REIMPRESSION;NOMBRE_LIGNES;TYPE_DOCUMENT;CODE_OPERATEUR;HORODATAGE;SIGNATURE_PRECEDENTE;PREMIERE_SIGNATURE |
entetes.cs | Historique des entêtes de documents | ID;NUMERO_DOCUMENT;VERSION;IMPRESSIONS;DUPLICATAS;SOCIETE_NOM;ADRESSE;CODE_POSTAL;VILLE;PAYS;SIRET;CODE_APE;NUMERO_TVA;CODE_VENDEUR;NOM_VENDEUR; CODE_OPERATEUR;NOM_OPERATEUR;CODE_CAISSE;RGPT;NOMBRE_CLIENTS;HORODATAGE;TYPE_OPERATION;TYPE_DOCUMENT;NOMBRE_LIGNES;SIGNATURE;PREMIERE_SIGNATURE |
factures.csv | Historique des factures | ID;SOCIETE;NOM;ADRESSE;CODE_POSTAL;VILLE;PAYS;SIRET;CODE_APE;NUMERO_TVA;NUMERO_FACTURE;SIGNATURE_PRECEDENTE;PREMIERE_SIGNATURE |
gt-periodes.csv | Grand totaux périodes | ID;PERIODE;DEBUT;FIN;TAUX_1;TVA_1;TAUX_2;TVA_2;TAUX_3;TVA_3;TAUX_4;TVA_4;TAUX_5;TVA_5;MONTANT;GT;GP;SIGNATURE_PRECEDENTE;PREMIERE_SIGNATURE |
gt-tickets | Grands totaux tickets | I D;NUMERO_DOCUMENT;TAUX_1;TVA_1;TAUX_2;TVA_2;TAUX_3;TVA_3;TAUX_4;TVA_4;TAUX_5;TVA_5;HORODATAGE;MONTANT;GT;GP;SIGNATURE_PRECEDENTE;PREMIERE_SIGNATURE |
jet.csv | détail du JET | ID;CODE_EVENEMENT;DESCRIPTIF;OPERATEUR;TERMINAL;TYPE_DE_DONNEES;HORODATAGE;INFORMATIONS;SIGNATURE_PRECEDENTE;PREMIERE_SIGNATURE |
reglements.csv | historique des réglements | ID;NUMERO_DOCUMENT;TYPE_REGLEMENT;NUMERO_CLIENT;CODE_REGLEMENT;LIBELLE_REGLEMENT;MONTANT_EURO;QUANTITE;CODE_DEVISE;TAUX_DEVISE;LIBELLE_DEVISE; MONTANT_DEVISE;TYPE_OPERATION;CODE_UTILISATEUR;HORODATAGE;CODE_MAGASIN;CODE_CAISSE;CODE_VENDEUR;CODE_OPERATION |
totaux.csv | historique des totaux tickets | ID;NUMERO_DOCUMENT;NUMERO_LIGNE;TOTAL_HT;TOTAL_TTC;TAUX_SERVICE;CALCUL_SERVICE;MONTANT_SERVICE |
Gestion de la séquence continue
La signature électronique
Journal électronique des transactions (jet)
Gestion de la séquence continue
La signature électronique
Journal électronique des transactions (jet)
Gestion de la séquence continue
Gestion de la séquence continue
Gestion de la séquence continue
Gestion de la séquence continue
La signature électronique
La signature électronique
L'application génère automatiquement un fichier de trace des transactions. Ce fichier est écrite dans le répertoire AppData\Local\Crisalid de l'utilisateur Windows:
Ci dessous la liste des évènements tracés dans le Jet:
Le ticket
Pour imprimer un ticket il existe plusieurs méthodes :
- ESC/POS (ou STAR) en direct
- Surcouche OPOS
- ESC/POS en mode RAW via le driver Windows
- Mode graphique via le driver Windows
Les commandes ESC/POS ou STAR fonctionnent toujours sur le même principe : on envoie un code de contrôle à l’imprimante comme ESC (ASCII #27), FS (ASCII #28), GS (ASCII #29) ou suivi du code d’une commande (souvent une lettre majuscule ou minuscule) et de ses paramètres.
Le mode ESC/POS direct est très complexe à mettre en oeuvre lorsque l’imprimante est connectée en USB.
D’où l’idée de passer par une surcouche exposant une interface de programmation commune qui prend en charge la complexité de la communication avec le périphérique : OPOS
OPOS est l’implémentation d’une norme (UPOS : Unified Point of Sales) dans le monde Windows (OLE for Point of Sales). Il existe une autre implémentation d’UPOS dans le monde JAVA : JavaPOS.
OPOS s’appuie sur l’infrastructure OLE (ActiveX) de Windows. Le fabricant du matériel met à disposition les Objets de Service (SO : Service Objects) et en tant qu’éditeur de logiciel, nous n’en n’utilisons que la partie commune : les objets de contrôle communs (CCO : Common Control Objects). Via OLE/ActiveX nous demandons la création d’une instance du périphérique qui nous intéresse (OPOSPOSPrinter dans le cas des imprimantes) et Windows se charge du reste : il trouve l’objet de contrôle commun approprié et nous le renvoie. Lorsque nous appelons la méthode Open de l’objet, la magie opère grâce à la configuration qui est dans la base des registres (HKLM\Software\OLEforRetail) : l’objet de contrôle commun trouve l’objet de service correspondant au périphérique, l’instancie, cet objet se configure automatiquement et prend en charge la communication avec le périphérique à travers les drivers Windows de bas niveau qui ont été installés avec les périphériques.
La couche d’abstraction d’OPOS nous permet de communiquer de la même manière avec tous les périphériques compatibles et essaye de gommer les différences entre les différents périphériques.
OPOS est donc composé :
- des objets de contrôle communs (CCO) que l’application caisse utilise,
- des objets de service (SO) que le fabriquant fournit
Le processus de déploiement d’OPOS se fait en trois étapes :
- Il faut commencer par installer les drivers spécifiques des fabricants
- Puis utiliser les outils de configuration pour “créer” les périphériques et les configurer. C’est à cette étape que l’on peut donner un nom logique au périphérique (LDN : Logical Device Name ou plus simplement ”alias”). Le nom logique est un nom plus parlant qui permet de simplifier la configuration dans l’application caisse.
- Et enfin il faut installer le pack OPOS Crisalid qui va forcer le déploiement des objets de contrôle communs dans la version exacte attendue par l’application caisse. L’architecture d’OPOS garanti que les objets de contrôle communs sont toujours compatibles avec toutes les versions des objets de service.
L’impression d’un ticket est un processus d’extraction et de transformation des données contenues dans le ticket XML en commandes ESC/POS.
Les techniques pour réaliser cette opération sont nombreuses mais souvent propriétaires et fermées. Chez Crisalid nous avons choisi un moyen standard et ouvert de traiter les tickets XML afin de les convertir en “autre chose”. Cette technologie s’appelle XSL-T (eXtensible Stylesheet Language - Transformation). Elle utilise un processus externe appelé “Processeur XSLT” qui met en rapport le document XML et le script XSLT afin de produire un nouveau document. Le document produit peut être un fichier texte, une page HTML ou un nouveau document XML.
Le processeur XSLT utilisé par l’application caisse est celui de Microsoft et fait partie du package MSXML Core Services 6.0.
Pour des raisons techniques, il n’est cependant pas possible de générer un fichier de commandes ESC/POS par XSLT car les commandes ESC/POS contiennent des caractères non imprimables.
Nous avons donc créé un langage intermédiaire, en XML, qui représente ces séquences de commandes d’impression et qui est ensuite traité par l’application caisse pour générer les séquences ESC/POS ou OPOS définitives.
La liste des instructions de ce langage intermédiaire est décrite dans les fichiers “Drivers” : OPOS.XML, OPOS2.XML et RS232.XML. Les deux premiers génèrent des séquences d’impression “OPOS” et le dernier directement des séquences d’impression ESC/POS
Le flux de traitement de l’impression d’un ticket peut se résumer par le schéma suivant :
Ticket XML + modèle XSL + processeur XSLT → séquence de commandes d’impression XML + fichier des commandes (OPOS.XML, OPOS2.XML ou RS232.XML) → séquences de commandes ESC/POS ou OPOS + driver RS232 ou OPOS → périphérique.
L’avantage de ce système est qu’à partir d’un ticket XML et d’un même fichier XSL, on peut générer des commandes d’impression pour une imprimante pilotée par OPOS aussi bien que pour une imprimante RS232 pilotée en direct par l’application.
En résumé : Le but du fichier XSL est de générer un “fichier” de commandes d’impression en utilisant celles qui sont décrites dans les fichiers OPOS.XML ou RS232.XML
L’application se charge ensuite de faire le nécessaire en fonction du mode de pilotage de l’imprimante pour que ces séquences de commandes d’impression soient exécutées.
Structure d’un fichier XML
Un fichier XML minimal doit ressembler à ça :
<?xml version=”1.0” encoding=”utf-8” ?>
<noeud-racine>
<sous-noeud attribut=”valeur de l’attribut”>valeur du noeud</sous-noeud>
</noeud-racine>
La ligne <?xml… est une instruction de traitement. Elle sert à indiquer à l’analyseur XML ce qu’il va trouver dans la suite du fichier. En particulier, l’attribut “encoding” qui indique que les caractères Unicodes sont encodés en UTF8 (important pour les caractères spéciaux ou accentués comme €, é, à, ê...).
Dans un fichier XML, on ne peut pas utiliser les caractères suivants sans prendre de précautions car ils servent au balisage des données : <, >, “, ‘, &. Pour les utiliser dans les données ou dans les attributs il faut les “échapper” en utilisant la notation des entités : < devient < > devient > “ devient " ‘ devient ' et & devient &
Exemple : en XML, la chaîne de caractères PAINS & CHOCOLATS “du chef” (> 300g) s’écrit : PAINS & CHOCOLATS "du chef" (> 300g)
La règle est que dans un fichier XML les balises doivent être correctement balancées : toute balise ouverte doit être fermée dans l’ordre inverse :
<a><b> doit être fermé : </b></a>. Un fichier XML qui contiendrait cette séquence de balises <a><b></a></b> par exemple n’est pas “bien formé” et sa lecture provoquera une erreur.
La valeur d’une balise est ce qui se trouve entre la balise ouvrante <a> et la balise fermante </a>. Une balise peut donc contenir comme valeur soit rien, soit du texte, soit d’autres noeuds XML.
Une balise qui n’a pas de valeur peut-être fermée immédiatement : <a/> au lieu de <a></a>.
Il est possible d’inclure des commentaires dans un fichier XML en les encadrant à l’aide des balises spéciales <!-- et -->, lorsque le fichier XML est lu par l’analyseur, les commentaires sont ignorés.
Exemple : <!-- Ceci est un commentaire -->
Structure d’un fichier XSL
La première chose à noter concernant les fichier XSL c’est que ce sont des fichier XML dont certaines balises sont normalisées et ont un sens précis. Pour indiquer au processeur XSLT où sont ces balises spéciales, on les préfixe grâce à un espace de nommage.Exemple : <xsl:value-of select=”...” /> est la balise XSL qui permet d’extraire les données du document “source” pour les injecter dans le document “cible”. L’espace de nommage est “xsl”
L’espace de nommage “xsl” des balises est déclaré au début du fichier dans un attribut xmlns (pour xml namespace)
Un fichier XSL minimal ressemble à ça :
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8"/>
</xsl:stylesheet>
On retrouve l’instruction de traitement <?xml... qui nous confirme qu’un fichier XSL est bien un fichier XML ainsi que l’espace de nommage xsl dont la valeur est normalisée :
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
Ce que la balise xsl:output nous indique c’est que le document attendu à la sortie du traitement du document XML d’entrée par cette feuille de style XSLT sera un nouveau fichier XML (method=”xml”) qui sera encodé en UTF8 (encoding=”utf-8”)
Cette feuille de style XSL seule ne sert à rien puisque rien n’indique comment traiter le document d’entrée pour produire ce qui est attendu en sortie.
Modèle de ticket minimal :
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" version="1.0" encoding="utf-8"/>
<!-- Paramètres fournis par l’application -->
<xsl:param name="double_affichage">false</xsl:param>
<xsl:param name="devise">Francs</xsl:param>
<xsl:param name="symbole">F</xsl:param>
<xsl:param name="taux">6.55957</xsl:param>
<xsl:param name="message"></xsl:param>
<xsl:param name="total_fidelite">false</xsl:param>
<xsl:param name="langue">FR</xsl:param>
<!-- Paramètres uniquement disponibles avec les tickets “cuisine” -->
<xsl:param name=”id_caisse”>1</xsl:param>
<xsl:param name=”caisse”>Caisse 1</xsl:param>
<xsl:param name=”observateur”>Chaud</xsl:param>
<xsl:template match="/">
<ticket>
<select>imprimante</select>
<pagecode>858</pagecode>
</ticket>
</xsl:template>
</xsl:stylesheet>
Les valeurs des paramètres xsl:param (double_affichage, devise, symbole…) sont passés au processeur XSLT par l’application caisse, leurs valeurs changent en fonction de la configuration de la caisse. Ce mécanisme permet aux feuilles de style XSL de s’adapter au comportement attendu par le paramétrage de la caisse.
Les balises XML en gras qui ne sont pas préfixées par xsl: ne font pas partie de XSLT : ce sont les balises qui constitueront le document XML de sortie. En l’occurrence, il s’agit des commandes d’impression qui seront traduites dans un second temps en commandes ESC/POS ou OPOS.
Liste des commandes d’impression disponibles :
<select>imprimante</select> | Obligatoire au début du ticket pour s’assurer que les commandes vont bien être envoyées à une imprimante. |
<pagecode>858</pagecode> | Page de code des données à envoyer à l’imprimante. 858 obligatoire pour le symbole €. |
<lf/> | Saut de ligne |
<tab/> | Saut de tabulation (voir <definitabs>) |
<definitabs>...</definitabs> | … : position des taquets de tabulation Exemple : <definitabs>0g 10d 42d</definitabs> Premier taquet à 0 aligné à gauche, deuxième à 10 aligné à droite et troisième à 42 caractères aligné à droite. On utilise ensuite <tab/> dans le texte pour sauter au taquet suivant et aligner automatiquement le texte correspondant. |
<identification niveau=”1” /> | Imprime les infirmations d’identification du magasin. Niveau 1 = NOM du magasin, infos légales Niveau 2 = ADRESSE du magasin, infos légales Niveau 3 = ADRESSE du magasin + téléphone, fax, émail, infos légales Niveau 4 = RESPONSABLE du magasin + ADRESSE + téléphone, fax, émail, infos légales |
<traduction langue=”EN” max=”20”>...</traduction> | Traduit une chaîne de caractères en regardant dans la table de traductions de la base de données. langue : code langue parmi les langues disponibles max : coupe la chaîne traduite au bout de max caractères. … : chaîne à traduire |
<date format=”...” heures=”...” minutes=”...” jours=”...” semaines=”...” mois=”...” annees=”...” /> <heure /> <dateheure /> | Imprime la date/heure courante. format : chaine de format. ex : yyyy-mm-dd autres paramètres : offset par rapport à la date/heure courante (servent à calculer des dates relatives à la date/heure courante) |
<contact id=”...” /> <fidelite id=”...” /> <compte id=”...” /> | Charge les informations dynamiques du contact (ou du compte fidélité ou du compte client) en cherchant l’id spécifié dans la base de données. |
<article tarif=”...” ref=”...” cab=”...” /> | charge les informations dynamiques de l’article dont le cab ou la ref sont spécifiées avec les prix correspondant au numéro de tarif indiqué. |
<dynamic>...</dynamic> | Accède au champ spécifié de l’ensemble de données chargé par la commande <contact />, <fidelite />, <compte /> ou <article /> qui précède. |
<sequence synchro=”...” step=”...”>...</sequence> | Crée un générateur de séquence ou se synchronise avec un autre générateur de séquence. |
<aligne>gauche</aligne> | Change l’alignement de la ligne courante Autres options :droite, centre |
<decoupe>defaut</decoupe> | Massicote le ticket manuellement Autres options : immediat, etiquette |
<avance>coupe</avance> | Massicote le ticket manuellement (autre méthode) |
<massicot>complet</massicot> | Massicote le ticket manuellement (autre méthode) |
<recule>ligne</recule> | Si l’imprimante le supporte, recule le papier. Autre option : max |
<ecrit>petit</ecrit> | Change la police d’impression |
Autre option : normal | <taille>double</taille> Change la taille d’impression Autres options : normal, doublel, doubleh, quadruple, quadruplel, quadrupleh |
<style>gras</style> | Changer le style d’écriture Autre option : normal |
<couleur>rouge</couleur> | Change la couleur d’impresion (si l’imprimante le supporte) Autre option : noir |
<inverse>oui</inverse> | Imprime en inversion vidéo (blanc sur fond noir) Autre option : normal |
<souligne>fin</souligne> | Imprime le texte souligné Autres options : non, epais |
<barre>oui</barre> | Imprime le texte barré Autre option : non |
<ligne>complete</ligne> | Imprime une ligne continue de différentes longueurs (complete = 42 caractères) Autres options : l10, l20, demi, quart, tml60, tml76 |
<logo>normal</logo> | Imprime le “logo” (chaîne de texte stockée dans l’imprimante) Autres options : doublelarge, doublehaut, doublelargehaut |
<logonv>n1</logonv> | Imprime un logo graphique dynamique stocké dans l’imprimante. Autres options : n2, n3, …, n9 |
<dessin>debut</dessin> | Active le mode “dessin” ASCII Autre option : fin (pour sortir du mode dessin) |
<interligne>petit</interligne> | Réduit l’interligne (permet de condenser le ticket) Autre option : normal |
<code-barres symbologie=”code128” binaire=”...” bcd=”...” masque=”...”>...</code-barres> | Imprime un code-barres calculé par l’imprimante. symbologies : code128_voucher, code128_ticket, ean13, ean8, ean8_notext binaire=”oui” si les données sont données en binaire bcd=”oui” si les données sont codées en BCD sinon les données sont du texte. … : données du codes barres <qrcode taille=”moyen”>...</qrcode> Génère un QRCode de taille normale ou de taille moyenne et l’envoie comme une image à l’imprimante pour qu’elle l’imprime. |
<gadget type=”sudoku”>...</gadget> | Génère un gadget et l’imprime comme une image. Gadgets supportés : sudoku, logo |
<publicite max=”...” /> | Imprime “max” caractères d’une des lignes du tableau de chaînes de publicité qui est envoyé en paramètre au processeur XSL lors du traitement du ticket. |
Ces commandes permettent de générer du contenu dynamique à incorporer au ticket imprimé (contact, fidelite, dynamic, code-barres, qrcode, gadget, logonv…) et de mettre en page les données du ticket XML (aligne, ecrit, style, taille, inverse), de structurer la génération de tableaux (definitabs et tab).
Exemple de séquences d’impression de ticket
<ticket>
<select>imprimante</select>
<pagecode>858</pagecode>
<aligne>centre</aligne>”BIENVENUE CHEZ CRISALID”<lf/>
<logonv>n2</logonv>
</ticket>
Cet exemple permet de comprendre les points clés de ce format intermédiaire fait de commandes d’impression et de données à imprimer :
<a>TEXTE</a> | <a>⤶ ⌴⌴TEXTE⤶ </a> |
[TEXTE] | [⤶ ⌴⌴TEXTE⤶ ] |
TEXTE | ⤶ ⌴⌴TEXTE⤶ |
La solution retenue a été de d’indiquer par des guillemets les bornes des sections de texte à imprimer :
XML | <a>”TEXTE”</a> | <a>⤶ ⌴⌴“TEXTE”⤶ </a> |
Texte vu par l’analyseur XML | [“TEXTE”] | [⤶ ⌴⌴“TEXTE”⤶ ] |
Texte envoyé à l’imprimante | [TEXTE] | [TEXTE] |
Voici un exemple tiré d’un modèle de ticket qui montre comment les guillemets permettent d’indenter et de mettre en forme le modèle de ticket de façon qu’il soit facile à lire et à modifier.
<aligne>centre</aligne>
”BIENVENUE CHEZ CRISALID”
<lf/>
La structure
Exemple, pour écrire du texte en taille double et en gras, on peut utiliser la séquence :
<taille>double</taille><style>gras</style>
”TEXTE DOUBLE EN GRAS”
<style>normal</style><taille>normal</taille>
L’objet des feuilles de styles XSL est donc de générer cette séquence de commandes d’impression intermédiaires à partir du ticket XML d’origine.
Le ticket XML
Le ticket XML de l’application caisse Crisalid est une structure complexe qui évolue depuis une dizaine d’années grâce à XML et son langage de balisage “ouvert”. Il est en effet possible de faire évoluer la structure d’un document XML en ajoutant des noeuds ou des attributs sans casser la compatibilité avec d’anciennes versions. Ce qui serait problématique serait de supprimer des balises ou des attributs considérés comme obligatoires par d’anciennes versions de l’application.La structure de base du ticket
Le ticket contient trois noeuds principaux : entete, lignes et bilan
<?xml version=”1.0” encoding=”utf-8” ?>
<ticket>
<entete></entete>
<lignes></lignes>
<bilan></bilan>
</ticket>
- entete contient des métadonnées indispensables pour situer le ticket dans son contexte : date de création, date de modification, nombre de plateaux, informations sur le vendeur et la table s’il s’agit d’un ticket qui a été fait pour une table.
- lignes contient le contenu principal du ticket : les articles, les sous-totaux et les menus avec leurs remises associées.
- bilan contient les informations récapitulatives du ticket : le montant total, la remise globale, les encaissements et le récapitulatif par taux de TVA.
Voir le XML du ticket
Une méthode pour voir le XML du ticket courant est d’utiliser la macro #VOIR_XML# : le ticket est formaté et affiché dans le bloc notes. Cette macro peut aussi être utilisée depuis le rappel ticket pour voir la source XML de n’importe quel ticket.
Pour un confort de lecture maximal, il est conseillé de sauvegarder le ticket sur disque dans un fichier avec l’extension XML et de l’ouvrir avec un éditeur muni de la fonctionnalité de mise en évidence de la syntaxe par coloration. Notepad++, SciTE et Sublime Text Editor entre autres savent le faire.
Exemple de ticket
L’indentation d’un ticket peut différer puisque les blancs (sauts de lignes et espacements) ne sont pas significatifs, l’ordre des attributs des nœuds n’est pas non plus significatif. Seule la structure d’imbrication des noeuds est importante.
<?xml version="1.0" encoding="utf-8"?>
<ticket version="2"
type="VTE" devise="EURO"
uid="{A39D6CC4-4073-4188-9D4F-56DA5E2EBD06}"
caisse="1" numero="751"
annule="N" memo="N" imprime="O" attente="N" encaisse="O"
clotureID="201505004">
<entete>
<creation iso="2014-06-06T15:54:57.499+02:00">
<date>06/06/2014</date>
<heure>15:54:57</heure>
</creation>
<modification iso="2015-02-23T09:48:11.513+01:00">
<date>23/02/2015</date>
<heure>09:48:11</heure>
</modification>
<stats iso="2015-02-23T09:48:11.513+01:00">
<date>23/02/2015</date>
<heure>09:48:11</heure>
</stats>
<caissier numero="0">Inconnu</caissier>
<vendeur numero="2" service="0.00">MARIE</vendeur>
<table numero="6">
<couverts>2</couverts>
</table>
<cab>VTE751D141570954</cab>
</entete>
<lignes nombre="1">
<article
numero="1" plu="1208" quantite="1.000" ht="N" base="12.0000" base_ht="10.9091"
valeur="12.0000" valeur_ht="10.9091" net="12.0000" net_ht="0.0000" tva="10.00"
code="120120009" cab="" codif="" addon="" scanning="N" tarif="0" unite="U" pesee="N"
hca="N" coupon="N" annule="N" controle="O" imprime="O" points="0" action="0" bonus="0.00"
fidelite="O" stock="O" bloque_zero="N" achat="0.0000" etats="7" prioritaire="N"
horodatage="2014-06-06T15:54:57.497+02:00" tri="0" regroupement="N" fournisseur="">
<libelle>PIZZA FRUIT DE MER</libelle>
<groupe code="12">PIZZAS</groupe>
<famille code="12">PIZZAS</famille>
<tags>
<cuisine>CHAUD</cuisine>
<tag>57160</tag>
</tags>
<commentaires>
<liste code="13" nom="PIZZAS-" optionnel="oui"/>
</commentaires>
</article>
</lignes>
<bilan montantTTC="12.00" brut="12.00" fidelite="12.00" remise="0.0000" service="0.00">
<tvas montantTaxes="1.09">
<tva taux="10.00" base="12.00" nombre="1.000">1.09</tva>
</tvas>
<encaissements montantEncaisse="12.00">
<encaissement
horodatage="2015-02-23T09:48:11.446+01:00" mode="ESPECES" devise="EURO"
nombre="1" rendu="oui" avoir="non" acompte="non">40.50</encaissement>
</encaissements>
</bilan>
</ticket>
Conventions : pour différencier des attributs des autres noeuds enfants du noeud courant dans cette table ou dans les explications on les préfixe par @.
Ticket
@version | Numéro de version du ticket (mis à jour lorsque la structure du ticket est modifiée de telle façon qu’elle n’est plus compatible avec les versions précédentes.) |
@uid | UUID unique du ticket |
@type | code de 3 caractères qui identifie le type du ticket (VTE = Vente, MMO = Mémo, TAB = Table en cours, RUP = Rupture, IVT = Inventaire, IND = Invendus, RAZ = RAZ Stock…) |
@clotureID | Numéro de la clôture à laquelle appartient le ticket. Pour mémoire, les numéros de clôture sont de la forme YYYYDDDNN avec YYYY l’année en cours, DDD le numéro du jour dans l’année (32 = 1er février) et NN le numéro de la clôture de cette journée. |
@caisse | Numéro de la caisse sur laquelle le ticket a été encaissé. Caisse = -1 pour les tickets MEMO |
@numero | Numéro séquentiel du ticket par rapport à la caisse sur laquelle le ticket a été encaiss”. Les tickets d’évènement sont numérotés en négatif et les tickets MEMO sont numérotés indépendemment. |
@annule | [O/N] Vaut “O” si le ticket a été annulé par la macro TICKET ANNULE |
@memo | [O/N] Vaut “O” si le ticket a été marqué pour annulation par la macro TICKET MARQUE |
@imprime | [O/N] Vaut “O” si le ticket a été imprimé |
@encaisse | [O/N] Vaut “O” si la ticket a été encaissé (si on annule l’encaissement, @encaisse reste à “O”) |
@devise | La devise du ticket. En général vaut EURO |
@attente | [O/N] Vaut toujours “N” lorsque le ticket est encaissé et imprimable. Vaut “O” lorsque le ticket est “en attente” mais lorsqu’un ticket est “en attente”, on ne peut rien en faire. |
@prix-achat | [O/N] Si le ticket est un ticket d’évènement, ce flag indique que les prix sont des prix d’achat. |
@gestion-stock | [O/N] Si le ticket est un ticket d’évènement, ce flag indique que le ticket est un ticket de gestion du stock. |
creation, modification, stats | Même structure pour tous les horodatages attachés au ticket. Ces 3 horodatages sont toujours présents, ils contiennent respectivement la date de création du ticket, la date de la dernière modification du ticket et la date à laquelle les stats du ticket ont été calculées. L’intérêt est que si le ticket est modifié, les stats soient recalculée toujours au même moment. @iso contient l’horodatage au format ISO8601 qui est décomposé dans les noeuds enfant <date> et <heure> |
caissier caissier/@numero | [ Pas utilisé ] |
vendeur vendeur/@numero vendeur/@service | Nom du vendeur. Le code du vendeur est dans @numero et le taux de commission du service est dans @service |
table/@numero table/@sous-numero | Numéro de la table. S’il s’agit d’une sous-table, l’attribut @sous-numero est présent. En général on formate le numéro de table pour l’affichage en concaténant @numero et @sous-numero avec un “.” (1.1, 1.2…) : |
table/couverts | Nombre de couverts |
cab | Code barres du ticket. Reprend le type du ticket, son numéro et son timestamp encodé comme un nombre entier. Cette valeur est destinée à être présentée dans un CAB Code128 qui, lorsqu’il est scanné par l’application caisse ouvre automatiquement le rappel ticket positionné sur le ticket correspondant. |
carte | Code de la carte qui identifie le compte client ou le compte fidélité. |
flash | Message “flash”, disponible uniquement dans les tickets “cuisine” qui disparaît lorsque le ticket est imprimé. |
commentaire | Commentaire global au “ticket”, les lignes sont séparées par des tags <lf/> |
plateau/@nombre | Nombre de sous-total “plateau” dans le ticket. |
fidelite/@id | Numéro interne de la carte de fidélité (utile pour récupérer les informations “live” sur la carte de fidélité avec <dynamic />) |
fidelite/@appliquee | [O/N] Vaut “O” lorsqu’une action fidélité a été appliquée dans le ticket. |
compte/@id | Numéro interne du compte client (utile pour récupérer les informations “live” sur le compte client avec <dynamic />) |
compte/@libelle compte/@solde | Libellé (nom/prénom ou raison sociale) du compte client et solde du compte AVANT le ticket courant. |
contact/@id | Numéro interne du contact (utile pour récupérer les informations “live” sur le contact avec <dynamic />) |
facture/numero facture/debut facture/fin | Contient le numéro de la facture récapitulative des tickets d’un compte client qui a été générée entre les dates debut et fin. |
remise/@typeRemise remise/@valeur remise/@montant | Type et valeur de la remise globale appliquée au ticket (en plus des éventuelles remises locales faites sur les articles et les sous-totaux.) |
transfert/origine transfert/origine/@code | Nom et code interne du magasin à l’origine d’un transfert de produits dont ce ticket est la preuve. |
transfert/destination transfert/destination/@code | Nom et code interne du magasin de destination d’un transfert de produits dont ce ticket est la preuve. |
wallet/@balance wallet/@encours wallet/@ticket | Informations sur la transaction de paiement faite via Crisalid Wallet. |
Si des promotions automatiques ont été appliquées au ticket, un noeud enfant <promotions> est ajouté à l’<entete> du ticket. Et les informations sur chaque promotion appliquée sont dans un noeud enfant <promotion>. La liste des articles à l’origine de chaque promotion est ajoutée dans un ensemble de noeuds enfant <article>.
promotion/@code | Code de la promotion qui a été appliquée dans le ticket. |
promotion/@nombre | Nombre de fois où cette promotion a été appliquée dans le ticket. |
promotion/article | Code interne de l’article |
promotion/article/@addon promotion/article/@annee | Code addon et année de parution de l’article s’il s’agit d’un article presse |
Si des paiments via des services (ou des webservices) tiers ont été enregistrés (Paypal, FlashIZ, DigiCash…) alors les informations sur les transactions de ces paiement sont stockées dans des noeuds enfant <paiement> du noeud <paiements> qui est ajouté à l’<entete> du ticket.
paiement/@id | ID de la transaction de paiement fourni par le service tiers. |
paiement/@service | Nom du service tiers qui a enregistré la transaction |
paiement/@payeur | Nom ou ID interne au service tiers du payeur. |
paiement/@montant | Montant de la transaction enregistrée par le service tiers. |
paiement/tag | Contenu du code barres (ou du QRCode) qui déclenche la transaction chez le fournisseur du service tiers. |
paiement/creation paiement/modification paiement/annulation | Horodatages des échanges avec le service tiers. Le format est celui des horodatages de l’entête du ticket. L’attribut @iso contient l’horodatage complet au format ISO8601 et la date et l’heure correspondantes sont dans les noeuds enfant <date> et <heure>. |
Le nom des noeuds réclamation correspond au nom des noeuds <tag> séparateur des articles.
Exemple : si le tag “séparateur” configuré dans le logiciel est “cuisine”, alors les articles seront imprimés en cuisine d’après le contenu des tags article/tags/cuisine et les réclamations correspondantes seront enregistrées dans les noeuds entete/reclamations/cuisine
<nom>/@mode | Le nom de la séquence qui est réclamée. Correspond aux valeurs des noeuds tags des articles. |
<nom>/@iso <nom>/date <nom>/heure | Les informations habituelles des horodatages : L’attribut @iso contient l’horodatage complet au format ISO8601 et la date et l’heure correspondantes sont dans les noeuds enfant <date> et <heure>. |
@nombre | Nombre de lignes du ticket. Permet de naviguer dans le ticket en respectant l’ordre de création des lignes. |
Tous les noeuds qui sont ensuite imbriqués dans le noeud <lignes> ont un attribut @numero qui est le numéro séquentiel de création de la ligne dans le ticket.
<lignes nombre=”3”>
<sous-total numero=”3”>
<article numero=”1” />
<article numero=”2” />
</sous-total>
</lignes>
Il est alors possible de parcourir itérativement le ticket pour afficher à l’écran (ou imprimer) :
- ARTICLE 1
- ARTICLE 2
- SOUS-TOTAL
Alors que dans la structure XML, les noeuds <article> sont enfants du noeud <sous-total>
Ligne Article (noeuds <article>)
@numero | Le numéro d’ordre séquentiel de création de la ligne dans le ticket |
@plu | Code PLU de l’article |
@code | Code interne de l’article. Généralement au format GGFFFAAAA[@CC] avec GG le numéro du groupe, FF celui de la famille, AA celui de l’article et CC le numéro du conditionnement (@CC est facultatif) et tous ces numéros sont encodés au format NEP36. |
@quantite | Nombre d’unités, de pièces, poids... |
@tarif | Numéro du tarif (utilisé pour les changements de tarif et les stats) |
@ht | [O/N] Vaut “O” si l’article a été vendu Hors Taxes. Si “N”, l’article a été vendu TTC. |
@base | Prix de base (utile pour les calculs de menus et de remises) |
@base_ht | Prix de base HT |
@valeur | Prix unitaire |
@valeur_ht | Prix unitaire HT |
@net | Prix de vente Net (après remises et proratas liés aux menus et aux remises sur le sous-total englobant). C’est la valeur qui est utilisée pour le calcul des stats. |
@net_ht | Prix de vente Net HT |
@tva | Taux de TVA (en pourcentage) |
@participation | Montant des taxes supplémentaires (Eco-taxe par exemple) |
@supplement | Montant du supplément engendré par le fait d’avoir mis cet article dans un menu. |
@typeRemise @remise | [N, S, P, M, …] Type et valeur (en montant ou en pourcentage) de la remise appliquée à cet article |
@cab | Code Barres de l’article au moment de la vente |
@codif | Codif de l’article pour les articles Presse |
@addon | Addon de l’article pour les articles Presse |
@annee | Année de parution d’un article Presse |
@scanning | [O/N] Vaut “O” si l’article a été scanné (utile pour la remontée des ventes Presse) |
@prioritaire | [O/N] Vaut “O” si l’article est un article Presse prioritaire |
@unite | [U/P/K/M/L/E] Type d’article (Unité, Pièce, Kilo, Menu, Libre, Etendu) |
@plugin | Si @unite = ‘E’ alors contient le nom du plugin (.AEM) qui gère cet article particulier. |
@pesee | [O/N] Vaut “O” si l’article a été pesé (avec une balance connectée) |
@brut_pesee | Valeur brute (en kg) de la pesée |
@id_pesee | ID de la transaction de pesée (correspond à un enregistrement dans le fichier log des pesées) |
@tare_pesee | Valeur de la tare au moment de la pesée |
@hca | [O/N] Vaut “O” si l’article est Hors Chiffre d’Affaires (pour les stats). Info : dès lors qu’au moins UN article du ticket contient un article flaggé @hca=”O”, le ticket est comptabilité dans le nombre de tickets HCA du financier. |
@coupon | [O/N] Vaut “O” si l’article doit, provoquer l’édition d’un coupon |
@annule | [N/D/E/R] Vaut “N” si l’article n’a jamais été annulé. D = annulation de type “Dernier”, E = après encaissement et R = retour avant encaissement |
@controle | [O/N] Vaut “O” lorsque l’article est sorti en cuisine ou sur une imprimante de contrôle |
@imprime | [O/N] Vaut “O” lorsque l’article a été imprimé |
@points | Nombre de points que rapporte l’article sur une carte de fidélité |
@action | Nombre de points d’action que coûte l’article à une carte de fidélité |
@bonus | Bonus que rapporte l’article sur une carte de fidélité |
@fidelite | [N/A] Vaut “A” si une opération fidélité a été appliquée et que cet article est concerné. |
@stock | [O/N] Vaut “O” lorsque le stock de l’article est géré |
@valstock | Quantité en stock AVANT la vente |
@alertstock | Niveau d’alerte du stock sur ce produit |
@bloque_zero | [O/N] Vaut “O” lorsque la vente de l’article est bloquée car son stock est nul ou négatif. |
@achat | Prix d’achat |
@etats | ET binaire entre les états suivants : 1 : Vendable, 2 : Commandable, 3 : Exportable. 0 = retiré, 7 = article vendable, commandable et exportable. |
@horodatage | Horodatage du moment où l’article a été mis dans le ticket |
@tri | Ordre de tri de l’article (pour les éditions des bons en cuisine) |
@regroupement | [N/F/G] Vaut “O” si l’article doit être regroupé avec les autres articles de la même Famille ou du même Groupe. |
@fournisseur | Code du fournisseur de l’article |
@date_validite @heure_validite | Date et heure de validité du produit |
@composant | Numéro du composant du menu auquel cet article correspond |
@promos | Liste des codes des promotions séparées par des virgules que cet article a participé à générer. |
@quantite_originale @was_in_menu | Quantité originale de la vente: utilisé lorsque les articles sont dispatchés entre les menus pour reconstituer le ticket lorsque les menus sont annulés ou modifiés. Et par souci d’exhaustivité @was_in_menu est un attribut Interne qui sert à se souvenir quels articles étaient dans quels menus lorsqu’il s’agit de recalculer les menus du ticket en provoquant le moins de modifications possibles. |
libelle | Libellé de l’article |
groupe groupe/@code | Libellé et numéro du groupe auquel appartient l’article |
famille famille/@code | Libellé et numéro de la famille à laquelle appartient l’article |
fournisseur fournisseur/@code | Nom et Numéro du fournisseur de l’article |
transaction/@id1 transaction/@id2 transaction/horodatage | Si la vente de l’article en engendré l’appel à un WebService (via un plugin d’extension .AEM - cf @unite et @plugin) alors les détails de la transaction sont stockés dans les attributs @id1 et @id2 ainsi que l’horodatage de la transaction au format habituel (@iso contient l’horodatage ISO8601 et date et heure correspondantes sont dans les noeuds enfant <date> et <heure>) |
tags/tag | Liste des tags “automatiques” (ajoutés automatiquement lors de la vente de l’article car ils sont déclarés dans la fiche article) |
tags/<nom> | Tags supplémentaires manuels. Par exemple en mode restaurant on tagge les articles en direct/à suivre à l’aide du tag “cuisine”. (Macro : TAG ARTICLE cuisine=*/DIRECT) ce qui va générer cette structure de noeuds : <tags><cuisine>DIRECT</cuisine></tags> |
commentaire | Commentaire libre, il s’agit de noeuds #TEXT séparés par des noeuds <lf/>. Exemple : <commentaire>Code Postal<lf>57160<lf>Joyeux Anniversaire</commentaire> |
commentaires/liste | Liste des commentaires automatiques associés à l’article. Le code de la liste est dans l’attribut @code, le nom de la liste dans l’attribut @nom et l’attribut @optionnel peut valoir [O/N]. S’il vaut “O”, le commentaire est optionnel et la fenêtre qui permet d’en demander la valeur ne s’affiche que si on le demande explicitement. |
composant | Nom du composant correspondant dans le menu |
composant/@numero | Numéro (pour l’affichage) du composant correspondant dans le menu |
composant/@id | ID interne du composant correspondant dans le menu |
composant/@code | Code interne du composant correspondant dans le menu |
composant/@prix-max | Prix max du composant correspondant dans le menu |
composant/@nombre | Nombre d’instances du composant correspondant dans le menu |
composant/@sequence | Tag automatique de l’article pour le séquencement en cuisine |
@numero | Le numéro d’ordre séquentiel de création de la ligne dans le ticket |
@quantite | Nombre d’unités vendues |
@code | Code interne de l’article. Généralement au format GGFFFAAAA[@CC] avec GG le numéro du groupe, FF celui de la famille, AA celui de l’article et CC le numéro du conditionnement (@CC est facultatif) et tous ces numéros sont encodés au format NEP36. |
@tarif | Numéro du tarif (utilisé pour les changements de tarif et les stats) |
@annule | [N/D/E/R] Vaut “N” si l’article n’a jamais été annulé. D = annulation de type “Dernier”, E = après encaissement et R = retour avant encaissement |
@base | Prix de base du menu (somme des prix unitaire des articles * quantité * nombre de menus) |
@valeur | Prix unitaire du menu |
@typeRemise @remise | [N, S, P, M, …] Type et valeur (en montant ou en pourcentage) de la remise appliquée à cet article |
@supplement | Montant du supplément total des articles ayant généré un supplément dans le menu. |
@net @net_ht | Prix net et prix net_ht du menu (Prix de vente final tenant compte de la remise appliquée au menu, au sous-total englobant le menu ou globalement à tout le ticket) |
@tri | Ordre de tri de l’article (pour les éditions des bons en cuisine) |
@points @action @bonus @fidelite | Nombre de points que rapporte l’article sur une carte de fidélité, nombre de points d’action que coûte l’article à une carte de fidélité, bonus que rapporte l’article sur une carte de fidélité. @fidelité vaut “A” si une opération fidélité a été appliquée et que cet article est concerné, “N” sinon. |
libelle | Libellé du menu |
article | Voir la description des noeuds <article> |
composant | Nom du composant |
composant/@numero | Numéro (ordre pour l’affichage) du composant |
composant/@id | ID interne du composant |
composant/@code | Code interne du composant |
composant/@prix-max | Prix max des articles du composant. Si un article dont le prix dépasse @prix-max est associé au menu alors il générera un supplément. |
composant/@nombre | Nombre d’instances de ce composant |
composant/@sequence | Tag de séquencement automatique pour les articles de ce composant. |
Rappel de ce qui est expliqué à la section “Articles composants de menu” : Lorsqu’un article est vendu et prend la place d’un composant du menu, le noeud <composant> correspondant est déplacé dans le noeud <article>. Ainsi, si l’article est annulé par la suite, on peut remettre en place le noeud <composant> dans le menu et revenir à l’état initial.
Sous-Totaux et Sous-totaux “Plateau”
Les sous-totaux sont simplement des regroupements d’articles ou de menus sur lesquels on peut faire des remises ou des offerts.
(sous-total | plateau)/@numero | Numéro (ordre pour l’affichage) du sous-total |
(sous-total | plateau)/@valeur | Montant brut des articles ou des menus contenus dans le sous-total ou le sous-total plateau |
(sous-total | plateau)/@typeRemise (sous-total | plateau)/@remise | [N, S, P, M, …] Type et valeur (en montant ou en pourcentage) de la remise appliquée à ce sous-total |
Sous-tickets
Ce noeud interne ne devrait jamais être accessible de l’extérieur. Il s’agit d’une espèce spéciale de sous-total temporaire qui est transformé en ticket au moment de l’encaissement. Je le mentionne ici uniquement par souci d’exhaustivité.
Bilan
@montantTTC | Montant TTC du ticket |
@brut | Montant brut du ticket (hors remises) |
@fidelite | Montant des articles qui ne sont pas hors fidélité dans le ticket |
@remise | Montant de la remise globale effectuée sur le ticket |
@service | Montant du service (dépend du taux de service défini dans la configuration du vendeur) |
Lorsque l’encaissement d’un ticket provoque la génération d’un avoir, son code est stocké dans le noeud bilan/avoir
bilan/avoir | Code de l’avoir (destiné à être imprimé sous la forme d’un code 128) |
bilan/avoir/@validite | Validité de l’avoir généré |
Les vouchers (chèques cadeaux, bons d’achat) générés lors de l’encaissement du ticket suite à l’application d’un avantage fidélité ou d’une promotion sont stockés dans le noeud bilan/voucher.
bilan/voucher | Code du voucher (destiné à être imprimé sous la forme d’un code 128) |
bilan/voucher/@montant | Valeur du voucher |
bilan/voucher/@debut-validite bilan/voucher/@fin-validite | Dates de validité du voucher (le début de validité d’un voucher peut commencer après la date du jour où il a été généré.) |
tvas/@montantTaxes | Montant total des taxes |
Contenant un noeud <tva> par TVA représentée dans le ticket
tvas/tva | Montant de la TVA |
tvas/tva/@taux | Taux en pourcentage |
tvas/tva/@base | Montant taxable |
tvas/tva/@nombre | Nombre d’articles concernés |
Les montants calculés dans @rendu, @surplus et @avoir dépendent de la configuration des modes de règlement utilisés dans le ticket.
encaissements/@montantEncaisse | Montant total des encaissements |
encaissements/@rendu | Montant du rendu calculé |
encaissements/@surplus | Montant du surplus calculé |
encaissements/@avoir | Montant de l’avoir calculé |
. | Montant de l’encaissement (dans la valeur du noeud) |
@mode | Nom du mode de règlement |
@horodatage | Horodatage exact du moment où l’encaissement a été enregistré dans le ticket. |
@devise | Devise du règlement. Vaut EURO en général. |
@nombre | Nombre de règlements identiques |
@rendu | [oui/non] Vaut “oui” si l’encaissement en surplus avec ce mode de règlement peut donner naissance à un rendu en monnaie. |
@avoir | [oui/non] Vaut “oui” si l’encaissement en surplus avec ce mode de règlement peut créer un avoir. |
@acompte | [oui/non] Vaut “oui” si l’encaissement est un acompte. |
@cab | Code barres du mode de règlement (ticket restaurant) s’il a été scanné |
@id | Numéro du mode de règlement (numéro du chèque s’il a été lu par un périphérique ou du ticket restaurant) |
@validite | Validité du mode de règlement (cas des tickets restaurant) |
Structure générale des modèles de ticket
Un document de type “ticket” imprimé se compose généralement de 3 parties :
une entête avec le numéro du ticket, la date a laquelle il a été fait, l’identification du magasin et éventuellement le nom et le code du vendeur qui l’a encaissé, le numéro de table, le commentaire global…
le corps du ticket avec les lignes articles contenant obligatoirement le libellé de chaque article, son prix unitaire et la quantité vendue
le pied du ticket avec le montant total, éventuellement le montant total hors-taxes, la liste des encaissements, le détail des TVA et éventuellement le commentaire global, des informations sur le compte client ou la carte de fidélité et un message de remerciement.
Il y a deux manières de “naviguer” dans un fichier XML avec XSL :
En mode “pull” on utilise <xsl:call-template name=”...” /> pour appeler des <xsl:template name=”...” /> dans lesquels on utilise <xsl:value-of select=”...” /> pour “tirer” les données du fichier XML, les extraire et les placer dans le document de sortie à l’endroit où l’on se trouve.
En mode “push” on “pousse” une sélection de noeuds avec <xsl:apply-templates select=”...” /> et on demande au processeur XSLT de trouver dans le document XSL les <xsl:template match=”...” /> qui correspondent le mieux à ces noeuds. Dans ces templates on utilise alors <xsl:value-of select=”...” /> pour extraire les données.
Le mode “push” est idéal pour travailler sur une collection de noeuds, c’est une sorte de boucle déguisée. Alors que le mode “pull” sert à extraire les données lorsqu’on sait exactement où elles se trouvent.
Pour générer le rendu du ticket on utilise les deux : le mode “push” pour organiser le ticket en sections “entête”, “corps” et “pied” et le mode “pull” dans ces sections pour extraire les données et les mettre en forme.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8"/>
<!-- Paramètres fournis par l’application -->
<xsl:param name="double_affichage">false</xsl:param>
<xsl:param name=”...”>...</xsl:param>
<xsl:template match="/">
<ticket>
<select>imprimante</select>
<pagecode>858</pagecode>
<xsl:apply-templates select="ticket/entete" />
<xsl:apply-templates select="ticket/lignes" />
<xsl:apply-templates select="ticket/bilan" />
<xsl:call-template name="pied"/>
</ticket>
</xsl:template>
<xsl:template match=”entete”>
<!-- Un ticket doit obligatoirement utiliser la commande “<identification/>” -->
<!-- NOM DU MAGASIN EN HAUT DU TICKET avec les coordonnées du magasin -->
<lf/>
<aligne>centre</aligne>
<style>gras</style><identification /><style>normal</style><lf/>
<identification niveau="3" /><lf/>
<!-- COMMENTAIRE GLOBAL EN HAUT DU TICKET -->
<!--
<xsl:call-template name="commentaire" />
-->
<!-- Imprimer l’entête du ticket : logo, vendeur, date, numero, entetes
de la table des articles... -->
</xsl:template>
<xsl:termplate match=”article”>
<!-- Imprimer la ligne correspondante à un article -->
</xsl:template>
<xsl:termplate match=”menu”>
<!-- Imprimer la ligne correspondante à un menu -->
</xsl:template>
<xsl:template match=”sous-total | plateau”>
<!-- Imprimer les articles du menu -->
<xsl:apply-templates select="*" />
<!-- Imprimer la ligne du menu -->
</xsl:template>
<xsl:template match="bilan">
<!-- Imprimer le total du ticket -->
<!-- Imprimer les encaissements dans un certain ordre -->
<xsl:if test="encaissements[encaissement or acompte or avoir or voucher]">
<xsl:apply-templates select="encaissements/acompte" />
<xsl:apply-templates select="encaissements/avoir" />
<xsl:apply-templates select="encaissements/voucher" />
<xsl:apply-templates select="encaissements/encaissement" />
<xsl:apply-templates select="encaissements/@rendu" />
<xsl:apply-templates select="encaissements/@surplus" />
</xsl:if>
<!-- Imprimer les TVAs -->
<xsl:apply-templates select="tvas"/>
</xsl:template>
<xsl:template match="acompte">
</xsl:template>
<xsl:template match="avoir">
</xsl:template>
<xsl:template match="voucher">
</xsl:template>
<xsl:template match="encaissement">
</xsl:template>
<xsl:template match="@rendu">
</xsl:template>
<xsl:template match="@surplus">
</xsl:template>
<xsl:template match=”tva[. > 0]”>
<!-- Imprimer la ligne TVA > 0 -->
</xsl:template>
<!-- La TVA est à zéro : ne rien faire pour ne pas l’imprimer -->
<xsl:template match=”tva[.=0]”>
</xsl:template>
<xsl:template name=”commentaire”>
</xsl:template>
<xsl:template name=”pied”>
<!-- COMMENTAIRE GLOBAL EN BAS DU TICKET -->
<!--
<xsl:call-template name=”commentaire” />
-->
<!-- Un ticket doit obligatoirement utiliser la commande “<identification/>” -->
<!-- NOM DU MAGASIN EN BAS DU TICKET avec un message de remerciement -->
<lf/>
<aligne>centre</aligne>
<identification />" VOUS REMERCIE..."<lf/>
<aligne>gauche</aligne>
</xsl:template>
</xsl:stylesheet>
Technologies
Il s'agit d'une application Microsoft Windows. Elle est optimisée pour Windows XP Pro et Windows XP Embedded for Point of Sale (WePOS) et POS Ready2009, POS Ready7.elle est développée en Delphi (Pascal Objet) à l’aide de Borland Developer Studio 2006 Architect (www.codegear.com, anciennement Borland www.borland.com), CRISALID s’attache à suivre l’évolution des technologies Borland (tous les logiciels CRISALID ont été développés avec les outils Borland/CodeGear, depuis Turbo Pascal « Objet » version 5.5 pour les outils MS-DOS)
Pour une grande partie de ses développements et de ses architectures, le choix de CRISALID s’est porté sur le logiciel libre. La communauté et le dynamisme des développeurs de toutes les nationalités qui participent à ces projets permettent à CRISALID d’avancer toujours plus vite et de rester toujours à la pointe des innovations technologiques. CRISALID participe activement à l’amélioration, aux tests et au développement de Logiciels Libres.
Le SGBD utilisé est Firebird (www.firebirdsql.org), un dérivé Open Source issu d’Interbase 6.0. La version actuellement embarquée de Firebird est la 2.1. Firebird ne nécessite pas d’administration (hormis les sauvegardes régulières des bases de données) et embarque toutes les technologies de pointe en matière de SGBD : Multi-Plateformes (Windows, Linux, MacOS, Solaris), Architecture Multi-Générationnelle (MGA) de la lignée Interbase, Triggers (déclencheurs), Procédures Stockées, Fonctions Utilisateur, Exceptions, Domaines, Evènements, Blobs (Objets binaires), Optimiseur, Combinaison des index par les opérations de l’algèbre booléenne (Index Bitmaps)… Voir le livre blanc « Firebird en Entreprise » annexé à ce document.
le ogiciel utilise intensivement le format XML pour stocker les données et les configurations locales. Le moteur XML embarqué est MSXML 4.0 de Microsoft (http://msdn.microsoft.com/xml) qui permet la transformation des flux XML par des feuilles de styles XSL-T (eXtensible Styesheet Language - Transformation), l’interrogation des ensembles de données XML par XPath, la manipulation et la création par le Document Object Model (DOM).
Le reporting est réalisé par FastReport 4 (www.fast-report.com). FastReport permet l’export des rapports au format PDF, l’impression de codes à barres et la redistribution de son modeleur de rapports sans royalties au client final. Tous les rapports imprimables de Neptis sont ainsi modifiables sans recompilation du projet.
Les grilles de données sont gérées par les composants commerciaux de TMS Software (www.tmssoftware.com) et par Virtual TreeView (www.soft-gems.net)
L’interface est enrichie à l’aide des composants OpenSource JVCL (http://homepages.borland.com/jedi/jvcl) et JCL (http://homepages.borland.com/jedi/jcl)
La connexion à Firebird est prise en charge par les composants OpenSource UIB (www.progdigy.com) dont CRISALID est l’un des contributeurs.
Le pilotage des périphériques Point de Vente est opéré par OPOS (OLE for Point of Sales) et les objets de contrôle communs sont ceux fournis par Monroe Consulting Services (www.monroecs.com). Cette technologie permet à Neptis d’adresser tous les périphériques des classes de périphériques qu’il prend en charge et dont les fabricants fournissent des objets de service (comme Samsung, Epson, Citizen, PSC…) Neptis est cependant capable d’utiliser des imprimantes Windows (A4) et des imprimantes label professionnelles (Zebra, SATO, Toshiba…)
La gestion des exceptions non gérées par le code (bugs) est assurée par EurekaLog (www.eurekalog.com) qui permet l’envoi de mails contenant un rapport précis du problème qui permet à CRISALID d’obtenir jusqu’à la ligne de code qui a généré l’erreur et la pile des appels de méthodes qui ont conduit à cette erreur.
L’application est déployée à l’aide d’InnoSetup (www.jrsoftware.org) qui est un générateur d’assistants d’installation Open Source dont Crisalid est le traducteur officiel pour la langue française.
Panorama des fonctionnalités de Neptis
- Encaissement tactile ergonomique qui permet une grande fluidité au magasin
- Technologie exclusive de Queue Boosting qui permet d’augmenter sa capacité d’encaissement jusqu’à 20% lorsque 80% des encaissements sont réalisés habituellement en espèces
- Contrôle du point de vente : rappel des tickets, filtrage multi-critères, éditions et rapports qui permettent au gestionnaire de suivre pas à pas le fonctionnement de son magasin
- Gestion des comptes clients
- Gestion des cartes de fidélité
- Gestion des vendeurs, identification des vendeurs, hiérarchisation et gestion des autorisations
- Attribution d’un tiroir par vendeur
- Pilotage des périphériques point de vente standards :
- Imprimantes
- Afficheurs clients
- Tiroirs caisse
- Scanners et Douchettes de Codes à Barres
- Systèmes d’identification des vendeurs (stylos magnétiques, clés dallas)
- Imprimantes de chèques et lecteurs CMC7
- Balances
- Terminaux de Paiement Electronique
- Gestion automatique des espècesLecteurs de cartes magnétiques
- Edition d’étiquettes sur planches d’étiquettes (Imprimantes A4) ou sur rouleaux d’étiquettes (Imprimantes Label professionnelles). Les étiquettes sont personnalisables et tous les formats sont réalisables, par exemple : Etiquettes « anneaux » que l’on noue autours d’un arbuste ou étiquettes « piquets » à planter pour la fleuristerie.
- Capacités de stockage limitées seulement par la taille des disques
- Interface entièrement adaptable à chaque métier
- Lancement d’applications Microsoft Windows tierce directement depuis l’interface du logiciel. Cela limite les risques d’erreurs de manipulation de Windows par du personnel qui n’est pas toujours formé à son utilisation ainsi que les risques d’utilisation frauduleuse du système par des opérateurs malveillants.
- Modulaire : les fonctionnalités de gestion et de reporting sont réalisées par un ensemble de plugins
- Extensible : l’architecture Client-Serveur de Neptis lui confère la capacité à se connecter aussi simplement en réseau LAN, WAN qu’à fonctionner en monoposte.
- Communiquant : Neptis est un système ouvert, les partenaires logiciels et matériels sont encouragés à développer leurs propres extensions pour Neptis. Les technologies embarquées (SGBD Open Source, XML) permettent une compatibilité et une ouverture maximum vers les technologies de pointe.
- Robuste : Chaque nouvelle version de Neptis subit une période de tests intensifs. Puis est déployée chez un ensemble de sites pilotes appartenant à tous les corps de métiers.
La politique de développement de logiciels de CRISALID est rationnelle et a pour objectif principal de limiter les risques. Toutes les demandes spécifiques de nos clients sont étudiées par nos services techniques et commerciaux. Lorsqu’un accord a été trouvé entre ces différents acteurs, les nouvelles fonctionnalités sont intégrées à la version standard du logiciel. Elles sont ainsi accessibles à tous les clients de CRISALID garantissant une évolutivité constante de nos solutions. De plus la limitation du nombre des versions du logiciel actives simultanément permet de réduire les coûts de maintenance et de formation des techniciens, des distributeurs et des commerciaux.
Fonctionnalités
La fonctionnalité principale est de gérer l’encaissement et la facturation dans un magasin.L’accessibilité est considérée chez CRISALID comme une fonctionnalité indissociable du logiciel. Plus de 25 années d’expérience chez CRISALID nous ont permis de concevoir un logiciel ergonomiquement accessible à tous les publics d’utilisateurs.
La stabilité et la fiabilité son traitées prioritairement à toutes les autres fonctionnalités. CRISALID vend ses logiciels directement à ses clients dans les régions couvertes par ses filiales (Nord-est, Sud-est et Bourgogne). Cette proximité avec le terrain nous pousse constamment à améliorer la fiabilité de nos logiciels.
Fonctions standard :
ADDON | Permet de valider ou de modifier le code Addon lors de la saisie manuelle des articles presse. |
ANNULE | Annule l'élément sélectionné sur le ticket actif. Gère automatiquement le type d'annulation (DERNIER, RETOUR, APRES ENCAISSEMENT) selon l'état du ticket. |
AUTORISE | Utilise le TPE configuré pour autoriser un paiement électronique (CARTE ou CHEQUE). Supporte également le TPE Axalto et l’extension fidélité de la société APPLICAM. |
AVOIR | Crée un avoir manuel en utilisant le montant tapé sur le pavé numérique. |
CAISSE | Fonctions de gestion de la caisse, permet la saisie de fond de caisse, d’entrées et de sorties d’argent, les remises en banque, la clôture et le calcul du financier. |
COMMENTAIRE | Permet d’ajouter un commentaire (Texte libre) au ticket ou à l’article sélectionné. |
COMPTE | Accès aux comptes clients. Ajoute le ticket courant au compte spécifié. |
EXECUTE | Exécute une application externe (exécutable Windows) |
EXPORT | Export natif de certaines données (Presse et Pointages) |
FICHE | Ouvre les fiches de paramétrage (articles, configuration, rappel de tickets, recherches alphanumériques…) |
FICHE_REPAS | Impression d’une fiche type « Repas Complet » à partir du montant du ticket en cours. |
FIDELITE | Accès aux cartes de fidélité. |
GESTION | Fonctions de gestion, transforme le ticket actif en ticket d’inventaire, d’entrée de stock, de commande… |
IMPORT | Import natif de tickets (XML) |
MANUEL | Ouvre une boîte de dialogue dans laquelle l’utilisateur peut taper une fonction interne à exécuter. |
PART | Accès aux conditionnements d’un article pendant la vente. Permet d’utiliser une même touche pour vendre plusieurs conditionnements d’un même article (Baguette et ½ Baguette ou Paquet et Cartouche, ou Gâteau en 2, 4, 6, 8, 10, 12… personnnes) |
PLU | Vend un article d’après son code PLU |
PLUGIN | Lance un module d’extension |
POINTAGE | Pointage et dépointage des vendeurs |
PORTABLE | Téléchargement des fichiers d’un portable de saisie Opticon PHL 1700/2700 |
PRIX | Gestion des prix de vente : activation, marquage pour mise à jour manuelle et modification des prix. |
PROGRAMME | Accès au mode de programmation des touches du clavier. |
QUANTITE | Modification du multiplicateur de quantité qui permet de vendre la même quantité de plusieurs articles en une seule fois. |
QUITTE | Ferme l’application et permet de redémarrer ou d’éteindre Windows. |
REMISE | Effectue une remise sur le dernier article ou le dernier sous-total. Remises supportées : en pourcentage, en montant, offerts, prix spécial et prix menu. |
SON | Joue une séquence de notes sur le buzzer interne de la machine. |
ST | Crée un sous-total ou un sous-total « Plateau » en regroupant tous les articles saisis jusqu’au précédent sous-total ou au début du ticket. |
STOCK | Transforme le ticket actif en ticket de gestion du stock (inventaire, inventaires morcellés, remise à zéro du stock…) |
TARIF | Modification du tarif de vente. Peut s’appliquer au ticket complet ou seulement aux nouveaux articles saisis. |
TEST | Accès au mode test : les articles scannés ne sont pas vendus mais s’ils sont identifiés une fiche descriptive est affichée à la place du ticket. |
TICKET | Fonctions de gestion du ticket. Permet de mettre un ticket en attente, de l’imprimer, de l’encaisser, de le marquer pour validation ultérieure, de l’annuler, de le transformer en commande (mise en attente prolongée), de faire une remise globale ou de pré remplir le pavé numérique avec une valeur calculée d’après un pourcentage du montant du ticket. |
TIROIR | Ouverture manuelle du tiroir. Attribution d’un tiroir à un vendeur. |
TOUCHE | Simule la saisie d’une touche sur le pavé numérique |
VENDEUR | Connexion et déconnexion d’un vendeur. |
Fonctions étendues :
Ces fonctions ne servent pas directement à la vente mais elles sont utiles pour la maintenance, les tests et le débogage du logiciel.
#ALEA# | Générateur de données aléatoires. Permet de générer des codes à barres, des prix, des valeurs numériques ou des quantités. |
#FILTRER_RAPPEL# | Filtrage des tickets dans le rappel tickets. Permet de rechercher les tickets par leur numéro, le vendeur qui les a encaissé, leur montant, ceux qui ont été imprimés, mis en compte, marqués pour validation ultérieure ou annulés. |
#MAINTENANCE# | Accès au module de maintenance des bases de données. |
#RECALCULER_STATS# | Recalcule les Statistiques de tous les tickets. |
#VOIRXML# | Permet de visualiser le document XML « brut » qui constitue le ticket. |
Modules d’extension standard :
Ces modules d’extension sont fournis dans toutes les versions de Neptis. Ils permettent de réaliser les tâches administratives et de gestion. Ils permettent à CRISALID de spécialiser facilement l’application pour un métier donné.
ASSISTANT | Générateur de claviers. Ce module permet de créer des claviers d’articles en utilisant la base de données et une fenêtre modèle. |
COMPTES | Traitements de masse sur les comptes clients et les cartes de fidélité. |
ETICAB | Imprime une planche d’étiquettes à partir du ticket actif. |
ETIQUETTES | Imprime une planche d’étiquettes à partir de la base de données. |
EXPORT | Exportation du fichier des articles. |
IMPORT | Importation des articles, des fenêtres et des comptes clients. |
INTERNET | Lance une connexion réseau RAS. Supporte le service MiniDNS d’association d’IP dynamique avec un nom de domaine. |
INVENTAIRE | Etat du stock et écart d’inventaire. |
NAVIGATEUR | Navigateur Web simplifié. |
STATS | Navigateur de Statistiques. Permet de naviguer intuitivement dans les résultats financiers. |
SYNTHESE | Interroge les tickets et extrait toutes les informations de mouvement d’articles sur une période donnée. Ces informations sont corrélées avec la base des articles et cela permet de générer, par exemple des rapports de calcul de marges. |
VENTES | Etat des ventes. |
VERIFBDD | Vérifie la structure et les données des bases de données. |
Modules d’extension métiers :
Pour Atthis (Tabac/Presse) nous fournissons un module de commande Tabac qui sait fabriquer des propositions de commande et les envoyer, via un émulateur minitel ou Internet au serveur d’Altadis Distribution France. Le Module Web d’Altadis Distribution France a été développé en collaboration avec CRISALID.
Pour Aliris (Boulangerie/Pâtisserie) nous fournissons deux modules d’exportation des bandes de contrôle (tickets et informations logistiques) vers EPI (Ancien logiciel CRISALID) et VIF (Fournisseur d’applications de gestion) .
Fidélité :
CRISALID fournit, en standard 5 moteurs de fidélité :
- NULL permet d’utiliser le moteur d’identification et de stockage de la fidélité sans prendre de décision. C’est un moyen élégant d’identifier les clients par leur nom.
- POINTS permet d’associer des points à chaque article acheté par le client. Les points sont cumulés dans la « CARTE de fidélité » gérée par l’application. Grâce à ses points le client peut acquérir d’autres articles.
- BONUS permet de constituer un Porte Monnaie Electronique. Chaque article acheté par le client lui rapporte un bonus qu’il peut ensuite déduire du montant de son ticket comme bon lui semble (Remise Immédiate)
- SIMPLE et PASSAGES permettent d’associer une action de fidélité (Ex. Remise d’un pourcentage du montant des achats cumulé sur la carte de fidélité) à un nombre de passages.
Architecture du moteur de fidélité Crisalid
Le fonctionnement du moteur de fidélité Crisalid repose sur deux constats : chaque client est différent et la nécessité d’ouverture. Le challenge a consisté à construire une architecture ouverte, capable de se connecter à des systèmes de gestion de la fidélité tiers et faciles à adapter aux besoins de chacun de nos clients en prenant en compte chacune de leurs spécificités. Cette architecture repose trois modèles de la base de données : le modèle d’articles, celui du ticket et le modèle des clients. Le moteur de fidélité permet de faire le lien entre les articles, la carte de fidélité ou l’historique du client et le ticket en cours de création.
Un moteur de fidélité gère un déclencheur qui peut être n’importe quelle variable des modèles ticket, article et client. Par exemple, un déclencheur courant est basé sur le nombre de passages, il s’exprime sous la forme : « au dixième passage faire quelque chose pour le client », ou bien « lorsque le montant du ticket dépasse … » ou encore « à chacun des ticket… »
Lorsque le déclencheur est activé, le contrôleur de l’application demande au moteur de fidélité de lui fournir les caractéristiques de l’action à effectuer : « … offrir tel ou tel article » ou bien « faire une remise de x % du cumul des achats précédents au ticket courant » ou encore « faire une remise de y % sur le montant du ticket courant »
Si le déclencheur n’est pas activé, le contrôleur demande au moteur de fidélité de prendre en compte le passage du client, cette opération est systématique : on cumule un passage sur la carte de fidélité ainsi que le montant des achats réalisés dans le compteur d’achats. Dans le cas contraire, si une action fidélité a été réalisée, la carte courant est cumulée dans un historique des cartes de fidélité et elle est remise à zéro. Dans certains cas on peut choisir de pré-initialiser la nouvelle carte, par exemple en prenant en compte un pourcentage du cumul des achats de la carte précédente.
Une autre méthode consiste à prendre en compte les attributs des articles présents dans le ticket. On peut alors décider qu’un article rapporte un certain nombre de « points ». Lorsque ces points sont cumulés ils permettent d’obtenir d’autres articles gratuitement en dépensant ces points pour acquérir des articles dont le nombre de « points d’action » est inférieur au nombre de points détenus par le client.
La dernière méthode est celle du porte-monnaie électronique. Chaque article rapporte un « bonus » convertible en euros que l’on peut à tout moment utiliser comme réduction immédiate sous forme d’une remise en valeur sur le ticket courant. Le montant est utilisé entièrement à chaque fois. Le déclencheur peut-être programmé pour n’autoriser l’utilisation du porte-monnaie électronique que dans certaines conditions (montant des achats minimum, valeur du porte monnaie…)
.