# -*- coding: utf-8 -*-
#  Copyright (c) 2019-2021 Ivan LUCAS.
#  Noethysweb, application de gestion multi-activités.
#  Distribué sous licence GNU GPL.

import logging
logger = logging.getLogger(__name__)
from core.utils import utils_dates, utils_impression, utils_preferences
from decimal import Decimal

from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors
# from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate, NextPageTemplate
from reportlab.platypus import Paragraph, Spacer, Table, TableStyle, PageBreak
# from reportlab.platypus.flowables import ParagraphAndImage, Image
# from reportlab.platypus.frames import Frame, ShowBoundaryValue
# from reportlab.lib.pagesizes import A4
# from reportlab.lib.units import inch, cm, mm
# from reportlab.lib.utils import ImageReader
# from reportlab.lib import colors
# from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
# from reportlab.pdfgen.canvas import Canvas
# from reportlab.graphics.barcode import code39, qr
# from reportlab.graphics.shapes import Drawing
# from reportlab.graphics import renderPDF
from reportlab.platypus.flowables import DocAssign, Flowable
from core.models import MessageFacture



def PeriodeComplete(mois, annee):
    listeMois = ("Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre")
    periodeComplete = "%s %d" % (listeMois[mois-1], annee)
    return periodeComplete

def GetDatesListes(listeDates):
    listeDatesTemp = []
    for dictTemp in listeDates :
        if type(dictTemp) == dict :
            date = dictTemp["date"]
        else :
            date = dictTemp
        if date not in listeDatesTemp :
            listeDatesTemp.append(date)
    return listeDatesTemp


class Impression(utils_impression.Impression):
    def __init__(self, *args, **kwds):
        self.mode = kwds.pop("mode", "facture")
        self.messages = MessageFacture.objects.all()
        utils_impression.Impression.__init__(self, *args, **kwds)

    def Draw(self):
        styleSheet = getSampleStyleSheet()
        h3 = styleSheet['Heading3']
        styleTexte = styleSheet['BodyText'] 
        styleTexte.fontName = "Helvetica"
        styleTexte.fontSize = 9
        styleTexte.borderPadding = 9
        styleTexte.leading = 12

        # Importation des messages de factures
        messages_factures = []
        for message in self.messages:
            if message.texte[-1] not in "!?.": message.texte += "."
            messages_factures.append("<b>%s : </b>%s" % (message.titre, message.texte))

        # ----------- Insertion du contenu des frames --------------
        listeNomsSansCivilite = []
        for IDfamille, dictValeur in self.dict_donnees.items():
            if isinstance(dictValeur, dict):
                listeNomsSansCivilite.append((dictValeur["nomSansCivilite"], IDfamille))
        listeNomsSansCivilite.sort() 
        
        for nomSansCivilite, IDfamille in listeNomsSansCivilite:
            dictValeur = self.dict_donnees[IDfamille]
            if dictValeur["select"] == True:
                
                self.story.append(DocAssign("ID", IDfamille))
                nomSansCivilite = dictValeur["nomSansCivilite"]
                self.story.append(utils_impression.Bookmark(nomSansCivilite, str(IDfamille)))

                # ------------------- TITRE -----------------
                if self.dict_options["afficher_titre"] == True:
                    titre = ""
                    if self.mode == "facture": titre = "Facture"
                    if self.mode == "attestation": titre = "Attestation de présence"
                    if self.mode == "devis": titre = "Devis"
                    if "texte_titre" in dictValeur: titre = dictValeur["texte_titre"]
                    dataTableau = []
                    largeursColonnes = [self.taille_cadre[2], ]
                    dataTableau.append((titre,))
                    texteDateDebut = utils_dates.ConvertDateENGtoFR(str(dictValeur["date_debut"]))
                    texteDateFin = utils_dates.ConvertDateENGtoFR(str(dictValeur["date_fin"]))
                    if self.dict_options["afficher_periode"] == True:
                        dataTableau.append((u"Période du %s au %s" % (texteDateDebut, texteDateFin),))
                    styles = [
                            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                            ('FONT', (0, 0), (0, 0), "Helvetica-Bold", int(self.dict_options["taille_texte_titre"])),
                            ('LINEBELOW', (0, 0), (0 ,0), 0.25, colors.black),
                            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
                            ]

                    if self.dict_options["afficher_periode"] == True:
                        styles.append(('FONT', (0, 1), (0, 1), "Helvetica", int(self.dict_options["taille_texte_periode"])))
                    tableau = Table(dataTableau, largeursColonnes)
                    tableau.setStyle(TableStyle(styles))
                    self.story.append(tableau)
                    self.story.append(Spacer(0, 20))

                if self.dict_options["texte_introduction"] != "":
                    paraStyle = ParagraphStyle(name="introduction",
                                          fontName="Helvetica",
                                          fontSize=int(self.dict_options["taille_texte_introduction"]),
                                          leading=14,
                                          spaceBefore=0,
                                          spaceafter=0,
                                          leftIndent=5,
                                          rightIndent=5,
                                          alignment=int(self.dict_options["alignement_texte_introduction"]),
                                          backColor=self.dict_options["couleur_fond_introduction"],
                                          borderColor=self.dict_options["couleur_bord_introduction"],
                                          borderWidth=0.5,
                                          borderPadding=5)
                    texte = dictValeur["texte_introduction"].replace("\\n", "<br/>")
                    if self.dict_options["style_texte_introduction"] == "0": texte = "<para>%s</para>" % texte
                    if self.dict_options["style_texte_introduction"] == "1": texte = "<para><i>%s</i></para>" % texte
                    if self.dict_options["style_texte_introduction"] == "2": texte = "<para><b>%s</b></para>" % texte
                    if self.dict_options["style_texte_introduction"] == "3": texte = "<para><i><b>%s</b></i></para>" % texte
                    self.story.append(Paragraph(texte, paraStyle))
                    self.story.append(Spacer(0, 20))

                    
                couleurFond = self.dict_options["couleur_fond_1"]
                couleurFondActivite = self.dict_options["couleur_fond_2"]

                # ------------------- TABLEAU CONTENU -----------------
                montantPeriode = Decimal(0)
                montantVentilation = Decimal(0)
                nbre_total_prestations_anterieures = 0

                # Recherche si TVA utilisée
                activeTVA = False
                for IDindividu, dictIndividus in dictValeur["individus"].items():
                    for IDactivite, dictActivites in dictIndividus["activites"].items():
                        for date, dictDates in dictActivites["presences"].items():
                            for dictPrestation in dictDates["unites"] :
                                if dictPrestation["tva"] != None and dictPrestation["tva"] != 0.0:
                                    activeTVA = True

                # Remplissage
                listeIndividusTemp = []
                for IDindividu, dictIndividus in dictValeur["individus"].items():
                    listeIndividusTemp.append((dictIndividus["texte"], IDindividu, dictIndividus))
                listeIndividusTemp.sort() 
                
                for texteTemp, IDindividu, dictIndividus in listeIndividusTemp:
                    
                    if dictIndividus["select"] == True :

                        nbre_prestations_anterieures = 0
                        listeIndexActivites = []
                        montantPeriode += dictIndividus["total"]
                        montantVentilation += dictIndividus["ventilation"]
                        
                        # Initialisation des largeurs de tableau
                        largeurColonneDate = int(self.dict_options["largeur_colonne_date"])
                        largeurColonneMontantHT = int(self.dict_options["largeur_colonne_montant_ht"])
                        largeurColonneTVA = int(self.dict_options["largeur_colonne_montant_tva"])
                        largeurColonneMontantTTC = int(self.dict_options["largeur_colonne_montant_ttc"])
                        largeurColonneBaseTTC = int(largeurColonneMontantTTC)
                        
                        if activeTVA == True and self.dict_options["affichage_prestations"] == "0":
                            largeurColonneIntitule = self.taille_cadre[2] - largeurColonneDate - largeurColonneMontantHT - largeurColonneTVA - largeurColonneMontantTTC
                            largeursColonnes = [largeurColonneDate, largeurColonneIntitule, largeurColonneMontantHT, largeurColonneTVA, largeurColonneMontantTTC]
                        else :
                            if self.dict_options["affichage_prestations"] != "0":
                                largeurColonneIntitule = self.taille_cadre[2] - largeurColonneDate - largeurColonneBaseTTC - largeurColonneMontantTTC
                                largeursColonnes = [largeurColonneDate, largeurColonneIntitule, largeurColonneBaseTTC, largeurColonneMontantTTC]
                            else :
                                largeurColonneIntitule = self.taille_cadre[2] - largeurColonneDate - largeurColonneMontantTTC
                                largeursColonnes = [largeurColonneDate, largeurColonneIntitule, largeurColonneMontantTTC]
                        
                        # Insertion du nom de l'individu
                        paraStyle = ParagraphStyle(name="individu",
                                              fontName="Helvetica",
                                              fontSize=int(self.dict_options["taille_texte_individu"]),
                                              leading=int(self.dict_options["taille_texte_individu"]),
                                              spaceBefore=0,
                                              spaceafter=0)
                        texteIndividu = Paragraph(dictIndividus["texte"], paraStyle)
                        dataTableau = []
                        dataTableau.append([texteIndividu,])
                        tableau = Table(dataTableau, [self.taille_cadre[2],])
                        listeStyles = [
                                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                ('FONT', (0, 0), (-1, -1), "Helvetica", int(self.dict_options["taille_texte_individu"])),
                                ('GRID', (0, 0), (-1, -1), 0.25, colors.black),
                                ('BACKGROUND', (0, 0), (-1, 0), couleurFond),
                                ]
                        tableau.setStyle(TableStyle(listeStyles))
                        self.story.append(tableau)
                        
                        # Insertion du nom de l'activité
                        listeIDactivite = []
                        for IDactivite, dictActivites in dictIndividus["activites"].items():
                            listeIDactivite.append((dictActivites["texte"], IDactivite, dictActivites))
                        listeIDactivite.sort() 
                        
                        for texteActivite, IDactivite, dictActivites in listeIDactivite:

                            texteActivite = dictActivites["texte"]
                            if texteActivite != None :
                                dataTableau = []
                                dataTableau.append([texteActivite,])
                                tableau = Table(dataTableau, [self.taille_cadre[2],])
                                listeStyles = [
                                    ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                    ('FONT', (0, 0), (-1, -1), "Helvetica", int(self.dict_options["taille_texte_activite"])),
                                    ('GRID', (0, 0), (-1, -1), 0.25, colors.black),
                                    ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
                                    ('BACKGROUND', (0, 0), (-1, 0), couleurFondActivite),
                                    ]
                                tableau.setStyle(TableStyle(listeStyles))
                                self.story.append(tableau)

                            # Style de paragraphe normal
                            paraStyle = ParagraphStyle(name="prestation",
                                          fontName="Helvetica",
                                          fontSize=int(self.dict_options["taille_texte_prestation"]),
                                          leading=int(self.dict_options["taille_texte_prestation"]),
                                          spaceBefore=0,
                                          spaceAfter=0)

                            paraLabelsColonnes = ParagraphStyle(name="paraLabelsColonnes",
                                          fontName="Helvetica",
                                          fontSize=int(self.dict_options["taille_texte_noms_colonnes"]),
                                          leading=int(self.dict_options["taille_texte_noms_colonnes"]),
                                          spaceBefore=0,
                                          spaceAfter=0)

                            if self.dict_options["affichage_prestations"] != "0":
                                
                                # -------------- MODE REGROUPE ----------------
                                
                                # Regroupement par prestations identiques
                                dictRegroupement = {}
                                for date, dictDates in dictActivites["presences"].items():
                                    total = dictDates["total"]
                                    for dictPrestation in dictDates["unites"]:
                                        label = dictPrestation["label"]
                                        listeDatesUnite = GetDatesListes(dictPrestation["listeDatesConso"])
                                        montant = dictPrestation["montant"]
                                        deductions = dictPrestation["deductions"]
                                        tva = dictPrestation["tva"]
                                        
                                        if self.dict_options["affichage_prestations"] == "1": labelkey = label
                                        if self.dict_options["affichage_prestations"] == "2": labelkey = label + " P.U. " + "%.2f %s" % (montant, utils_preferences.Get_symbole_monnaie())

                                        # Si c'est une prestation antérieure
                                        if date < dictValeur["date_debut"]:
                                            nbre_prestations_anterieures += 1
                                            nbre_total_prestations_anterieures += 1
                                            label += "*"

                                        if (labelkey in dictRegroupement) == False:
                                            dictRegroupement[labelkey] = {"labelpresta": label, "total": 0, "nbre": 0, "base": 0, "dates_forfait": None}
                                            dictRegroupement[labelkey]["base"] = montant
                                        
                                        dictRegroupement[labelkey]["total"] += montant
                                        dictRegroupement[labelkey]["nbre"] += 1
                                        
                                        if self.dict_options["affichage_prestations"] == "1":
                                            dictRegroupement[labelkey]["base"] = dictRegroupement[labelkey]["total"] / dictRegroupement[labelkey]["nbre"]
 
                                        if len(listeDatesUnite) > 1:
                                            listeDatesUnite.sort()
                                            date_debut = listeDatesUnite[0]
                                            date_fin = listeDatesUnite[-1]
                                            nbreDates = len(listeDatesUnite)
                                            dictRegroupement[labelkey]["dates_forfait"] = "<BR/><font size=5>Du %s au %s soit %d jours</font>" % (utils_dates.ConvertDateENGtoFR(date_debut), utils_dates.ConvertDateENGtoFR(date_fin), nbreDates)
        
                                # Insertion des prestations regroupées
                                listeLabels = list(dictRegroupement.keys()) 
                                listeLabels.sort() 

                                dataTableau = [(
                                    Paragraph("<para align='center'>Quantité</para>", paraLabelsColonnes),
                                    Paragraph("<para align='center'>Prestation</para>", paraLabelsColonnes),
                                    Paragraph("<para align='center'>Base</para>", paraLabelsColonnes),
                                    Paragraph("<para align='center'>Montant</para>", paraLabelsColonnes),
                                    ),]

                                for labelkey in listeLabels :
                                    label = dictRegroupement[labelkey]["labelpresta"]
                                    nbre = dictRegroupement[labelkey]["nbre"]
                                    total = dictRegroupement[labelkey]["total"]
                                    base = dictRegroupement[labelkey]["base"]

                                    # recherche d'un commentaire
                                    if "dictCommentaires" in self.dict_options:
                                        key = (label, IDactivite)
                                        if key in self.dict_options["dictCommentaires"]:
                                            commentaire = self.dict_options["dictCommentaires"][key]
                                            label = "%s <i><font color='#939393'>%s</font></i>" % (label, commentaire)
                                            
                                    # Formatage du label
                                    intitule = Paragraph(label, paraStyle)
                                    
                                    # Rajout des dates de forfait
                                    #dates_forfait = dictRegroupement[label]["dates_forfait"]
                                    #if dates_forfait != None :
                                    #    intitule = [intitule, Paragraph(dates_forfait, paraStyle)]

                                    dataTableau.append([Paragraph("<para align='center'>%d</para>" % nbre, paraStyle), intitule, Paragraph("<para align='center'>%.02f %s</para>" % (base, utils_preferences.Get_symbole_monnaie()), paraStyle), Paragraph(u"<para align='center'>%.02f %s</para>" % (total, utils_preferences.Get_symbole_monnaie()), paraStyle)])
 
                            else:
                                
                                # -------------------------------------------------------------- MODE DETAILLE ------------------------------------------------------------------


                                # Insertion de la date
                                listeDates = []
                                for date, dictDates in dictActivites["presences"].items():
                                    listeDates.append(date)
                                listeDates.sort() 
                                
                                paraStyle = ParagraphStyle(name="prestation",
                                              fontName="Helvetica",
                                              fontSize=int(self.dict_options["taille_texte_prestation"]),
                                              leading=int(self.dict_options["taille_texte_prestation"]),
                                              spaceBefore=0,
                                              spaceAfter=0)

                                dataTableau = []

                                if activeTVA == True :
                                    dataTableau.append([
                                        Paragraph("<para align='center'>Date</para>", paraLabelsColonnes),
                                        Paragraph("<para align='center'>Prestation</para>", paraLabelsColonnes),
                                        Paragraph("<para align='center'>Montant HT</para>", paraLabelsColonnes),
                                        Paragraph("<para align='center'>Taux TVA</para>", paraLabelsColonnes),
                                        Paragraph("<para align='center'>Montant TTC</para>", paraLabelsColonnes),
                                        ])

                                for date in listeDates:
                                    dictDates = dictActivites["presences"][date]

                                    dateFr = dictDates["texte"]
                                    prestations = dictDates["unites"]
                                    
                                    # Insertion des unités de présence
                                    listeIntitules = []
                                    listeMontantsHT = []
                                    listeTVA = []
                                    listeMontantsTTC = []
                                    texteIntitules = ""
                                    texteMontantsHT = ""
                                    texteTVA = ""
                                    texteMontantsTTC = ""
                                    
                                    # Tri par ordre alpha des prestations
                                    listeDictPrestations = []
                                    for dictPrestation in prestations:
                                        listeDictPrestations.append((dictPrestation["label"], dictPrestation))
                                    listeDictPrestations.sort() 
                                    
                                    for labelTemp, dictPrestation in listeDictPrestations:
                                        label = dictPrestation["label"]
                                        listeDatesUnite = GetDatesListes(dictPrestation["listeDatesConso"])
                                        montant_initial = dictPrestation["montant_initial"]
                                        montant = dictPrestation["montant"]
                                        deductions = dictPrestation["deductions"]
                                        tva = dictPrestation["tva"]

                                        # Date
                                        texteDate = Paragraph("<para align='center'>%s</para>" % dateFr, paraStyle)
                                        
                                        # recherche d'un commentaire
                                        if "dictCommentaires" in self.dict_options:
                                            key = (label, IDactivite)
                                            if key in self.dict_options["dictCommentaires"]:
                                                commentaire = self.dict_options["dictCommentaires"][key]
                                                label = "%s <i><font color='#939393'>%s</font></i>" % (label, commentaire)

                                        # Si c'est une prestation antérieure
                                        if date < dictValeur["date_debut"]:
                                            nbre_prestations_anterieures += 1
                                            nbre_total_prestations_anterieures += 1
                                            label += "*"

                                        # Affiche le Label de la prestation
                                        listeIntitules.append(Paragraph(label, paraStyle)) 
                                        
                                        # Recherche si c'est un forfait
                                        if len(listeDatesUnite) > 1:
                                            listeDatesUnite.sort()
                                            date_debut = listeDatesUnite[0]
                                            date_fin = listeDatesUnite[-1]
                                            nbreDates = len(listeDatesUnite)
                                            label = "<BR/><font size=5>Du %s au %s soit %d jours</font>" % (utils_dates.ConvertDateENGtoFR(date_debut), utils_dates.ConvertDateENGtoFR(date_fin), nbreDates)
                                            listeIntitules.append(Paragraph(label, paraStyle)) 
                                                                                
                                        # TVA
                                        if activeTVA == True:
                                            if tva == None : tva = 0.0
                                            montantHT = (100.0 * float(montant)) / (100 + float(tva))
                                            listeMontantsHT.append(Paragraph("<para align='center'>%.02f %s</para>" % (montantHT, utils_preferences.Get_symbole_monnaie()), paraStyle))
                                            listeTVA.append(Paragraph("<para align='center'>%.02f %%</para>" % tva, paraStyle))
                                        else :
                                            listeMontantsHT.append("")
                                            listeTVA.append("")
                                            
                                        # Affiche total
                                        listeMontantsTTC.append(Paragraph(u"<para align='center'>%.02f %s</para>" % (montant, utils_preferences.Get_symbole_monnaie()), paraStyle))
                                    
                                        # Déductions
                                        if len(deductions) > 0:
                                            for dictDeduction in deductions :
                                                listeIntitules.append(Paragraph("<para align='left'><font size=5 color='#939393'>- %.02f %s : %s</font></para>" % (dictDeduction["montant"], utils_preferences.Get_symbole_monnaie(), dictDeduction["label"]), paraStyle))
                                                #listeIntitules.append(Paragraph("<para align='left'><font size=5 color='#939393'>%s</font></para>" % dictDeduction["label"], paraStyle))
                                                listeMontantsHT.append(Paragraph("&nbsp;", paraStyle))
                                                listeTVA.append(Paragraph("&nbsp;", paraStyle))
                                                listeMontantsTTC.append(Paragraph("&nbsp;", paraStyle))
                                                #listeMontantsTTC.append(Paragraph(u"<para align='center'><font size=5 color='#939393'>- %.02f %s</font></para>" % (dictDeduction["montant"], utils_preferences.Get_symbole_monnaie()), paraStyle))
                                                
                                        
                                    if len(listeIntitules) == 1:
                                        texteIntitules = listeIntitules[0]
                                        texteMontantsHT = listeMontantsHT[0]
                                        texteTVA = listeTVA[0]
                                        texteMontantsTTC = listeMontantsTTC[0]
                                    if len(listeIntitules) > 1:
                                        texteIntitules = listeIntitules
                                        texteMontantsHT = listeMontantsHT
                                        texteTVA = listeTVA
                                        texteMontantsTTC = listeMontantsTTC
                                                                        
                                    if activeTVA == True :
                                        dataTableau.append([texteDate, texteIntitules, texteMontantsHT, texteTVA, texteMontantsTTC])
                                    else :
                                        dataTableau.append([texteDate, texteIntitules, texteMontantsTTC])
                                    
                            # Style du tableau des prestations
                            tableau = Table(dataTableau, largeursColonnes)
                            listeStyles = [
                                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                ('FONT', (0, 0), (-1, -1), "Helvetica", int(self.dict_options["taille_texte_prestation"])),
                                ('GRID', (0, 0), (-1,-1), 0.25, colors.black), 
                                ('ALIGN', (0, 0), (-1, -1), 'CENTRE'),
                                ('ALIGN', (1, 0), (1, -1), 'LEFT'),
                                ('TOPPADDING', (0, 0), (-1, -1), 1), 
                                ('BOTTOMPADDING', (0, 0), (-1, -1), 3), 
                                ]
                            tableau.setStyle(TableStyle(listeStyles))
                            self.story.append(tableau)

                        # Préparation du texet des prestations antérieures
                        if nbre_prestations_anterieures == 0:
                            texte_prestations_anterieures = ""
                        elif nbre_prestations_anterieures == 1:
                            texte_prestations_anterieures = "* 1 prestation antérieure reportée"
                        else :
                            texte_prestations_anterieures = "* %d prestations antérieures reportées" % nbre_prestations_anterieures

                        # Insertion des totaux
                        dataTableau = []
                        if activeTVA == True and self.dict_options["affichage_prestations"] == "0":
                            dataTableau.append([texte_prestations_anterieures, "", "", "", Paragraph("<para align='center'>%.02f %s</para>" % (dictIndividus["total"], utils_preferences.Get_symbole_monnaie()), paraStyle)])
                        else :
                            if self.dict_options["affichage_prestations"] != "0" :
                                dataTableau.append([texte_prestations_anterieures, "", "", Paragraph("<para align='center'>%.02f %s</para>" % (dictIndividus["total"], utils_preferences.Get_symbole_monnaie()), paraStyle)])
                            else :
                                dataTableau.append([texte_prestations_anterieures, "", Paragraph("<para align='center'>%.02f %s</para>" % (dictIndividus["total"], utils_preferences.Get_symbole_monnaie()), paraStyle)])
                        
                        listeStyles = [
                                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                ('FONT', (0, 0), (-1, -1), "Helvetica", int(self.dict_options["taille_texte_prestation"])),
                                ('GRID', (-1, -1), (-1,-1), 0.25, colors.black), 
                                ('ALIGN', (-1, -1), (-1, -1), 'CENTRE'),
                                ('BACKGROUND', (-1, -1), (-1, -1), couleurFond), 
                                ('TOPPADDING', (0, 0), (-1, -1), 1), 
                                ('BOTTOMPADDING', (0, 0), (-1, -1), 3),
                                ('SPAN', (0, -1), (-2, -1)), # Fusion de la dernière ligne pour le texte_prestations_anterieures
                                ('FONT', (0, -1), (0, -1), "Helvetica", int(self.dict_options["taille_texte_prestations_anterieures"])),
                            ]
                            
                        # Création du tableau
                        tableau = Table(dataTableau, largeursColonnes)
                        tableau.setStyle(TableStyle(listeStyles))
                        self.story.append(tableau)
                        self.story.append(Spacer(0, 10))
                
                # Intégration des messages, des reports et des qf
                listeMessages = []
                paraStyle = ParagraphStyle(name="message",
                                          fontName="Helvetica",
                                          fontSize=int(self.dict_options["taille_texte_messages"]),
                                          leading=int(self.dict_options["taille_texte_messages"]),
                                          spaceAfter=2)

                # Texte Prestations antérieures
                texte_prestations_anterieures = self.dict_options["texte_prestations_anterieures"]
                if nbre_total_prestations_anterieures > 0 and len(texte_prestations_anterieures) > 0:
                    texte = "<b>%d prestations antérieures : </b>%s" % (nbre_total_prestations_anterieures, texte_prestations_anterieures)
                    listeMessages.append(Paragraph(texte, paraStyle))

                # QF aux dates de facture
                if self.mode == "facture" and self.dict_options["afficher_qf_dates"] == True:
                    dictQfdates = dictValeur["qfdates"]
                    listeDates = list(dictQfdates.keys()) 
                    listeDates.sort() 
                    if len(listeDates) > 0:
                        for dates in listeDates :
                            qf = dictQfdates[dates]
                            texteQf = "<b>Votre quotient familial : </b>Votre QF est de %s sur la période %s." % (qf, dates)
                            listeMessages.append(Paragraph(texteQf, paraStyle))

                # Reports
                if self.mode == "facture" and self.dict_options["afficher_impayes"] == True:
                    dictReports = dictValeur["reports"]
                    listePeriodes = list(dictReports.keys()) 
                    listePeriodes.sort() 
                    if len(listePeriodes) > 0:
                        if self.dict_options["integrer_impayes"] == True:
                            texteReport = "<b>Détail des impayés : </b>"
                        else :
                            texteReport = "<b>Impayés : </b>Merci de bien vouloir nous retourner également le règlement des prestations impayées suivantes : "
                        for periode in listePeriodes:
                            annee, mois = periode
                            nomPeriode = PeriodeComplete(mois, annee)
                            montant_impaye = dictReports[periode]
                            texteReport += "%s (%.02f %s), " % (nomPeriode, montant_impaye, utils_preferences.Get_symbole_monnaie())
                        texteReport = texteReport[:-2] + "."
                        listeMessages.append(Paragraph(texteReport, paraStyle))
                
                # Règlements
                if self.mode == "facture" and self.dict_options["afficher_reglements"] == True:
                    dictReglements = dictValeur["reglements"]
                    if len(dictReglements) > 0 :
                        listeTextesReglements = []
                        for IDreglement, dictTemp in dictReglements.items():
                            if dictTemp["emetteur"] not in ("", None) :
                                emetteur = " (%s) " % dictTemp["emetteur"]
                            else :
                                emetteur = ""
                            if dictTemp["numero"] not in ("", None) :
                                numero = " n°%s " % dictTemp["numero"]
                            else :
                                numero = ""
                                
                            montantReglement = "%.02f %s" % (dictTemp["montant"], utils_preferences.Get_symbole_monnaie())
                            montantVentilation = "%.02f %s" % (dictTemp["ventilation"], utils_preferences.Get_symbole_monnaie())
                            if dictTemp["ventilation"] != dictTemp["montant"] :
                                texteMontant = u"%s utilisés sur %s" % (montantVentilation, montantReglement)
                            else :
                                texteMontant = montantReglement
                                
                            texte = "%s%s%s de %s (%s)" % (dictTemp["mode"], numero, emetteur, dictTemp["payeur"], texteMontant)
                            listeTextesReglements.append(texte)
                        
                        if dictValeur["solde"] > Decimal(0) :
                            intro = "Période partiellement réglée avec"
                        else :
                            intro = "Période réglée en intégralité avec"
                            
                        texteReglements = "<b>Règlement : </b> %s %s." % (intro, " + ".join(listeTextesReglements))
                        listeMessages.append(Paragraph(texteReglements, paraStyle))
                                
                # Messages
                if self.mode == "facture":
                    if self.dict_options["afficher_messages"] == True:
                        for message in messages_factures:
                            listeMessages.append(Paragraph(message, paraStyle))

                        for message_familial in dictValeur["messages_familiaux"]:
                            texte = message_familial["texte"]
                            if len(texte) > 0 and texte[-1] not in ".!?":
                                texte = texte + "."
                            texte = "<b>Message : </b>%s" % texte
                            listeMessages.append(Paragraph(texte, paraStyle))

                if len(listeMessages) > 0:
                    listeMessages.insert(0, Paragraph("<u>Informations :</u>", paraStyle))
                
                # ------------------ CADRE TOTAUX ------------------------
                dataTableau = []
                largeurColonneLabel = 110
                largeursColonnes = [self.taille_cadre[2] - largeurColonneMontantTTC - largeurColonneLabel, largeurColonneLabel, largeurColonneMontantTTC]

                if self.mode == "devis":
                    dataTableau.append((listeMessages, "Total :", "%.02f %s" % (dictValeur["total"], utils_preferences.Get_symbole_monnaie())))
                else:
                    dataTableau.append((listeMessages, "Total période :", u"%.02f %s" % (dictValeur["total"], utils_preferences.Get_symbole_monnaie())))
                    dataTableau.append(("", "Montant déjà réglé :", u"%.02f %s" % (dictValeur["ventilation"], utils_preferences.Get_symbole_monnaie())))
                
                    if self.mode == "facture" and self.dict_options["integrer_impayes"] == True and dictValeur["total_reports"] > 0.0:
                        dataTableau.append(("", "Report impayés :", "%.02f %s" % (dictValeur["total_reports"], utils_preferences.Get_symbole_monnaie()) ))
                        dataTableau.append(("", "Reste à régler :", "%.02f %s" % (dictValeur["solde"] + dictValeur["total_reports"], utils_preferences.Get_symbole_monnaie()) ))
                        rowHeights=[10, 10, 10, None]
                    else :
                        dataTableau.append(("", "Reste à régler :", "%.02f %s" % (dictValeur["solde"], utils_preferences.Get_symbole_monnaie()) ))
                        rowHeights=[18, 18, None]
                    
                style = [
                        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), 

                        # Lignes Période, avoir, impayés
                        ('FONT', (1, 0), (1, -2), "Helvetica", 8),
                        ('FONT', (2, 0), (2, -2), "Helvetica-Bold", 8),
                        
                        # Ligne Reste à régler
                        ('FONT', (1, -1), (1, -1), "Helvetica-Bold", int(self.dict_options["taille_texte_labels_totaux"])),
                        ('FONT', (2, -1), (2, -1), "Helvetica-Bold", int(self.dict_options["taille_texte_montants_totaux"])),
                        
                        ('GRID', (2, 0), (2, -1), 0.25, colors.black),
                        
                        ('ALIGN', (1, 0), (1, -1), 'RIGHT'),
                        ('ALIGN', (2, 0), (2, -1), 'CENTRE'), 
                        ('BACKGROUND', (2, -1), (2, -1), couleurFond),
                        
                        ('SPAN', (0, 0), (0, -1)), 
                        ]
                
                if self.mode == "facture" and len(listeMessages) > 0:
                    #style.append( ('BACKGROUND', (0, 0), (0, 0), couleurFondActivite) )
                    style.append( ('FONT', (0, 0), (0, -1), "Helvetica", 8))
                    style.append( ('VALIGN', (0, 0), (0, -1), 'TOP'))
                    
                tableau = Table(dataTableau, largeursColonnes)
                tableau.setStyle(TableStyle(style))
                self.story.append(tableau)
                
                # ------------------------- PRELEVEMENTS --------------------
                if "afficher_avis_prelevements" in self.dict_options and "prelevement" in dictValeur:
                    if dictValeur["prelevement"] != None and self.dict_options["afficher_avis_prelevements"] == True:
                        paraStyle = ParagraphStyle(name="intro",
                              fontName="Helvetica",
                              fontSize=8,
                              leading=11,
                              spaceBefore=2,
                              spaceafter=2,
                              alignment=1,
                              backColor=couleurFondActivite)
                        self.story.append(Spacer(0, 20))
                        self.story.append(Paragraph(u"<para align='center'><i>%s</i></para>" % dictValeur["prelevement"], paraStyle))
                
                # Texte conclusion
                if self.dict_options["texte_conclusion"] != "":
                    self.story.append(Spacer(0, 20))
                    paraStyle = ParagraphStyle(name="conclusion",
                                          fontName="Helvetica",
                                          fontSize=int(self.dict_options["taille_texte_conclusion"]),
                                          leading=14,
                                          spaceBefore=0,
                                          spaceafter=0,
                                          leftIndent=5,
                                          rightIndent=5,
                                          alignment=int(self.dict_options["alignement_texte_conclusion"]),
                                          backColor=self.dict_options["couleur_fond_conclusion"],
                                          borderColor=self.dict_options["couleur_bord_conclusion"],
                                          borderWidth=0.5,
                                          borderPadding=5)
            
                    texte = dictValeur["texte_conclusion"].replace("\\n", "<br/>")
                    if self.dict_options["style_texte_conclusion"] == "0": texte = "<para>%s</para>" % texte
                    if self.dict_options["style_texte_conclusion"] == "1": texte = "<para><i>%s</i></para>" % texte
                    if self.dict_options["style_texte_conclusion"] == "2": texte = "<para><b>%s</b></para>" % texte
                    if self.dict_options["style_texte_conclusion"] == "3": texte = "<para><i><b>%s</b></i></para>" % texte
                    self.story.append(Paragraph(texte, paraStyle))
                    
                # Image signature
                # if self.dict_options["image_signature"] != "" :
                #     cheminImage = self.dict_options["image_signature"]
                #     if os.path.isfile(cheminImage) :
                #         img = Image(cheminImage)
                #         largeur, hauteur = int(img.drawWidth * 1.0 * self.dict_options["taille_image_signature"] / 100.0), int(img.drawHeight * 1.0 * self.dict_options["taille_image_signature"] / 100.0)
                #         if largeur > self.taille_cadre[2] or hauteur > self.taille_cadre[3] :
                #             raise Exception(_(u"L'image de signature est trop grande. Veuillez diminuer sa taille avec le parametre Taille."))
                #         img.drawWidth, img.drawHeight = largeur, hauteur
                #         if self.dict_options["alignement_image_signature"] == "0" : img.hAlign = "LEFT"
                #         if self.dict_options["alignement_image_signature"] == "1" : img.hAlign = "CENTER"
                #         if self.dict_options["alignement_image_signature"] == "2" : img.hAlign = "RIGHT"
                #         self.story.append(Spacer(0,20))
                #         self.story.append(img)

                # Saut de page
                self.story.append(PageBreak())



if __name__ == u"__main__":
    Impression()
