com.axelor.apps.account.service.cfonb.CfonbExportService.java Source code

Java tutorial

Introduction

Here is the source code for com.axelor.apps.account.service.cfonb.CfonbExportService.java

Source

/**
 * Axelor Business Solutions
 *
 * Copyright (C) 2015 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.axelor.apps.account.service.cfonb;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;

import com.axelor.apps.account.db.AccountConfig;
import com.axelor.apps.account.db.CfonbConfig;
import com.axelor.apps.account.db.DirectDebitManagement;
import com.axelor.apps.account.db.Invoice;
import com.axelor.apps.account.db.MoveLine;
import com.axelor.apps.account.db.PaymentSchedule;
import com.axelor.apps.account.db.PaymentScheduleLine;
import com.axelor.apps.account.db.Reimbursement;
import com.axelor.apps.account.db.repo.InvoiceRepository;
import com.axelor.apps.account.db.repo.PaymentScheduleLineRepository;
import com.axelor.apps.account.db.repo.ReimbursementRepository;
import com.axelor.apps.account.exception.IExceptionMessage;
import com.axelor.apps.account.service.config.CfonbConfigService;
import com.axelor.apps.base.db.BankDetails;
import com.axelor.apps.base.db.Company;
import com.axelor.apps.base.db.Partner;
import com.axelor.apps.base.service.PartnerService;
import com.axelor.apps.base.service.administration.GeneralServiceImpl;
import com.axelor.apps.tool.StringTool;
import com.axelor.apps.tool.file.FileTool;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.IException;
import com.axelor.i18n.I18n;
import com.google.inject.Inject;

public class CfonbExportService {

    protected CfonbConfig cfonbConfig;
    protected CfonbToolService cfonbToolService;
    protected CfonbConfigService cfonbConfigService;
    protected ReimbursementRepository reimbursementRepo;
    protected PaymentScheduleLineRepository paymentScheduleLineRepo;
    protected InvoiceRepository invoiceRepo;
    protected PartnerService partnerService;
    private boolean sepa;

    @Inject
    public CfonbExportService(CfonbToolService cfonbToolService, CfonbConfigService cfonbConfigService,
            ReimbursementRepository reimbursementRepo, PaymentScheduleLineRepository paymentScheduleLineRepo,
            InvoiceRepository invoiceRepo, PartnerService partnerService) {

        this.cfonbToolService = cfonbToolService;
        this.cfonbConfigService = cfonbConfigService;
        this.reimbursementRepo = reimbursementRepo;
        this.paymentScheduleLineRepo = paymentScheduleLineRepo;
        this.invoiceRepo = invoiceRepo;
        this.partnerService = partnerService;

    }

    private void init(CfonbConfig cfonbConfig) {

        this.cfonbConfig = cfonbConfig;

    }

    public void setSepa(boolean sepa) {

        this.sepa = sepa;

    }

    /****************************************  Export CFONB  *****************************************************/

    /**
     * Mthode permettant d'exporter les remboursements au format CFONB
     * @param reimbursementExport
     * @param dateTime
     * @param reimbursementList
     * @throws AxelorException
     */
    public void exportCFONB(Company company, DateTime dateTime, List<Reimbursement> reimbursementList,
            BankDetails bankDetails) throws AxelorException {

        this.testCompanyExportCFONBField(company);

        // paramtre obligatoire : au minimum
        //      un enregistrement emetteur par date de rglement (code 03)
        //       un enregistrement destinataire (code 06)
        //       un enregistrement total (code 08)

        String senderCFONB = this.createSenderReimbursementCFONB(dateTime, bankDetails);
        List<String> multiRecipientCFONB = new ArrayList<String>();
        for (Reimbursement reimbursement : reimbursementList) {
            reimbursement = reimbursementRepo.find(reimbursement.getId());

            multiRecipientCFONB.add(this.createRecipientCFONB(reimbursement));
        }
        String totalCFONB = this
                .createReimbursementTotalCFONB(this.getTotalAmountReimbursementExport(reimbursementList));

        cfonbToolService.testLength(senderCFONB, totalCFONB, multiRecipientCFONB, company);

        List<String> cFONB = this.createCFONBExport(senderCFONB, multiRecipientCFONB, totalCFONB);

        // Mise en majuscule des enregistrement
        cFONB = this.toUpperCase(cFONB);

        this.createCFONBFile(cFONB, dateTime, company.getAccountConfig().getReimbursementExportFolderPathCFONB(),
                "virement");
    }

    /**
     * Mthode permettant d'exporter les prlvements d'chance de mensu au format CFONB
     * @param paymentScheduleExport
     * @param paymentScheduleLineList
     * @param company
     * @throws AxelorException
     */
    public void exportPaymentScheduleCFONB(DateTime processingDateTime, LocalDate scheduleDate,
            List<PaymentScheduleLine> paymentScheduleLineList, Company company, BankDetails bankDetails)
            throws AxelorException {

        if (paymentScheduleLineList == null || paymentScheduleLineList.isEmpty()) {
            return;
        }

        this.testCompanyExportCFONBField(company);

        // paramtre obligatoire : au minimum
        //      un enregistrement emetteur par date de rglement (code 03)
        //       un enregistrement destinataire (code 06)
        //       un enregistrement total (code 08)

        String senderCFONB = this.createSenderMonthlyExportCFONB(scheduleDate, bankDetails);
        List<String> multiRecipientCFONB = new ArrayList<String>();

        List<DirectDebitManagement> directDebitManagementList = new ArrayList<DirectDebitManagement>();
        for (PaymentScheduleLine paymentScheduleLine : paymentScheduleLineList) {
            paymentScheduleLine = paymentScheduleLineRepo.find(paymentScheduleLine.getId());
            if (paymentScheduleLine.getDirectDebitManagement() == null) {
                multiRecipientCFONB.add(this.createRecipientCFONB(paymentScheduleLine, true));
            } else {
                if (!directDebitManagementList.contains(paymentScheduleLine.getDirectDebitManagement())) {
                    directDebitManagementList.add(paymentScheduleLine.getDirectDebitManagement());
                }
            }
        }

        for (DirectDebitManagement directDebitManagement : directDebitManagementList) {
            multiRecipientCFONB.add(this.createRecipientCFONB(directDebitManagement, false));
        }

        String totalCFONB = this.createPaymentScheduleTotalCFONB(company,
                this.getTotalAmountPaymentSchedule(paymentScheduleLineList));

        cfonbToolService.testLength(senderCFONB, totalCFONB, multiRecipientCFONB, company);

        List<String> cFONB = this.createCFONBExport(senderCFONB, multiRecipientCFONB, totalCFONB);

        // Mise en majuscule des enregistrement
        cFONB = this.toUpperCase(cFONB);

        this.createCFONBFile(cFONB, processingDateTime,
                company.getAccountConfig().getPaymentScheduleExportFolderPathCFONB(), "prelevement");
    }

    /**
     * Mthode permettant d'exporter les prlvements de facture au format CFONB
     * @param paymentScheduleExport
     * @param paymentScheduleLineList
     * @param invoiceList
     * @param company
     * @throws AxelorException
     */
    public void exportInvoiceCFONB(DateTime processingDateTime, LocalDate scheduleDate, List<Invoice> invoiceList,
            Company company, BankDetails bankDetails) throws AxelorException {

        if ((invoiceList == null || invoiceList.isEmpty())) {
            return;
        }

        this.testCompanyExportCFONBField(company);

        // paramtre obligatoire : au minimum
        //      un enregistrement emetteur par date de rglement (code 03)
        //       un enregistrement destinataire (code 06)
        //       un enregistrement total (code 08)

        String senderCFONB = this.createSenderMonthlyExportCFONB(scheduleDate, bankDetails);
        List<String> multiRecipientCFONB = new ArrayList<String>();

        List<DirectDebitManagement> directDebitManagementList = new ArrayList<DirectDebitManagement>();

        for (Invoice invoice : invoiceList) {
            invoice = invoiceRepo.find(invoice.getId());
            if (invoice.getDirectDebitManagement() == null) {
                multiRecipientCFONB.add(this.createRecipientCFONB(company, invoice));
            } else {
                if (!directDebitManagementList.contains(invoice.getDirectDebitManagement())) {
                    directDebitManagementList.add(invoice.getDirectDebitManagement());
                }
            }
        }

        for (DirectDebitManagement directDebitManagement : directDebitManagementList) {
            multiRecipientCFONB.add(this.createRecipientCFONB(directDebitManagement, true));
        }

        BigDecimal amount = this.getTotalAmountInvoice(invoiceList);

        String totalCFONB = this.createPaymentScheduleTotalCFONB(company, amount);

        cfonbToolService.testLength(senderCFONB, totalCFONB, multiRecipientCFONB, company);

        List<String> cFONB = this.createCFONBExport(senderCFONB, multiRecipientCFONB, totalCFONB);

        // Mise en majuscule des enregistrement
        cFONB = this.toUpperCase(cFONB);

        this.createCFONBFile(cFONB, processingDateTime,
                company.getAccountConfig().getPaymentScheduleExportFolderPathCFONB(), "prelevement");
    }

    /**
     * Mthode permettant d'exporter les prlvements de facture et d'chance de paiement au format CFONB
     * @param paymentScheduleExport
     * @param paymentScheduleLineList
     * @param invoiceList
     * @param company
     * @throws AxelorException
     */
    public void exportCFONB(DateTime processingDateTime, LocalDate scheduleDate,
            List<PaymentScheduleLine> paymentScheduleLineList, List<Invoice> invoiceList, Company company,
            BankDetails bankDetails) throws AxelorException {

        if ((paymentScheduleLineList == null || paymentScheduleLineList.isEmpty())
                && (invoiceList == null || invoiceList.isEmpty())) {
            return;
        }

        this.testCompanyExportCFONBField(company);

        // paramtre obligatoire : au minimum
        //      un enregistrement emetteur par date de rglement (code 03)
        //       un enregistrement destinataire (code 06)
        //       un enregistrement total (code 08)

        String senderCFONB = this.createSenderMonthlyExportCFONB(scheduleDate, bankDetails);
        List<String> multiRecipientCFONB = new ArrayList<String>();

        // Echanciers
        List<DirectDebitManagement> directDebitManagementList = new ArrayList<DirectDebitManagement>();
        for (PaymentScheduleLine paymentScheduleLine : paymentScheduleLineList) {
            paymentScheduleLine = paymentScheduleLineRepo.find(paymentScheduleLine.getId());
            if (paymentScheduleLine.getDirectDebitManagement() == null) {
                multiRecipientCFONB.add(this.createRecipientCFONB(paymentScheduleLine, false));
            } else {
                if (!directDebitManagementList.contains(paymentScheduleLine.getDirectDebitManagement())) {
                    directDebitManagementList.add(paymentScheduleLine.getDirectDebitManagement());
                }
            }
        }

        for (DirectDebitManagement directDebitManagement : directDebitManagementList) {
            multiRecipientCFONB.add(this.createRecipientCFONB(directDebitManagement, false));
        }

        // Factures
        directDebitManagementList = new ArrayList<DirectDebitManagement>();
        for (Invoice invoice : invoiceList) {
            invoice = invoiceRepo.find(invoice.getId());
            if (invoice.getDirectDebitManagement() == null) {
                multiRecipientCFONB.add(this.createRecipientCFONB(company, invoice));
            } else {
                if (!directDebitManagementList.contains(invoice.getDirectDebitManagement())) {
                    directDebitManagementList.add(invoice.getDirectDebitManagement());
                }
            }
        }

        for (DirectDebitManagement directDebitManagement : directDebitManagementList) {
            multiRecipientCFONB.add(this.createRecipientCFONB(directDebitManagement, true));
        }

        BigDecimal amount = this.getTotalAmountPaymentSchedule(paymentScheduleLineList)
                .add(this.getTotalAmountInvoice(invoiceList));

        String totalCFONB = this.createPaymentScheduleTotalCFONB(company, amount);

        cfonbToolService.testLength(senderCFONB, totalCFONB, multiRecipientCFONB, company);

        List<String> cFONB = this.createCFONBExport(senderCFONB, multiRecipientCFONB, totalCFONB);

        // Mise en majuscule des enregistrement
        cFONB = this.toUpperCase(cFONB);

        this.createCFONBFile(cFONB, processingDateTime,
                company.getAccountConfig().getPaymentScheduleExportFolderPathCFONB(), "prelevement");
    }

    /**
     * Mthode permettant de mettre en majuscule et sans accent un CFONB
     * @param cFONB
     * @return
     *       Le CFONB nettoy
     */
    private List<String> toUpperCase(List<String> cFONB) {
        List<String> upperCase = new ArrayList<String>();
        for (String s : cFONB) {
            upperCase.add(StringTool.deleteAccent(s.toUpperCase()));
        }
        return upperCase;
    }

    /**
     * Mthode permettant de rcuprer la facture depuis une ligne d'criture de facture ou une ligne d'criture de rejet de facture
     * @param moveLine
     *          Une ligne d'criture de facture ou une ligne d'criture de rejet de facture
     * @return
     *          La facture trouve
     */
    public Invoice getInvoice(MoveLine moveLine) {
        Invoice invoice = null;
        if (moveLine.getMove().getRejectOk()) {
            invoice = moveLine.getInvoiceReject();
        } else {
            invoice = moveLine.getMove().getInvoice();
        }
        return invoice;
    }

    /**
     * Fonction permettant de crer un enregistrement 'metteur' pour un virement des remboursements
     * @param company
     *             Une socit
     * @param dateTime
     *             Une heure
     * @return
     *             Un enregistrement 'emetteur'
     * @throws AxelorException
     */
    private String createSenderReimbursementCFONB(DateTime dateTime, BankDetails bankDetails)
            throws AxelorException {

        DateFormat ddmmFormat = new SimpleDateFormat("ddMM");
        String date = ddmmFormat.format(dateTime.toDate());
        date += String.format("%s", StringTool.truncLeft(String.format("%s", dateTime.getYear()), 1));

        // Rcupration des valeurs
        String a = this.cfonbConfig.getSenderRecordCodeExportCFONB(); // Code enregistrement
        String b1 = this.cfonbConfig.getTransferOperationCodeExportCFONB(); // Code opration
        String b2 = ""; // Zone rserve
        String b3 = this.cfonbConfig.getSenderNumExportCFONB(); // Numro d'metteur
        String c1One = ""; // Code CCD
        String c1Two = ""; // Zone rserve
        String c1Three = date; // Date d'chance
        String c2 = this.cfonbConfig.getSenderNameCodeExportCFONB(); // Nom/Raison sociale du donneur d'ordre
        String d1One = ""; // Rfrence de la remise
        String d1Two = ""; // Zone rserve
        String d2One = ""; // Zone rserve
        String d2Two = "E"; // Code monnaie
        String d2Three = ""; // Zone rserve
        String d3 = bankDetails.getSortCode(); // Code guichet de la banque du donneur d'ordre
        String d4 = bankDetails.getAccountNbr(); // Numro de compte du donneur dordre
        String e = ""; // Identifiant du donneur d'ordre
        String f = ""; // Zone rserve
        String g1 = bankDetails.getBankCode(); // Code tablissement de la banque du donneur d'ordre
        String g2 = ""; // Zone rserve

        // Tronquage / remplissage  droite (chaine de caractre)
        b2 = StringTool.fillStringRight(b2, ' ', 8);
        b3 = StringTool.fillStringRight(b3, ' ', 6);
        c1One = StringTool.fillStringRight(c1One, ' ', 1);
        c1Two = StringTool.fillStringRight(c1Two, ' ', 6);
        c2 = StringTool.fillStringRight(c2, ' ', 24);
        d1One = StringTool.fillStringRight(d1One, ' ', 7);
        d1Two = StringTool.fillStringRight(d1Two, ' ', 17);
        d2One = StringTool.fillStringRight(d2One, ' ', 2);
        d2Three = StringTool.fillStringRight(d2Three, ' ', 5);
        d4 = StringTool.fillStringRight(d4, ' ', 11);
        e = StringTool.fillStringRight(e, ' ', 16);
        f = StringTool.fillStringRight(f, ' ', 31);
        g2 = StringTool.fillStringRight(g2, ' ', 6);

        // Tronquage / remplissage  gauche (nombre)
        a = StringTool.fillStringLeft(a, '0', 2);
        b1 = StringTool.fillStringLeft(b1, '0', 2);
        c1Three = StringTool.fillStringLeft(c1Three, '0', 5);
        d3 = StringTool.fillStringLeft(d3, '0', 5);
        g1 = StringTool.fillStringLeft(g1, '0', 5);

        // Vrification AN / N / A
        cfonbToolService.testDigital(a, 0);
        cfonbToolService.testDigital(b1, 0);
        cfonbToolService.testDigital(d3, 0);
        cfonbToolService.testDigital(g1, 0);

        // cration de l'enregistrement
        return a + b1 + b2 + b3 + c1One + c1Two + c1Three + c2 + d1One + d1Two + d2One + d2Two + d2Three + d3 + d4
                + e + f + g1 + g2;
    }

    /**
     * Fonction permettant de crer un enregistrement 'metteur' pour un export de prlvement de mensu
     * @param company
     *             Une socit
     * @param localDate
     *             Une date
     * @return
     *             Un enregistrement 'emetteur'
     * @throws AxelorException
     */
    private String createSenderMonthlyExportCFONB(LocalDate localDate, BankDetails bankDetails)
            throws AxelorException {

        DateFormat ddmmFormat = new SimpleDateFormat("ddMM");
        String date = ddmmFormat.format(localDate.toDateTimeAtCurrentTime().toDate());
        date += String.format("%s", StringTool.truncLeft(String.format("%s", localDate.getYear()), 1));

        // Rcupration des valeurs
        String a = this.cfonbConfig.getSenderRecordCodeExportCFONB(); // Code enregistrement
        String b1 = this.cfonbConfig.getDirectDebitOperationCodeExportCFONB(); // Code opration
        String b2 = ""; // Zone rserve
        String b3 = this.cfonbConfig.getSenderNumExportCFONB(); // Numro d'metteur
        String c1One = ""; // Zone rserve
        String c1Two = date; // Date d'chance
        String c2 = this.cfonbConfig.getSenderNameCodeExportCFONB(); // Nom/Raison sociale du donneur d'ordre
        String d1One = ""; // Rfrence de la remise
        String d1Two = ""; // Zone rserve
        String d2 = ""; // Zone rserve
        String d3 = bankDetails.getSortCode(); // Code guichet de la banque du donneur d'ordre
        String d4 = bankDetails.getAccountNbr(); // Numro de compte du donneur dordre
        String e = ""; // Zone rserve
        String f = ""; // Zone rserve
        String g1 = bankDetails.getBankCode(); // Code tablissement de la banque du donneur d'ordre
        String g2 = ""; // Zone rserve

        // Tronquage / remplissage  droite (chaine de caractre)
        b2 = StringTool.fillStringRight(b2, ' ', 8);
        b3 = StringTool.fillStringRight(b3, ' ', 6);
        c1One = StringTool.fillStringRight(c1One, ' ', 7);
        c2 = StringTool.fillStringRight(c2, ' ', 24);
        d1One = StringTool.fillStringRight(d1One, ' ', 7);
        d1Two = StringTool.fillStringRight(d1Two, ' ', 17);
        d2 = StringTool.fillStringRight(d2, ' ', 8);
        d4 = StringTool.fillStringRight(d4, ' ', 11);
        e = StringTool.fillStringRight(e, ' ', 16);
        f = StringTool.fillStringRight(f, ' ', 31);
        g2 = StringTool.fillStringRight(g2, ' ', 6);

        // Tronquage / remplissage  gauche (nombre)
        a = StringTool.fillStringLeft(a, '0', 2);
        b1 = StringTool.fillStringLeft(b1, '0', 2);
        c1Two = StringTool.fillStringLeft(c1Two, '0', 5);
        d3 = StringTool.fillStringLeft(d3, '0', 5);
        g1 = StringTool.fillStringLeft(g1, '0', 5);

        // Vrification AN / N / A
        cfonbToolService.testDigital(a, 0);
        cfonbToolService.testDigital(b1, 0);
        cfonbToolService.testDigital(d3, 0);
        cfonbToolService.testDigital(g1, 0);

        // cration de l'enregistrement
        return a + b1 + b2 + b3 + c1One + c1Two + c2 + d1One + d1Two + d2 + d3 + d4 + e + f + g1 + g2;
    }

    /**
     * Fonction permettant de crer un enregistrement 'destinataire' pour un virement de remboursement
     * @param company
     *             Une socit
     * @param reimbursement
     *             Un remboursement
     * @return
     *          Un enregistrement 'destinataire'
     * @throws AxelorException
     */
    private String createRecipientCFONB(Reimbursement reimbursement) throws AxelorException {
        BankDetails bankDetails = reimbursement.getBankDetails();

        if (bankDetails == null) {
            throw new AxelorException(String.format("%s :\n " + I18n.get(IExceptionMessage.CFONB_EXPORT_1) + " %s",
                    GeneralServiceImpl.EXCEPTION, reimbursement.getRef()), IException.CONFIGURATION_ERROR);
        }

        BigDecimal amount = reimbursement.getAmountReimbursed();

        String ref = reimbursement.getRef(); // Rfrence
        String partner = this.getPayeurPartnerName(reimbursement.getPartner()); // Nom/Raison sociale du bnficiaire
        String operationCode = this.cfonbConfig.getTransferOperationCodeExportCFONB(); // Code opration

        return this.createRecipientCFONB(amount, ref, partner, bankDetails, operationCode);
    }

    /**
     * Fonction permettant de crer un enregistrement 'destinataire' pour un export de prlvement d'une chance
     * @param company
     *             Une socit
     * @param paymentScheduleLine
     *             Une chance
     * @return
     *             Un enregistrement 'destinataire'
     * @throws AxelorException
     */
    private String createRecipientCFONB(PaymentScheduleLine paymentScheduleLine, boolean mensu)
            throws AxelorException {
        Partner partner = paymentScheduleLine.getPaymentSchedule().getPartner();
        BankDetails bankDetails = paymentScheduleLine.getPaymentSchedule().getBankDetails();
        if (bankDetails == null) {
            bankDetails = partnerService.getDefaultBankDetails(partner);
        }

        if (bankDetails == null) {
            throw new AxelorException(String.format(I18n.get(IExceptionMessage.PAYMENT_SCHEDULE_2),
                    GeneralServiceImpl.EXCEPTION, partner.getName()), IException.CONFIGURATION_ERROR);
        }

        BigDecimal amount = paymentScheduleLine.getDirectDebitAmount();

        String ref = paymentScheduleLine.getDebitNumber(); // Rfrence
        String partnerName = this.getPayeurPartnerName(partner); // Nom/Raison sociale du dbiteur
        String operationCode = this.cfonbConfig.getDirectDebitOperationCodeExportCFONB(); // Code opration

        return this.createRecipientCFONB(amount, ref, partnerName, bankDetails, operationCode);
    }

    /**
     * Fonction permettant de crer un enregistrement 'destinataire' pour un export de prlvement de plusieurs chances par le biais d'un objet de gestion de prlvement
     * @param company
     *             Une socit
     * @param paymentScheduleLine
     *             Une chance
     * @return
     *             Un enregistrement 'destinataire'
     * @throws AxelorException
     */
    private String createRecipientCFONB(DirectDebitManagement directDebitManagement, boolean isForInvoice)
            throws AxelorException {
        BankDetails bankDetails = null;
        String partnerName = "";
        if (isForInvoice) {
            Invoice invoice = (Invoice) directDebitManagement.getInvoiceSet().toArray()[0];
            Partner partner = invoice.getPartner();
            bankDetails = partnerService.getDefaultBankDetails(partner);
            partnerName = this.getPayeurPartnerName(invoice.getPartner()); // Nom/Raison sociale du dbiteur
            if (bankDetails == null) {
                throw new AxelorException(String.format(I18n.get(IExceptionMessage.PAYMENT_SCHEDULE_2),
                        GeneralServiceImpl.EXCEPTION, partner.getName()), IException.CONFIGURATION_ERROR);
            }
        } else {
            PaymentSchedule paymentSchedule = directDebitManagement.getPaymentScheduleLineList().get(0)
                    .getPaymentSchedule();
            Partner partner = paymentSchedule.getPartner();
            partnerName = this.getPayeurPartnerName(partner); // Nom/Raison sociale du dbiteur

            bankDetails = paymentSchedule.getBankDetails();
            if (bankDetails == null) {
                bankDetails = partnerService.getDefaultBankDetails(partner);
            }
            if (bankDetails == null) {
                throw new AxelorException(String.format(I18n.get(IExceptionMessage.PAYMENT_SCHEDULE_2),
                        GeneralServiceImpl.EXCEPTION, partner.getName()), IException.CONFIGURATION_ERROR);
            }
        }

        BigDecimal amount = this.getAmount(directDebitManagement, isForInvoice);

        String ref = directDebitManagement.getDebitNumber(); // Rfrence

        String operationCode = this.cfonbConfig.getDirectDebitOperationCodeExportCFONB(); // Code opration

        return this.createRecipientCFONB(amount, ref, partnerName, bankDetails, operationCode);
    }

    private BigDecimal getAmount(DirectDebitManagement directDebitManagement, boolean isForInvoice) {
        BigDecimal amount = BigDecimal.ZERO;

        if (isForInvoice) {
            for (Invoice invoice : directDebitManagement.getInvoiceSet()) {
                amount = amount.add(invoice.getDirectDebitAmount());
            }
        } else {
            for (PaymentScheduleLine paymentScheduleLine : directDebitManagement.getPaymentScheduleLineList()) {
                amount = amount.add(paymentScheduleLine.getDirectDebitAmount());
            }
        }

        return amount;
    }

    /**
     * Fonction permettant de crer un enregistrement 'destinataire' pour un export de prlvement d'une facture
     * @param company
     *             Une socit
     * @param moveLine
     *             L' criture d'export des prlvement d'une facture
     * @return
     *             Un enregistrement 'destinataire'
     * @throws AxelorException
     */
    private String createRecipientCFONB(Company company, Invoice invoice) throws AxelorException {
        Partner partner = invoice.getPartner();
        BankDetails bankDetails = partnerService.getDefaultBankDetails(partner);
        if (bankDetails == null) {
            throw new AxelorException(String.format(I18n.get(IExceptionMessage.PAYMENT_SCHEDULE_2),
                    GeneralServiceImpl.EXCEPTION, partner.getName()), IException.CONFIGURATION_ERROR);
        }

        BigDecimal amount = invoice.getDirectDebitAmount();

        String ref = invoice.getDebitNumber(); // Rfrence
        String partnerName = this.getPayeurPartnerName(partner); // Nom/Raison sociale du dbiteur
        String operationCode = this.cfonbConfig.getDirectDebitOperationCodeExportCFONB(); // Code opration

        return this.createRecipientCFONB(amount, ref, partnerName, bankDetails, operationCode);
    }

    /**
     * Fonction permettant de crer un enregistrement 'destinataire'
     * @param company
     *             Une socit
     * @param amount
     *             Le montant de l'enregistrement
     * @param ref
     *             Une rfrence de prlvement
     * @param label
     *             Un libell
     * @param partner
     *             Un tiers payeur
     * @param bankDetails
     *             Un RIB
     * @param operationCode
     *       Le code d'opration dfini par socit
     * @return
     *             L'enregistrement 'destinataire'
     * @throws AxelorException
     */
    private String createRecipientCFONB(BigDecimal amount, String ref, String partner, BankDetails bankDetails,
            String operationCode) throws AxelorException {
        this.testBankDetailsField(bankDetails);

        String amountFixed = amount.setScale(2).toString().replace(".", "");

        // Rcupration des valeurs
        String a = this.cfonbConfig.getRecipientRecordCodeExportCFONB(); // Code enregistrement
        String b1 = operationCode; // Code opration
        String b2 = ""; // Zone rserve
        String b3 = this.cfonbConfig.getSenderNumExportCFONB(); // Numro d'metteur
        String c1 = ref; // Rfrence
        String c2 = partner; // Nom/Raison sociale du bnficiaire
        String d1 = bankDetails.getBankAddress(); // Domiciliation
        String d2 = ""; // Dclaration de la balance des paiement
        String d3 = bankDetails.getSortCode(); // Code guichet de la banque du donneur d'ordre / du dbiteur
        String d4 = bankDetails.getAccountNbr(); // Numro de compte du bnficiaire / du dbiteur
        String e = amountFixed; // Montant du virement
        String f = ref; // Libell
        String g1 = bankDetails.getBankCode(); // Code tablissement de la banque du donneur d'ordre / du dbiteur
        String g2 = ""; // Zone rserve

        // Tronquage / remplissage  droite (chaine de caractre)
        b2 = StringTool.fillStringRight(b2, ' ', 8);
        b3 = StringTool.fillStringRight(b3, ' ', 6);
        c1 = StringTool.fillStringRight(c1, ' ', 12);
        c2 = StringTool.fillStringRight(c2, ' ', 24);
        d1 = StringTool.fillStringRight(d1, ' ', 24);
        d2 = StringTool.fillStringRight(d2, ' ', 8);
        d4 = StringTool.fillStringRight(d4, ' ', 11);
        f = StringTool.fillStringRight(f, ' ', 31);
        g2 = StringTool.fillStringRight(g2, ' ', 6);

        // Tronquage / remplissage  gauche (nombre)
        a = StringTool.fillStringLeft(a, '0', 2);
        b1 = StringTool.fillStringLeft(b1, '0', 2);
        d3 = StringTool.fillStringLeft(d3, '0', 5);
        e = StringTool.fillStringLeft(e, '0', 16);
        g1 = StringTool.fillStringLeft(g1, '0', 5);

        return a + b1 + b2 + b3 + c1 + c2 + d1 + d2 + d3 + d4 + e + f + g1 + g2;
    }

    /**
     * Fonction permettant de crer un enregistrement 'total' au format CFONB pour un remboursement
     * @param company
     *             Une socit
     * @param amount
     *             Le montant total des enregistrements 'destinataire'
     * @return
     */
    private String createReimbursementTotalCFONB(BigDecimal amount) {

        // Code opration
        String operationCode = this.cfonbConfig.getTransferOperationCodeExportCFONB();

        return this.createTotalCFONB(amount, operationCode);
    }

    /**
     * Fonction permettant de crer un enregistrement 'total' au format CFONB pour un chancier
     * @param company
     *             Une socit
     * @param amount
     *             Le montant total des enregistrements 'destinataire'
     * @return
     *             L'enregistrement 'total'
     */
    private String createPaymentScheduleTotalCFONB(Company company, BigDecimal amount) {

        // Code opration
        String operationCode = this.cfonbConfig.getDirectDebitOperationCodeExportCFONB();

        return this.createTotalCFONB(amount, operationCode);
    }

    /**
     * Fonction permettant de crer un enregistrement 'total' au format CFONB
     * @param company
     *             Une socit
     * @param amount
     *             Le montant total des enregistrements 'destinataire'
     * @param operationCode
     *       Le type d'opration :
     *       <ul>
      *      <li>0 = Virement</li>
      *      <li>1 = Prlvement</li>
      *      <li>2 = TIP</li>
      *     </ul>
     * @return
     *             L'enregistrement 'total'
     */
    private String createTotalCFONB(BigDecimal amount, String operationCode) {
        String totalAmount = amount.setScale(2).toString().replace(".", "");

        // Rcupration des valeurs
        String a = this.cfonbConfig.getTotalRecordCodeExportCFONB(); // Code enregistrement
        String b1 = operationCode; // Code opration
        String b2 = ""; // Zone rserve
        String b3 = this.cfonbConfig.getSenderNumExportCFONB(); // Numro d'metteur
        String c1 = ""; // Zone rserve
        String c2 = ""; // Zone rserve
        String d1 = ""; // Zone rserve
        String d2 = ""; // Zone rserve
        String d3 = ""; // Zone rserve
        String d4 = ""; // Zone rserve
        String e = totalAmount; // Montant de la remise
        String f = ""; // Zone rserve
        String g1 = ""; // Zone rserve
        String g2 = ""; // Zone rserve

        // Tronquage / remplissage  droite (chaine de caractre)
        b2 = StringTool.fillStringRight(b2, ' ', 8);
        b3 = StringTool.fillStringRight(b3, ' ', 6);
        c1 = StringTool.fillStringRight(c1, ' ', 12);
        c2 = StringTool.fillStringRight(c2, ' ', 24);
        d1 = StringTool.fillStringRight(d1, ' ', 24);
        d2 = StringTool.fillStringRight(d2, ' ', 8);
        d3 = StringTool.fillStringRight(d3, ' ', 5);
        d4 = StringTool.fillStringRight(d4, ' ', 11);
        f = StringTool.fillStringRight(f, ' ', 31);
        g1 = StringTool.fillStringRight(g1, ' ', 5);
        g2 = StringTool.fillStringRight(g2, ' ', 6);

        // Tronquage / remplissage  gauche (nombre)
        a = StringTool.fillStringLeft(a, '0', 2);
        b1 = StringTool.fillStringLeft(b1, '0', 2);
        e = StringTool.fillStringLeft(e, '0', 16);

        return a + b1 + b2 + b3 + c1 + c2 + d1 + d2 + d3 + d4 + e + f + g1 + g2;
    }

    /**
     * Fonction permettant de crer le CFONB
     * @param senderCFONB
     *             Un enregistrement 'metteur'
     * @param recipientCFONB
     *             Un liste d'enregistrement 'destinataire'
     * @param totalCFONB
     *             Un enregistrement 'total'
     * @return
     *             Le CFONB
     */
    private List<String> createCFONBExport(String senderCFONB, List<String> recipientCFONB, String totalCFONB) {
        // checker meme compte emetteur
        // checker meme type de virement
        // checker meme date de rglement

        List<String> cFONB = new ArrayList<String>();
        cFONB.add(senderCFONB);
        cFONB.addAll(recipientCFONB);
        cFONB.add(totalCFONB);
        return cFONB;
    }

    /**
     * Procdure permettant de crer un fichier CFONB au format .dat
     * @param cFONB
     *          Le contenu du fichier, des enregistrements CFONB
     * @param dateTime
     *          La date permettant de dterminer le nom du fichier cr
     * @param destinationFolder
     *          Le rpertoire de destination
     * @param prefix
     *          Le prfix utilis
     * @throws AxelorException
     */
    private void createCFONBFile(List<String> cFONB, DateTime dateTime, String destinationFolder, String prefix)
            throws AxelorException {
        DateFormat yyyyMMddHHmmssFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String dateFileName = yyyyMMddHHmmssFormat.format(dateTime.toDate());
        String fileName = String.format("%s%s.dat", prefix, dateFileName);

        try {
            FileTool.writer(destinationFolder, fileName, cFONB);
        } catch (IOException e) {
            throw new AxelorException(
                    String.format(I18n.get(IExceptionMessage.CFONB_EXPORT_2), GeneralServiceImpl.EXCEPTION, e),
                    IException.CONFIGURATION_ERROR);
        }

    }

    /**
     * Mthode permettant de construire le Nom/Raison sociale du tiers payeur d'un mmoire
     * @param memory
     *             Un mmoire
     * @return
     *             Civilit + Nom + Prnom    si c'est une personne physique
     *             Civilit + Nom             sinon
     */
    private String getPayeurPartnerName(Partner partner) {

        if (partner.getTitleSelect() != null) {
            return String.format("%s %s", partner.getTitleSelect(), partner.getName());
        } else {
            return String.format("%s", partner.getName());
        }

    }

    /**
     * Mthode permettant de calculer le montant total des remboursements
     * @param reimbursementList
     *             Une liste de remboursement
     * @return
     *             Le montant total
     */
    private BigDecimal getTotalAmountReimbursementExport(List<Reimbursement> reimbursementList) {
        BigDecimal totalAmount = BigDecimal.ZERO;
        for (Reimbursement reimbursement : reimbursementList) {
            reimbursement = reimbursementRepo.find(reimbursement.getId());
            totalAmount = totalAmount.add(reimbursement.getAmountReimbursed());
        }
        return totalAmount;
    }

    /**
     * Fonction permettant de rcuprer le montant total  prlever d'une liste d'chance de mensu
     * @param paymentScheduleLineList
     *          Une liste d'chance de mensu
     * @return
     *          Le montant total  prlever
     */
    private BigDecimal getTotalAmountPaymentSchedule(List<PaymentScheduleLine> paymentScheduleLineList) {
        BigDecimal totalAmount = BigDecimal.ZERO;

        for (PaymentScheduleLine paymentScheduleLine : paymentScheduleLineList) {

            totalAmount = totalAmount
                    .add(paymentScheduleLineRepo.find(paymentScheduleLine.getId()).getDirectDebitAmount());

        }
        return totalAmount;
    }

    /**
     * Fonction permettant de rcuprer le montant total  prlever d'une liste d'chance de mensu
     * @param paymentScheduleLineList
     *          Une liste d'chance de mensu
     * @return
     *          Le montant total  prlever
     */
    private BigDecimal getTotalAmountInvoice(List<Invoice> invoiceList) {
        BigDecimal totalAmount = BigDecimal.ZERO;

        for (Invoice invoice : invoiceList) {

            totalAmount = totalAmount.add(invoiceRepo.find(invoice.getId()).getDirectDebitAmount());
        }

        return totalAmount;
    }

    /**
     * Procdure permettant de vrifier la conformit des champs en rapport avec les exports CFONB d'une socit
     * @param company
     *          La socit
     * @throws AxelorException
     */
    public void testCompanyExportCFONBField(Company company) throws AxelorException {

        AccountConfig accountConfig = cfonbConfigService.getAccountConfig(company);

        cfonbConfigService.getReimbursementExportFolderPathCFONB(accountConfig);
        cfonbConfigService.getPaymentScheduleExportFolderPathCFONB(accountConfig);

        this.init(cfonbConfigService.getCfonbConfig(company));

        cfonbConfigService.getSenderRecordCodeExportCFONB(this.cfonbConfig);
        cfonbConfigService.getSenderNumExportCFONB(this.cfonbConfig);
        cfonbConfigService.getSenderNameCodeExportCFONB(this.cfonbConfig);
        cfonbConfigService.getRecipientRecordCodeExportCFONB(this.cfonbConfig);
        cfonbConfigService.getTotalRecordCodeExportCFONB(this.cfonbConfig);
        cfonbConfigService.getTransferOperationCodeExportCFONB(this.cfonbConfig);
        cfonbConfigService.getDirectDebitOperationCodeExportCFONB(this.cfonbConfig);

    }

    /**
     * Procdure permettant de vrifier la conformit des champs d'un RIB
     * @param bankDetails
     *          Le RIB
     * @throws AxelorException
     */
    public void testBankDetailsField(BankDetails bankDetails) throws AxelorException {
        if (bankDetails.getSortCode() == null || bankDetails.getSortCode().isEmpty()) {
            throw new AxelorException(
                    String.format(I18n.get(IExceptionMessage.CFONB_EXPORT_3), GeneralServiceImpl.EXCEPTION,
                            bankDetails.getIban(), bankDetails.getPartner().getName()),
                    IException.CONFIGURATION_ERROR);
        }
        if (bankDetails.getAccountNbr() == null || bankDetails.getAccountNbr().isEmpty()) {
            throw new AxelorException(
                    String.format(I18n.get(IExceptionMessage.CFONB_EXPORT_4), GeneralServiceImpl.EXCEPTION,
                            bankDetails.getIban(), bankDetails.getPartner().getName()),
                    IException.CONFIGURATION_ERROR);
        }
        if (bankDetails.getBankCode() == null || bankDetails.getBankCode().isEmpty()) {
            throw new AxelorException(
                    String.format(I18n.get(IExceptionMessage.CFONB_EXPORT_5), GeneralServiceImpl.EXCEPTION,
                            bankDetails.getIban(), bankDetails.getPartner().getName()),
                    IException.CONFIGURATION_ERROR);
        }
        if (bankDetails.getBankAddress() == null || bankDetails.getBankAddress().isEmpty()) {
            throw new AxelorException(
                    String.format(I18n.get(IExceptionMessage.CFONB_EXPORT_6), GeneralServiceImpl.EXCEPTION,
                            bankDetails.getIban(), bankDetails.getPartner().getName()),
                    IException.CONFIGURATION_ERROR);
        }
    }

}