Vous consultez une page technique concernant le logiciel de gestion Mercator. Celle-ci contient des informations spécifiques destinées aux professionnels de Mercator. Souhaitez-vous être redirigés vers des informations plus générales ?


   Ne plus poser cette question

MercatorPenguin en tant que lecteur de codes-barres virtuel sans fil

0000002916     -      23/05/2019

MercatorPenguin peut être utilisé en tant que lecteur de codes-barres virtuel sans fil pour Mercator ERP. Il s'agit bien d'une émulation d'une douchette codes-barres, fonctionnant en mode "émulation clavier". La séquence de touches envoyée l'est donc dans la zone qui a le focus.

Pour utiliser cette fonctionnalité, il faut

  • disposer d'une version 10.5 ou ultérieure de Mercator,
  • un appareil mobile (smartphone ou tablette), connecté à Internet et disposant d'un MercatorPenguin 2.5 ou ultérieur,
  • dans ce MercatorPenguin, activer et accepter les notifications; cela se fait au départ de l'écran d'information accessible depuis le bouton "i",
  • noter l'ID qui apparaît une fois les notifications activées,
  • et placer un objet de type PenguinVirtualScanner dans un écran de vente, d'achat, d'inventaire ou de transfert de dépôts.

Dans les options "Matériel Caisse", il faut compléter la valeur de "Scan via MercatorPenguin : player id" (id = PENVIRSCAN) avec l'identifiant noté dans MercatorPenguin dans l'écran d'information. Cet identifiant peut être obtenu facilement via cette requête, où xyz correspondent aux trois premiers caractères lus dans MercatorPenguin :

select id from PENGUIN_PLAYERS where id like 'xyz%'

Quand le switch de l'objet PenguinVirtualScanner est activé, Mercator ERP envoie une notification à MercatorPenguin permettant d'établir la liaison entre le document en cours et MercatorPenguin. L'ouverture de la notification conduit vers un écran permettant le scanninng de codes-barres. L'activation de ce switch met aussi le focus dans le LinesEditor de l'écran dans Mercator ERP.

Cet écran permet la saisie d'une quantité et/ou d'un prix unitaire avant le scanning du code-barres. Cette saisie est réglée par les options BehaviorPrice et BehaviorQty de l'objet PenguinVirtualScanner. Elles peuvent prendre ces valeurs :

  • Invisible : la zone n'est pas affichée dans MercatorPenguin
  • Optional : la zone est visible dans MercatorPenguin et une valeur numérique peut y être saisie
  • Mandatory : la zone est visible dans MercatorPenguin, une valeur numérique doit y être saisie et validée par le bouton "OK" du clavier.

La propriété Termination permet de déterminer le ou les caractères envoyés à Mercator en mode "émulation clavier" après le code-barres. Par défaut, cette option vaut {ENTER} qui équivaut à une pression sur la touche "Enter".

  • Si on souhaite simuler deux pressions de touche "Enter" : {ENTER}{ENTER}.
  • Si on souhaite simuler une pression de "flèche vers le bas" : "{DOWN}"

Cette option doit être coordonnée avec la séquence EnterStop dans le LinesEditor.

Le bouton "Arrêter" permet de mettre un terme à la séquence de scanning associée à ce document. Dans Mercator ERP, le switch sera automatiquement remis à "Inactif".


Dans MercatorPenguin, le second onglet, "Document", permet d'interroger Mercator ERP pour connaître le contenu de la grille de saisie des articles.

     

Dans un souci d'optimisation, cette liste n'est mise à jour que si on a scanné un article depuis son dernier affichage. Il est toutefois possible de forcer le rafraîchissement de cette liste en la tirant vers le bas.

Dans cette liste, une ligne peut être supprimée :

  • sous Android : en appuyant et en maintenant appuyé sur cette ligne et en cliquant ensuite sur le bouton "Supprimer"
                 
  • sous iOS : en tirant la ligne vers la gauche et en cliquant ensuite sur "Supprimer"
                 

La ligne correspondante sera automatiquement supprimée dans Mercator ERP.

La présentation de cette liste est personnalisable (voir les exemples ci-dessous).


Dans le troisième onglet, il est possible de déterminer certains paramètres de fonctionnement.

Le premier déroulant permet de choisir si on utilise l'appareil photo pour scanner les codes-barres ou un scanner intégré (si l'appareil est doté de ce type dispositif).

Le second déroulant permet de définir un comportement de MercatorPenguin indiquant à l'utilisateur que l'envoi du code-barres a été effectué avec succès. (Cela ne présage toutefois pas de la suite réservée à cette séquence de touches, qui pourrait ne pas conduire à la réelle saisie d'un article).

  • Aucune confirmation
  • Toast court : affichage d'un message centré pour une durée de 2 secondes
  • Toast long : affichage d'un message centré pour une durée de 3.5 secondes
  • Stop : affichage d'une boîte de dialogue "bloquante"

La liste permet quant à elle de choisir les types de codes-barres qui sont susceptibles d'être reconnus par l'appareil photo. (Cette liste n'est donc pas visible quand on utilise le scanner intégré. Dans ce cas, il faut se reporter au paramétrage spécifique de ce scanner intégré). Il est recommandé de n'activer que les types de codes-barres réellement utilisés. En effet, la détection de types non attendus peut provoquer des lectures incorrectes.


Evènements liés à l'utilisation de PenguinVirtualScanner

Les BillingEngine, TransferEngine et InventoryEngine disposent de ces évènements :

  • PenguinVirtualScannerAddingItem : durant la composition de la ListView du second onglet, lors de l'ajout d'un item correspondant à une ligne du LinesEditor
  • PenguinVirtualScannerDataPrepared : durant la composition de la ListView du second onglet, quand tous les items ont été ajoutés. C'est notamment à cet endroit que l'on pourra modifier le code XAML de la ListViewCell.

PenguinVirtualScannerBeforeSendKeys : avant l'envoi de la séquence de touches correspondant au code-barres. Cette séquence de touche peut être modifiée via e.Keys ou annulée via e.Cancel = true.


Paramétrage de la ListView du second onglet

Par défaut, le code XAML de chaque cellule de cette ListView vaut :

<Label Text="{Binding Path=Data[Cell1]}" HorizontalOptions="StartAndExpand" LineBreakMode="WordWrap" VerticalTextAlignment="Center" FontSize="Medium" />
<Label Text="{Binding Path=Data[Cell2]}" HorizontalOptions="StartAndExpand" LineBreakMode="WordWrap" VerticalTextAlignment="Center" FontSize="Small" />

Le binding de cette ListView est de type List<ShowDocLine>

Zoom
    public class ShowDocLine
    {
        public Dictionary<string, string> Data { get; set; }
    }

 

Pour agir sur cette source de données, on peut utiliser l'évènement PenguinVirtualScannerAddingItem de l'engine correspondant, qui va être levé pour chaque DataGridViewRow visible de la grille du LinesEditor. Via e.Item, on peut agir sur le Dictionary<string, string> qui va définir le contenu. 

  • la clé du dictionnaire est le nom de l'élément de cellule (nom libre, par défaut Cell1, Cell2, ...)
  • la valeur sera le contenu de cet élément de cellule (toujours de type string)

Cette illustration permet de comprendre l'organisation des éléments de cellules pour le code XAML par défaut :


Ci-dessous un exemple de customizer Billing qui permet d'ajouter une ligne supplémentaire dont la valeur provient de la colonne read-only DISPO.DISPO du LinesEditor.

Zoom
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Windows.Forms;
using MercatorApi;
using MercatorExtensions;
using MercatorUi;
using System.Linq;

namespace Billing
{
    public class Customizer : MercatorUi.ICustomizers.IBillingEngineCreated, MercatorUi.ICustomizers.IBillingEngineClosed
    {
        public void BillingEngineCreated(MercatorUi.Engine.Gescom.BillingEngine billingEngine)
        {
            billingEngine.PenguinVirtualScannerAddingItem += BillingEngine_PenguinVirtualScannerAddingItem;
            billingEngine.PenguinVirtualScannerDataPrepared += BillingEngine_PenguinVirtualScannerDataPrepared;
        }

        public void BillingEngineClosed(MercatorUi.Engine.Gescom.BillingEngine billingEngine)
        {
            billingEngine.PenguinVirtualScannerAddingItem -= BillingEngine_PenguinVirtualScannerAddingItem;
            billingEngine.PenguinVirtualScannerDataPrepared -= BillingEngine_PenguinVirtualScannerDataPrepared;
        }

        private void BillingEngine_PenguinVirtualScannerAddingItem(object sender, MercatorUi.Engine.Gescom.BillingEngine.PenguinVirtualScannerAddingItemEventArgs e)
        {
            // on cherche la colonne calculée DISPO.DISPO
            MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
            var colDispo = billingEngine.BillingForm.LinesEditor.Grid.Columns.OfType<MercatorUi.MovableControls.CommonObjects.LinesEditorReadOnlyColumnTextBox>().Where(c => c.SqlMember == "DISPO.DISPO").FirstOrDefault();
            if (colDispo == null)
                throw new ApplicationException("Read-only column DISPO.DISPO not found!");
            e.Item.Add("Cell3", "Stock = " + e.DataGridViewRow.Cells[colDispo.Name].FormattedValue.ToString());
        }

        private void BillingEngine_PenguinVirtualScannerDataPrepared(object sender, MercatorUi.Engine.Gescom.BillingEngine.PenguinVirtualScannerDataPreparedEventArgs e)
        {
            e.Xaml += "<Label Text=\"{Binding Path=Data[Cell3]}\" HorizontalOptions=\"StartAndExpand\" LineBreakMode=\"WordWrap\" VerticalTextAlignment=\"Center\" FontSize=\"Small\" />";
        }
    }
}

 

Il est permis de remplacer totalement le contenu XAML par un contenu personnalisé. Ainsi, il est par exemple possible de colorer certaines lignes. De même, via l’évènement PenguinVirtualScannerDataPrepared et e.Items, il est possible d'apporter toutes les modifications souhaitées aux données en tant que telles. Par ce biais, il serait par exemple possible d'ajouter un item correspondant à des informations provenant du pied du document. La seule contrainte est que tous les dictionnaires de cette liste contiennent les mêmes clés. (Cell1, Cell2, ...)

Toutes les propriétés habituellement bindables peuvent être liées via cette syntaxe : 

{Binding Path=Data[Cellx]}

Dans cette syntaxe, Cellx doit correspondre à la clé de dictionnaire. Il s'agit de la seule partie variable dans ce binding.


Cet autre exemple de customizer permet d'afficher la photo de l'article dans le secong onglet.

Zoom
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Windows.Forms;
using MercatorApi;
using MercatorExtensions;
using MercatorUi;
using System.Linq;

namespace Billing
{
    public class Customizer : MercatorUi.ICustomizers.IBillingEngineCreated, MercatorUi.ICustomizers.IBillingEngineClosed
    {
        public void BillingEngineCreated(MercatorUi.Engine.Gescom.BillingEngine billingEngine)
        {
            billingEngine.PenguinVirtualScannerAddingItem += BillingEngine_PenguinVirtualScannerAddingItem;
            billingEngine.PenguinVirtualScannerDataPrepared += BillingEngine_PenguinVirtualScannerDataPrepared;
        }

        public void BillingEngineClosed(MercatorUi.Engine.Gescom.BillingEngine billingEngine)
        {
            billingEngine.PenguinVirtualScannerAddingItem -= BillingEngine_PenguinVirtualScannerAddingItem;
            billingEngine.PenguinVirtualScannerDataPrepared -= BillingEngine_PenguinVirtualScannerDataPrepared;
        }

        private void BillingEngine_PenguinVirtualScannerAddingItem(object sender, MercatorUi.Engine.Gescom.BillingEngine.PenguinVirtualScannerAddingItemEventArgs e)
        {
            e.Item.Add("id_article", e.DataGridViewRow.Cells["id_article"].Value.ToString());
        }

        private void BillingEngine_PenguinVirtualScannerDataPrepared(object sender, MercatorUi.Engine.Gescom.BillingEngine.PenguinVirtualScannerDataPreparedEventArgs e)
        {
            e.Xaml = "<StackLayout Orientation=\"Horizontal\">"
                       + "<m:Image Table=\"STOCK\" Index=\"S_ID\" Value=\"{Binding Path=Data[id_article]}\" Field=\"S_IMAGE1\" WidthRequest=\"40\" HeightRequest=\"40\" Margin=\"0,0,20,0\" />"
                       + "<StackLayout VerticalOptions=\"Center\">"
                           + e.Xaml
                       + "</StackLayout>"
                   + "</StackLayout>";
        }
    }
}