Search code examples
pythonodooodoo-12odoo-13

How to convert attachment file to different format in odoo?


How to add an observer on attachment upload in odoo to check for a certain file type and to do operation on this file? For example to convert to another format on upload.

EDIT

values variable that is modified in my code still has no effect in addons/web/controllers/main.py:upload_attachment(), as there file storage variable is an old, unmodified still.

EDIT2

Here I have added the error from when I try to change the name of the file uploaded in the custom function. Because in the method addons/web/controllers/main.py:upload_attachment() old upload file name persists.

ERROR odoo13 odoo.addons.web.controllers.main: Fail to upload attachment docum2.doc 
Traceback (most recent call last):
  File "/home/computer/13-ver-odoo/addons/web/controllers/main.py", line 1512, in upload_attachment
    attachment = Model.create({
  File "<decorator-gen-94>", line 2, in create
  File "/home/computer/13-ver-odoo/odoo/api.py", line 314, in _model_create_single
    return create(self, arg)
  File "/home/computer/13-ver-odoo/local-addons/crm_checklist/models/ir_attachment.py", line 54, in create
    return super(IrAttachment, self).create(values)
  File "<decorator-gen-39>", line 2, in create
  File "/home/computer/13-ver-odoo/odoo/api.py", line 335, in _model_create_multi
    return create(self, [arg])
  File "/home/computer/13-ver-odoo/odoo/addons/base/models/ir_attachment.py", line 515, in create
    values.update(self._get_datas_related_values(values.pop('datas'), values['mimetype']))
  File "/home/computer/13-ver-odoo/odoo/addons/base/models/ir_attachment.py", line 212, in _get_datas_related_values
    bin_data = base64.b64decode(data) if data else b''
  File "/usr/lib/python3.8/base64.py", line 80, in b64decode
    s = _bytes_from_decode_data(s)
  File "/usr/lib/python3.8/base64.py", line 45, in _bytes_from_decode_data
    raise TypeError("argument should be a bytes-like object or ASCII "
TypeError: argument should be a bytes-like object or ASCII string, not 'tuple'

Solution

  • The file upload is handled by the web client and it is written in javascript.

    To convert the file in the backend (Python), you need to convert the file before it is written to the database and to do that you need to override the create/write methods.

    Example: using the ir.attachment model and datas binary field

    class IrAttachment(models.Model):
        _inherit = 'ir.attachment'
    
        def process_attachment(self, values):
            pass
    
        @api.model
        def create(self, values):
            self.process_attachment(values)
            return super(IrAttachment, self).create(values)
    
        @api.multi
        def write(self, values):
            self.process_attachment(values)
            return super(IrAttachment, self).write(values)