github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/core/utils/pdf/pdf.go (about) 1 package pdf 2 3 import ( 4 "fmt" 5 "io" 6 "strings" 7 8 dm "github.com/benoitkugler/goACVE/server/core/datamodel" 9 rd "github.com/benoitkugler/goACVE/server/core/rawdata" 10 ) 11 12 // Modifie l'accès aux images inclues dans les pdfs (logo, etc...) 13 var IMAGES_PATH = "ressources/images/" 14 15 const ( 16 marginTop = 8 17 paddingFooter = 2 18 heightFooter = 18 19 paddingHeaderTop = 2 20 spacingHeader = 12 21 sideMargin = 10 22 spacingBandeDestinataire = 18 23 leftListSpacing = 7 24 ) 25 26 var ( 27 primaryColor = rgb{122, 206, 240} 28 secondaryColor = rgb{184, 219, 241} 29 accentColor = rgb{255, 209, 18} 30 grayColor = rgb{200, 200, 200} 31 ) 32 33 const ( 34 fpParticipant rd.Field = iota 35 fpCamp 36 fpDates 37 fpPrixBase 38 fpAides 39 fpSousTotal 40 ) 41 42 var ( // headers 43 44 fieldsListeVetements = []ColumnMetas{ 45 {Field: rd.VQuantite, Label: "NB", Width: 0.08}, 46 {Field: rd.VDescription, Label: "VETEMENTS", Width: 0.68, Align: "L"}, 47 {Field: rd.VArrivee, Label: "ARRIVEE", Width: 0.12}, 48 {Field: rd.VDepart, Label: "DEPART", Width: 0.12}, 49 } 50 51 fieldsFactureParticipant = []ColumnMetas{ 52 {Field: fpParticipant, Label: "Participant", Width: 0.20}, 53 {Field: fpCamp, Label: "Camp", Width: 0.22}, 54 {Field: fpDates, Label: "Dates", Width: 0.17, Align: "C"}, 55 {Field: fpPrixBase, Label: "Prix", Width: 0.11, Align: "C"}, 56 {Field: fpAides, Label: "Aides extérieures", Width: 0.18}, 57 {Field: fpSousTotal, Label: "Sous-total", Width: 0.12, Align: "L"}, 58 } 59 ) 60 61 func ListeParticipants(headers []ColumnMetas, participants rd.Table, labelCamp string, out io.Writer) error { 62 pdf := initPdf() 63 pdf.DrawHeader(rd.ExpediteurDefault, 0, 0) 64 pdf.SetFont("Arial", "I", 14) 65 pdf.CellFormat(0, 20, fmt.Sprintf("Liste des participants - %s", labelCamp), "", "MC", false) 66 pdf.Ln(-1) 67 pdf.drawTable(headers, participants) 68 return pdf.Output(out) 69 } 70 71 func ListeVetements(vetements rd.Table, complement, labelCamp string, out io.Writer) error { 72 pdf := initPdf() 73 pdf.DrawHeader([]string{labelCamp}, 0, 0) 74 pdf.SetFont("Arial", "I", 14) 75 pdf.CellFormat(0, 20, pdf.Tr("Liste de vêtements"), "", "MC", false) 76 pdf.Ln(10) 77 pdf.SetFontSize(9) 78 pdf.CellFormat(0, 20, pdf.Tr("Nom et prénom du participant : "), "", "L", false) 79 pdf.Ln(-1) 80 pdf.SetFont("Arial", "", 12) 81 pdf.drawTable(fieldsListeVetements, vetements) 82 pdf.Ln(-1) 83 pdf.Ln(-1) 84 pdf.SetFontStyle("") 85 pdf.SetFontSize(13.5) 86 h := pdf.HTMLBasicNew() 87 h.Write(pdf.LineHeight(), pdf.Tr(complement)) 88 return pdf.Output(out) 89 } 90 91 func Facture(destinataire rd.Destinataire, bilan dm.BilanFacture, out io.Writer) error { 92 pdf := initPdf() 93 pdf.DrawHeader(rd.ExpediteurDefault, 0, 0) 94 pdf.drawBandeDestinataire("Facture", destinataire) 95 96 pdf.SetFontSize(10) 97 lH := pdf.LineHeight() 98 pdf.SetFillColor(accentColor) 99 fields := pdf.drawHeaderTable(fieldsFactureParticipant) 100 pdf.SetFillColor(grayColor) 101 lastColWidth := fields[len(fields)-1].Width 102 marginLeft := pdf.AreaWidth() * 0.15 103 for index, part := range bilan.Participants { 104 fill := index%2 == 0 105 partPers := part.GetPersonne().RawData() 106 camp := part.GetCamp().RawData() 107 plage := rd.Plage{From: camp.DateDebut, To: camp.DateFin} 108 partS := fmt.Sprintf("%s\n(né%s le %s)", partPers.NomPrenom(), partPers.Sexe.Accord(), partPers.DateNaissance) 109 bilanPrix := part.EtatFinancier(nil, false) 110 descAides := make([]string, len(bilanPrix.Aides)) 111 for index, aide := range bilanPrix.Aides { 112 descAides[index] = aide.Description 113 } 114 datas := rd.Item{Fields: rd.F{ 115 fpParticipant: rd.String(partS), 116 fpCamp: rd.String(fmt.Sprintf("%s\nN° JS : %s", camp.Label(), camp.NumeroJS)), 117 fpDates: rd.String(fmt.Sprintf("du %s\nau %s", plage.From, plage.To)), 118 fpPrixBase: rd.String(fmt.Sprintf("%s %s", bilanPrix.PrixBase, bilanPrix.DescriptionPrix)), 119 fpAides: rd.String(strings.Join(descAides, "\n")), 120 fpSousTotal: bilanPrix.PrixSansRemises(), 121 }} 122 pdf.drawRow(fields, datas, lH, paddingCells, fill, false, false) 123 124 remises := strings.Join(part.RawData().Remises.Description("\t"), "\t") 125 sousTotal := bilanPrix.PrixNet().String() 126 if remises != "" { 127 pdf.drawMergedColumns(marginLeft, lastColWidth, lH, remises, 128 sousTotal, fill) 129 } 130 } 131 132 marginLeftTotal := pdf.AreaWidth() * 0.6 133 pdf.drawMergedColumns(marginLeftTotal, lastColWidth, lH, "<i>Total (après remises)</i>", 134 fmt.Sprintf("<b>%s</b>", bilan.Demande), false) 135 136 marginLeft = pdf.AreaWidth() * 0.3 137 for _, paiement := range bilan.Paiements { 138 desc, montant := paiement.Description() 139 pdf.drawMergedColumns(marginLeft, lastColWidth, lH, desc, 140 montant, false) 141 } 142 143 pdf.drawMergedColumns(marginLeftTotal, lastColWidth, lH, "<i>Total (après paiements)</i>", 144 fmt.Sprintf("<b>%s</b>", bilan.ApresPaiement()), false) 145 pdf.Ln(5) 146 147 if bilan.IsAcquitte() { 148 if pdf.GetY()+lH > pdf.areaBottomLimit() { 149 pdf.AddPage() 150 } 151 pdf.SetFontStyle("I") 152 pdf.Write(lH, pdf.Tr("Facture acquittée par l'ACVE.")) 153 } else { 154 h := pdf.HTMLBasicNew() 155 if pdf.GetY()+3*lH > pdf.areaBottomLimit() { 156 pdf.AddPage() 157 } 158 h.Write(lH, pdf.Tr("<i>Merci de bien vouloir adresser votre paiement dès ce jour.</i>")) 159 pdf.Ln(-1) 160 h.Write(lH, pdf.Tr("<i>Les chèques sont à l'ordre <b>ACVE</b> et encaissés environ 10 jours avant le début du séjour.</i>")) 161 pdf.Ln(-1) 162 h.Write(lH, pdf.Tr("<i>En cas de difficultés financières, veuillez contacter le centre d'inscriptions.</i>")) 163 } 164 165 return pdf.Output(out) 166 } 167 168 func AttestationPresence(destinataire rd.Destinataire, participants []dm.AccesParticipant, out io.Writer) error { 169 pdf := initPdf() 170 pdf.DrawHeader(rd.ExpediteurDefault, 0, 0) 171 pdf.drawBandeDestinataire("Attestation de présence", destinataire) 172 173 lH := pdf.LineHeight() 174 msg := "Le centre d'inscriptions ACVE certifie par la présente " 175 if len(participants) > 1 { 176 msg += "les participations suivantes :" 177 } else { 178 msg += "la participation suivante :" 179 } 180 pdf.Write(lH, pdf.Tr(msg)) 181 pdf.Ln(lH + 2) 182 mL, _, _, _ := pdf.GetMargins() 183 pdf.SetLeftMargin(mL + leftListSpacing + 5) 184 h := pdf.HTMLBasicNew() 185 for _, part := range participants { 186 pdf.Circle(mL+leftListSpacing, pdf.GetY()+3, 1, "F") 187 camp := part.GetCamp().RawData() 188 plage := rd.Plage{From: camp.DateDebut, To: camp.DateFin} 189 partPers := part.GetPersonne().RawData() 190 partS := fmt.Sprintf("%s (né%s le %s)", partPers.NomPrenom(), partPers.Sexe.Accord(), partPers.DateNaissance) 191 h.Write(lH, pdf.Tr( 192 fmt.Sprintf("<i>%s</i>, au séjour <b>%s</b>, d'agrément Jeunesse et Sport <i>%s</i>, du <b>%s</b> au <b>%s</b>", 193 partS, camp.Nom, 194 camp.NumeroJS, 195 plage.From, 196 plage.To))) 197 pdf.Ln(lH + 2) 198 } 199 pdf.SetLeftMargin(mL) 200 201 return pdf.Output(out) 202 }