Vous consultez une page technique concernant le logiciel de gestion Mercator. Celle-ci contient des informations spécifiques destinées aux professionnels de Mercator. Souhaitez-vous être redirigés vers des informations plus générales ?


   Ne plus poser cette question

Génération automatique d'une O.D. avec les intérêts et pénalités lors de l'impression des rappels

0000002342     -      10/11/2016

Par défaut, Mercator ne mouvemente pas le solde comptable du client lorsqu'un rappel a été émis et que celui-ci contient des intérêts ou amendes. Ceci peut toutefois être facilement mis en place à l'aide du customizer dont le code est fourni ci-dessous.

Pour que ce paramétrage fonctionne, il faut ajouter ces champs dans la table LIGNES_C :

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

Il faut aussi ajouter un index sur ce champ DL_ID_RAPP : CREATE NONCLUSTERED INDEX DL_ID_RAPP ON dbo.LIGNES_C (DL_ID_RAPP)

Le code source repris-ci dessous doit être modifié :

  • InitNew(4, "ODV") : ODV doit être remplacé par le journal d'O.D. souhaité
  • dicoAmendeInteret.Add("743000", tot_amende) : 743000 doit être remplacé par le compte général pour amendes souhaité
  • dicoAmendeInteret.Add("754000", tot_interet) : 754000 doit être remplacé par le compte général pour intérêts souhaité

Comme une même écriture comptable au débit du compte client peut faire l'objet de plusieurs rappels, le champ DL_ID_RAPP va permettre de garder la trace des intérêts et amendes déjà comptabilisés et qui devront donc être déduits du calcul en cours.

Le code ci-dessous doit être installé en tant que customizer Main. (Le code n'est pris en compte qu'après redémarrage de Mercator) Il exploite l'évènement AfterGenerate de MercatorUi.Forms.Accounting.AccountingRemindersForm. Cet évènement est levé à la suite des mises à jour résultant de la question "Enregistrer les informations de rappels dans les documents et les fiches clients ?".

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 += new MercatorUi.Main.BaseFormCreatingEventHandler(Main_BaseFormCreating);
            }
            else if (Action == MercatorUi.ICustomizers.ExecAction.DossierClose)
            {
                Globals.Main.BaseFormCreating -= new MercatorUi.Main.BaseFormCreatingEventHandler(Main_BaseFormCreating);
            }
        }

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

        void Form_Shown(object sender, EventArgs e)
        {
            MercatorUi.Forms.Accounting.AccountingRemindersForm accountingRemindersForm = (MercatorUi.Forms.Accounting.AccountingRemindersForm)sender;
            accountingRemindersForm.AfterGenerate += new MercatorUi.Forms.Accounting.AccountingRemindersForm.AfterGenerateEventHandler(accountingRemindersForm_AfterGenerate);
            accountingRemindersForm.Shown -= new EventHandler(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 -= new FormClosedEventHandler(Form_FormClosed);
            accountingRemindersForm.AfterGenerate -= new MercatorUi.Forms.Accounting.AccountingRemindersForm.AfterGenerateEventHandler(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.PIEDS_C["reference"] = "Intérêts et amendes sur rappels";

                int n;
                double tot_amende = 0;
                double tot_interet = 0;
                
                // cette requête va lire les montants déjà passés précédemment par ce type d'OD afin de ne pas comptabiliser 2 fois les mêmes amendes/intérêts pour une même écriture faisant l'objet d'un rappel
                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", "Straf", "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 = compte d'imputation pour les amendes
                dicoAmendeInteret.Add("754000", tot_interet); // 754000 = compte d'imputation pour les intérêts

                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.Key contient le compte général
                        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 contient respectivement tot_amende ou 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)) // la sauvegarde est effectuée dans la même transaction que la mise à jour des infos clients depuis les rappels
                {
                    Dialogs.Stop(_Divers.Iif_langue(Globals.Langue, "Impossible to save the M.O. !", "Onmogelelijk de D.V. te bewaren !", "Impossible d'enregistrer l'O.D. !") + (string.IsNullOrEmpty(bookingEngine.LastError) ? "" : "\r\n" + bookingEngine.LastError));
                    e.RollBackTransaction = true;
                    return;
                }
                Dialogs.Stop(string.Format("Une O.D. d'intérêts et amendes sur rappels a été créée : {0} {1} !", bookingEngine.Journal, bookingEngine.Piece));
            }
        }
    }
}

Remarque : pour que ce module fonctionne, vous devez disposer de l'option ENGB (Engine sur Bookings)