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

Exécuter des tâches dans Mercator en mode console

0000003239     -      07/08/2024

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 

  • Task1
  • Task2
  • ...

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 :

Zoom
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

Zoom
string myValue = MercatorUi.Globals.MercatorTasksToMain.IniFile.IniReadValue("MercatorTasks", "MyOption");

2. Ecrire dans le log

Zoom
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

Zoom
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

Zoom
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

Zoom
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)

 

Zoom
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)