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

Automatisch D.V. aanmaken met rentes en boetes bij het afdrukken van herinneringen

0000002342     -      02-12-2025

Standaard beweegt Mercator het rekeningsaldo van de klant niet wanneer een herinnering wordt uitgestuurd en dat die de rente en boetes bevat. Dit kan echter gemakkelijk worden geïmplementeerd met behulp van een customizer wiens code hieronder wordt gegeven.

Om deze parameters te laten werken moet u velden toevoegen aan de LIGNES_C tabel:

  • DL_ID_RAPP : char(10)
  • AMEND_RAPP : float
  • INTER_RAPP : float

Je dient ook een index toe te voegen op het veld DL_ID_RAPP : CREATE NONCLUSTERED INDEX DL_ID_RAPP ON dbo.LIGNES_C (DL_ID_RAPP)

alter table LIGNES_C add DL_ID_RAPP char(10) not null default '',
AMEND_RAPP float not null default 0,
INTER_RAPP float not null default 0
GO
CREATE NONCLUSTERED INDEX DL_ID_RAPP ON dbo.LIGNES_C (DL_ID_RAPP)

De broncode hieronder dient te worden veranderd:

  • InitNew(4, "ODV") : ODV moet worden vervangen door de gewenste D.B. log
  • dicoAmendeInteret.Add("743000", tot_amende) : 743000 moet worden vervangen door de gewenste algemene rekening voor de boetes
  • dicoAmendeInteret.Add("754000", tot_interet) : 754000 moet worden vervangen door de gewenste algemene rekening voor de rentes

👉 Aangezien een zelfde boeking op het debet van een klantenrekening betrekking kan hebben op meerdere aanmaningen, zal het veld DL_ID_RAPP helpen om de oorsprong van de reeds geboekte intresten en boetes bij te houden en dan af te trekken van de huidige berekening.

De code hieronder dient te worden geïnstalleerd als de Main customizer. (Er wordt geen rekening gehouden met de code tot Mercator herstart wordt).Het maakt gebruik van het eventAfterGenerate van MercatorUi.Forms.Accounting.AccountingRemindersForm. Dit event wordt verhoogd ten gevolge van updates door de vraag “Informatie van de herinneringen opslaan in de documenten en klanten fiches?".

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

namespace Main
{
    public class Customizer : MercatorUi.ICustomizers.IExec
    {
        public void Main(MercatorUi.ICustomizers.ExecAction action)
        {
            if (action == MercatorUi.ICustomizers.ExecAction.DossierOpen)
            {
                Globals.Main.BaseFormCreating += Main_BaseFormCreating;
            }
            else if (action == MercatorUi.ICustomizers.ExecAction.DossierClose)
            {
                Globals.Main.BaseFormCreating -= Main_BaseFormCreating;
            }
        }

        void Main_BaseFormCreating(object sender, MercatorUi.Main.BaseFormCreatingEventArgs e)
        {
            if (e.Form is MercatorUi.Forms.Accounting.AccountingRemindersForm)
            {
                e.Form.Shown += Form_Shown;
                e.Form.FormClosed += Form_FormClosed;
            }
        }

        void Form_Shown(object sender, EventArgs e)
        {
            MercatorUi.Forms.Accounting.AccountingRemindersForm accountingRemindersForm = (MercatorUi.Forms.Accounting.AccountingRemindersForm)sender;
            accountingRemindersForm.AfterGenerate += accountingRemindersForm_AfterGenerate;
            accountingRemindersForm.Shown -= Form_Shown; // désinscrire l'évènement
        }

        void Form_FormClosed(object sender, FormClosedEventArgs e)
        {
            MercatorUi.Forms.Accounting.AccountingRemindersForm accountingRemindersForm = (MercatorUi.Forms.Accounting.AccountingRemindersForm)sender;
            accountingRemindersForm.FormClosed -= Form_FormClosed;
            accountingRemindersForm.AfterGenerate -= accountingRemindersForm_AfterGenerate;
        }

        void accountingRemindersForm_AfterGenerate(object sender, MercatorUi.Forms.Accounting.AccountingRemindersForm.AfterGenerateEventArgs e)
        {
            MercatorUi.Forms.Accounting.AccountingRemindersForm accountingRemindersForm = (MercatorUi.Forms.Accounting.AccountingRemindersForm)sender;
            using (MercatorUi.Engine.Cpta.BookingEngine bookingEngine = MercatorUi.Engine.Cpta.BookingEngine.InitNew(4, "ODV"))
            {
                if (!string.IsNullOrEmpty(bookingEngine.LastError))
                {
                    Dialogs.Stop(bookingEngine.LastError);
                    e.RollBackTransaction = true;
                    return;
                }
                bookingEngine.PiedsCRecord.REFERENCE = "Intérêts et amendes sur rappels";

                int n;
                double tot_amende = 0;
                double tot_interet = 0;
                
                // Deze query leest de bedragen die eerder via dit type D.P. werden geboekt, zodat dezelfde boetes/intresten niet tweemaal worden geboekt voor eenzelfde boeking die het onderwerp is van een aanmaning.
                e.Cmd.CommandText = "select isnull(sum(amend_rapp),0) as prec_amende,isnull(sum(inter_rapp),0) as prec_interet from lignes_c where (dl_id_rapp=@dl_id_rapp)";
                    
                MercatorUi.Sig.Sig sigCli = MercatorUi.Sig._SigsStatic.SigByModule(MercatorUi.Sig._SigEnum.CLI);
                foreach (DataRow dr in accountingRemindersForm.DataSet.Tables[1].Select("(sel=1) and ((amende<>0) or (interet<>0))"))
                {
                    e.Cmd.Parameters.Clear();
                    e.Cmd.Parameters.AddWithValue("@dl_id_rapp", dr["dl_id"]).SqlDbType = SqlDbType.Char;

                    DataSet dsOdPrecedentes = Api.Zselect(e.Cmd.Connection, e.Cmd);
                    if (dsOdPrecedentes == null)
                    {
                        e.RollBackTransaction = true;
                        return;
                    }
                    double tot = Convert.ToDouble(dr["amende"]) + Convert.ToDouble(dr["interet"]) - Convert.ToDouble(dsOdPrecedentes.Tables[0].Rows[0]["prec_amende"]) - Convert.ToDouble(dsOdPrecedentes.Tables[0].Rows[0]["prec_interet"]);
                    if (Math.Round(tot, 2) == 0)
                        continue;
                    
                    n = bookingEngine.AppendLine();
                    bookingEngine.InsertAccount(sigCli, accountingRemindersForm.DataSet.Tables[2].Select(string.Format("c_id='{0}'", Api.UnquoteSql(dr["id_cli"].ToString())))[0], bookingEngine.LIGNES_C.Rows[n]);
                    if (!string.IsNullOrEmpty(bookingEngine.LastError))
                    {
                        Dialogs.Stop(bookingEngine.LastError);
                        e.RollBackTransaction = true;
                        return;
                    }
                    bookingEngine.LIGNES_C.Rows[n]["tot_dv"] = Math.Abs(tot);
                    bookingEngine.LIGNES_C.Rows[n]["signe"] = tot > 0 ? "D" : "C";
                    bookingEngine.LIGNES_C.Rows[n]["dl_id_rapp"] = dr["dl_id"];
                    bookingEngine.LIGNES_C.Rows[n]["amend_rapp"] = Convert.ToDouble(dr["amende"]) - Convert.ToDouble(dsOdPrecedentes.Tables[0].Rows[0]["prec_amende"]);
                    bookingEngine.LIGNES_C.Rows[n]["inter_rapp"] = Convert.ToDouble(dr["interet"]) - Convert.ToDouble(dsOdPrecedentes.Tables[0].Rows[0]["prec_interet"]);
                    bookingEngine.LIGNES_C.Rows[n]["commentair"] = string.Format("{0} = {1} | {2} = {3}",
                        _Divers.Iif_langue(Globals.Langue, "Penalty", "Boete", "Amende"),
                        Api.Transform(Convert.ToDouble(dr["amende"]), Globals.PictCpta).TrimStart(),
                        _Divers.Iif_langue(Globals.Langue, "Interests", "Intresten", "Intérêts"),
                        Api.Transform(Convert.ToDouble(dr["interet"]), Globals.PictCpta).TrimStart());

                    tot_amende += Convert.ToDouble(dr["amende"]) - Convert.ToDouble(dsOdPrecedentes.Tables[0].Rows[0]["prec_amende"]);
                    tot_interet += Convert.ToDouble(dr["interet"]) - Convert.ToDouble(dsOdPrecedentes.Tables[0].Rows[0]["prec_interet"]);
                }

                Dictionary<string, double> dicoAmendeInteret = new Dictionary<string,double>();
                dicoAmendeInteret.Add("743000", tot_amende); // 743000 = rekening voor de aanrekening van de boetes
                dicoAmendeInteret.Add("754000", tot_interet); // 754000 = rekening voor de aanrekening van de interesten

                MercatorUi.Sig.Sig sigGen = MercatorUi.Sig._SigsStatic.SigByModule(MercatorUi.Sig._SigEnum.GEN);
                foreach (KeyValuePair<string, double> kvp in dicoAmendeInteret)
                {
                    if (Math.Round(kvp.Value, 2) != 0)
                    {
                        n = bookingEngine.AppendLine();
                        bookingEngine.InsertAccount(sigGen, kvp.Key, bookingEngine.LIGNES_C.Rows[n]); // kvp.Keybevat de algemene rekening
                        if (!string.IsNullOrEmpty(bookingEngine.LastError))
                        {
                            Dialogs.Stop(bookingEngine.LastError);
                            e.RollBackTransaction = true;
                            return;
                        }
                        bookingEngine.LIGNES_C.Rows[n]["tot_dv"] = Math.Abs(kvp.Value); // kvp.Value bevat respectievelijk tot_amende of tot_interet
                        bookingEngine.LIGNES_C.Rows[n]["signe"] = kvp.Value > 0 ? "C" : "D";
                    }
                }

                if (bookingEngine.LIGNES_C.Rows.Count == 0)
                {
                    Dialogs.Stop("Aucune O.D. d'intérêts et amendes sur rappels ne doit être créée !");
                    return;
                }

                bookingEngine.UpdateAmounts();
                if (!bookingEngine.Save(false, e.Cmd.Connection, e.Cmd.Transaction)) // de opslag wordt uitgevoerd in dezelfde transactie als de update van de klanteninformatie vanuit de aanmaningen
                {
                    Dialogs.Stop(_Divers.Iif_langue(Globals.Langue, "Impossible to save the M.O. !", "Onmogelelijk de D.P.te bewaren !", "Impossible d'enregistrer l'O.D. !") + (string.IsNullOrEmpty(bookingEngine.LastError) ? "" : "\r\n" + bookingEngine.LastError));
                    e.RollBackTransaction = true;
                    return;
                }
                Dialogs.Stop(string.Format("Een D.P. met intresten en boetes op aanmaningen werd aangemaakt.: {0} {1} !", bookingEngine.Journal, bookingEngine.Piece));
            }
        }
    }
}

Opmerking : Voor deze module te laten werken is de optie ENGB (Booking Engine) nodig.



Functionele cookies: Cookies die nodig zijn voor het gebruik van de website en voorkeurscookies. Ze bevatten geen persoonsgegevens. (Meer informatie)

Analytische cookies: Verzamelen van statistieken met betrekking tot het gedrag van internetgebruikers. (Meer informatie)

Marketingcookies: Om bezoekers op verschillende websites te volgen voor advertentiedoeleinden. (Meer informatie)