class CTRL(HTL.HyperTreeList): def __init__(self, parent): HTL.HyperTreeList.__init__(self, parent, -1) self.parent = parent self.dictImpression = {} # Paramètres self.mode_affichage = "mois" # "mois", "annee" self.affichage_details = True self.type = "depots" self.date_debut = None self.date_fin = None self.listeActivites = [] self.listeDepots = [] ## # Création de l'ImageList ## il = wx.ImageList(16, 16) ## self.img_ok = il.Add(wx.Bitmap(Chemins.GetStaticPath('Images/16x16/Ok.png'), wx.BITMAP_TYPE_PNG)) ## self.img_pasok = il.Add(wx.Bitmap(Chemins.GetStaticPath('Images/16x16/Interdit.png'), wx.BITMAP_TYPE_PNG)) ## self.AssignImageList(il) # wx.TR_COLUMN_LINES | | wx.TR_HAS_BUTTONS self.SetBackgroundColour(wx.WHITE) if 'phoenix' in wx.PlatformInfo: TR_COLUMN_LINES = HTL.TR_COLUMN_LINES else : TR_COLUMN_LINES = wx.TR_COLUMN_LINES self.SetAGWWindowStyleFlag(wx.TR_HIDE_ROOT | wx.TR_ROW_LINES | TR_COLUMN_LINES | wx.TR_HAS_BUTTONS | wx.TR_HAS_VARIABLE_ROW_HEIGHT | wx.TR_FULL_ROW_HIGHLIGHT ) # HTL.TR_NO_HEADER def SetModeAffichage(self, mode="depots"): self.mode_affichage = mode def SetAffichageDetails(self, etat=True): self.affichage_details = etat def SetTypeDepots(self, listeDepots=[]): self.type = "depots" self.listeDepots = listeDepots def SetTypePrestations(self, date_debut=None, date_fin=None, listeActivites=[]): self.type = "prestations" self.date_debut = date_debut self.date_fin = date_fin self.listeActivites = listeActivites def SetTypeVide(self): self.type = "vide" def Importation_depots(self): """ Importation des données """ DB = GestionDB.DB() if len(self.listeDepots) == 0 : conditionDepots = "()" elif len(self.listeDepots) == 1 : conditionDepots = "(%d)" % self.listeDepots[0] else : conditionDepots = str(tuple(self.listeDepots)) req = """SELECT depots.IDdepot, depots.date, nom, verrouillage, depots.IDcompte, SUM(reglements.montant) FROM depots LEFT JOIN reglements ON reglements.IDdepot = depots.IDdepot WHERE depots.IDdepot IN %s GROUP BY depots.IDdepot ORDER BY depots.date ;""" % conditionDepots DB.ExecuterReq(req) listeDonnees = DB.ResultatReq() dictDepots = {} for IDdepot, date, nom, verrouillage, IDcompte, montantTotal in listeDonnees : date = UTILS_Dates.DateEngEnDateDD(date) if montantTotal == None : montantTotal = 0.0 dictDepots[IDdepot] = {"date":date, "nom":nom, "verrouillage":verrouillage, "IDcompte":IDcompte, "montantTotal":montantTotal} DB.Close() return dictDepots def Importation_ventilation(self): """ Importation des données """ DB = GestionDB.DB() if self.type == "depots" : # Type Dépôts if len(self.listeDepots) == 0 : condition = "depots.IDdepot IN ()" elif len(self.listeDepots) == 1 : condition = "depots.IDdepot IN (%d)" % self.listeDepots[0] else : condition = "depots.IDdepot IN %s" % str(tuple(self.listeDepots)) else: # Type Prestations if len(self.listeActivites) == 0 : conditionActivites = "" elif len(self.listeActivites) == 1 : conditionActivites = "AND prestations.IDactivite=%d" % self.listeActivites[0] else : conditionActivites = "AND prestations.IDactivite IN %s" % str(tuple(self.listeActivites)) condition = "prestations.date>='%s' AND prestations.date<='%s' %s" % (self.date_debut, self.date_fin, conditionActivites) # Récupèration de la ventilation des prestations des dépôts req = """SELECT ventilation.IDventilation, ventilation.IDreglement, ventilation.IDprestation, ventilation.montant, reglements.date, reglements.date_saisie, depots.IDdepot, depots.date, prestations.date, prestations.label, prestations.IDactivite, activites.nom, activites.abrege FROM ventilation LEFT JOIN reglements ON reglements.IDreglement = ventilation.IDreglement LEFT JOIN prestations ON prestations.IDprestation = ventilation.IDprestation LEFT JOIN depots ON depots.IDdepot = reglements.IDdepot LEFT JOIN activites ON activites.IDactivite = prestations.IDactivite WHERE %s ORDER BY prestations.date; """ % condition DB.ExecuterReq(req) listeVentilation = DB.ResultatReq() dictVentilation = {} listePeriodes = [] dictIDreglements = {} for IDventilation, IDreglement, IDprestation, montantVentilation, dateReglement, dateSaisieReglement, IDdepot, dateDepotReglement, datePrestation, labelPrestation, IDactivite, nomActivite, abregeActivite in listeVentilation : dateReglement = UTILS_Dates.DateEngEnDateDD(dateReglement) dateSaisieReglement = UTILS_Dates.DateEngEnDateDD(dateSaisieReglement) dateDepotReglement = UTILS_Dates.DateEngEnDateDD(dateDepotReglement) datePrestation = UTILS_Dates.DateEngEnDateDD(datePrestation) # Compte le nombre de règlements dans chaque dépôt if dictIDreglements.has_key(IDdepot) == False : dictIDreglements[IDdepot] = [] if IDreglement not in dictIDreglements[IDdepot] : dictIDreglements[IDdepot].append(IDreglement) # Rajoute le nom de l'activité dans le label de la prestation if nomActivite != None : labelPrestation = u"%s - %s" % (nomActivite, labelPrestation) # Retient la période de ventilation if datePrestation != None : annee = datePrestation.year mois = datePrestation.month if self.mode_affichage == "mois" : periode = (annee, mois) else: periode = annee if periode not in listePeriodes : listePeriodes.append(periode) if dictVentilation.has_key(IDdepot) == False : dictVentilation[IDdepot] = {} if dictVentilation[IDdepot].has_key(periode) == False : dictVentilation[IDdepot][periode] = {} if dictVentilation[IDdepot][periode].has_key(labelPrestation) == False : dictVentilation[IDdepot][periode][labelPrestation] = 0.0 dictVentilation[IDdepot][periode][labelPrestation] += montantVentilation DB.Close() listePeriodes.sort() return dictVentilation, listePeriodes, dictIDreglements def CreationColonnes(self, listePeriodes=[]): """ Création des colonnes """ # Création de la première colonne self.AddColumn(_(u"Dépôts")) self.SetColumnWidth(0, 270) self.SetColumnAlignment(0, wx.ALIGN_LEFT) # Création des colonnes périodes numColonne = 1 if self.mode_affichage == "mois" : # Mode affichage MOIS for annee, mois in listePeriodes : self.AddColumn(PeriodeComplete(mois, annee)) self.SetColumnWidth(numColonne, 65) self.SetColumnAlignment(numColonne, wx.ALIGN_CENTRE) numColonne += 1 else: # Mode affichage ANNEE for annee in listePeriodes : self.AddColumn(str(annee)) self.SetColumnWidth(numColonne, 65) self.SetColumnAlignment(numColonne, wx.ALIGN_CENTRE) numColonne += 1 # Création de la colonne Non Ventilé if self.type == "depots" : self.AddColumn(_(u"Non ventilé")) self.SetColumnWidth(numColonne, 65) self.SetColumnAlignment(numColonne, wx.ALIGN_CENTRE) numColonne += 1 # Création de la colonne Total self.AddColumn(_(u"Total")) self.SetColumnWidth(numColonne, 75) self.SetColumnAlignment(numColonne, wx.ALIGN_CENTRE) def MAJ(self): """ Remplissage du ctrl """ if self.type == "vide" : self.RAZ() return # Importation des données dictVentilation, listePeriodes, dictIDreglements = self.Importation_ventilation() if self.type == "prestations" : self.listeDepots = dictVentilation.keys() if None in self.listeDepots : self.listeDepots.remove(None) dictDepots = self.Importation_depots() # Si on est en type PRESTATIONS, on crée un dépôt virtuel pour les règlements non déposées if self.type == "prestations" and dictVentilation.has_key(None) : dictDepots[None] = {"date":datetime.date(1977, 1, 1), "nom":_(u"----- %d règlements non déposés -----") % len(dictIDreglements[None]), "verrouillage":False, "IDcompte":None, "montantTotal":0.0} self.dictImpression = { "entete" : [], "contenu" : [], "total" : [], "coloration" : [] } # Mémorisation des colonnes dictColonnes = {} index = 1 self.dictImpression["entete"].append(_(u"Dépôts")) for periode in listePeriodes : dictColonnes[periode] = index if self.mode_affichage == "mois" : label = PeriodeComplete(periode[1], periode[0]) else: label = str(periode) self.dictImpression["entete"].append(label) index += 1 if self.type == "depots" : dictColonnes["sansVentilation"] = index self.dictImpression["entete"].append(_(u"Non ventilé")) index += 1 dictColonnes["total"] = index self.dictImpression["entete"].append(_(u"Total")) # Initialisation du CTRL self.RAZ() self.CreationColonnes(listePeriodes) self.root = self.AddRoot(_(u"Racine")) # Création des branches # ------------------ Branches DEPOTS ----------------- # Tri des dépôts par date de dépôt listeDepotsTemp = [] for IDdepot, dictDepot in dictDepots.iteritems() : if dictDepot["date"] == None : dateDepot = datetime.date(1977, 1, 1) else: dateDepot = dictDepot["date"] listeDepotsTemp.append( (dateDepot, IDdepot, dictDepot) ) listeDepotsTemp.sort() dictLigneTotal = {} totalSansVentilation = 0.0 for dateDepot, IDdepot, dictDepot in listeDepotsTemp : if dateDepot == datetime.date(1977, 1, 1) : dateStr = _(u"Sans date de dépôt") else: dateStr = u"%02d/%02d/%04d" % (dateDepot.day, dateDepot.month, dateDepot.year) label = u"%s (%s - %.2f %s)" % (dictDepot["nom"], dateStr, dictDepot["montantTotal"], SYMBOLE) if IDdepot == None : label = dictDepot["nom"] niveauDepot = self.AppendItem(self.root, label) impressionLigne = [label,] if self.affichage_details == True : self.dictImpression["coloration"].append(len(self.dictImpression["contenu"])) # Colonnes périodes totalLigne = 0.0 for periode in listePeriodes : if dictVentilation.has_key(IDdepot) and dictVentilation[IDdepot].has_key(periode) : valeur = 0.0 for labelPrestation, montantVentilation in dictVentilation[IDdepot][periode].iteritems() : valeur += montantVentilation totalLigne += valeur texte = u"%.2f %s" % (valeur, SYMBOLE) self.SetItemText(niveauDepot, texte, dictColonnes[periode]) impressionLigne.append(texte) else: impressionLigne.append("") # Colonne NON VENTILE if self.type == "depots" : totalDepot = dictDepots[IDdepot]["montantTotal"] sansVentilation = totalDepot - totalLigne if sansVentilation != 0.0 : totalLigne += sansVentilation totalSansVentilation += sansVentilation texte = u"%.2f %s" % (sansVentilation, SYMBOLE) self.SetItemText(niveauDepot, texte, dictColonnes["sansVentilation"]) impressionLigne.append(texte) else: impressionLigne.append(u"") # Colonne Total texte = u"%.2f %s" % (totalLigne, SYMBOLE) self.SetItemText(niveauDepot, texte, dictColonnes["total"]) impressionLigne.append(texte) self.dictImpression["contenu"].append(impressionLigne) # ----------------- Branches LABELS DE PRESTATIONS ------------- listeLabelsPrestations = [] for periode in listePeriodes : if dictVentilation.has_key(IDdepot) : if dictVentilation[IDdepot].has_key(periode) : for labelPrestation, montantVentilation in dictVentilation[IDdepot][periode].iteritems() : if labelPrestation not in listeLabelsPrestations : listeLabelsPrestations.append(labelPrestation) listeLabelsPrestations.sort() for labelPrestation in listeLabelsPrestations : if self.affichage_details == True : niveauPrestation = self.AppendItem(niveauDepot, labelPrestation) self.SetItemFont(niveauPrestation, wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.SetItemTextColour(niveauPrestation, wx.Colour(160, 160, 160) ) impressionLigne = [labelPrestation,] # Colonnes périodes totalLigne = 0.0 for periode in listePeriodes : texte = None if dictVentilation.has_key(IDdepot) : if dictVentilation[IDdepot].has_key(periode) : if dictVentilation[IDdepot][periode].has_key(labelPrestation) : valeur = dictVentilation[IDdepot][periode][labelPrestation] totalLigne += valeur if dictLigneTotal.has_key(labelPrestation) == False : dictLigneTotal[labelPrestation] = {} if dictLigneTotal[labelPrestation].has_key(periode) == False : dictLigneTotal[labelPrestation][periode] = 0.0 dictLigneTotal[labelPrestation][periode] += valeur if self.affichage_details == True : texte = u"%.2f %s" % (valeur, SYMBOLE) self.SetItemText(niveauPrestation, texte, dictColonnes[periode]) impressionLigne.append(texte) if texte == None and self.affichage_details == True : impressionLigne.append("") # Colonne Non ventilé if self.type == "depots" and self.affichage_details == True : impressionLigne.append(u"") # Colonne Total if self.affichage_details == True : texte = u"%.2f %s" % (totalLigne, SYMBOLE) self.SetItemText(niveauPrestation, texte, dictColonnes["total"]) impressionLigne.append(texte) self.dictImpression["contenu"].append(impressionLigne) # ------------ Ligne Total -------------- niveauTotal = self.AppendItem(self.root, _(u"Total")) self.SetItemBackgroundColour(niveauTotal, wx.Colour(150, 150, 150) ) self.SetItemTextColour(niveauTotal, wx.Colour(255, 255, 255) ) impressionLigne = [_(u"Total"),] listeLabels = dictLigneTotal.keys() listeLabels.sort() # Ligne de TOTAL pour chaque PERIODE totalLigne = 0.0 for periode in listePeriodes : totalColonne = 0.0 for dateDepot, IDdepot, dictDepot in listeDepotsTemp : for label in listeLabels : if dictVentilation.has_key(IDdepot) : if dictVentilation[IDdepot].has_key(periode): if dictVentilation[IDdepot][periode].has_key(label): valeur = dictVentilation[IDdepot][periode][label] totalColonne += valeur texte = u"%.2f %s" % (totalColonne, SYMBOLE) totalLigne += totalColonne self.SetItemText(niveauTotal, texte, dictColonnes[periode]) impressionLigne.append(texte) # Total SANS VENTILATION if self.type == "depots" : texte = u"%.2f %s" % (totalSansVentilation, SYMBOLE) totalLigne += totalSansVentilation self.SetItemText(niveauTotal, texte, dictColonnes["sansVentilation"]) impressionLigne.append(texte) # Total de la ligne de Total texte = u"%.2f %s" % (totalLigne, SYMBOLE) self.SetItemText(niveauTotal, texte, dictColonnes["total"]) impressionLigne.append(texte) self.dictImpression["total"].append(impressionLigne) # Total des colonnes par label de prestation if self.affichage_details == True : for label in listeLabels : niveauPrestation = self.AppendItem(niveauTotal, label) self.SetItemFont(niveauPrestation, wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.SetItemTextColour(niveauPrestation, wx.Colour(120, 120, 120) ) self.SetItemBackgroundColour(niveauPrestation, wx.Colour(210, 210, 210) ) impressionLigne = [label,] totalLigne = 0.0 for periode in listePeriodes : texte = None if dictLigneTotal.has_key(label): if dictLigneTotal[label].has_key(periode) : valeur = dictLigneTotal[label][periode] totalLigne += valeur texte = u"%.2f %s" % (valeur, SYMBOLE) self.SetItemText(niveauPrestation, texte, dictColonnes[periode]) impressionLigne.append(texte) if texte == None : impressionLigne.append(u"") # Colonne None ventilé if self.type == "depots" : impressionLigne.append(u"") # Colonne Total texte = u"%.2f %s" % (totalLigne, SYMBOLE) self.SetItemText(niveauPrestation, texte, dictColonnes["total"]) impressionLigne.append(texte) self.dictImpression["total"].append(impressionLigne) self.ExpandAllChildren(self.root) def RAZ(self): self.DeleteAllItems() for indexColonne in range(self.GetColumnCount()-1, -1, -1) : self.RemoveColumn(indexColonne) self.DeleteRoot() def DevelopperTout(self): item = self.GetFirstChild(self.root)[0] for index in range(0, self.GetChildrenCount(self.root)-1) : self.Expand(item) item = self.GetNext(item) def ReduireTout(self): item = self.GetFirstChild(self.root)[0] for index in range(0, self.GetChildrenCount(self.root)-1) : self.Collapse(item) item = self.GetNext(item) def Imprimer(self): dlg = DLG_Options_impression_pdf.Dialog(self, categorie="synthese_ventilation", ctrl=CTRL_Parametres) if dlg.ShowModal() == wx.ID_OK: dictOptions = dlg.GetOptions() dlg.Destroy() else : dlg.Destroy() return # Création du PDF from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.styles import ParagraphStyle hauteur_page = A4[0] largeur_page = A4[1] # Initialisation du PDF nomDoc = FonctionsPerso.GenerationNomDoc("STATS_VENTILATION", "pdf") if sys.platform.startswith("win") : nomDoc = nomDoc.replace("/", "\\") doc = SimpleDocTemplate(nomDoc, pagesize=(largeur_page, hauteur_page), topMargin=30, bottomMargin=30) story = [] # Création du titre du document def Header(): dataTableau = [] largeursColonnes = ( (largeur_page-175, 100) ) dateDuJour = UTILS_Dates.DateEngFr(str(datetime.date.today())) dataTableau.append( (_(u"Analyse croisée ventilation/dépôts"), _(u"%s\nEdité le %s") % (UTILS_Organisateur.GetNom(), dateDuJour)) ) style = TableStyle([ ('BOX', (0,0), (-1,-1), 0.25, colors.black), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('ALIGN', (0,0), (0,0), 'LEFT'), ('FONT',(0,0),(0,0), "Helvetica-Bold", 16), ('ALIGN', (1,0), (1,0), 'RIGHT'), ('FONT',(1,0),(1,0), "Helvetica", 6), ]) tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(style) story.append(tableau) story.append(Spacer(0,20)) # Insère un header Header() # Tableau dataTableau = [] largeursColonnes = [dictOptions["largeur_colonne_labels"],] for x in range(0, len(self.dictImpression["entete"])-1): largeursColonnes.append(dictOptions["largeur_colonne_valeurs"]) # Entetes labels dataTableau.append(self.dictImpression["entete"]) paraNormal = ParagraphStyle(name="normal", fontName="Helvetica", fontSize=dictOptions["taille_texte"], spaceAfter=0, leading=dictOptions["taille_texte"]+1, spaceBefore=0) paraTitre = ParagraphStyle(name="titre", fontName="Helvetica-Bold", fontSize=dictOptions["taille_texte"], spaceAfter=0, leading=dictOptions["taille_texte"]+1, spaceBefore=0) # Contenu du tableau listeRubriques = ("contenu", "total") for rubrique in listeRubriques : listeLignes = self.dictImpression[rubrique] indexLigne = 0 for ligne in listeLignes : ligneTemp = [] indexColonne = 0 for texte in ligne : # Aligne à droite les montants if indexColonne > 0 : texte = _(u"<para align='right'>%s</para>") % texte case = Paragraph(texte, paraNormal) # Ligne de titre if rubrique == "contenu" and indexLigne in self.dictImpression["coloration"] : case = Paragraph(texte, paraTitre) ligneTemp.append(case) indexColonne += 1 dataTableau.append(ligneTemp) indexLigne += 1 positionLigneTotal = len(self.dictImpression["contenu"]) + 1 listeStyles = [ ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), # Centre verticalement toutes les cases ('FONT',(0,0),(-1,-1), "Helvetica", dictOptions["taille_texte"]), # Donne la police de caract. + taille de police ('GRID', (0,0), (-1,-1), 0.25, colors.black), # Crée la bordure noire pour tout le tableau ('ALIGN', (0,0), (-1,-1), 'CENTRE'), # Centre les cases ('BACKGROUND', (0,0), (-1,0), UTILS_Divers.ConvertCouleurWXpourPDF(dictOptions["couleur_fond_entetes"]) ), # Donne la couleur de fond du label ('BACKGROUND', (0, positionLigneTotal), (-1, positionLigneTotal), UTILS_Divers.ConvertCouleurWXpourPDF(dictOptions["couleur_fond_total"]) ), # Donne la couleur de fond du label ] # Formatage des lignes "Activités" for indexColoration in self.dictImpression["coloration"] : listeStyles.append( ('BACKGROUND', (0, indexColoration+1), (-1, indexColoration+1), UTILS_Divers.ConvertCouleurWXpourPDF(dictOptions["couleur_fond_depot"]))) # Création du tableau tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(TableStyle(listeStyles)) story.append(tableau) story.append(Spacer(0,20)) # Enregistrement du PDF doc.build(story) # Affichage du PDF FonctionsPerso.LanceFichierExterne(nomDoc)
if (numColonne in dict_totaux_colonnes) == False: dict_totaux_colonnes[numColonne] = 0 dict_totaux_colonnes[numColonne] += valeur else: style = style_texte valeur = valeur.replace("\n", "<br/>") ligne.append(Paragraph(six.text_type(valeur), style)) numColonne += 1 # Ajout de la ligne au tableau dataTableau.append(ligne) # Style du tableau couleur_fond_entetes = UTILS_Divers.ConvertCouleurWXpourPDF( dictOptions["couleur_fond_entetes"]) couleur_fond_total = UTILS_Divers.ConvertCouleurWXpourPDF( dictOptions["couleur_fond_total"]) listeStyles = [ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('FONT', (0, 0), (-1, -1), "Helvetica", dictOptions["taille_texte"]), ('GRID', (0, 0), (-1, -1), 0.25, colors.black), ('ALIGN', (0, 1), (-2, -1), 'RIGHT'), # Centre les cases ('FONT', (0, 0), (0, -1), "Helvetica-Bold", dictOptions["taille_texte"]), ('FONT', (0, 0), (-1, 0), "Helvetica-Bold", dictOptions["taille_texte"]), ('BACKGROUND', (0, 0), (-1, 0), couleur_fond_entetes), ('BACKGROUND', (0, 0), (0, -1), couleur_fond_entetes),
def OnBoutonOk(self, event): dictParametres = self.ctrl_notebook.GetParametres() # Récupération et vérification des données listeActivites = dictParametres["liste_activites"] if len(listeActivites) == 0 : self.ctrl_notebook.AffichePage("generalites") dlg = wx.MessageDialog(self, _(u"Vous devez obligatoirement cocher au moins une activité !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Récupération et vérification des données listeGroupes = dictParametres["liste_groupes"] if len(dictParametres["liste_groupes"]) == 0 : self.ctrl_notebook.AffichePage("generalites") dlg = wx.MessageDialog(self, _(u"Vous devez obligatoirement cocher au moins un groupe !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Vérification qu'il y a des colonnes if not dictParametres["colonnes"]: dlg = wx.MessageDialog(self, _(u"Vous devez obligatoirement créer au moins une colonne !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Recherche les catégories utilisées liste_categories_utilisees = [] for nom_categorie, categories in dictParametres["colonnes"]: for IDcategorie in UTILS_Texte.ConvertStrToListe(categories): if IDcategorie not in liste_categories_utilisees : liste_categories_utilisees.append(IDcategorie) # Création du PDF from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak from reportlab.platypus.flowables import ParagraphAndImage, Image from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.styles import ParagraphStyle self.taille_page = A4 if dictParametres["orientation"] == "portrait" : self.hauteur_page = self.taille_page[1] self.largeur_page = self.taille_page[0] else: self.hauteur_page = self.taille_page[0] self.largeur_page = self.taille_page[1] # Création des conditions pour les requêtes SQL conditionsPeriodes = GetSQLdates(dictParametres["liste_periodes"]) if len(listeActivites) == 0 : conditionActivites = "()" elif len(listeActivites) == 1 : conditionActivites = "(%d)" % listeActivites[0] else : conditionActivites = str(tuple(listeActivites)) if len(listeGroupes) == 0 : conditionGroupes = "()" elif len(listeGroupes) == 1 : conditionGroupes = "(%d)" % listeGroupes[0] else : conditionGroupes = str(tuple(listeGroupes)) # Récupération des noms des groupes dictGroupes = dictParametres["dict_groupes"] dictActivites = dictParametres["dict_activites"] DB = GestionDB.DB() # ------------ MODE PRESENTS --------------------------------- if dictParametres["mode"] == "presents" : # Récupération de la liste des groupes ouverts sur cette période req = """SELECT IDouverture, IDactivite, IDunite, IDgroupe FROM ouvertures WHERE ouvertures.IDactivite IN %s AND %s AND IDgroupe IN %s ; """ % (conditionActivites, conditionsPeriodes, conditionGroupes) DB.ExecuterReq(req) listeOuvertures = DB.ResultatReq() dictOuvertures = {} for IDouverture, IDactivite, IDunite, IDgroupe in listeOuvertures : if (IDactivite in dictOuvertures) == False : dictOuvertures[IDactivite] = [] if IDgroupe not in dictOuvertures[IDactivite] : dictOuvertures[IDactivite].append(IDgroupe) # Récupération des individus grâce à leurs consommations req = """SELECT individus.IDindividu, IDactivite, IDgroupe, IDcivilite, nom, prenom, date_naiss FROM consommations LEFT JOIN individus ON individus.IDindividu = consommations.IDindividu WHERE consommations.etat IN ("reservation", "present") AND IDactivite IN %s AND %s GROUP BY individus.IDindividu, IDactivite, IDgroupe ORDER BY nom, prenom ;""" % (conditionActivites, conditionsPeriodes) DB.ExecuterReq(req) listeIndividus = DB.ResultatReq() # ------------ MODE INSCRITS --------------------------------- if dictParametres["mode"] == "inscrits" : dictOuvertures = {} for IDgroupe, dictGroupe in dictGroupes.items() : IDactivite = dictGroupe["IDactivite"] if (IDactivite in dictOuvertures) == False : dictOuvertures[IDactivite] = [] if IDgroupe not in dictOuvertures[IDactivite] : dictOuvertures[IDactivite].append(IDgroupe) # Récupération des individus grâce à leurs consommations req = """SELECT individus.IDindividu, IDactivite, IDgroupe, IDcivilite, nom, prenom, date_naiss FROM individus LEFT JOIN inscriptions ON inscriptions.IDindividu = individus.IDindividu WHERE inscriptions.statut='ok' AND IDactivite IN %s GROUP BY individus.IDindividu, IDactivite, IDgroupe ORDER BY nom, prenom ;""" % conditionActivites DB.ExecuterReq(req) listeIndividus = DB.ResultatReq() # Analyse des individus dictIndividus = {} listeIDindividus = [] for IDindividu, IDactivite, IDgroupe, IDcivilite, nom, prenom, date_naiss in listeIndividus: if date_naiss != None: date_naiss = UTILS_Dates.DateEngEnDateDD(date_naiss) age = self.GetAge(date_naiss) # Mémorisation de l'individu dictIndividus[IDindividu] = { "IDcivilite": IDcivilite, "nom": nom, "prenom": prenom, "age": age, "date_naiss": date_naiss, "IDgroupe": IDgroupe, "IDactivite": IDactivite, } # Mémorisation du IDindividu if IDindividu not in listeIDindividus: listeIDindividus.append(IDindividu) # Dict Informations médicales req = """SELECT IDprobleme, IDindividu, IDtype, intitule, date_debut, date_fin, description, traitement_medical, description_traitement, date_debut_traitement, date_fin_traitement, eviction, date_debut_eviction, date_fin_eviction FROM problemes_sante WHERE diffusion_listing_enfants=1 ;""" DB.ExecuterReq(req) listeInformations = DB.ResultatReq() DB.Close() dictInfosMedicales = {} for IDprobleme, IDindividu, IDtype, intitule, date_debut, date_fin, description, traitement_medical, description_traitement, date_debut_traitement, date_fin_traitement, eviction, date_debut_eviction, date_fin_eviction in listeInformations : if (IDindividu in dictInfosMedicales) == False : dictInfosMedicales[IDindividu] = [] dictTemp = { "IDprobleme" : IDprobleme, "IDcategorie" : IDtype, "intitule" : intitule, "date_debut" : date_debut, "date_fin" : date_fin, "description" : description, "traitement_medical" : traitement_medical, "description_traitement" : description_traitement, "date_debut_traitement" : date_debut_traitement, "date_fin_traitement" : date_fin_traitement, "eviction" : eviction, "date_debut_eviction" : date_debut_eviction, "date_fin_eviction" : date_fin_eviction, } dictInfosMedicales[IDindividu].append(dictTemp) # Récupération des photos individuelles dictPhotos = {} taillePhoto = 128 if dictParametres["afficher_photos"] == "petite" : tailleImageFinal = 16 if dictParametres["afficher_photos"] == "moyenne" : tailleImageFinal = 32 if dictParametres["afficher_photos"] == "grande" : tailleImageFinal = 64 if dictParametres["afficher_photos"] != "non" : for IDindividu in listeIDindividus : IDcivilite = dictIndividus[IDindividu]["IDcivilite"] nomFichier = Chemins.GetStaticPath("Images/128x128/%s" % DICT_CIVILITES[IDcivilite]["nomImage"]) IDphoto, bmp = CTRL_Photo.GetPhoto(IDindividu=IDindividu, nomFichier=nomFichier, taillePhoto=(taillePhoto, taillePhoto), qualite=100) # Création de la photo dans le répertoire Temp nomFichier = UTILS_Fichiers.GetRepTemp(fichier="photoTmp%d.jpg" % IDindividu) bmp.SaveFile(nomFichier, type=wx.BITMAP_TYPE_JPEG) img = Image(nomFichier, width=tailleImageFinal, height=tailleImageFinal) dictPhotos[IDindividu] = img # ---------------- Création du PDF ------------------- # Initialisation du PDF nomDoc = FonctionsPerso.GenerationNomDoc("LISTE_INFORMATIONS_MEDICALES", "pdf") if sys.platform.startswith("win") : nomDoc = nomDoc.replace("/", "\\") doc = SimpleDocTemplate(nomDoc, pagesize=(self.largeur_page, self.hauteur_page), topMargin=30, bottomMargin=30) story = [] largeurContenu = self.largeur_page - 75 # Création du titre du document def Header(): dataTableau = [] largeursColonnes = ( (largeurContenu-100, 100) ) dateDuJour = UTILS_Dates.DateEngFr(str(datetime.date.today())) dataTableau.append( (_(u"Informations médicales"), _(u"%s\nEdité le %s") % (UTILS_Organisateur.GetNom(), dateDuJour)) ) style = TableStyle([ ('BOX', (0,0), (-1,-1), 0.25, colors.black), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('ALIGN', (0,0), (0,0), 'LEFT'), ('FONT',(0,0),(0,0), "Helvetica-Bold", 16), ('ALIGN', (1,0), (1,0), 'RIGHT'), ('FONT',(1,0),(1,0), "Helvetica", 6), ]) tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(style) story.append(tableau) story.append(Spacer(0,20)) # Insère un header Header() # Activités for IDactivite in listeActivites : # Groupes if IDactivite in dictOuvertures : nbreGroupes = len(dictOuvertures[IDactivite]) indexGroupe = 1 for IDgroupe in dictOuvertures[IDactivite] : nomGroupe = dictGroupes[IDgroupe]["nom"] if isinstance(dictActivites[IDactivite], dict): nomActivite = dictActivites[IDactivite]["nom"] else: nomActivite = dictActivites[IDactivite] # Initialisation du tableau dataTableau = [] largeursColonnes = [] labelsColonnes = [] # Recherche des entêtes de colonnes : if dictParametres["afficher_photos"] != "non" : labelsColonnes.append(_(u"Photo")) largeursColonnes.append(tailleImageFinal+6) labelsColonnes.append(_(u"Nom - prénom")) if dictParametres["largeur_colonne_nom"] == "automatique" : largeursColonnes.append(120) else : largeursColonnes.append(int(dictParametres["largeur_colonne_nom"])) if dictParametres["afficher_age"] == True : labelsColonnes.append(_(u"Âge")) if dictParametres["largeur_colonne_age"] == "automatique": largeursColonnes.append(20) else: largeursColonnes.append(int(dictParametres["largeur_colonne_age"])) # Calcule la largeur restante largeurRestante = largeurContenu - sum(largeursColonnes) # Calcul des largeurs de colonnes largeurColonnes = largeurRestante * 1.0 / len(dictParametres["colonnes"]) for nom_categorie, categories in dictParametres["colonnes"]: labelsColonnes.append(nom_categorie) largeursColonnes.append(largeurColonnes) # Création de l'entete de groupe ligne = [u"%s - %s" % (nomActivite, nomGroupe),] for x in range(0, len(labelsColonnes)-1): ligne.append("") dataTableau.append(ligne) # Création des entêtes ligne = [] for label in labelsColonnes : ligne.append(label) dataTableau.append(ligne) # --------- Création des lignes ----------- # Création d'une liste temporaire pour le tri listeIndividus = [] if IDactivite in dictOuvertures : if IDgroupe in dictOuvertures[IDactivite] : for IDindividu in listeIDindividus : dictIndividu = dictIndividus[IDindividu] if dictIndividu["IDgroupe"] == IDgroupe : valeursTri = (IDindividu, dictIndividu["nom"], dictIndividu["prenom"], dictIndividu["age"]) # + Sélection uniquement des individus avec infos if dictParametres["individus_avec_infos"] == False or (dictParametres["individus_avec_infos"] == True and IDindividu in dictInfosMedicales ) : listeIndividus.append(valeursTri) if dictParametres["tri"] == "nom" : paramTri = 1 # Nom if dictParametres["tri"] == "prenom" : paramTri = 2 # Prénom if dictParametres["tri"] == "age" : paramTri = 3 # Age if dictParametres["ordre"] == "croissant" : ordreDecroissant = False else: ordreDecroissant = True listeIndividus = sorted(listeIndividus, key=operator.itemgetter(paramTri), reverse=ordreDecroissant) # Récupération des lignes individus for IDindividu, nom, prenom, age in listeIndividus : dictIndividu = dictIndividus[IDindividu] ligne = [] # Photo if dictParametres["afficher_photos"] != "non" and IDindividu in dictPhotos : img = dictPhotos[IDindividu] ligne.append(img) # Nom ligne.append(u"%s %s" % (nom, prenom)) # Age if dictParametres["afficher_age"] == True : if age != None : ligne.append(age) else: ligne.append("") # Informations médicales paraStyle = ParagraphStyle(name="infos", fontName="Helvetica", fontSize=7, leading=8, spaceAfter=2, ) # Création des colonnes has_infos = False for nom_categorie, categories in dictParametres["colonnes"]: liste_categories = UTILS_Texte.ConvertStrToListe(categories) case = [] # Recherche s'il y a une info médicale dans cette case if IDindividu in dictInfosMedicales: for infoMedicale in dictInfosMedicales[IDindividu] : IDcategorie = infoMedicale["IDcategorie"] if IDcategorie in liste_categories or (0 in liste_categories and IDcategorie not in liste_categories_utilisees) : intitule = infoMedicale["intitule"] description = infoMedicale["description"] traitement = infoMedicale["traitement_medical"] description_traitement = infoMedicale["description_traitement"] date_debut_traitement = infoMedicale["date_debut_traitement"] date_fin_traitement = infoMedicale["date_fin_traitement"] # Intitulé et description if description != None and description != "": texteInfos = u"<b>%s</b> : %s" % (intitule, description) else: texteInfos = u"%s" % intitule if len(texteInfos) > 0 and texteInfos[-1] != ".": texteInfos += u"." # Traitement médical if traitement == 1 and description_traitement != None and description_traitement != "": texteDatesTraitement = u"" if date_debut_traitement != None and date_fin_traitement != None: texteDatesTraitement = _(u" du %s au %s") % (UTILS_Dates.DateEngFr(date_debut_traitement), UTILS_Dates.DateEngFr(date_fin_traitement)) if date_debut_traitement != None and date_fin_traitement == None: texteDatesTraitement = _(u" à partir du %s") % UTILS_Dates.DateEngFr(date_debut_traitement) if date_debut_traitement == None and date_fin_traitement != None: texteDatesTraitement = _(u" jusqu'au %s") % UTILS_Dates.DateEngFr(date_fin_traitement) texteInfos += _(u"Traitement%s : %s.") % (texteDatesTraitement, description_traitement) # Création du paragraphe case.append(Paragraph(texteInfos, paraStyle)) has_infos = True # Ajoute la case à la ligne ligne.append(case) # Ajout de la ligne individuelle dans le tableau if dictParametres["individus_avec_infos"] == False or (dictParametres["individus_avec_infos"] == True and has_infos == True): dataTableau.append(ligne) # Création des lignes vierges for x in range(0, dictParametres["nbre_lignes_vierges"]): ligne = [] for col in labelsColonnes : ligne.append("") dataTableau.append(ligne) # Style du tableau couleur_fond_entetes = UTILS_Divers.ConvertCouleurWXpourPDF(dictParametres["couleur_fond_entetes"]) style = TableStyle([ ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), # Centre verticalement toutes les cases ('FONT',(0,0),(-1,-1), "Helvetica", 7), # Donne la police de caract. + taille de police ('GRID', (0,0), (-1,-1), 0.25, colors.black), # Crée la bordure noire pour tout le tableau ('ALIGN', (0,1), (-2,-1), 'CENTRE'), # Centre les cases ('ALIGN', (0,1), (-1,1), 'CENTRE'), # Ligne de labels colonne alignée au centre ('FONT',(0,1),(-1,1), "Helvetica", 6), # Donne la police de caract. + taille de police des labels ('SPAN',(0,0),(-1,0)), # Fusionne les lignes du haut pour faire le titre du groupe ('FONT',(0,0),(0,0), "Helvetica-Bold", 10), # Donne la police de caract. + taille de police du titre de groupe ('BACKGROUND', (0,0), (-1,0), couleur_fond_entetes), # Donne la couleur de fond du titre de groupe ]) # Création du tableau tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(style) story.append(tableau) story.append(Spacer(0,20)) # Saut de page après un groupe if dictParametres["saut_page_groupe"] == True : story.append(PageBreak()) # Insère un header if indexGroupe < nbreGroupes : Header() indexGroupe += 1 # Enregistrement du PDF doc.build(story) # Affichage du PDF FonctionsPerso.LanceFichierExterne(nomDoc)