Parametrering van electronische facturen

0000002718     -      09-10-2023

Voor de parametrering van electronische facturen beschikt de BillingEngine over 3 events:

  • EinvNodeAdding: tijdens het toevoegen van elke node in de XML-structuur. Door de property e.Cancel op true te plaatsen, hebben we de mogelijkheid om een node niet toe te voegen.
  • EinvNodeAdded: wanneer een node toegevoegd wordt aan de XML-tree
  • EinvFileCreating: wanneer de gehele XML-tree klaar is net alvorens het XML-bestand gegenereerd wordt. De property e.FileName laat ons toe om de naam van het bestand dat geproduceerd zal worden te wijzigen.

Zie ook:

Hieronder tonen we enkele voorbeeld-instellingen. Voor elk van deze voorbeelden is de vertrek customizer de volgende. Het volstaat om deze te wijzigen in functie van de inhoud van volgende delegates: délégués BillingEngine_EinvNodeAdding, BillingEngine_EinvNodeAdded et BillingEngine_EinvFileCreating.

Zoom
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Windows.Forms;
using MercatorApi;
using MercatorUi;
using System.Xml;
using MercatorExtensions;

namespace Billing
{
    public class Customizer : MercatorUi.ICustomizers.IBillingEngineCreated, MercatorUi.ICustomizers.IBillingEngineClosed
    {
        public void BillingEngineCreated(MercatorUi.Engine.Gescom.BillingEngine BillingEngine)
        {
            BillingEngine.EinvNodeAdding += BillingEngine_EinvNodeAdding;
            BillingEngine.EinvNodeAdded += BillingEngine_EinvNodeAdded;
            BillingEngine.EinvFileCreating += BillingEngine_EinvFileCreating;
        }

        public void BillingEngineClosed(MercatorUi.Engine.Gescom.BillingEngine BillingEngine)
        {
            BillingEngine.EinvNodeAdding -= BillingEngine_EinvNodeAdding;
            BillingEngine.EinvNodeAdded -= BillingEngine_EinvNodeAdded;
            BillingEngine.EinvFileCreating -= BillingEngine_EinvFileCreating;
        }

        void BillingEngine_EinvNodeAdding(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddingEventArgs e)
        {
        }

        void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
        {
        }

        void BillingEngine_EinvFileCreating(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvFileCreatingEventArgs e)
        {
        }

    }
}

De inhoud van PIEDS_V.NOTE1 niet verzenden

Zoom
void BillingEngine_EinvNodeAdding(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddingEventArgs e)
{
    if (e.Node.Name == "cbc:Note")
        e.Cancel = true;
}

De bankrekening van de afzender wijzigen

Zoom
void billingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if ((e.Node.Name == "cbc:ID") && (e.Node.ParentNode != null) && (e.Node.ParentNode.Name == "cac:PayeeFinancialAccount"))
    {
        e.Node.InnerText = "BE99999999999999";
    }
}

Vervang note1 door note2  (note1 moet niet leeg zijn opdat Mercator de node "cbc:Note" aanmaakt)

Zoom
void BillingEngine_EinvNodeAdding(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddingEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if (e.Node.Name == "cbc:Note")
    {
        if (billingEngine.PIEDS["note2"].ToString().Trim() == string.Empty)
            e.Cancel = true;
        else
            e.Node.InnerText = billingEngine.PIEDS["note2"].ToString().Trim();
    }
}

Voeg de referentie toe van het contract vertrekkende vanuit het veld PIEDS_V.LIBRE1

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if ((e.Node.Name == "cac:OrderReference") && (billingEngine.PIEDS["libre1"].ToString().Trim() != string.Empty))
    {
        XmlNode n = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:ContractDocumentReference");
        billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:ID", billingEngine.PIEDS["libre1"].ToString().Trim());
        billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:DocumentTypeCode", "105", new MercatorUi.Engine.Gescom.Tools.EinvNodeAttribute("listID", "UNCL1001"));
        billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:DocumentType", "Purchase order");
    }
}

105 = aankoopbestelling volgens deze liste


Voeg de referentie van het contract toe vertrekkende vanuit het veld PIEDS_V.LIBRE1, met de begin- en einddatum van het contract (PIEDS_V.DATE_CTRAT_1 en DATE_CTRAT_2)

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if ((e.Node.Name == "cac:OrderReference") && (billingEngine.PIEDS["libre1"].ToString().Trim() != string.Empty))
    {
        XmlNode n1 = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:ContractDocumentReference");
        billingEngine.EinvAddNode(e.eInvoiceEnum, n1, "cbc:ID", billingEngine.PIEDS["libre1"].ToString().Trim());
        billingEngine.EinvAddNode(e.eInvoiceEnum, n1, "cbc:DocumentTypeCode", "105", new MercatorUi.Engine.Gescom.Tools.EinvNodeAttribute("listID", "UNCL1001"));
        billingEngine.EinvAddNode(e.eInvoiceEnum, n1, "cbc:DocumentType", "Purchase order");
        XmlNode n2 = billingEngine.EinvAddNode(e.eInvoiceEnum, n1, "cac:ValidityPeriod");
        billingEngine.EinvAddNode(e.eInvoiceEnum, n2, "cbc:StartDate", Convert.ToDateTime(billingEngine.PIEDS["date_ctrat_1"]));
        billingEngine.EinvAddNode(e.eInvoiceEnum, n2, "cbc:EndDate", Convert.ToDateTime(billingEngine.PIEDS["date_ctrat_2"]));
    }
}

Voeg de periodiciteit van de factuur toe: op basis van PIEDS_V.DATE_1 en DATE_2

Zoom
void BillingEngine_EinvNodeAdding(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if (e.Node.Name == "cac:OrderReference")
    {
        XmlNode n = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:InvoicePeriod");
        billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:StartDate", Convert.ToDateTime(billingEngine.PIEDS["date_1"]));
        billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:EndDate", Convert.ToDateTime(billingEngine.PIEDS["date_2"]));
    }
}

Inclusief alle PDF-bestanden van het tabblad Bestanden. 

Zoom
void BillingEngine_EinvNodeAdding(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddingEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if (e.Node.Name == "cac:AccountingSupplierParty")
    {
        string dirSqlFiles = "<" + Api.SqlFilePathRoots.Files.ToString() + "\\" + billingEngine.Journal + "\\" + billingEngine.Id;
        foreach (string file in Api.GetFiles(dirSqlFiles, "*.pdf"))
        {
            XmlNode n1 = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:AdditionalDocumentReference");
            billingEngine.EinvAddNode(e.eInvoiceEnum, n1, "cbc:ID", Api.JustFName(file));
            billingEngine.EinvAddNode(e.eInvoiceEnum, n1, "cbc:DocumentType", "Appendix");
            XmlNode n2 = billingEngine.EinvAddNode(e.eInvoiceEnum, n1, "cac:Attachment");
            billingEngine.EinvAddNode(e.eInvoiceEnum, n2, "cbc:EmbeddedDocumentBinaryObject", Convert.ToBase64String(Api.SqlFileToBytes(file)), new MercatorUi.Engine.Gescom.Tools.EinvNodeAttribute("mimeCode""application/pdf"), new MercatorUi.Engine.Gescom.Tools.EinvNodeAttribute("filename", Api.JustFName(file)));
        }
    }
}

Voeg een PDF-bestand toe van op de harde schijf

Zoom
void BillingEngine_EinvNodeAdding(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddingEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if (e.Node.Name == "cac:AccountingSupplierParty")
    {
        string file = @"C:\Test.pdf";
        XmlNode n1 = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:AdditionalDocumentReference");
        billingEngine.EinvAddNode(e.eInvoiceEnum, n1, "cbc:ID", Api.JustFName(file));
        billingEngine.EinvAddNode(e.eInvoiceEnum, n1, "cbc:DocumentType", "Appendix");
        XmlNode n2 = billingEngine.EinvAddNode(e.eInvoiceEnum, n1, "cac:Attachment");
billingEngine.EinvAddNode(e.eInvoiceEnum, n2, "cbc:EmbeddedDocumentBinaryObject"Convert.ToBase64String(System.IO.File.ReadAllBytes(file)), new MercatorUi.Engine.Gescom.Tools.EinvNodeAttribute("mimeCode""application/pdf")new MercatorUi.Engine.Gescom.Tools.EinvNodeAttribute("filename", Api.JustFName(file)));
    }
}

Verander de betaalwijze: standaard neemt Mercator code "1 = Instrument not defined" voor de tag "cbc:PaymentMeansCode".
Het voorbeeld hieronder toont hoe je dit kan veranderen. Zie deze lijst.

Zoom
void BillingEngine_EinvNodeAdding(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddingEventArgs e)
{
    if (e.Node.Name == "cbc:PaymentMeansCode")
            e.Node.InnerText = "25"; // Certified cheque
}

Inclusief de contactgegevens van de klant: op basis van PIEDS_V.ID_TACT1: naam, telefoon en email.

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if ((e.Node.Name == "cac:PartyLegalEntity") && (e.Node.ParentNode.ParentNode.Name == "cac:AccountingCustomerParty") && (billingEngine.PIEDS["id_tact1"].ToString() != string.Empty))
    {
        DataSet ds = Api.Zselect(Globals.RepData, "select rtrim(t_nom) as nom,rtrim(t_num_tel) as num_tel,rtrim(t_email) as email from TACT where t_id=@t_id", new MercatorSqlParam("@t_id", billingEngine.PIEDS["id_tact1"], SqlDbType.Char));
        if ((ds != null) && (ds.Tables[0].Rows.Count > 0))
        {
            XmlNode n = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:Contact");
            billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:Name", ds.Tables[0].Rows[0]["nom"].ToString());
            if (ds.Tables[0].Rows[0]["num_tel"].ToString() != string.Empty)
                billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:Telephone", ds.Tables[0].Rows[0]["num_tel"].ToString());
            if (ds.Tables[0].Rows[0]["email"].ToString() != string.Empty)
                billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:ElectronicMail", ds.Tables[0].Rows[0]["email"].ToString());
        }
    }
}

De leverdatum toevoegen: op basis van PIES_V.DATE_LIVR

Zoom
void BillingEngine_EinvNodeAdding(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if ((billingEngine.CLI_LIV != null) && (billingEngine.CLI_LIV["c_id"].ToString() != billingEngine.CLI["c_id"].ToString()))
    {
        // Mercator ajoute le noeud cac:Delivery
        if (e.Node.Name == "cac:DeliveryLocation")
        {
            billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cbc:ActualDeliveryDate", Convert.ToDateTime(billingEngine.PIEDS["date_livr"]));
        }
    }
    else
    {
        // Mercator n'ajoute pas le noeud cac:Delivery
        if (e.Node.Name == "cac:PaymentMeans")
        {
            XmlNode n = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:Delivery");
            billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:ActualDeliveryDate", Convert.ToDateTime(billingEngine.PIEDS["date_livr"]));
        }
    }
}

Inclusief de betaaltermijn in text-formaat: dit op basis van CLI.C_PAIEM

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if (e.Node.Name == "cac:PaymentMeans")
    {
        XmlNode n = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:PaymentTerms");
        billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:Note", MercatorController.xFunctions.xDelai(billingEngine.CLI["c_paiem"].ToString(), billingEngine.CLI["c_langue"].ToString()));
    }
}

Vervang je het artikel-ID door S_CLE1 op lijnniveau: standaard zit het artikel-id in het veld LIGNES_V.ID_ARTICLE (wat overeenkomt met S_ID)

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    if ((e.Node.Name == "cbc:ID") && (e.ParentNode.Name == "cac:SellersItemIdentification"))
        e.Node.InnerText = e.DrLigne["s_cle1"].ToString();
}

De EAN13 barcode meegeven op lijnniveau: in dit voorbeeld bevind deze zich in STOCK.S_CLE3

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if (e.Node.Name == "cac:SellersItemIdentification")
    {
        string ean13 = MercatorController.xFunctions.xLookUpString("STOCK", "S_ID", e.DrLigne["id_article"], "rtrim(S_CLE3)"); // on peut aussi ajouter S_CLE3 dans LIGNES_V pour économiser ce xLookup et obtenir alors la valeur par e.DrLigne["S_CLE3"]
        if (ean13 != string.Empty)
        {
            XmlNode n = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:StandardItemIdentification");
            billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:ID", ean13, new MercatorUi.Engine.Gescom.Tools.EinvNodeAttribute("schemeID", "EAN13"), new MercatorUi.Engine.Gescom.Tools.EinvNodeAttribute("schemeAgencyID", "9"));
        }
    }
}

De vervaldatum van een artikel afkomstig uit een lot vermelden op lijnniveau: in dit voorbeeld bevindt deze zich in het veld ARTLOT.PEREMPT

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if (e.Node.Name == "cbc:LotNumberID")
        billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cbc:ExpiryDate", MercatorController.xFunctions.xLookUpDateTime("ARTLOT", "ID_LOT", e.DrLigne["id_lot"], "perempt"));
}

De Bebat- of Recupelbijdrage vermelden op lijnniveau: voorbeeld is toegepast op deze configuratie

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    
    if (e.Node.Name == "cbc:PriceAmount")
    {
        double s_bebat = Convert.ToDouble(e.DrLigne["s_bebat"]);
        if (s_bebat.CompareTo(0d, 2) != 0)
        {
            e.Node.InnerText = Api.Transform(Api.ValSafeDouble(e.Node.InnerText) - s_bebat, "#########0.00"); // diminuer le prix unitaire de la cotisation Bebat
            XmlNode n = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:AllowanceCharge");
            billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:ChargeIndicator", "true"); // true = charge
            billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:AllowanceChargeReason", "Bebat");
            billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:Amount", Api.Transform(s_bebat, "#########0.00"), new MercatorUi.Engine.Gescom.Tools.EinvNodeAttribute("currencyID", billingEngine.LibDev));
        }
    }
}

De hoeveelheidseenheid wijzigen op lijnniveau: standaard gebruikt Mercator de code C62 = STUK. de verschillende bruikbare codes zijn bruikbaar in deze lijst.

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    if ((e.Node.Name == "cbc:InvoicedQuantity") || (e.Node.Name == "cbc:CreditedQuantity"))
    {
        string s_unite = e.DrLigne["s_unite"].ToString();
        if (s_unite == "litre")
            e.Node.Attributes["unitCode"].Value = "LTR";
        else if (s_unite == "m")
            e.Node.Attributes["unitCode"].Value = "MTR";
        else if (s_unite == "m²")
            e.Node.Attributes["unitCode"].Value = "MTK";
        else if (s_unite == "m³")
            e.Node.Attributes["unitCode"].Value = "MTQ";
        else if (s_unite == "ångström") // ;-)
            e.Node.Attributes["unitCode"].Value = "A11";
    }
}

De referentie uit de bestelling meegeven op lijnniveau.

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if ((e.Node.Name == "cbc:LineExtensionAmount") && ((e.ParentNode.Name == "cac:InvoiceLine") || (e.ParentNode.Name == "cac:CreditNoteLine")) && (e.DrLigne["commande"].ToString() != string.Empty))
    {
        XmlNode n = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:OrderLineReference");
        billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:LineID", e.DrLigne["commande"].ToString());
    }
}

De leverdatum meegeven op lijnniveau: vertrekkend vanuit LIGNES_V.DATE_LIVR

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if ((e.Node.Name == "cbc:LineExtensionAmount") && ((e.ParentNode.Name == "cac:InvoiceLine") || (e.ParentNode.Name == "cac:CreditNoteLine")) && (Convert.ToDateTime(e.DrLigne["date_livr"]) > new DateTime(1900, 1, 1)))
    {
        XmlNode n = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:Delivery");
        billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:ActualDeliveryDate", Convert.ToDateTime(e.DrLigne["date_livr"]));
    }
}

Een opmerking toevoegen op lijnniveau: vertrekkend vanuit LIGNES_V.MEMO

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if ((e.Node.Name == "cbc:ID") && ((e.ParentNode.Name == "cac:InvoiceLine") || (e.ParentNode.Name == "cac:CreditNoteLine")) && (e.DrLigne["memo"].ToString() != string.Empty))
        billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cbc:Note", e.DrLigne["memo"].ToString());
}

De maat en kleur meegeven op lijnniveau (gamma's)

Zoom
void BillingEngine_EinvNodeAdded(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvNodeAddedEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
    if ((e.Node.Name == "cac:ClassifiedTaxCategory") && (e.ParentNode.Name == "cac:Item"))
    {
        if (e.DrLigne["s_gamenum1"].ToString() != string.Empty)
        {
            XmlNode n = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:AdditionalItemProperty");
            billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:Name", Api.Iif_langue(billingEngine.CLI["c_langue"].ToString(), "Size", "Maat", "Taille"));
            billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:Value", MercatorController.xFunctions.xGamEnum(null, e.DrLigne["s_gamenum1"].ToString(), billingEngine.CLI["c_langue"].ToString()));
        }
        if (e.DrLigne["s_gamenum2"].ToString() != string.Empty)
        {
            XmlNode n = billingEngine.EinvAddNode(e.eInvoiceEnum, e.ParentNode, "cac:AdditionalItemProperty");
            billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:Name", Api.Iif_langue(billingEngine.CLI["c_langue"].ToString(), "Color", "Kleur", "Couleur"));
            billingEngine.EinvAddNode(e.eInvoiceEnum, n, "cbc:Value", MercatorController.xFunctions.xGamEnum(null, e.DrLigne["s_gamenum2"].ToString(), billingEngine.CLI["c_langue"].ToString()));
        }
    }
}

Houdt rekening met artikelen die vrijgesteld zijn van BTW: bij voorbeeld leeggoed, uitbetalingen voor rekening van derden,...

Bij de verkoop van een artikel aan 0% BTW beschouwt Mercator dit standaard als een verkoop aan 0% BTW (Vak 00 in de BTW-aangifte). In vele gevallen gaat dit vaak over een BTW-vrijstelling. Het voorbeeld hieronder toont een BTW-vrijstelling voor LEEGGOED (waarborg). 
Het artikel "leeggoed" is gekend door zijn S_ID (VIDA06B416). Standaard zal Mercator een node <cac:TaxSubtotal> aanmaken in een XML-bestand voor dit tarief van 0%.

  • Hetzij dat alle artikelen van 0% BTW leeggoed zijn. In dit geval kan de node <cac:TaxSubtotal> van 0% BTW gewijzigd worden door deze te vervangen door de instellingen voor BTW-vrijstelling.
  • Hetzij andere artikelen echt verkocht worden aan 0% BTW. In dit geval wordt de node <cac:TaxSubtotal> van 0% gedupliceerd.  
     De oorspronkelijke knoop ziet zijn bedrag TaxableAmount van het bedrag van het leeggoed verminderen, terwijl de nieuwe knoop de parameters van de vrijstelling van BTW op leeggoed bevat.
Zoom
void BillingEngine_EinvFileCreating(object sender, MercatorUi.Engine.Gescom.BillingEngine.EinvFileCreatingEventArgs e)
{
    MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;

    double totVidanges = Api.ConvertToDouble(billingEngine.LIGNES.Compute("sum(total)", "id_article='VIDA06B416'"));
    if (totVidanges.CompareTo(0d, 2) != 0)
    {
        XmlNodeList nodeTaxCategoryVatZero = e.XmlDocument.ChildNodes[1].SelectNodes("cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory[cbc:Percent='0.00']", e.XmlNamespaceManager);
        if (nodeTaxCategoryVatZero.Count > 0)
        {
            XmlNode nodeTaxSubtotalZero = nodeTaxCategoryVatZero[0].ParentNode; // <cac:TaxSubtotal>
            double taxableAmount = Api.ValSafeDouble(nodeTaxSubtotalZero.ChildNodes[0].InnerText);
            XmlNode xmlNodeTaxSubtotalZeroVidanges;
            if (taxableAmount.CompareTo(totVidanges, 2) != 0) // il y a d'autres articles réellement à 0% de TVA. On doit dupliquer le noeud
            {
                xmlNodeTaxSubtotalZeroVidanges = nodeTaxSubtotalZero.Clone();
                nodeTaxSubtotalZero.ChildNodes[0].InnerText = Api.Transform(Api.ValSafeDouble(nodeTaxSubtotalZero.ChildNodes[0].InnerText) - totVidanges, "#########0.00"); // <cbc:TaxableAmount solde TVA 0%
                xmlNodeTaxSubtotalZeroVidanges.ChildNodes[0].InnerText = Api.Transform(totVidanges, "#########0.00"); // <cbc:TaxableAmount vidanges
                nodeTaxSubtotalZero.ParentNode.AppendChild(xmlNodeTaxSubtotalZeroVidanges);
            }
            else
            {
                xmlNodeTaxSubtotalZeroVidanges = nodeTaxSubtotalZero; // on peut continuer avec le noeud existant 0% de TVA
            }
            XmlNodeList nodeTaxCategoryId = xmlNodeTaxSubtotalZeroVidanges.SelectNodes("cac:TaxCategory/cbc:ID", e.XmlNamespaceManager);
            nodeTaxCategoryId[0].InnerText = "E"; // Excluded from VAT
            XmlNodeList nodeTaxCategoryName = xmlNodeTaxSubtotalZeroVidanges.SelectNodes("cac:TaxCategory/cbc:Name", e.XmlNamespaceManager);
            nodeTaxCategoryName[0].InnerText = "NA"; // code belge
            XmlNodeList nodeTaxCategoryPercent = xmlNodeTaxSubtotalZeroVidanges.SelectNodes("cac:TaxCategory/cbc:Percent", e.XmlNamespaceManager);

            XmlNode nodeReason = billingEngine.EinvAddNode(e.eInvoiceEnum, nodeTaxCategoryName[0].ParentNode, "cbc:TaxExemptionReason", "Vidanges");
            nodeTaxCategoryName[0].ParentNode.InsertAfter(nodeReason, nodeTaxCategoryPercent[0]); // placer ce noeud sous <cbc:Percent>
        }
    }
}