Paramétrage de factures électroniques

0000002718     -      09/10/2023

Pour le paramétrage des factures électroniques, le BillingEngine met à disposition 3 événements :

  • EinvNodeAdding : lors de l'ajout de chaque nœud dans la structure XML. En mettant e.Cancel = true, on a la possibilité de ne pas ajouter le nœud
  • EinvNodeAdded : quand le noeud vient d'être ajouté à l’arborescence XML
  • EinvFileCreating : lorsque toute l’arborescence XML est prête, juste avant de produire le fichier XML. La propriété e.FileName permet de modifier le nom du fichier qui va être produit.

Voir aussi : 

Nous reprenons ci-dessous des exemples de paramétrage. Pour tous ces exemples, le customizer de base est le suivant. Il suffira de l'adapter en fonction du contenu des 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)
        {
        }

    }
}

Ne pas envoyer le contenu de PIEDS_V.NOTE1

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

Modifier le compte bancaire de l'expéditeur

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";
    }
}

Remplacer la note1 par la note2 (la note1 doit être non vide pour que Mercator crée le noeud "cbc:Note")

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();
    }
}

Ajouter la référence du contrat à partir du champ 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 = purchase order selon cette liste


Ajouter la référence du contrat à partir du champ PIEDS_V.LIBRE1, avec date de début et date de fin de contrat (PIEDS_V.DATE_CTRAT_1 et 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"]));
    }
}

Inclure la périodicité de la facture : sur base de PIEDS_V.DATE_1 et 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"]));
    }
}

Inclure tous les fichiers PDF de l'onglet explorateur de fichiers SQL 

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)));
                }
            }
        }

Inclure un fichier PDF présent sur disque

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)));
    }
}

Changer le mode de paiement : par défaut, Mercator passe le code "1 = Instrument not defined" pour la balise "cbc:PaymentMeansCode". L'exemple ci-dessous montre comment changer cela. Voir cette liste.

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

Inclure les coordonnées du contact chez le client : sur base de PIEDS_V.ID_TACT1 : nom, téléphone, 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());
        }
    }
}

Ajouter la date de livraison : sur base de PIEDS_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"]));
        }
    }
}

Inclure le délai de paiement en "texte" : sur base de 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()));
    }
}

Dans les lignes, remplacer l'ID de l'article par S_CLE1 : par défaut, l'ID de l'article est la zone LIGNES_V.ID_ARTICLE, soit le 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();
}

Dans les lignes, indiquer le code-barres EAN13 : dans cet exemple, il se trouve dans 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"));
        }
    }
}

Dans les lignes, pour un article à lot, indiquer la date de péremption : dans cet exemple, elle se trouve dans 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"));
}

Dans les lignes, mentionner la cotisation Bebat ou Recupel : exemple appliqué sur base de ce paramétrage

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));
        }
    }
}

Dans les lignes, adapter l'unité de quantité : par défaut, Mercator utilise le code C62 = une pièce. Les différents codes utilisables sont disponibles dans cette liste.

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";
    }
}

Dans les lignes, indiquer les références de la commande

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());
    }
}

Dans les lignes, indiquer la date de livraison : à partir de 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"]));
    }
}

Dans les lignes, ajouter une note : à partir de 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());
}

Dans les lignes, préciser la taille et la couleur (gammes)

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()));
        }
    }
}

Tenir compte d'articles exonérés de TVA : par exemple vidanges, débours pour compte de tiers, ...

Lors de la vente d'un article à 0% de TVA, par défaut Mercator considère qu'il s'agit d'une vente à 0% de TVA (case 00 de la déclaration belge). Dans bien des cas, il s'agit plutôt d'exemption de TVA. L'exemple ci-dessous montre une exemption de TVA pour vidanges (caution). L'article "vidange" est reconnu par son S_ID (VIDA06B416). Par défaut, dans le fichier XML, Mercator crée un nœud <cac:TaxSubtotal> pour ce taux de 0%.

  • Soit tous les articles à 0% de TVA sont des vidanges. Dans ce cas, le nœud <cac:TaxSubtotal> 0% de TVA peut être modifié pour le remplacer par les paramètres de l'exemption TVA.
  • Soit d'autres articles sont réellement vendus à 0% de TVA. Dans ce cas, le nœud <cac:TaxSubtotal> 0% de TVA est dupliqué. Le nœud d'origine voit son montant TaxableAmount diminué du montant des vidanges, tandis que le nouveau nœud reprend les paramètres de l'exemption TVA liée aux vidanges.
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>
        }
    }
}