U bevindt zich nu op een technische pagina over de software Mercator. Deze pagina bevat specifieke informatie die bestemd is voor professionals van de software Mercator. Wenst u naar algemenere informatie over Mercator door te gaan?


   Deze vraag niet meer stellen

Een offerte sturen voor aanvaarding via eSignature (Ok!Sign)

0000003141     -      13-06-2023

De hier geïllustreerde programmering laat zien hoe het verzenden van een offerte naar een klant voor acceptatie via een externe handtekening met behulp van de OkSign-service kan worden geautomatiseerd.

Om het in te stellen, moet je :

  • de aanmaak van PDF-duplicaten in de offerte-sequentie activeren
  • plaats een handtekeningmarkering _Signature_ in het afdruksjabloon (voorbeeldsjabloon beschikbaar in het onderstaande zip-bestand)
  • voeg de kolommen toe aan de PIEDS_V tabel met het onderstaande SQL script
  • de bewerkbare velden toevoegen die overeenkomen met deze kolommen (tabbladbestand beschikbaar in het onderstaande zip-bestand).
alter table PIEDS_V add NOM char(30) not null default ''
alter table PIEDS_V add FONCTION char(20) not null default ''
alter table PIEDS_V add EMAIL char(40) not null default ''
alter table PIEDS_V add NUM_GSM char(20) not null default ''
alter table PIEDS_V add OKSIGN_DOC_ID char(50) not null default ''
alter table PIEDS_V add OKSIGN_SENT datetime not null default '19000101'

 

Het voorgestelde tabblad ziet er als volgt uit:

De handtekening wordt gevraagd in de PDF van dit formulier :

Naar de Billing customizer waarvan de code hieronder is afgebeeld, moet worden verwezen in de sequentie.

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

// <CompileWithRoslyn />

namespace Billing
{
    public class Customizer : MercatorUi.ICustomizers.IBillingEngineCreated, MercatorUi.ICustomizers.IBillingEngineClosed
    {
        public void BillingEngineCreated(MercatorUi.Engine.Gescom.BillingEngine billingEngine)
        {
            billingEngine.TagString = "999999;999999-9FB99999-99CD-9F99-9B99-B9EAE99DDC99;As99ErT999XX999XxxXXxxXx9";
            billingEngine.BeforeSave += BillingEngine_BeforeSave;
            billingEngine.PdfDuplicateCreated += BillingEngine_PdfDuplicateCreated;
        }

        public void BillingEngineClosed(MercatorUi.Engine.Gescom.BillingEngine billingEngine)
        {
            billingEngine.BeforeSave -= BillingEngine_BeforeSave;
            billingEngine.PdfDuplicateCreated -= BillingEngine_PdfDuplicateCreated;
        }

        private void BillingEngine_BeforeSave(object sender, MercatorUi.Engine.Gescom.BillingEngine.BeforeSaveEventArgs e)
        {
            MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
            if (billingEngine.IsNew)
            {
                Dictionary<string, string> dicoNotEmpty = new Dictionary<string, string>
                {
                    { "NOM", _Divers.Iif_langue(Globals.Langue, "Name", "Naam", "Nom") },
                    { "EMAIL", _Divers.Iif_langue(Globals.Langue, "Email", "Email", "Email") },
                    { "FONCTION", _Divers.Iif_langue(Globals.Langue, "Function", "Functie", "Fonction") },
                    { "NUM_GSM", _Divers.Iif_langue(Globals.Langue, "Mobile", "GSM", "GSM") },
                };
                foreach (KeyValuePair<string, string> kvp in dicoNotEmpty)
                {
                    if (string.IsNullOrWhiteSpace(billingEngine.PIEDS[kvp.Key].ToString()))
                    {
                        Dialogs.Stop(string.Format(_Divers.Iif_langue(Globals.Langue,
                            "The \"{0}\" field is mandatory!",
                            "Het veld \"{0}\" is verplicht!",
                            "Le champ \"{0}\" est obligatoire !"), kvp.Value));
                        List<Control> l = billingEngine.BillingForm.FindMovableControlsBySource(kvp.Key);
                        if (l.Any())
                            _Divers.FocusError(l[0]);
                        e.CancelSave = true;
                        return;
                    }
                }

                Regex regex = new Regex(@"^\+?[1-9]\d{1,14}$");
                if (!regex.IsMatch(billingEngine.PiedsVRecord.NUM_GSM))
                {
                    Dialogs.Stop(_Divers.Iif_langue(Globals.Langue,
                        "The mobile phone number must start with + and contain only digits!",
                        "Het GSM nummer moet beginnen met + en mag alleen cijfers bevatten!",
                        "Le numéro de GSM doit commencer par + et ne contenir que des chiffres !"));
                    List<Control> l = billingEngine.BillingForm.FindMovableControlsBySource("NUM_GSM");
                    if (l.Any())
                        _Divers.FocusError(l[0]);
                    e.CancelSave = true;
                    return;
                }
            }
        }


        private void BillingEngine_PdfDuplicateCreated(object sender, MercatorUi.Engine.Gescom.BillingEngine.PdfDuplicateCreatedEventArgs e)
        {
            MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
            if (billingEngine.IsNew)
            {
                MercatorSigning.OkSign.FormDescriptor.FormHelper formHelper1 = new MercatorSigning.OkSign.FormDescriptor.FormHelper
                {
                    FieldMarker = "_Signature_",
                    FieldWidth = 175,
                    FieldHeight = 70,
                    FieldSigningOptions = MercatorSigning.OkSign.FormDescriptor.FormHelper.SigningOptionsEnum.Tan | MercatorSigning.OkSign.FormDescriptor.FormHelper.SigningOptionsEnum.Eid | MercatorSigning.OkSign.FormDescriptor.FormHelper.SigningOptionsEnum.Pen | MercatorSigning.OkSign.FormDescriptor.FormHelper.SigningOptionsEnum.Itsme,
                    SignerInfoName = billingEngine.PiedsVRecord.NOM,
                    SignerInfoMobile = billingEngine.PiedsVRecord.NUM_GSM,
                    SignerInfoActingAs = billingEngine.PiedsVRecord.FONCTION,
                    SignerInfoEmail = billingEngine.PiedsVRecord.EMAIL
                };
                MercatorSigning.OkSign.FormDescriptor formDescriptor = new MercatorSigning.OkSign.FormDescriptor
                {
                    SendToMeEmail = "info@mercator.eu", // niet vereist als het te gebruiken e-mailadres dat van het OkSign-account is.
                    Logo = "https://www.mercator.eu/assets/images/logo.png", // niet vereist als het te gebruiken logo het logo in het OkSign-account is
                    FileName = $"Devis_{billingEngine.Piece}.pdf" // naam van het bestand dat zichtbaar is voor de ondertekenaar. Mag een vrije string bevatten die eindigt op .pdf
                };
                formDescriptor.FormHelpers.Add(formHelper1);

                MercatorUi.Wait.WaitStatic.WaitWindow("OkSign...");

                MercatorSigning.OkSign.OkSignResponse response = MercatorSigning.OkSign.UploadPdfForSignature(e.PdfFile, formDescriptor, billingEngine.TagString, out string error);;
                if (!string.IsNullOrEmpty(error))
                {
                    MercatorUi.Wait.WaitStatic.WaitClear();
                    Dialogs.Stop(error);
                }
                else
                {
                    bool isOk;
                    using (SqlCommand cmd = new SqlCommand("update PIEDS_V set OKSIGN_DOC_ID=@OKSIGN_DOC_ID,OKSIGN_SENT=getdate() where (id=@id) and (journal=@journal) and (piece=@piece)"))
                    {
                        cmd.Parameters.AddWithValue("@id", billingEngine.Id).SqlDbType = SqlDbType.Char;
                        cmd.Parameters.AddWithValue("@journal", billingEngine.Journal).SqlDbType = SqlDbType.Char;
                        cmd.Parameters.AddWithValue("@piece", billingEngine.Piece);
                        cmd.Parameters.AddWithValue("@OKSIGN_DOC_ID", response.DocId);
                        isOk = Api.SqlExec(MercatorUi.Globals.RepData, cmd);
                    }
                    if (!isOk)
                    {
                        MercatorUi.Wait.WaitStatic.WaitClear();
                    }
                    else
                    {
                        billingEngine.PIEDS["OKSIGN_DOC_ID"] = response.DocId;
                        billingEngine.PIEDS["OKSIGN_SENT"] = DateTime.Now;

                        string msg = "Beste klant<br><br>"
                                   + "Gebruik onderstaande link als u onze offerte wilt accepteren.<br>"
                                   + string.Format("<a href=\"{0}\">Link</a><br>", response.Result[0].Url)
                                   + response.Result[0].Url // URL van de eerste ondertekenaar. Foreach vereist indien meerdere ondertekenaars om een verschillende e-mail naar elke ondertekenaar te sturen.
                                   + "<br><br>"
                                   + "Wij danken u hiervoor.<br><br>"
                                   + "Sales Team";

                        Smtp mail = new Smtp
                        {
                            MailServer = Globals.Params["SMTP_HOST"],
                            Recipient = billingEngine.PiedsVRecord.EMAIL,
                            SenderEmail = Globals.CurrentUserRecord.CRM_MAIL,
                            SenderName = Globals.CurrentUserRecord.CRM_NOM,
                            Subject = billingEngine.BillingForm.Text,
                            ForceHtml = true,
                            Message = "<html><body>" + msg + "</body></html>"
                        };
                        if (!mail.SendMail())
                        {
                            MercatorUi.Wait.WaitStatic.WaitClear();
                            Dialogs.Stop(mail.Error);
                        }
                        else
                        {
                            MercatorUi.Wait.WaitStatic.WaitClear();
                            Dialogs.Stop("Offerte correct verzonden voor aanvaarding via Ok!Sign !");
                         }
                    }
                }
            }
        }
    }
}

 

De customizer-code moet worden aangepast door de x-oksign-authorization die is verkregen op het Ok!Sign-portaal te plaatsen in billingEngine.TagString. Hierdoor kan deze parameter één keer worden ingesteld en op verschillende punten in de offerte worden gebruikt.

Bij het opslaan van de offerte,

  • De Mercator API wordt gebruikt om te communiceren met de Ok!Sign servers en de te ondertekenen dubbele PDF en het handtekeningformulier door te sturen.
  • indien succesvol, wordt een e-mail gestuurd naar de externe ondertekenaar met een link om het document online te ondertekenen.

De knop "Handtekeningstatus" geeft aan of

  • het document wacht op ondertekening,
  • is gedeeltelijk ondertekend,
  • werd door alle partijen ondertekend.

Wanneer deze 3e status is bereikt, is het mogelijk om het ondertekende document te downloaden via de knop "Getekend document ophalen". Het gedownloade bestand wordt direct in de SqlFileView of FileView van de offerte geplaatst met de naam signed.pdf. Het systeem stelt dan voor om het bestand van het Ok!Sign portaal te verwijderen. Dit wordt aanbevolen om het ruimtegebruik op het portaal te beperken. (Let op: bestanden worden nooit automatisch verwijderd, behalve via dit proces).

 

 

Trefwoorden : OkSign.jpg

Te laden : 0000003141.zip (37 Kb - 20-03-2023)