Profil développeur _ Consultant technique
Généralités développeur
La fonction WMTM000.Tester_Depot_WMS permet de savoir si le dépôt est géré ou non en WMS.
Elle vous permettra d'orienter vos spécifiques en fonction de ce contexte. Divalto Achat-Vente utilise cette fonction également en standard.
Code-barres
Généralités
Le WMS traite différentes symbologies de code-barres. Il s'agit essentiellement d'une problématique de configuration de lecteur.
Le lecteur devra être configuré avec un retour chariot après chaque scan pour que la saisie soit automatiquement validée.
Exemple de code 128 d'un emplacement :
Code 39 d'un emplacement :
Simple datamatrix (AIM ]d1 si rendu)
AIM
Le code AIM permet d'identifier le type de code-barres. Divalto filtre l'AIM s'il est rendu par le lecteur, et ne rend dans le champ de saisie que la valeur sans l'AIM.
Le code AIM doit impérativement être rendu par le lecteur en cas de GS1-128. Cf. plus bas.
Exemples d'AIM :
]d2 |
|
]C1 |
|
]e0 |
|
]I0 |
ITF14, check digit was not transmitted by the scanner |
]I1 |
GS1 ITF14, check digit has been validated and transmitted by the scanner |
]E0 |
|
]E1 |
Two digit Add-On symbol |
]E2 |
Five digit Add-On symbol |
]E3 |
EAN-13, UPC-A or UPC-E with Add-On symbol |
]E4 |
GS1-128
Le GS1-128 est un code-barres particulier, normé, qui permet de stocker différentes informations dans le même code-barres :
- SSCC
- Article
- Quantité
- Lot
- Poids
- ...
Divalto WMS intègre en standard un décodage du GS1-128. Il peut être en 1D ou 2D. Le code AIM devra être restitué par le lecteur pour permettre à Divalto d'activer ses fonctions de décodage du GS1-128.
L'avantage de l'utilisation de ce code-barres réside dans le fait qu'en un seul scan de code-barres, plusieurs champs/étapes du scénario de saisie sont remplis : inventaire, réception, préparation...
La quantité contenue dans un GS1-128 doit TOUJOURS être exprimée en unité de travail.
GS1-128 1D (AIM ]c1)
GS1-128 Datamatrix 2D (AIM ]d2)
Quelques segments du GS1-128
Code |
Description |
data length (without AI) |
00 |
18 |
|
01 |
Global Trade Item Number (GTIN) |
14 |
02 |
GTIN of Contained Trade Items |
14 |
10 |
Batch/Lot Number |
variable, up to 20 |
11 |
Production Date |
6 |
12 |
Due Date |
6 |
13 |
Packaging Date |
6 |
15 |
Best Before Date (YYMMDD) |
6 |
17 |
Expiration Date |
6 |
20 |
Product Variant |
2 |
21 |
Serial Number |
variable, up to 20 |
37 |
Number of Units Contained |
variable, up to 8 |
314y |
Qty in square meters |
6 |
330y |
Container Gross Weight (kg) |
6 |
Des AIM séparateurs entre deux segments peuvent être insérés pour les segments de taille variable afin que vous ne soyez pas obligé d'utiliser tous les caractères du segment (qté...). Cependant, pour certains segments, il n'est pas possible de procéder autrement (lot...), sauf si vous placez ces segments à la fin.
Exemple de lecture dans le bloc-notes d'un GS1-128 :
]d2000623680009000009180200623680000377370000006033000002001519071910887788
]d20006236800090000091802006236800003773760|33000002001519071910887788
]d20006236800090000091802006236800003773760|10887788|330000020015190719
Plus d'informations ici : https://www.gs1.fr
Si vous avez besoin de stocker une information « spécifique », Divalto vous invite à le faire dans un segment 91-99 prévu à cet effet et qui ne sera pas interprété par le standard.
Vous pouvez surcharger la fonction GS1_Decoder_SegmentInconnu de wmtmbarcod pour décoder cette partie.
;* |
Suivant le contexte :
- wmbarcodval peut être alimenté par la valeur lue,
- le record wmGS1128 est à surcharger dans le dictionnaire pour ajouter votre segment, segment que vous remplirez dans cette fonction.
Cf. :
- https://en.wikipedia.org/wiki/GS1-128
- Fichier joint GS1_Datamatrix_GuideLine.pdf
Edition des codes-barres
Les masques d'impression Divalto permettent en standard toute sortie de code-barres, dont le GS1-128.
Divalto WMS permet en standard de sortir divers codes-barres.
La génération est basée sur une DLL venant du logiciel Zint https://sourceforge.net/projects/zint/, qui peut aussi être utilisé en dehors de Divalto si vous souhaitez éditer des codes-barres en dehors de Divalto.
Sinon, nombreux sont les sites Web qui conviennent pour faire des tests unitaires.
Le code-barres GS1-DataMatrix se présente en général sous la forme d'un seul carré, mais suivant les paramètres du code-barres et son contenu, on peut passer de 1 à 2, voire 4 carrés. L'important est que ce code-barres soit bien lu avec vos lecteurs, aux distances souhaitées (min et max).
Si vous voulez intervenir sur la forme du code-barres, ou sa taille pour ajuster les distances de lecture, intervenez sur la fonction suivante située dans les masques dhsi :
;{}* |
Code Block 5 Masque DHSI
EAN/UPC/EAN8/GTIN14...
Lorsque Divalto imprime une étiquette article, cela ne présente pas de problème particulier. On imprime la valeur contenue dans le champ EAN de Divalto : sous-référence, à défaut article.
En revanche, lors de l'impression (codage) ou de la lecture (décodage) d'un GS1-128, ce code-barres contiendra toujours 14 caractères pour le code article. Cependant, si l'on prend le cas d'un UPC, il fait 12 caractères, et non 13 caractères.
La logique suivante a été retenue. Le GTIN14 est tout d'abord recherché dans le champ dédié sur les colis types. A défaut, on soustrait tous les « 0 » situés au début pour en trouver le code-barres article à chercher dans Divalto.
Exemple de décodage GTIN :
EAN
01234567890128 => recherche GTIN à défaut 1234567890128
21234567890122 => recherche GTIN à défaut 1234567890128 => Ici, on ne finit pas par un « 2 ». La clé de contrôle change puisqu'on n'a plus le « 2 » du préfixe GTIN-14.
UPC
00123456789012 => recherche GTIN à défaut 123456789012
20123456789016 => recherche GTIN à défaut 123456789012 => Ici, on ne finit pas par un « 6 ». La clé de contrôle change puisqu'on n'a plus le « 2 » du préfixe GTIN-14.
Divalto recalcule donc parfois la clé de contrôle pour trouver la valeur correcte dans Divalto.
Remarque : les modules WMPMBARCOD et WMTMBARCOD gèrent ces notions.
Exemple d'utilisation du premier caractère du GTIN 14 (devant le code article EAN) :
Fichiers joints :
Fichier |
Modifié(e) |
Fichier PNGimage2018-7-6_10-10-27.png |
06 juil., 2018byCédric Duhil |
Fichier PNGimage2018-7-6_10-11-26.png |
06 juil., 2018byCédric Duhil |
Fichier PNGimage2018-7-6_10-17-2.png |
06 juil., 2018byCédric Duhil |
Fichier PNGimage2018-7-6_12-12-1.png |
06 juil., 2018byCédric Duhil |
Fichier PNGimage2018-7-6_12-50-12.png |
06 juil., 2018byCédric Duhil |
Fichier PNGimage2018-6-7_14-13-16.png |
29 août, 2018byCédric Duhil |
Fichier PNGimage2018-10-11_15-48-37.png |
11 oct., 2018byCédric Duhil |
Fichier PNGimage2018-11-12_8-48-48.png |
12 nov., 2018byCédric Duhil |
Fichier PNGimage2018-12-10_8-47-38.png |
10 déc., 2018byCédric Duhil |
Fichier PNGimage2018-12-10_8-59-55.png |
10 déc., 2018byCédric Duhil |
Fichier PDFWMS Documentation-v14-20190607_160613.pdf |
07 juin, 2019byCédric Duhil |
GS1 Company Prefix
Le préfixe GS1 est attribué par l'organisation GS1. La licence permettant d'obtenir un préfixe est payante. Le préfixe identifie de manière unique la société.
Extract from GS1.org :
Company prefixes are based on the GS1 prefixes below. Note that since GS1 member companies can manufacture products anywhere in the world, GS1 prefixes do not identify the country of origin for a given product.
Prefix |
Description |
00000 |
Unused to avoid collision with GTIN-8 |
00001 – 00009 |
GS1 US |
020 - 029 |
Used to issue restricted circulation numbers within a geographic region (MO defined) |
030 - 039 |
GS1 US |
040 - 049 |
Used to issue GS1 restricted circulation numbers within a company |
050 - 059 |
GS1 US reserved for future use |
060 - 139 |
GS1 US |
200 - 299 |
Used to issue GS1 restricted circulation number within a geographic region (MO defined) |
300 - 379 |
GS1 France |
380 |
GS1 Bulgaria |
383 |
GS1 Slovenija |
385 |
GS1 Croatia |
387 |
GS1 BIH (Bosnia-Herzegovina) |
389 |
GS1 Montenegro |
400 - 440 |
GS1 Germany |
450 - 459 & 490 - 499 |
GS1 Japan |
460 - 469 |
GS1 Russia |
470 |
GS1 Kyrgyzstan |
471 |
GS1 Chinese Taipei |
474 |
GS1 Estonia |
475 |
GS1 Latvia |
476 |
GS1 Azerbaijan |
477 |
GS1 Lithuania |
478 |
GS1 Uzbekistan |
479 |
GS1 Sri Lanka |
480 |
GS1 Philippines |
481 |
GS1 Belarus |
482 |
GS1 Ukraine |
483 |
GS1 Turkmenistan |
484 |
GS1 Moldova |
485 |
GS1 Armenia |
486 |
GS1 Georgia |
487 |
GS1 Kazakstan |
488 |
GS1 Tajikistan |
489 |
GS1 Hong Kong, China |
500 - 509 |
GS1 UK |
520 - 521 |
GS1 Association Greece |
528 |
GS1 Lebanon |
529 |
GS1 Cyprus |
530 |
GS1 Albania |
531 |
GS1 Macedonia |
535 |
GS1 Malta |
539 |
GS1 Ireland |
540 - 549 |
GS1 Belgium & Luxembourg |
560 |
GS1 Portugal |
569 |
GS1 Iceland |
570 - 579 |
GS1 Denmark |
590 |
GS1 Poland |
594 |
GS1 Romania |
599 |
GS1 Hungary |
600 - 601 |
GS1 South Africa |
603 |
GS1 Ghana |
604 |
GS1 Senegal |
608 |
GS1 Bahrain |
609 |
GS1 Mauritius |
611 |
GS1 Morocco |
613 |
GS1 Algeria |
615 |
GS1 Nigeria |
616 |
GS1 Kenya |
618 |
GS1 Ivory Coast |
619 |
GS1 Tunisia |
620 |
GS1 Tanzania |
621 |
GS1 Syria |
622 |
GS1 Egypt |
623 |
GS1 Brunei |
624 |
GS1 Libya |
625 |
GS1 Jordan |
626 |
GS1 Iran |
627 |
GS1 Kuwait |
628 |
GS1 Saudi Arabia |
629 |
GS1 Emirates |
640 - 649 |
GS1 Finland |
690 - 699 |
GS1 China |
700 - 709 |
GS1 Norway |
729 |
GS1 Israel |
730 - 739 |
GS1 Sweden |
740 |
GS1 Guatemala |
741 |
GS1 El Salvador |
742 |
GS1 Honduras |
743 |
GS1 Nicaragua |
744 |
GS1 Costa Rica |
745 |
GS1 Panama |
746 |
GS1 Republica Dominicana |
750 |
GS1 Mexico |
754 - 755 |
GS1 Canada |
759 |
GS1 Venezuela |
760 - 769 |
GS1 Schweiz, Suisse, Svizzera |
770 - 771 |
GS1 Colombia |
773 |
GS1 Uruguay |
775 |
GS1 Peru |
777 |
GS1 Bolivia |
778 - 779 |
GS1 Argentina |
780 |
GS1 Chile |
784 |
GS1 Paraguay |
786 |
GS1 Ecuador |
789 - 790 |
GS1 Brasil |
800 - 839 |
GS1 Italy |
840 - 849 |
GS1 Spain |
850 |
GS1 Cuba |
858 |
GS1 Slovakia |
859 |
GS1 Czech |
860 |
GS1 Serbia |
865 |
GS1 Mongolia |
867 |
GS1 North Korea |
868 - 869 |
GS1 Turkey |
870 - 879 |
GS1 Netherlands |
880 |
GS1 South Korea |
884 |
GS1 Cambodia |
885 |
GS1 Thailand |
888 |
GS1 Singapore |
890 |
GS1 India |
893 |
GS1 Vietnam |
896 |
GS1 Pakistan |
899 |
GS1 Indonesia |
900 - 919 |
GS1 Austria |
930 - 939 |
GS1 Australia |
940 - 949 |
GS1 New Zealand |
950 |
GS1 Global Office |
951 |
Global Office - General Manager Number, see Note 2 |
955 |
GS1 Malaysia |
958 |
GS1 Macau, China |
960-969 |
Global Office - GTIN-8, see note 3 |
977 |
Serial publications (ISSN) |
978 - 979 |
Bookland (ISBN) |
980 |
Refund receipts |
981 - 984 |
GS1 coupon identification for common currency areas |
99 |
GS1 coupon identification |
Surcharges des créations de pièces de stock
Le WMS génère une pièce Achat-Vente lorsque la manipulation effectuée doit impacter le stock Achat-Vente.
Un changement de position n'entraîne pas la création de pièce Achat-Vente par exemple.
Cas |
Programme concerné |
Réception (fournisseur, client, interne) |
wmttrf020.dhsp |
Régularisation de stock |
La régularisation passe par un GTFI. Il est plus prudent de surcharger directement l'intégrateur de pièce (gttt150), |
Changement de nature de stock |
wmpprf057 et wmpprf051 |
Génération et validation d'inventaire |
wmpp600 et wmpp625 |
Validation des préparations en BL |
wmpp642 |
Saisie d'un masque sous Telnet
Présentation
Le module APM_TNT_SAISIE_PAGE.DHOP contient les routines nécessaires à une saisie Telnet.
Un masque .dhsi sera interprété pour faire le masque écran.
Programme
Les routines à utiliser sont basées sur les prototypes que la partie xwpf. Vous pouvez donc vous référer à la documentation existante. Ces routines sont simplement suffixées de TNT_.
;Chargement des pages |
Code Block 6 Exemple de boucle de saisie sous Telnet
A l'exception du _BUF qui n'existe pas côté Xwpf, l'algorithme de saisie est le même :
Masque
Il n'est pas nécessaire de compiler un masque Telnet ; il est interprété en mode texte par le module pour l'exécution sous Telnet.
On utilise dans le SDK XWIN l'outil de création d'un masque d'impression caractère, qui est détourné pour cette exécution. Son extension est donc dhsi. On nommera par convention le masque xxeerfxxx.dhsi. « ee » permet de rappeler qu'il s'agit bien d'un masque écran.
Les attributs des champs et labels posés dans le masque sont détournés :
Attribut DHSI |
Fonction dans le Telnet |
Gras = Oui |
Affichage en gras |
Italique = Oui |
Champ en saisie (que l'on met habituellement en gras en standard) |
Souligné = Oui |
Affichage en souligné |
Commentaire |
Cf. chapitre dédié |
Nom sélection |
ISO |
Position / Taille / Cadrage |
ISO |
Les fonctions suivantes sont utilisables avec le paramètre Nom sélection :
- TNT_GetVisible et TNT_SetVisible, TNT_Afficher et TNT_Cacher
- TNT_GetAlignement et TNT_SetAlignement
- TNT_GetGras et TNT_SetGras
- TNT_GetHauteur, TNT_SetHauteur, TNT_GetLargeur, TNT_SetLargeur
- TNT_GetVideoInverse et TNT_SetVideoInverse
- TNT_GetSurligne et TNT_SetSurligne
- TNT_GetOrdreSaisi et TNT_SetOrdreSaisi
- TNT_GetSaisissable et TNT_SetSaisissable
- TNT_GetObligatoire et TNT_SetObligatoire
- TNT_GetTexteAide et TNT_SetTexteAide
- TNT_getPositionCol et TNT_SetPositionCol
- TNT_GetPositionLig et TNT_SetPositionLig
- TNT_GetSaisissable et TNT_SetSaisissable
Attribut Commentaire
Gestion des attributs d'un champ en saisie
Exemple de l'attribut Commentaire :
Nom de la balise au format HMP |
Fonction |
ORDRESAISI |
Ordre de saisie dans la page (si Italique = Oui (saisie)) |
SEQAV |
Traitement avant l'entrée dans le champ |
SEQAP |
Traitement exécuté en sortie du champ si champ saisissable |
SEQBUF |
Traitement exécuté avant l'affectation de la valeur dans le champ |
;* |
Code Block 7 xxx_BUF
L'algorithme de saisie du Telnet poursuit alors selon l'ordre défini, comme s'il n'était pas passé par là.|
PAAV |
Point d'arrêt exécuté en entrée dans le champ |
PAAP |
Point d'arrêt exécuté en sortie dans le champ |
CONVERSION |
1 = Aucune conversion |
POINTSEQ |
|
VIDEOINVERSE |
|
TRADUIRE |
|
OBLIG |
Champ obligatoire. Valeur 1 ; sinon, 0. |
TEXTEAIDE |
Texte affiché en légende en bas de l'écran lorsque la saisie est en cours dans ce champ |
TOUCHEFCT |
Bouton affiché dynamiquement en fonction du champ en cours de saisie. Cf. ci-dessous pour plus de détails sur la syntaxe à respecter. |
Paramètre de la balise <TOUCHEFCT>.
Seuls ceux de type « K_Fx » sont visibles en saisie, et uniquement les n premiers (n dépend du paramètre <nbtouchefctaff> du fichier dhstelnet.txt ; sa valeur est fixée à 5 en général).
La touche système F6 (paramétrable dans le fichier dhstelnet.txt) permet d'afficher les autres.
L'ordre affiché correspond à l'ordre figurant dans la balise du champ.
Ordre |
Paramètres |
Exemple si touche |
Exemple si point d'arrêt |
Exemple si traitement |
1 |
Touche sur le format K_F1 à K_F8, K-ESCAPE ou K_RETURN (K_F6 est réservé pour le piano, cf. ci-dessous) |
K_F1 |
PA |
TRT |
2 |
Si touche, texte de correspondance affiché |
F1 |
N/A |
N/A |
3 |
Libellé en clair et complet |
Imprimer |
Valider |
Valider |
4 |
Valeur renvoyée au programme sous forme de point d'arrêt |
10 |
10 |
Outils_Bouton_Clic |
5 |
Permet de sortir de l'input, même s'il reste un champ obligatoire non renseigné. |
0 |
0 |
0 |
Création d'un masque d'édition d'étiquettes
Peu importent les valeurs, les paramètres du masque doivent simplement respecter le ratio largeur x hauteur de l'étiquette.
Exemple : 20 x 60 vaut 10 x 30.
Le rendu de l'édition sera le même.
Il s'agit de trouver les valeurs adéquates afin de respecter les feuilles de style standard et d'obtenir une visualisation qui soit satisfaisante dans XWIN, quitte à modifier les paramètres WYSIWYG.
L'orientation portrait/paysage n'est à définir que dans les paramètres du masque du fichier source DHSI (le pilote s'adapte, car xdivaltoviewer envoie les paramètres à l'imprimante).
Commande A propos sous Windows et Telnet
Sous Windows
Le menu Aide / A propos permet d'afficher les modules chargés et leur version.
=>
Sous Telnet
La touche réservée F12 permet d'afficher les modules chargés et leur version.
Logique standard Divalto WMS de paramétrage des numéros d'état
|
Orientation |
|
Taille |
Portrait |
Paysage |
A6 |
1 |
2 |
A5 |
3 |
4 |
A4 |
7 |
8 |
6"*8" |
5 |
6 |
Les listes livrées en A4 ont toutes le numéro d'état « 1 ».
Ajout de programme, zoom, fonction et gestion des confidentialités
Lors de l'ajout :
- d'un nouveau programme standard WMS,
- d'un zoom standard WMS,
- d'une fonction où une gestion de confidentialité est nécessaire,
pensez à ajouter une nouvelle confidentialité à la table MCONF, ainsi qu'au détail MCONFDET du groupe MCONFGRP Administrateur WMS « WM** ».
Vous pouvez partir du script SQL A5_MCONF_19_04.sql pour ajouter le nouveau choix.
Remarque : vous devrez passer en revue les utilisateurs concernés dans l'administration des utilisateurs pour prendre en compte cette nouvelle confidentialité.
Pour le choix de la confidentialité :
- soit vous ajoutez une nouvelle fonction qui concerne le même thème qu'une fonction existante, auquel cas vous pouvez utiliser une confidentialité existante,
- soit vous préférez créer une nouvelle confidentialité, auquel cas vous devez vous interroger sur l'emplacement le plus judicieux pour cette confidentialité :
- Menu : bloquera l'appel au menu (en cas d'appel d'un programme wmpp)
- Zoom : en modification/création...
- Dossier WMS, car opérations transversales. Dans ce cas, il vous faut bloquer l'opération par code diva :
- griser un bouton (en RF ou non)
- inactiver le menu. Ce cas existe surtout pour une gestion fine des régularisations, et uniquement en RF. Il s'agit ici de créer une fonction Tnt_Tester_Conf_Prg dans le code Diva du programme RF qui renverra True ou False suivant l'attendu.Le comportement fonctionnel est alors le même que si la confidentialité avait été placée directement sur le menu.
- En champ_av
- ...
Exemples de surcharge WMS
Conserver les réservations WMS en suppression de préparation par les modules d'administration
Concerne les modules d'administration des préparations et des ordres de préparation (wmpp631/wmtt631 et wmpp632/wmtt632).
Vous souhaitez dans un certain contexte ne pas supprimer les réservations WMS, et donc aussi ERP, lorsque l'utilisateur supprime une préparation (ou un ordre de préparation).
Il existe une procédure Suppression_Reservation_DAV dans wmpp631 que l'on peut appeler dans wmut631.
Valeurs de retour : choix de suppression des réservations DAV 1/2/3 - JAMAIS/TOUJOURS/DEMANDER
Elle conditionne le comportement du PP lors de la suppression initiée par l'utilisateur.
Il s'agit :
- d'inhiber la question à l'utilisateur lorsqu'il veut supprimer une préparation
- et de forcer la non-suppression des réservations ERP dans un premier temps :
Vous pouvez ainsi surcharger
DefProcDelete_PrepEnt_Av (wm631t1 est en ligne)
Suppression_Reservation_DAV(1)
Freturn(standard.DefProcDelete_PrepEnt_Av)
Puis remettre le comportement standard (cf. init dans prog_init)
DefProcDelete_PrepEnt_Ap
Suppression_Reservation_DAV(ancienne_valeur)
L'utilisateur peut aussi supprimer une seule ligne dans une préparation. Nous vous invitons donc à faire de même ici (wm613T1 et T2 sont alors en ligne).
DefProcDelete_PrepDet_Av
Suppression_Reservation_DAV(1)
Puis remettre le comportement standard (cf. init dans prog_init)
DefProcDelete_PrepDet_Ap
Suppression_Reservation_DAV(ancienne_valeur)
Il faut ensuite inhiber la suppression de la réservation WMS. Une seule méthode est appelée en suppression d'un WM631T1 complet, mais aussi en suppression unitaire de Wm631T2
ligne par ligne dans les deux cas. Il suffit ici de renvoyer N pour votre contexte.
;*
Public Function char Supprimer_PrepDet_ReservationsWms
;si N, les réservations WMS ne seront pas supprimées
;Possible uniquement si les réservations ERP sont conservées (cf. appel de Suppression_Reservation_DAV pour forcer une valeur)
;appelé dans ce cas pour chaque prepdet WM631T2.PrepDet
Beginf
Freturn('O')
Endf