Il est possible d'exécuter du code sur mesure dans l'instance de Mercator via MercatorPenguinServer depuis une CustomPage. Cela se fait par l'intermédiaire d'une assembly contenant une programmation personnalisée. Comme pour les CustomPages, il s'agit donc à nouveau d'une programmation 100% sur mesure, effectuée dans un projet autonome en Visual Studio.
1. Préparation du projet
Le code devra être placé dans une bibliothèque de classes (class library), mais orientée vers la plateforme Windows. En effet, l'instance de Mercator ERP qui fonctionne dans MercatorPenguinServer est une application destinée à cet environnement. (Le développement effectué ici n'est donc plus directement lié à MAUI).
Par convention, ce nouveau projet
- sera ajouté à la solution contenant la CustomPage correspondante,
- portera le même nom, suivi de Server.
Dans le projet, on trouvera ceci :
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
Ce projet doit référencer au minimum MercatorTunnel.dll et MercatorUi.dll du Mercator lié via MercatorPenguinServer. (Donc, les versions Windows de ces assemblies, pas les versions Android ou iOS).
<ItemGroup>
<Reference Include="MercatorTunnel">
<HintPath>C:\...\MercatorTunnel.dll</HintPath>
</Reference>
<Reference Include="MercatorUi">
<HintPath>C:\...\MercatorUi.dll</HintPath>
</Reference>
</ItemGroup>
2. Création du code custom
La bibliothèque de classes doit contenir une classe publique contenant une méthode publique acceptant un paramètre uniquement de type string et retournant un résultat string. Le nom de cette méthode est libre.
Le type string a été choisi pour la communication avec la CustomPage de MercatorPenguin parce qu'il peut transporter une chaîne de caractères correspondant à la représentation json d'un objet.
Il est important de considérer que le code en question va fonctionner au sein de l'instance de Mercator hébergée dans MercatorPenguinServer. En conséquence, tous les outils habituellement utilisés dans les développements sont disponibles : connexion au serveur SQL, accès aux propriétés statiques de MercatorUi.Globals, ... Le style de programmation est donc tout à fait semblable à celui qui prévaut pour l'écriture de customizers exécutés directement dans Mercator.
3. Mise à disposition de l'assembly pour MercatorPenguinServer
La compilation du projet évoqué ci-dessus va produire une DLL. Par convention, celle-ci sera placée dans les fichiers SQL > Autres, dans un sous-répertoire Server du répertoire correspondant à la CustomPage. (Cette DLL n'est pas à placer dans les fichiers SQL > Assemblies, car il ne s'agit pas d'une assembly qui doit être distribuée dans le répertoire principal de Mercator ERP).

4. Appel de la méthode évoquée au point 2 depuis la CustomPage
Nous illustrons ce point avec deux classes qui sont utilisées, respectivement pour le paramètre envoyé et le résultat obtenu. Ces classes sont personnalisées selon les besoins fonctionnels de la méthode appelée.
public class DoInMercatorInstanceRequest
{
public Int16 Type { get; set; }
public string Id { get; set; }
public string Journal { get; set; }
public Int64 Piece { get; set; }
}
public class DoInMercatorInstanceResponse
{
public string Result { get; set; }
public string Error { get; set; }
}
Le code de la CustomPage qui communique avec la méthode custom dans MercatorPenguinServer correspond à la ligne en surbrillance :
private bool isDoInMercatorInstanceBusy = false;
private async void Button_Clicked(object sender, EventArgs e)
{
if (isDoInMercatorInstanceBusy)
return;
Button button = (Button)sender;
HistoDescriptor histoDescriptor = (HistoDescriptor)button.CommandParameter;
button.IsEnabled = false;
isDoInMercatorInstanceBusy = true;
DoInMercatorInstanceRequest doInMercatorInstanceRequest = new DoInMercatorInstanceRequest
{
Type = histoDescriptor.Type,
Id = histoDescriptor.Id,
Journal = histoDescriptor.Journal,
Piece = histoDescriptor.Piece
};
MercatorPenguin.DoInMercatorInstanceDescriptor doInMercatorInstanceDescriptor = new MercatorPenguin.DoInMercatorInstanceDescriptor
{
Assembly = "<Other\\TestPenguinCustomServer\\Server\\TestPenguinCustomServer.dll",
ClassName = "TestPenguinCustomServer.TestClass",
MethodName = "DoubleQuantities",
Parameter = Api.JsonConvertSerializeObject(doInMercatorInstanceRequest)
};
activityIndicator.SetActive(true);
var r = await MercatorPenguin.BaseCustomPage.DoInMercatorInstance(doInMercatorInstanceDescriptor);
activityIndicator.SetActive(false);
if (r.Error != null)
{
_ = MercatorPenguin.Dialogs.Stop(this, r.Error);
}
else
{
DoInMercatorInstanceResponse doInMercatorInstanceResponse = Api.JsonConvertDeserializeObject<DoInMercatorInstanceResponse>(r.Result);
if (doInMercatorInstanceResponse.Error != null)
_ = MercatorPenguin.Dialogs.Stop(this, doInMercatorInstanceResponse.Error);
else
_ = MercatorPenguin.Dialogs.Stop(this, doInMercatorInstanceResponse.Result);
}
button.IsEnabled = true;
isDoInMercatorInstanceBusy = false;
}
On reconnait dans DoInMercatorInstanceDescriptor les paramètres suivants :
- le chemin SQL complet vers l'assembly,
- le nom de complet de la classe, sous la forme espace de nom, suivi d'un point, suivi du nom de la classe,
- le nom de la méthode,
- le paramètre string passé à cette méthode. Il correspond à la représentation json de l'objet doInMercatorInstanceRequest.
Le projet repris dans le zip de cette page reprend l'exemple illustré ci-dessus sous forme compilable.