0

I need to download files in zip format. I wrote code that for some reason does not work. I'm trying to do it with controller

enter image description here attachment.py

from odoo import api, fields, models, _
from odoo.odoo.exceptions import UserError


class IrAttachment(models.Model):
    _inherit = ["ir.attachment", "sale.order.line"]

    def download_product_attachments(self):
        attachment_id = self.datas
        if attachment_id:
            return {"type": "ir.actions.act_url",
                    "url": "/download_attachments?attachment_id={}".format(
                        ",".join([str(elem) for elem in attachment_id.ids])),
                    "target": "new",
                    "res_id": self.id,
                    }
        else:
            raise UserError("Photos were not found")

contriller/main.py

class DownloadZipFile(http.Controller):
    @http.route("/download_attachments", type="http", auth="user", website=True)
    def download_attachments_product_routes(self, **data):
        """Method compose data with attachments and send for download."""
        attachments_ids = [int(x) for x in data["attachment_id"].split(',')]
        attachments_items = request.env["ir.attachment"].search([("id", "in", attachments_ids)])
        in_memory = BytesIO()
        zip_archive = ZipFile(in_memory, "w")
        for attachment in attachments_items:
            zip_archive.writestr(attachment.filename, base64.b64decode(attachment.image))
        zip_archive.close()
        res = http.send_file(in_memory, filename="attachments.zip", as_attachment=True)
        return res

When I try to go to the /download_attachments. I get an error File "/home/user/PycharmProjects/Odoo14/custom/first_model/controllers/main.py", line 32, in download_attachments_product_routes attachments_ids = [int(x) for x in data["attachment_id"].split(',')] KeyError: 'attachment_id'

What's wrong with me?

1 Answers1

1

I found a solution to my question.

sale.py

class SaleOrder(models.Model):
    _inherit = "sale.order"
    attachment = fields.Many2one('ir.attachment')

    def download_product_attachments(self):

        return {"type": "ir.actions.act_url",
                "url": "/download_attachments?res_id={}".format(self.id),
                }

controllers/main.py

class DownloadZipFile(http.Controller):
    @http.route("/download_attachments/", type="http", auth="user", website=True)
    def download_attachments_product_routes(self, **data):
        """Method compose data with attachments and send for download."""
        attachments_items = request.env["ir.attachment"].search(
            [("res_id", "=", data.get('res_id')), ('res_model', '=', 'sale.order')])
        in_memory = BytesIO()
        zip_archive = ZipFile(in_memory, "w")
        for attachment in attachments_items:
            zip_archive.writestr(attachment.name, base64.b64decode(attachment.datas))
        zip_archive.close()
        res = http.send_file(in_memory, filename="attachments.zip", as_attachment=True)
        return res

sale.xml

<record id="view_order_form_inherit" model="ir.ui.view">
    <field name="name">sale.order.form</field>
    <field name="model">sale.order</field>
    <field name="inherit_id" ref="sale.view_order_form"/>
    <field name="arch" type="xml">

        <xpath expr="//header" position="inside">
            <button name="download_product_attachments" type="object" string="Download all files"/>
        </xpath>
    </field>
</record>