From 21e401fc161fb2b58f6d3a75417ad9e49a0a9783 Mon Sep 17 00:00:00 2001 From: det Date: Wed, 29 Mar 2023 13:24:50 +0000 Subject: [PATCH] [FIX] account: attachment_ids missing res_id Step to reproduce: - create 2 users without admin rights - go to reconcialiation widget - go to list view - add a bank statement in multi mode (via the wizard) with an attachment - change user and try to access bank statement > user errors: 'Sorry, you are not allowed to access this document.' This commit fixes this by adding the missing res_id to the attachment records. closes odoo/odoo#117268 Note: in master, we shouldn't use the m2m attachment_ids. Task-id: 3252972 X-original-commit: ea505d7421a7036d7a0d0152bd1cb79e28955eba Signed-off-by: Laurent Smet Signed-off-by: Detry Thomas (det) --- .../account/models/account_bank_statement.py | 38 +++++++++++++++++++ .../tests/test_account_bank_statement.py | 25 ++++++++++++ 2 files changed, 63 insertions(+) diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py index ab25e37e01d..0b3119aae31 100644 --- a/addons/account/models/account_bank_statement.py +++ b/addons/account/models/account_bank_statement.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +from contextlib import contextmanager + from odoo import api, fields, models, _, Command from odoo.exceptions import UserError from odoo.tools.misc import formatLang @@ -298,3 +300,39 @@ class AccountBankStatement(models.Model): defaults['line_ids'] = [Command.set(lines.ids)] return defaults + + @contextmanager + def _check_attachments(self, container, values_list): + attachments_to_fix_list = [] + for values in values_list: + attachment_ids = set() + for orm_command in values.get('attachment_ids', []): + if orm_command[0] == Command.LINK: + attachment_ids.add(orm_command[1]) + elif orm_command[0] == Command.SET: + for attachment_id in orm_command[2]: + attachment_ids.add(attachment_id) + + attachments = self.env['ir.attachment'].browse(list(attachment_ids)) + attachments_to_fix_list.append(attachments) + + yield + + for stmt, attachments in zip(container['records'], attachments_to_fix_list): + attachments.write({'res_id': stmt.id, 'res_model': stmt._name}) + + @api.model_create_multi + def create(self, vals_list): + container = {'records': self.env['account.bank.statement']} + with self._check_attachments(container, vals_list): + container['records'] = stmts = super().create(vals_list) + return stmts + + def write(self, values): + if len(self) != 1 and 'attachment_ids' in values: + values.pop('attachment_ids') + + container = {'records': self} + with self._check_attachments(container, [values]): + result = super().write(values) + return result diff --git a/addons/account/tests/test_account_bank_statement.py b/addons/account/tests/test_account_bank_statement.py index 6546de84c8e..b9dfa33e4b2 100644 --- a/addons/account/tests/test_account_bank_statement.py +++ b/addons/account/tests/test_account_bank_statement.py @@ -5,6 +5,7 @@ from odoo.tests.common import Form from odoo.exceptions import ValidationError, UserError from odoo import fields, Command +import base64 @tagged('post_install', '-at_install') class TestAccountBankStatementLine(AccountTestInvoicingCommon): @@ -1385,3 +1386,27 @@ class TestAccountBankStatementLine(AccountTestInvoicingCommon): 'is_valid': True, 'is_complete': True, }]) + + def test_statement_attachments(self): + ''' Ensure that attachments are properly linked to bank statements ''' + + attachment_vals = { + 'datas': base64.b64encode(b'My attachment'), + 'name': 'doc.txt', + } + + attachment = self.env['ir.attachment'].create(attachment_vals) + + statement = self.env['account.bank.statement'].create({ + 'name': 'test_statement', + 'attachment_ids': [Command.set(attachment.ids)], + }) + + attachment = self.env['ir.attachment'].create(attachment_vals) + + statement.write({'attachment_ids': [Command.link(attachment.id)]}) + + self.assertRecordValues(statement.attachment_ids, [ + {'res_id': statement.id, 'res_model': 'account.bank.statement'}, + {'res_id': statement.id, 'res_model': 'account.bank.statement'}, + ])