Sinds 1 januari 2020 moeten de brandstofkosten worden uitgesplitst per voertuig, met het oog op de VU-berekening rekening houdend met verschillende voertuig gerelateerde parameters. Hier geven we een code die van toepassing is op facturen van leverancier Total. Het is gebaseerd op een Excel-bestand dat is verkregen van het Total-portaal, via "Mijn dagelijkse monitoring / dagelijkse transacties". Het selectiescherm moet als volgt worden ingevuld, waarbij de datums worden aangepast aan de factureringsperiode.

Nadat u op de knop "Zoeken" hebt geklikt, moet u op de knop klikken
om het juiste Excel-bestand te maken.
De onderstaande code moet in een knop van het invoerscherm van aankopen in de boekhouding worden geplaatst. Het veronderstelt dat het tankkaartnummer is opgeslagen in sleutel 3 van de analytische rekeningen. Het principe is als volgt :
- De gebruiker start een inkoopinvoer en voert de leverancier in (Total)
- Hij controleert het Regime aan de hand van de factuur die hij codeert
- Is het een nationale factuur? -> Normaal
- Is het een buitenlandse factuur? -> Vrijgesteld
- Hij vult het bedrag van de factuur in. Als vanaf dat moment de standaard grootboekrekening correct wordt vermeld in het leveranciersbestand en als er op deze grootboekrekening een standaard btw-code aanwezig is, wordt de boeking naar het grootboek automatisch uitgevoerd.
- De gebruiker klikt op de betreffende knop en deze voegt de bewegingen in de analytische boekhouding toe. Als het bestand het verbruik in verschillende landen bevat, kunt u in een dialoogvenster het land selecteren dat overeenkomt met de factuur die wordt gecodeerd.
De code van de knop is als volgt :
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Linq;
using MercatorApi;
using MercatorController;
using System.Windows.Forms;
using MercatorExtensions;
using MercatorDatabase;
// <CompileWithRoslyn />
namespace MercatorUi.MovableControls.ButtonsCodes
{
public static class Script
{
private const int plan = 1;
public static void Exec(MercatorUi.MovableControls.MovableButton clickedButton)
{
if (!(clickedButton.Form is MercatorUi.Forms.Booking.BookingForm bookingForm))
return;
if ((bookingForm.BookingEngine.LIGNES_C.Rows.Count == 0) || string.IsNullOrWhiteSpace(bookingForm.BookingEngine.LignesCRecords[0].COMPTE))
{
MercatorUi.Dialogs.Stop("Men moet eerst de leverancier ingeven en de eerste imputatielijn moet vervolledigd worden !");
return;
}
string fichier = Dialogs.GetFile("Xls file (*.xls)|*.xls|All files (*.*)|*.*", _Divers.Iif_langue(Globals.Langue, "Which XLS file ?", "Welk XLS bestand ?", "Quel fichier XLS ?"), @"c:\");
if (fichier == "")
return;
var r = MercatorImporter.Importer.Import(MercatorImporter.ImporterFormats.Excel2003, fichier);
if (r == null)
return;
if (r.Result.Rows.Count == 0)
{
MercatorUi.Dialogs.Stop(Api.Iif_langue(MercatorUi.Globals.Langue, IifLangueEnum.NoRecordFound));
return;
}
string[] countries = r.Result.Rows.Cast<DataRow>().GroupBy(p => (string)p["code partenaire"]).Select(p => (string)p.First()["code partenaire"]).ToArray();
string country;
if (countries.Length == 1)
{
country = countries[0];
}
else
{
var l = new List<MercatorUi._BaseClasses.MercatorComboItem>();
foreach (string s in countries)
l.Add(new MercatorUi._BaseClasses.MercatorComboItem(s, s));
var askComboRet = MercatorUi.Dialogs.AskCombo("Voor welk land ?", l);
if (askComboRet == null)
return;
country = askComboRet.Id;
}
string montant_col = bookingForm.BookingEngine.PiedsCRecord.REGIME == RegimesEnum.Normal ? "montant ht" : "montant ttc";
var data = r.Result.Rows.Cast<DataRow>().Where(c => c["code partenaire"].Equals(country)).GroupBy(p => (string)p["carte"]).Select(p => new KeyValuePair<string, decimal>((string)p.First()["carte"], p.Sum(dr => Convert.ToDecimal(dr[montant_col]))));
var tot_xls = Convert.ToDouble(data.Sum(kvp => kvp.Value));
if (tot_xls.CompareTo(bookingForm.BookingEngine.LignesCRecords[0].TOT_DV, 2) != 0)
{
string msg = string.Format("Verschil tussen totaal van bestand en imputatie :\r\n"
+ " Imputatie = {0:### ##0.00} EUR\r\n"
+ " Bestand = {1:### ##0.00} EUR\r\n"
+ "Verder gaan ?", bookingForm.BookingEngine.LignesCRecords[0].TOT_DV, tot_xls);
if (!MercatorUi.Dialogs.AnswerYesNo(msg))
return;
}
bookingForm.BookingEngine.LIGNES_C_ANA.Rows.Clear();
MercatorUi.Sig.Sig sigAna = MercatorUi.Sig._SigsStatic.SigByModule(Sig._SigEnum.ANA);
string reqSql = string.Format("select {0} from ANA where (a_plan={1}) and (a_cle3 in ({2}))", sigAna.FieldsListForSelectRtrimOptimBytes, plan, string.Join(",", data.Select(kvp => "'" + kvp.Key + "'")));
DataSet ds = Api.Zselect(MercatorUi.Globals.RepData, reqSql);
if (ds == null)
return;
foreach(var kvp in data)
{
var anaRecord = ds.Tables[0].RowsEnumerable().FirstOrDefault(dr => dr["a_cle3"].Equals(kvp.Key));
if (anaRecord == null)
{
MercatorUi.Dialogs.Stop($"De kaart{kvp.Key} is niet geassocieerd met een analytische rekening !");
return;
}
int n = bookingForm.BookingEngine.AppendLineAna(plan, bookingForm.BookingEngine.LignesCRecords[0].DL_ID);
if (!bookingForm.BookingEngine.InsertAnaFull(anaRecord, bookingForm.BookingEngine.LIGNES_C_ANA.Rows[n], plan))
{
MercatorUi.Dialogs.Stop($"Niet mogelijk om analytische rekening in te geven \"{anaRecord["a_id"].ToString().TrimEnd()}\" lié à la carte {kvp.Key} !");
return;
}
bookingForm.BookingEngine.LIGNES_C_ANA.Rows[n]["tot_dv"] = kvp.Value;
}
bookingForm.BookingEngine.UpdateAmounts();
MercatorUi.Dialogs.Stop("De analytics zijn niet toepasbaar !");
}
}
}
Om ervoor te zorgen dat de tankkaartnummers uniek zijn in de tabel met analytische rekeningen, raden we aan deze index te installeren :
CREATE UNIQUE NONCLUSTERED INDEX A_CLE3_UNIQUE_OR_EMPTY_IN_ANA ON dbo.ANA(A_CLE3) where a_cle3<>''