def _decode_pdf(self, filename, content):
        """Decodes a pdf and unwrap sub-attachment into a list of dictionary each representing an attachment.

        :param filename:    The name of the pdf.
        :param content:     The bytes representing the pdf.
        :returns:           A list of dictionary for each attachment.
        * filename:         The name of the attachment.
        * content:          The content of the attachment.
        * type:             The type of the attachment.
        * xml_tree:         The tree of the xml if type is xml.
        * pdf_reader:       The pdf_reader if type is pdf.
        """
        to_process = []
        try:
            buffer = io.BytesIO(content)
            pdf_reader = OdooPdfFileReader(buffer, strict=False)
        except Exception as e:
            # Malformed pdf
            _logger.exception("Error when reading the pdf: %s" % e)
            return to_process

        # Process embedded files.
        for xml_name, content in pdf_reader.getAttachments():
            to_process.extend(self._decode_xml(xml_name, content))

        # Process the pdf itself.
        to_process.append({
            'filename': filename,
            'content': content,
            'type': 'pdf',
            'pdf_reader': pdf_reader,
        })

        return to_process
Exemplo n.º 2
0
    def _embed_edis_to_pdf(self, pdf_content, invoice):
        """ Create the EDI document of the invoice and embed it in the pdf_content.

        :param pdf_content: the bytes representing the pdf to add the EDIs to.
        :param invoice: the invoice to generate the EDI from.
        :returns: the same pdf_content with the EDI of the invoice embed in it.
        """
        attachments = []
        for edi_format in self:
            attachment = invoice.edi_document_ids.filtered(
                lambda d: d.edi_format_id == edi_format).attachment_id
            if attachment and edi_format._is_embedding_to_invoice_pdf_needed():
                datas = base64.b64decode(
                    attachment.with_context(bin_size=False).datas)
                attachments.append({'name': attachment.name, 'datas': datas})

        if attachments:
            # Add the attachments to the pdf file
            reader_buffer = io.BytesIO(pdf_content)
            reader = OdooPdfFileReader(reader_buffer)
            writer = OdooPdfFileWriter()
            writer.cloneReaderDocumentRoot(reader)
            for vals in attachments:
                writer.addAttachment(vals['name'], vals['datas'])
            buffer = io.BytesIO()
            writer.write(buffer)
            pdf_content = buffer.getvalue()
            reader_buffer.close()
            buffer.close()
        return pdf_content
Exemplo n.º 3
0
    def _embed_edis_to_pdf(self, pdf_content, invoice):
        """ Create the EDI document of the invoice and embed it in the pdf_content.

        :param pdf_content: the bytes representing the pdf to add the EDIs to.
        :param invoice: the invoice to generate the EDI from.
        :returns: the same pdf_content with the EDI of the invoice embed in it.
        """
        attachments = []
        for edi_format in self.filtered(lambda edi_format: edi_format.
                                        _is_embedding_to_invoice_pdf_needed()):
            attach = edi_format._get_embedding_to_invoice_pdf_values(invoice)
            if attach:
                attachments.append(attach)

        if attachments:
            # Add the attachments to the pdf file
            reader_buffer = io.BytesIO(pdf_content)
            reader = OdooPdfFileReader(reader_buffer, strict=False)
            writer = OdooPdfFileWriter()
            writer.cloneReaderDocumentRoot(reader)
            for vals in attachments:
                writer.addAttachment(vals['name'], vals['datas'])
            buffer = io.BytesIO()
            writer.write(buffer)
            pdf_content = buffer.getvalue()
            reader_buffer.close()
            buffer.close()
        return pdf_content
Exemplo n.º 4
0
    def _post_pdf(self, save_in_attachment, pdf_content=None, res_ids=None):
        # OVERRIDE to embed some EDI documents inside the PDF.
        if self.model == 'account.move' and res_ids and len(
                res_ids) == 1 and pdf_content:
            invoice = self.env['account.move'].browse(res_ids)
            if invoice.is_sale_document() and invoice.state != 'draft':
                to_embed = invoice.edi_document_ids
                # Add the attachments to the pdf file
                if to_embed:
                    reader_buffer = io.BytesIO(pdf_content)
                    reader = OdooPdfFileReader(reader_buffer, strict=False)
                    writer = OdooPdfFileWriter()
                    writer.cloneReaderDocumentRoot(reader)
                    for edi_document in to_embed:
                        edi_document.edi_format_id._prepare_invoice_report(
                            writer, edi_document)
                    buffer = io.BytesIO()
                    writer.write(buffer)
                    pdf_content = buffer.getvalue()
                    reader_buffer.close()
                    buffer.close()

        return super(IrActionsReport, self)._post_pdf(save_in_attachment,
                                                      pdf_content=pdf_content,
                                                      res_ids=res_ids)
Exemplo n.º 5
0
    def _render_qweb_pdf_prepare_streams(self, data, res_ids=None):
        # EXTENDS base
        collected_streams = super()._render_qweb_pdf_prepare_streams(data, res_ids=res_ids)

        if collected_streams \
                and res_ids \
                and len(res_ids) == 1 \
                and self.report_name in ('account.report_invoice_with_payments', 'account.report_invoice'):
            invoice = self.env['account.move'].browse(res_ids)
            if invoice.is_sale_document() and invoice.state != 'draft':
                to_embed = invoice.edi_document_ids
                # Add the attachments to the pdf file
                if to_embed:
                    pdf_stream = collected_streams[invoice.id]['stream']

                    # Read pdf content.
                    pdf_content = pdf_stream.getvalue()
                    reader_buffer = io.BytesIO(pdf_content)
                    reader = OdooPdfFileReader(reader_buffer, strict=False)

                    # Post-process and embed the additional files.
                    writer = OdooPdfFileWriter()
                    writer.cloneReaderDocumentRoot(reader)
                    for edi_document in to_embed:
                        edi_document.edi_format_id._prepare_invoice_report(writer, edi_document)

                    # Replace the current content.
                    pdf_stream.close()
                    new_pdf_stream = io.BytesIO()
                    writer.write(new_pdf_stream)
                    collected_streams[invoice.id]['stream'] = new_pdf_stream

        return collected_streams
Exemplo n.º 6
0
    def _embed_edis_to_pdf(self, pdf_content, invoice):
        """ Create the EDI document of the invoice and embed it in the pdf_content.

        :param pdf_content: the bytes representing the pdf to add the EDIs to.
        :param invoice: the invoice to generate the EDI from.
        :returns: the same pdf_content with the EDI of the invoice embed in it.
        """
        attachments = []
        for edi_format in self:
            try:
                vals = edi_format._export_invoice_to_embed_to_pdf(
                    pdf_content, invoice)
            except:
                continue
            if vals:
                attachments.append(vals)

        if attachments:
            # Add the attachments to the pdf file
            reader_buffer = io.BytesIO(pdf_content)
            reader = OdooPdfFileReader(reader_buffer)
            writer = OdooPdfFileWriter()
            writer.cloneReaderDocumentRoot(reader)
            for vals in attachments:
                writer.addAttachment(vals['name'], vals['datas'])
            buffer = io.BytesIO()
            writer.write(buffer)
            pdf_content = buffer.getvalue()
            reader_buffer.close()
            buffer.close()
        return pdf_content
Exemplo n.º 7
0
 def _render_qweb_pdf_prepare_streams(self, data, res_ids=None):
     # OVERRIDE
     res = super()._render_qweb_pdf_prepare_streams(data, res_ids)
     if res_ids and self.report_name in (
             'account.report_invoice_with_payments',
             'account.report_invoice'):
         invoices = self.env[self.model].browse(res_ids)
         # Determine which invoices need a QR/ISR.
         qr_inv_ids = []
         isr_inv_ids = []
         for invoice in invoices:
             if invoice.company_id.country_code != 'CH':
                 continue
             if invoice.l10n_ch_is_qr_valid:
                 qr_inv_ids.append(invoice.id)
             elif invoice.l10n_ch_isr_valid:
                 isr_inv_ids.append(invoice.id)
         # Render the additional reports.
         streams_to_append = {}
         if qr_inv_ids:
             qr_res = self.env.ref('l10n_ch.l10n_ch_qr_report'
                                   )._render_qweb_pdf_prepare_streams(
                                       data, res_ids=qr_inv_ids)
             for invoice_id, stream in qr_res.items():
                 streams_to_append[invoice_id] = stream
         if isr_inv_ids:
             isr_res = self.env.ref('l10n_ch.l10n_ch_isr_report'
                                    )._render_qweb_pdf_prepare_streams(
                                        data, res_ids=qr_inv_ids)
             for invoice_id, stream in isr_res.items():
                 streams_to_append[invoice_id] = stream
         # Add to results
         for invoice_id, additional_stream in streams_to_append.items():
             invoice_stream = res[invoice_id]['stream']
             writer = OdooPdfFileWriter()
             writer.appendPagesFromReader(
                 OdooPdfFileReader(invoice_stream, strict=False))
             writer.appendPagesFromReader(
                 OdooPdfFileReader(additional_stream['stream'],
                                   strict=False))
             new_pdf_stream = io.BytesIO()
             writer.write(new_pdf_stream)
             res[invoice_id]['stream'] = new_pdf_stream
             invoice_stream.close()
             additional_stream['stream'].close()
     return res
Exemplo n.º 8
0
    def _embed_edis_to_pdf(self, pdf_content, invoice):
        """ Create the EDI document of the invoice and embed it in the pdf_content.

        :param pdf_content: the bytes representing the pdf to add the EDIs to.
        :param invoice: the invoice to generate the EDI from.
        :returns: the same pdf_content with the EDI of the invoice embed in it.
        """
        to_embed = invoice.edi_document_ids
        # Add the attachments to the pdf file
        if to_embed:
            reader_buffer = io.BytesIO(pdf_content)
            reader = OdooPdfFileReader(reader_buffer, strict=False)
            writer = OdooPdfFileWriter()
            writer.cloneReaderDocumentRoot(reader)
            for edi_document in to_embed:
                edi_document.edi_format_id._prepare_invoice_report(writer, edi_document)
            buffer = io.BytesIO()
            writer.write(buffer)
            pdf_content = buffer.getvalue()
            reader_buffer.close()
            buffer.close()
        return pdf_content