From 291561a19741f81cdd2c6ba42a228f02d670c24e Mon Sep 17 00:00:00 2001
From: Denis Ledoux <dle@odoo.com>
Date: Thu, 9 Jun 2016 17:34:00 +0200
Subject: [PATCH] [FIX] report, account: invoice reset to draft attachments

When cancelling and resetting to draft an invoice,
delete only the invoice report attachment from the
attachment, not all of them.

The reason why the report is removed from the
attachments on the invoice resetted to draft
is explained in
db0def38cc91a4c089a52b9bee35ede7524534ff

opw-680295
---
 addons/account/models/account_invoice.py | 11 ++++++--
 addons/report/models/report.py           | 33 +++++++++++++++++-------
 2 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py
index 28fb87566165..a92d0b7ea223 100644
--- a/addons/account/models/account_invoice.py
+++ b/addons/account/models/account_invoice.py
@@ -520,8 +520,15 @@ class AccountInvoice(models.Model):
         self.write({'state': 'draft', 'date': False})
         self.delete_workflow()
         self.create_workflow()
-        # Delete attachments now since an invoice can also be generated when the invoice is cancelled
-        self.env['ir.attachment'].search([('res_model', '=', self._name), ('res_id', 'in', self.ids)]).unlink()
+        # Delete former printed invoice
+        report_invoice = self.env['report']._get_report_from_name('account.report_invoice')
+        if report_invoice:
+            for invoice in self:
+                with invoice.env.do_in_draft():
+                    invoice.number, invoice.state = invoice.move_name, 'open'
+                    attachment = self.env['report']._attachment_stored(invoice, report_invoice)[invoice.id]
+                if attachment:
+                    attachment.unlink()
         return True
 
     @api.multi
diff --git a/addons/report/models/report.py b/addons/report/models/report.py
index af1ebec359ef..bdfb405a11cf 100644
--- a/addons/report/models/report.py
+++ b/addons/report/models/report.py
@@ -296,19 +296,20 @@ class Report(osv.Model):
         save_in_attachment['loaded_documents'] = {}
 
         if report.attachment:
+            records = self.pool[report.model].browse(cr, uid, ids)
+            filenames = self._attachment_filename(cr, uid, records, report)
+            attachments = None
+            if report.attachment_use:
+                attachments = self._attachment_stored(cr, uid, records, report, filenames=filenames)
             for record_id in ids:
-                obj = self.pool[report.model].browse(cr, uid, record_id)
-                filename = eval(report.attachment, {'object': obj, 'time': time})
+                filename = filenames[record_id]
 
                 # If the user has checked 'Reload from Attachment'
-                if report.attachment_use:
-                    alreadyindb = [('datas_fname', '=', filename),
-                                   ('res_model', '=', report.model),
-                                   ('res_id', '=', record_id)]
-                    attach_ids = self.pool['ir.attachment'].search(cr, uid, alreadyindb)
-                    if attach_ids:
+                if attachments:
+                    attachment = attachments[record_id]
+                    if attachment:
                         # Add the loaded pdf in the loaded_documents list
-                        pdf = self.pool['ir.attachment'].browse(cr, uid, attach_ids[0]).datas
+                        pdf = attachment.datas
                         pdf = base64.decodestring(pdf)
                         save_in_attachment['loaded_documents'][record_id] = pdf
                         _logger.info('The PDF document %s was loaded from the database' % filename)
@@ -330,6 +331,20 @@ class Report(osv.Model):
         return Report._check_attachment_use(
             self._model, self._cr, self._uid, records.ids, report, context=self._context)
 
+    @api.model
+    def _attachment_filename(self, records, report):
+        return dict((record.id, eval(report.attachment, {'object': record, 'time': time})) for record in records)
+
+    @api.model
+    def _attachment_stored(self, records, report, filenames=None):
+        if not filenames:
+            filenames = self._attachment_filename(records, report)
+        return dict((record.id, self.env['ir.attachment'].search([
+            ('datas_fname', '=', filenames[record.id]),
+            ('res_model', '=', report.model),
+            ('res_id', '=', record.id)
+        ], limit=1)) for record in records)
+
     def _check_wkhtmltopdf(self):
         return wkhtmltopdf_state
 
-- 
GitLab