├── .vscode └── settings.json ├── README.md ├── __pycache__ └── send_email.cpython-38.pyc ├── assets ├── ZB Statement footer.jpg ├── ZB Statement1.pdf ├── ZB Statement2.pdf ├── ZB Statement3.pdf ├── back12.jpg ├── background.jpeg ├── background.jpg ├── background1.jpeg ├── header.jpeg ├── header.jpg ├── original.pdf ├── voucher.pdf └── zb-logo.png ├── convert_pop_to_pdf.py ├── create-pdf.py ├── generated-pdf ├── JPGK24VJ.pdf └── RN6NJLUV.pdf ├── send_email.py ├── templates ├── base_template.html └── footer.html └── version /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.formatting.provider": "black" 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##PDF Generator 2 | 3 | #how to install 4 | 5 | ```python3 -m pip install reportlab ``` 6 | ```python3 -m pip install PyPDF2 ``` 7 | -------------------------------------------------------------------------------- /__pycache__/send_email.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/__pycache__/send_email.cpython-38.pyc -------------------------------------------------------------------------------- /assets/ZB Statement footer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/ZB Statement footer.jpg -------------------------------------------------------------------------------- /assets/ZB Statement1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/ZB Statement1.pdf -------------------------------------------------------------------------------- /assets/ZB Statement2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/ZB Statement2.pdf -------------------------------------------------------------------------------- /assets/ZB Statement3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/ZB Statement3.pdf -------------------------------------------------------------------------------- /assets/back12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/back12.jpg -------------------------------------------------------------------------------- /assets/background.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/background.jpeg -------------------------------------------------------------------------------- /assets/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/background.jpg -------------------------------------------------------------------------------- /assets/background1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/background1.jpeg -------------------------------------------------------------------------------- /assets/header.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/header.jpeg -------------------------------------------------------------------------------- /assets/header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/header.jpg -------------------------------------------------------------------------------- /assets/original.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/original.pdf -------------------------------------------------------------------------------- /assets/voucher.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/voucher.pdf -------------------------------------------------------------------------------- /assets/zb-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/assets/zb-logo.png -------------------------------------------------------------------------------- /convert_pop_to_pdf.py: -------------------------------------------------------------------------------- 1 | from jinja2 import Environment, FileSystemLoader 2 | import os 3 | import pdfkit 4 | from PyPDF2 import PdfFileWriter, PdfFileReader 5 | import random 6 | import string 7 | 8 | def generate_pop( 9 | account_holder_name: str, 10 | account_holder_full_name: str, 11 | account_holder_address: str, 12 | account_holder_city_country: str, 13 | account_number: str, 14 | currency: str, 15 | account_type: str, 16 | transactions: list, 17 | ): 18 | """Create POP PDF 19 | 20 | Args: 21 | account_holder_name: account_holder_name, 22 | account_holder_full_name: account_holder_full_name, 23 | account_holder_address: account_holder_address, 24 | account_holder_city_country: account_holder_city_country, 25 | account_number: account_number, 26 | currency: currency, 27 | account_type: account_type, 28 | transactions: [ 29 | { 30 | "date": "07 Jun 21", 31 | "description": { 32 | "narration1":"OPENNING BALANCE", 33 | "narration2":"", 34 | "narration3":"", 35 | "narration4":"", 36 | "narration5":"", 37 | }, 38 | "debit": "", 39 | "credit": "", 40 | "balance": "100,000.19", 41 | }, 42 | 43 | ], 44 | 45 | """ 46 | # pass variables to our html template 47 | env = Environment(loader=FileSystemLoader(os.getcwd())) 48 | template = env.get_template("templates/base_template.html") 49 | html = template.render( 50 | account_holder_name=account_holder_name.upper(), 51 | account_holder_full_name=account_holder_full_name.upper(), 52 | account_holder_address=account_holder_address.upper(), 53 | account_holder_city_country=account_holder_city_country.upper(), 54 | account_number=account_number.upper(), 55 | currency=currency.upper(), 56 | account_type=account_type.upper(), 57 | transactions=transactions, 58 | ) 59 | 60 | # save the generated html file 61 | file = open("templates/temp-generated-html/"+account_number+".html", "w") 62 | file.write(html) 63 | file.close() 64 | 65 | 66 | options = { 67 | "page-size": "Letter", 68 | "margin-top": "0.0in", 69 | "margin-right": "0.0in", 70 | "margin-bottom": "1.5in", 71 | "margin-left": "0.0in", 72 | "encoding": "UTF-8", 73 | "footer-html": "templates/footer.html", 74 | # '--header-html': 'header.html', 75 | "custom-header": [("Accept-Encoding", "gzip")], 76 | "no-outline": None, 77 | } 78 | 79 | # convert the html file to a pdf file 80 | pdfkit.from_file("templates/temp-generated-html/"+account_number+".html", "generated-pdf/"+account_number+".pdf", options=options) 81 | 82 | os.remove("templates/temp-generated-html/"+account_number+".html") 83 | 84 | 85 | account_holder_name = "Nigel Bongani Zulu" 86 | account_holder_full_name = "Nigel Zulu" 87 | account_holder_address = "71314 Lobengula West" 88 | account_holder_city_country = "Bulawayo, Harare" 89 | account_number = "1003088252" 90 | currency = "ZWL" 91 | account_type = "Saving Account" 92 | 93 | transactions = [ 94 | { 95 | "date": "07 Jun 21", 96 | "description": { 97 | "narration1":"OPENNING BALANCE", 98 | "narration2":"", 99 | "narration3":"", 100 | "narration4":"", 101 | "narration5":"", 102 | }, 103 | "debit": "", 104 | "credit": "", 105 | "balance": "100,000.19", 106 | }, 107 | 108 | { 109 | "date": "07 Feb 21", 110 | "description": { 111 | "narration1":"WHATSAPP BALANCE ENQ", 112 | "narration2":"200T60187205725", 113 | "narration3":"WHATSAPP|CHARGES", 114 | "narration4":"4144601872200|4131847336932", 115 | "narration5":"263775580596", 116 | }, 117 | "debit": "22000.00", 118 | "credit": "", 119 | "balance": "22035.19", 120 | }, 121 | { 122 | "date": "07 Feb 21", 123 | "description": { 124 | "narration1":"WHATSAPP BALANCE ENQ", 125 | "narration2":"200T60187205725", 126 | "narration3":"WHATSAPP|CHARGES", 127 | "narration4":"4144601872200|4131847336932", 128 | "narration5":"263775580596", 129 | }, 130 | "debit": "", 131 | "credit": "22000.00", 132 | "balance": "22035.19", 133 | }, 134 | 135 | ] 136 | 137 | # i = 0 138 | # while i < 2: 139 | # test_account_number = "".join( 140 | # random.choice(string.ascii_uppercase + string.digits) for i in range(8) 141 | # ) 142 | 143 | generate_pop( 144 | account_holder_name=account_holder_name, 145 | account_holder_full_name=account_holder_full_name, 146 | account_holder_address=account_holder_address, 147 | account_holder_city_country=account_holder_city_country, 148 | account_number=test_account_number, 149 | currency=currency, 150 | account_type=account_type, 151 | transactions=transactions, 152 | ) 153 | 154 | # i += 1 155 | -------------------------------------------------------------------------------- /create-pdf.py: -------------------------------------------------------------------------------- 1 | from PyPDF2 import PdfFileWriter, PdfFileReader 2 | import io 3 | from reportlab.pdfgen import canvas 4 | from reportlab.lib.pagesizes import letter 5 | from send_email import EmailController as email_controller 6 | 7 | 8 | def create_pdf( 9 | amount: str, 10 | voucher_number: str, 11 | ): 12 | """Create PDF 13 | 14 | Args: 15 | amount: amount 16 | voucher: voucher 17 | 18 | """ 19 | packet = io.BytesIO() 20 | 21 | can = canvas.Canvas(packet, pagesize=letter) 22 | 23 | can.setFillColor("#144f5d") # 24 | can.setFont("Helvetica-Bold", 35) 25 | can.drawString(40, 130, amount) 26 | 27 | can.setFillColor("#144f5d") # 28 | can.setFont("Helvetica-Bold", 10) 29 | can.drawString(600, 250, voucher_number) 30 | 31 | can.setFillColor("#144f5d") # 32 | can.setFont("Helvetica-Bold", 20) 33 | can.drawString(300, 120, voucher_number) 34 | can.save() 35 | 36 | packet.seek(0) 37 | new_pdf = PdfFileReader(packet) 38 | # getting the existing pdf file 39 | existing_pdf = PdfFileReader(open("assets/voucher.pdf", "rb")) 40 | output = PdfFileWriter() 41 | 42 | # add our text to the pdf 43 | page = existing_pdf.getPage(0) 44 | page.mergePage(new_pdf.getPage(0)) 45 | output.addPage(page) 46 | 47 | # genertate a new pdf 48 | outputStream = open("generated-pdf/" + voucher_number + ".pdf", "wb") 49 | output.write(outputStream) 50 | outputStream.close() 51 | 52 | # email_controller.send_pop_as_email(transaction_reference) 53 | 54 | 55 | amount = "$USD50" 56 | voucher_number = "EW5144522885505575112" 57 | 58 | # i = 0 59 | # while i < 100: 60 | create_pdf( 61 | amount=amount, 62 | voucher_number=voucher_number, 63 | ) 64 | 65 | # i += 1 66 | -------------------------------------------------------------------------------- /generated-pdf/JPGK24VJ.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/generated-pdf/JPGK24VJ.pdf -------------------------------------------------------------------------------- /generated-pdf/RN6NJLUV.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nigelreign/pdf-generator/85f99eecfe1e52a364917e0872b220d6a18f8ac9/generated-pdf/RN6NJLUV.pdf -------------------------------------------------------------------------------- /send_email.py: -------------------------------------------------------------------------------- 1 | import smtplib 2 | from email.mime.multipart import MIMEMultipart 3 | from email.mime.text import MIMEText 4 | from email.mime.base import MIMEBase 5 | from email import encoders 6 | 7 | class EmailController: 8 | 9 | def send_pop_as_email(transaction_reference): 10 | """Send generated pdf as email 11 | 12 | Args: 13 | transaction_reference: transaction_reference 14 | 15 | 16 | """ 17 | # body of the email 18 | body = ''' 19 | Good day, 20 | Please find attached a copy of your proof of payment 21 | 22 | Kind regards 23 | Nigel Zulu 24 | ''' 25 | # ============================================ 26 | # sender email address eg zulunigelb@gmail.com 27 | # these will be used to authenticate to gmail 28 | sender = 'test@nigel.zulu' 29 | password = '*******' 30 | 31 | # enter the reciever email address eg danielzulu@gmail.com 32 | receiver = 'zulunigelb@gmail.com' 33 | 34 | message = MIMEMultipart() 35 | message['From'] = sender 36 | message['To'] = receiver 37 | message['Subject'] = 'ZB BANK PROOF OF PAYMENT' 38 | 39 | message.attach(MIMEText(body, 'plain')) 40 | 41 | # select the file you want to send 42 | pdfname = 'generated-pdf/'+transaction_reference+'.pdf' 43 | 44 | # rewrite the name of the pdf 45 | pdffilename = transaction_reference+'.pdf' 46 | 47 | # prepare payload 48 | binary_pdf = open(pdfname, 'rb') 49 | 50 | payload = MIMEBase('application', 'pdf', Name=pdfname) 51 | payload.set_payload((binary_pdf).read()) 52 | 53 | encoders.encode_base64(payload) 54 | 55 | payload.add_header('Content-Disposition', 'attachment', filename=pdffilename) 56 | message.attach(payload) 57 | 58 | #use gmail with port 59 | session = smtplib.SMTP('smtp.gmail.com', 587) 60 | 61 | #enable security 62 | session.starttls() 63 | 64 | #login with mail_id and password 65 | session.login(sender, password) 66 | 67 | text = message.as_string() 68 | session.sendmail(sender, receiver, text) 69 | session.quit() 70 | print('Mail Sent') 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /templates/base_template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 81 | 82 | 83 | 84 | 85 |
86 | 87 | 88 |
89 |

Interim Statement

90 |
91 | 92 | 93 | 94 | 95 | 352 | 353 | 354 | 355 | 356 |
96 | 97 | 98 | 99 | 145 | 146 | 147 | 187 | 188 | 189 | 197 | 198 |
100 | 101 | 102 | 103 | 104 | 107 | 110 | 111 | 112 | 115 | 118 | 119 | 120 | 123 | 126 | 127 | 128 | 131 | 134 | 135 | 136 | 139 | 142 | 143 |
105 |
{{account_holder_name}}
106 |
108 |
DATA CENTRE
109 |
113 |
{{ account_holder_full_name }}
114 |
116 |
CCIS Head office branch
117 |
121 |
{{account_holder_address}}
122 |
124 |
WESTEND
125 |
129 |
{{account_holder_city_country}}
130 |
132 |
HARARE
133 |
137 |
138 |
140 |
ZIM
141 |
144 |
148 | 149 | 150 | 151 | 152 | 153 | 156 | 159 | 162 | 163 | 164 | 167 | 170 | 173 | 174 | 175 | 178 | 181 | 184 | 185 |
154 |
Account Number
155 |
157 |
:
158 |
160 |
{{account_number}}
161 |
165 |
Currency
166 |
168 |
:
169 |
171 |
{{currency}}
172 |
176 |
Account Type
177 |
179 |
:
180 |
182 |
{{account_type}}
183 |
186 |
190 | 191 | 192 | 193 | 194 | 195 |
196 |
199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 234 | 235 | 238 | 241 | 244 | 247 | 248 | 251 | 252 | 255 | 258 | 261 | 262 | 265 | 268 | 269 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | {% for transaction in transactions %} 291 | 292 | 293 | 296 | 297 | 300 | 317 | 320 | 323 | 326 | 327 | 330 | 333 | 336 | 337 | 340 | 343 | 344 | 347 | 348 | 349 | {% endfor %} 350 |




















232 |
Date
233 |
236 |
237 |
239 |
Description
240 |
242 |
243 |
245 |
246 |
249 |
Credit
250 |
253 |
254 |
256 |
257 |
259 |
Debit
260 |
263 |
264 |
266 |
Balance
267 |
270 |
271 |












294 |
{{transaction.date}}
295 |
298 |
299 |
301 |
{% if transaction.description.narration1 %} 302 | {{ transaction.description.narration1 }}
303 | {% endif %} 304 | {% if transaction.description.narration2 %} 305 | {{ transaction.description.narration2 }}
306 | {% endif %} 307 | {% if transaction.description.narration3 %} 308 | {{ transaction.description.narration3 }}
309 | {% endif %} 310 | {% if transaction.description.narration4 %} 311 | {{ transaction.description.narration4 }}
312 | {% endif %} 313 | {% if transaction.description.narration5 %} 314 | {{ transaction.description.narration5 }}
315 | {% endif %}
316 |
318 |
319 |
321 |
322 |
324 |
{{transaction.credit}}
325 |
328 |
329 |
331 |
332 |
334 |
{{transaction.debit}}
335 |
338 |
339 |
341 |
{{transaction.balance}}
342 |
345 |
346 |
351 |
357 |
358 |
359 |
360 |
361 | 362 |
363 | 364 | 365 | -------------------------------------------------------------------------------- /templates/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /version: -------------------------------------------------------------------------------- 1 | 0.0.3 2 | --------------------------------------------------------------------------------