Mercator 11.0 peut exécuter des tâches en mode console. Ces tâches peuvent être déclenchées par le planificateur de tâches de Windows (tasks scheduler) par exemple. Cette exécution de Mercator se produit sans aucune interface. Un système de logging est disponible. Les logs sont placés dans le sous-répertoire LogFiles de Mercator. Ce répertoire est créé automatiquement.
Ce mode d'utilisation de Mercator requiert l'installation d'un certificat SSL qui va permettre de crypter les mots de passe évoqués ci-dessous.
Pour démarrer Mercator en mode console, il faut passer à Mercator.exe un paramètre/argument (toujours le premier) qui lui indique où trouver un fichier ini contenant les paramètres de la tâche.
C:\Mercator\Mercator.exe C:\Mercator\MercatorTasks.ini
Un exemple de fichier ini est disponible dans le zip ci-dessous. Ce fichier ini contient les paramètres suivants :
- IdDossier : vide ou id du dossier d'une configuration multi-dossiers.
- UserLogin : le nom d'un utilisateur de Mercator qui sera utilisé pour instancier Mercator.
- Password : son mot de passe. Celui-ci sera automatiquement crypté lors de la première exécution de la tâche.
- InitReporting : 1 si le générateur de rapports va être utilisé dans la tâche (par exemple pour générer des fichiers PDF), sinon 0.
- SendLog : envoi des logs par mail, en fin de tâche, à un ou plusieurs administrateurs
- 0 : jamais
- 1 : toujours
- 2 : uniquement en cas d'erreurs
Ce mode d'exécution de Mercator "consomme" une licence utilisateur durant toute la durée de la tâche qu'il réalise. Si aucune licence n'est disponible, un message d'erreur sera produit puisque Mercator ne pourra pas s'instancier.
Paramétrage de l'envoi des mails
Si l'envoi des logs par mail est utilisé, il faut compléter les paramètres de connexion au serveur de mails. Pour un serveur de mail classique :
- SmtpHost : nom du serveur de mails.
- StmpPort : port TCP à utiliser.
- SmtpSsl : 1 si SSL doit être activé, 0 sinon.
- SmtpLogin : login si connexion authentifiée, vide sinon.
- SmtpPassword : mot de passe pour une connexion authentifiée. Celui-ci sera automatiquement crypté lors de la première exécution de la tâche.
- SmtpSenderMail : adresse mail de l'expéditeur.
- SmtpSenderName : nom de l'expéditeur.
Pour l'envoi via Office365 - Api Graph, il est nécessaire de placer les paramètres ClientId, ClientSecret, Tenant et UserId dans la table SQL free_table_secrets, tel qu'expliqué sur cette page. Le fichier ini doit être complété comme suit :
- SmtpOffice365Graph : 1
- SmtpSenderMail : adresse mail de l'expéditeur
- SmtpSenderName : nom de l'expéditeur
Ensuite, dans les deux cas :
- SmtpRecipients : adresses mails de destination, séparées par ;
- SmtpCc : adresses mails en CC séparées par ;
Il est possible de tester l'envoi de mails, sans exécution de la tâche, en passant testmail comme second paramètre/argument à Mercator.exe.
C:\Mercator\Mercator.exe C:\Mercator\MercatorTasks.ini testmail
Paramétrage des tâches
Mercator en mode console peut exécuter un nombre illimité de tâches. Chaque tâche doit correspondre à une méthode publique sans paramètre, placée dans le customizer Main. Chaque nom de méthode doit être renseigné dans le fichier ini, sur une ligne
La numérotation des tâches doit commencer à 1, être croissante et ininterrompue.
Par exemple, si le fichier ini contient
Task1 = MethodForMercatorTasks1
Task2 = MethodForMercatorTasks2
Le customizer Main se présentera sous cette forme :
namespace Main
{
public class Customizer
{
public void MethodForMercatorTasks1()
{
// tâche 1
}
public void MethodForMercatorTasks2()
{
// tâche 2
}
}
}
Comme pour un customizer classique, il est possible de référencer un DLL externe pour en utiliser les fonctionnalités.
Le code C# de ces méthodes peut utiliser MercatorUi.Globals.MercatorTasksToMain pour :
1. Lire une option (existante ou personnalisée) dans le fichier ini
string myValue = MercatorUi.Globals.MercatorTasksToMain.IniFile.IniReadValue("MercatorTasks", "MyOption");
2. Ecrire dans le log
MercatorUi.Globals.MercatorTasksToMain.Log("Ecrire dans le log !");
Note importante : si le mode d'envoi de log utilisé est 2 (uniquement en cas d'erreurs), il est important de distinguer les logs d'erreurs des simples logs de suivi de l'activité. Par défaut, toute inscription dans le log est considérée comme n'étant pas une erreur. Si on souhaite que ce ne soit pas le cas, il faut passer à la méthode Log le paramètre supplémentaire isError: true.
3. Envoyer un mail selon les paramètres définis dans le fichier ini
IneoSmtp.Smtp mail = MercatorUi.Globals.MercatorTasksToMain.GetNewStmp();
mail.Subject = "Mon sujet";
mail.Message = "Mon message";
if (!mail.SendMail())
MercatorUi.Globals.MercatorTasksToMain.Log("Erreur envoi mail : " + mail.Error, isError: true);
else
MercatorUi.Globals.MercatorTasksToMain.Log("Mail correctement envoyé à " + mail.Recipient);
4. Placer un message en amont du log, qui sera repris dans le mail
MercatorUi.Globals.MercatorTasksToMain.CurrentLog.Insert(0, "Veuillez consulter ci-dessous le log de la tâche Mercator qui vient d'être exécutée en mode console.\r\n\r\n");
5. Exécuter du code quand toutes les tâches sont terminées
MercatorUi.Globals.MercatorTasksToMain.AllTasksFinished += (s, e) =>
{
if (MercatorUi.Globals.MercatorTasksToMain.CurrentLogContainsErrors)
MercatorUi.Globals.MercatorTasksToMain.CurrentLog.Append("\r\n\r\nATTENTION : ce log contient des erreurs !");
};
Notes importantes concernant la planification
Une tâche créée dans le planificateur de tâches de Windows doit tourner sous les crédentiales d'un utilisateur ayant la possibilité d'utiliser Mercator en mode "normal" (non console) sans erreurs ni restrictions.
Le certificat SSL doit avoir été installé dans le magasin de certificats de cet utilisateur.
Il est possible de créer différentes tâches utilisant, par exemple des fichiers ini différents, ou un même fichier ini.
Si plusieurs tâches sont créées, il est important qu'elles ne démarrent pas systématiquement au même moment.
Quand plusieurs actions doivent être effectuées, il est recommandé de les regrouper dans un même fichier ini (Task1, Task2, ...) plutôt que de créer des fichiers ini séparés et de lancer ces tâches successivement. En effet, le mode recommandé permet que la même instanciation de Mercator soit utilisée pour ces différentes tâches.
Exemple de tâche : centralisation en comptabilité des documents du jour
public void PostIntoAccounting()
{
MercatorUi.Forms.Accounting.AccountingProcedures.Procedures.PostIntoAccountingParams p = new MercatorUi.Forms.Accounting.AccountingProcedures.Procedures.PostIntoAccountingParams(
DateTime.Today, // date1
DateTime.Today, // date2
new string[3] { "VEN", "NCV", "FactF" }, // journaux à centraliser
true, // postPayments
true, // performMatching
"001" // dossier si multi
);
MercatorUi.Forms.Accounting.AccountingProcedures.Procedures.PostIntoAccounting(p, true);
if (!string.IsNullOrEmpty(p.LastError))
MercatorUi.Globals.MercatorTasksToMain.Log(p.LastError);
MercatorUi.Globals.MercatorTasksToMain.Log("VENTES & ACHATS");
MercatorUi.Globals.MercatorTasksToMain.Log(p.ResultPostSalesPurchases);
if (p.LogErrorsPostSalesPurchases != null)
MercatorUi.Globals.MercatorTasksToMain.Log(p.LogErrorsPostSalesPurchases.ToString(), isError: true);
MercatorUi.Globals.MercatorTasksToMain.Log("PAIEMENTS");
MercatorUi.Globals.MercatorTasksToMain.Log(p.ResultPostPayments);
if (p.LogErrorsPostPayments != null)
MercatorUi.Globals.MercatorTasksToMain.Log(p.LogErrorsPostPayments.ToString(), isError: true);
MercatorUi.Globals.MercatorTasksToMain.Log("LETTRAGE");
MercatorUi.Globals.MercatorTasksToMain.Log(p.ResultMatching, isError: p.ResultMatching != Api.Iif_langue(Globals.Langue, 47));
}
Dans le fichier ini :
Task1 = PostIntoAccounting
Exemple de tâche : facturation automatique des livraisons du jour
public void DeliveriesInvoicing()
{
doDeliveriesInvoicing("1Bliv", "1Fact");
doDeliveriesInvoicing("2Bliv", "2Fact");
doDeliveriesInvoicing("3Bliv", "3Fact");
}
private void doDeliveriesInvoicing(string seqLivr, string seqFactu)
{
MercatorUi.Globals.MercatorTasksToMain.Log($"Facturation des {seqLivr} vers {seqFactu}");
DataSet dsSequenc = Api.Zselect(Globals.RepData, "select * from SEQUENC where journal = @seqLivr \r\n"
+ "select * from SEQUENC where journal = @seqFactu",
new MercatorSqlParam("@seqLivr", seqLivr, SqlDbType.Char),
new MercatorSqlParam("@seqFactu", seqFactu, SqlDbType.Char));
if (dsSequenc == null)
{
MercatorUi.Globals.MercatorTasksToMain.Log("Sequenc select : " + Api.LastError, isError: true);
return;
}
if (dsSequenc.Tables[0].Rows.Count == 0)
{
MercatorUi.Globals.MercatorTasksToMain.Log($"La séquence {seqLivr} n'existe pas !", isError: true);
return;
}
if (dsSequenc.Tables[1].Rows.Count == 0)
{
MercatorUi.Globals.MercatorTasksToMain.Log($"La séquence {seqFactu} n'existe pas !", isError: true);
return;
}
MercatorUi.Forms.Gescom.GescomDialogs.GescomAskDeliveriesInvoicing.GescomAskDeliveriesInvoicingRet askRet =
new MercatorUi.Forms.Gescom.GescomDialogs.GescomAskDeliveriesInvoicing.GescomAskDeliveriesInvoicingRet(
dsSequenc.Tables[0].Rows[0], // sequencOrig
dsSequenc.Tables[1].Rows[0], // sequencDest
($"(pieds_v.date = '{DateTime.Today.ToString("yyyyMMdd")}')"), // whereClause
false, // groupLines
false, // groupCustNoVat
false, // invoiceAccount
false, // withQZero
false, // dateAllLines
false, // noComment
-99999); // minimum
Api.LastError = "";
int generatedInvoicesCount = MercatorUi.Forms.Gescom.GescomProcedures.Procedures.DeliveriesInvoicing(MercatorUi.Engine.Gescom.Billing.TypeVAEnum.V, askRet, true);
if (string.IsNullOrEmpty(Api.LastError))
MercatorUi.Globals.MercatorTasksToMain.Log($"Document(s) {seqFactu} généré(s) : {generatedInvoicesCount}.");
else
MercatorUi.Globals.MercatorTasksToMain.Log($"Document(s) {seqFactu} généré(s) : {generatedInvoicesCount}.\r\n" + Api.LastError, isError: true);
}
Dans le fichier ini :
Task1 = DeliveriesInvoicing
Exemple de tâche : envoi d'un reporting PDF par mail (Palmarès des clients pour le mois en cours)
public void SendPdfReport()
{
List<MercatorSqlParam> lp = new List<MercatorSqlParam>
{
new MercatorSqlParam("@DATE_1", new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1)),
new MercatorSqlParam("@DATE_2", DateTime.Today)
};
MercatorUi.Reporting.OutputDescriptorExport outputDescriptorExport = new MercatorUi.Reporting.OutputDescriptorExport(MercatorUi.Reporting.ExportReportEnum.PDF, null, MercatorUi.Reporting.ExportOpenAfterEnum.No) { ExportToBytes = true };
Api.LastError = "";
MercatorUi.Reporting.ReportingStatic.RunReportFromDocum("H2ZP118RW1", new List<MercatorUi.Reporting.OutputDescriptor> { outputDescriptorExport }, lp);
if (outputDescriptorExport.FileContent == null)
{
MercatorUi.Globals.MercatorTasksToMain.Log("Génération PDF : " + (!string.IsNullOrEmpty(Api.LastError) ? Api.LastError : "erreur inconnue"), isError: true);
}
else
{
IneoSmtp.Smtp mail = MercatorUi.Globals.MercatorTasksToMain.GetNewStmp();
mail.Subject = "Palmarès des clients";
mail.Message = "Ci-joint le palmarès de clients.";
mail.BytesAttachments = new Dictionary<string, byte[]> { { "Palmarès des clients.pdf", outputDescriptorExport.FileContent } };
if (!mail.SendMail())
MercatorUi.Globals.MercatorTasksToMain.Log("Erreur envoi mail : " + mail.Error, isError: true);
else
MercatorUi.Globals.MercatorTasksToMain.Log("Mail correctement envoyé à " + mail.Recipient);
}
}
Dans le fichier ini :
Task1 = SendPdfReport
A télécharger :
0000003239.zip (0 Kb - 05/08/2024)