
from odoo import api, fields, models


class IrAttachment(models.Model):
    _inherit = 'ir.attachment'

    @api.multi
    def _post_add_create(self):
        """ Overrides behaviour when the attachment is created through the controller
        """
        super(IrAttachment, self)._post_add_create()
        for record in self:
            record.register_as_main_attachment(force=False)

    @api.multi
    def unlink(self):
        self.remove_as_main_attachment()
        super(IrAttachment, self).unlink()

    @api.multi
    def remove_as_main_attachment(self):
        for attachment in self:
            related_record = self.env[attachment.res_model].browse(attachment.res_id)
            if related_record and hasattr(related_record, 'message_main_attachment_id'):
                if related_record.message_main_attachment_id == attachment:
                    related_record.message_main_attachment_id = False

    def register_as_main_attachment(self, force=True):
        """ Registers this attachment as the main one of the model it is
        attached to.
        """
        self.ensure_one()
        related_record = self.env[self.res_model].browse(self.res_id)
        # message_main_attachment_id field can be empty, that's why we compare to False;
        # we are just checking that it exists on the model before writing it
        if related_record and hasattr(related_record, 'message_main_attachment_id'):
            if force or not related_record.message_main_attachment_id:
                related_record.message_main_attachment_id = self


from odoo import api, fields, models


class IrAttachment(models.Model):
    _inherit = 'ir.attachment'

    @api.multi
    def _post_add_create(self):
        """ Overrides behaviour when the attachment is created through the controller
        """
        super(IrAttachment, self)._post_add_create()
        for record in self:
            record.register_as_main_attachment(force=False)

    def register_as_main_attachment(self, force=True):
        """ Registers this attachment as the main one of the model it is
        attached to.
        """
        self.ensure_one()
        related_record = self.env[self.res_model].browse(self.res_id)
        # message_main_attachment_id field can be empty, that's why we compare to False;
        # we are just checking that it exists on the model before writing it
        if related_record and hasattr(related_record, 'message_main_attachment_id'):
            if force or not related_record.message_main_attachment_id:
                related_record.message_main_attachment_id = self

Revert "[FIX] mail: remove attachment as main at unlink"
Revert "[FIX] mail: remove attachment as main at unlink"

This reverts commit abc45b1
Since by default the ondelete attribute of a many2one is `set null`,
this was completely unnecessary to begin with.

Bug caused by this commit:
Unlink a record that has some attachments.
The unlink first removes the record, then its related attachments.
It calls remove_as_main_attachment, which reads the attachment res_model and
res_id. This triggers a check that the related record can be read.
However the related record has already been removed, an exception is raised.
It is thus impossible to unlink a record.

Closes #32563

closes odoo/odoo#32572

Signed-off-by: Raphael Collet (rco) <fcee45b878db1f337818c5c606c1542797080a40@openerp.com>
  
  from odoo import api, fields, models
  
  
  class IrAttachment(models.Model):
      _inherit = 'ir.attachment'
  
      @api.multi
      def _post_add_create(self):
          """ Overrides behaviour when the attachment is created through the controller
          """
          super(IrAttachment, self)._post_add_create()
          for record in self:
              record.register_as_main_attachment(force=False)
  
-     @api.multi
-     def unlink(self):
-         self.remove_as_main_attachment()
-         super(IrAttachment, self).unlink()
- 
-     @api.multi
-     def remove_as_main_attachment(self):
-         for attachment in self:
-             related_record = self.env[attachment.res_model].browse(attachment.res_id)
-             if related_record and hasattr(related_record, 'message_main_attachment_id'):
-                 if related_record.message_main_attachment_id == attachment:
-                     related_record.message_main_attachment_id = False
- 
      def register_as_main_attachment(self, force=True):
          """ Registers this attachment as the main one of the model it is
          attached to.
          """
          self.ensure_one()
          related_record = self.env[self.res_model].browse(self.res_id)
          # message_main_attachment_id field can be empty, that's why we compare to False;
          # we are just checking that it exists on the model before writing it
          if related_record and hasattr(related_record, 'message_main_attachment_id'):
              if force or not related_record.message_main_attachment_id:
                  related_record.message_main_attachment_id = self
  
Revert "[FIX] mail: remove attachment as main at unlink"
## Code Before:

from odoo import api, fields, models


class IrAttachment(models.Model):
    _inherit = 'ir.attachment'

    @api.multi
    def _post_add_create(self):
        """ Overrides behaviour when the attachment is created through the controller
        """
        super(IrAttachment, self)._post_add_create()
        for record in self:
            record.register_as_main_attachment(force=False)

    @api.multi
    def unlink(self):
        self.remove_as_main_attachment()
        super(IrAttachment, self).unlink()

    @api.multi
    def remove_as_main_attachment(self):
        for attachment in self:
            related_record = self.env[attachment.res_model].browse(attachment.res_id)
            if related_record and hasattr(related_record, 'message_main_attachment_id'):
                if related_record.message_main_attachment_id == attachment:
                    related_record.message_main_attachment_id = False

    def register_as_main_attachment(self, force=True):
        """ Registers this attachment as the main one of the model it is
        attached to.
        """
        self.ensure_one()
        related_record = self.env[self.res_model].browse(self.res_id)
        # message_main_attachment_id field can be empty, that's why we compare to False;
        # we are just checking that it exists on the model before writing it
        if related_record and hasattr(related_record, 'message_main_attachment_id'):
            if force or not related_record.message_main_attachment_id:
                related_record.message_main_attachment_id = self

## Instruction:
Revert "[FIX] mail: remove attachment as main at unlink"
## Code After:

from odoo import api, fields, models


class IrAttachment(models.Model):
    _inherit = 'ir.attachment'

    @api.multi
    def _post_add_create(self):
        """ Overrides behaviour when the attachment is created through the controller
        """
        super(IrAttachment, self)._post_add_create()
        for record in self:
            record.register_as_main_attachment(force=False)

    def register_as_main_attachment(self, force=True):
        """ Registers this attachment as the main one of the model it is
        attached to.
        """
        self.ensure_one()
        related_record = self.env[self.res_model].browse(self.res_id)
        # message_main_attachment_id field can be empty, that's why we compare to False;
        # we are just checking that it exists on the model before writing it
        if related_record and hasattr(related_record, 'message_main_attachment_id'):
            if force or not related_record.message_main_attachment_id:
                related_record.message_main_attachment_id = self
