Files
hr-tools/hr_expense_report_merge_attachment/controllers/main.py

69 lines
3.0 KiB
Python

import odoo.addons.web.controllers.main as main
import ast
import base64
import io
from odoo.tools.pdf import OdooPdfFileReader, OdooPdfFileWriter
import PyPDF2
import logging
from odoo import http
from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
from reportlab.lib.pagesizes import letter, A4
logger = logging.getLogger(__name__)
class Extension(main.ReportController):
@http.route(['/report/download'], type='http', auth="user")
def report_download(self, data, token, context=None):
"""
In case of hr expense sheet report : merge PDF with other attachments
"""
res = super(Extension,self).report_download(data, token, context)
if "hr_expense.report_expense_sheet" in ast.literal_eval(data)[0]: #check if we are generating expense sheet report pdf
writer = OdooPdfFileWriter() #Open a file writer to create new PDF
# Open main pdf and read it and write it page by page in new pdf
main_pdf_reader = OdooPdfFileReader(io.BytesIO(res.data), strict=False)
for n in range(main_pdf_reader.getNumPages()):
writer.addPage(main_pdf_reader.getPage(n))
# Parse data (last char after "/") to get id of current sheet
expense_sheet_id = int(ast.literal_eval(data)[0].split('/')[-1])
# Get ids of related expenses
expense_ids = [e.id for e in http.request.env['hr.expense.sheet'].browse(expense_sheet_id).expense_line_ids]
# Get related attachments
attachments = http.request.env['ir.attachment'].search([('res_id','in',expense_ids),('res_model','=','hr.expense')])
# Open each attachments, and write it page by page in new pdf
for att in attachments:
if att.mimetype == "application/pdf":
try:
attachment_reader = OdooPdfFileReader(io.BytesIO(base64.b64decode(att.datas)), strict=False)
for n in range(attachment_reader.getNumPages()):
writer.addPage(attachment_reader.getPage(n))
except PyPDF2.utils.PdfReadError: # Case of non-pdf attachments
logger.info('Attachment %s cannot be merged in expense report'%(att.name,))
elif 'image/' in att.mimetype:
packet = io.BytesIO()
can = canvas.Canvas(packet)
img = ImageReader(io.BytesIO(base64.b64decode(att.datas)))
can.drawImage(img, 0, 0, A4[0]*0.9, A4[1]*0.9, preserveAspectRatio=True)
can.save()
packet.seek(0)
attachment_reader = OdooPdfFileReader(packet)
writer.addPage(attachment_reader.getPage(0))
# Write new pdf to res.data
buffer = io.BytesIO()
writer.write(buffer)
pdf_content = buffer.getvalue()
res.data = pdf_content
return res