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 ?".
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)