[FIX] account{,_edi,_ubl_cii}: mass export edi documents

When selecting several invoices from the list view, it is possible to trigger an action to export all edi documents in a zip file. This commit fixes 2 different issues:

a) We want to be able to export edi documents that have not been sent. Therefore, we no longer filter for 'sent' and 'cancelled' edi documents.

b) We want to also export edi documents that have ubl format. These documents are, from 16.2, in another field on account.move and no longer part of edi_document_ids. This is the reason why we had to move the logic from account_edi to account to make it overridable to other modules. This new way of overriding the function will also enable other formats to be included in the export function.

task-3441449 (issue 1)
task-3439427 (issue 2)

closes odoo/odoo#131242

X-original-commit: f8654b3501aca6e5d77ced5f73cb351c61684cd2
Related: odoo/enterprise#45529
Related: odoo/upgrade#5032
Signed-off-by: Laurent Smet (las) <las@odoo.com>
This commit is contained in:
hupo-odoo
2023-08-22 11:47:31 +02:00
committed by Laurent Smet
parent 568198374b
commit f2964dc02a
10 changed files with 79 additions and 52 deletions
+1
View File
@@ -3,3 +3,4 @@
from . import portal
from . import terms
from . import download_edi_docs
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import io
import zipfile
from odoo import http, _
from odoo.http import request, content_disposition
class AccountEdiDocumentDownloadController(http.Controller):
@http.route('/account/export_edi_documents', type='http', auth='user')
def export_edi_documents(self, **args):
ids = list(map(int, request.httprequest.args.getlist('ids')))
moves = request.env['account.move'].browse(ids)
moves.check_access_rights('read')
moves.check_access_rule('read')
attachments = moves._get_edi_doc_attachments_to_export()
if not attachments:
error_msg = _("No EDI documents found for export.")
return request.not_found(error_msg)
# Create zip file
buffer = io.BytesIO()
with zipfile.ZipFile(buffer, 'w', compression=zipfile.ZIP_DEFLATED) as zipfile_obj:
for attachment in attachments:
zipfile_obj.writestr(attachment.display_name, attachment.raw)
content = buffer.getvalue()
headers = [
('Content-Type', 'zip'),
('X-Content-Type-Options', 'nosniff'),
('Content-Length', len(content)),
('Content-Disposition', content_disposition('edi_documents.zip')),
]
return request.make_response(content, headers)
+23
View File
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
from werkzeug.urls import url_encode
from collections import defaultdict
from contextlib import ExitStack, contextmanager
from datetime import date, timedelta
@@ -3101,6 +3103,27 @@ class AccountMove(models.Model):
return success
####################################################
# Export Electronic Document
####################################################
def _action_download_electronic_invoice(self):
if not self:
return False
return {
'type': 'ir.actions.act_url',
'url': '/account/export_edi_documents?%s' % url_encode({'ids': self.ids}),
'target': 'new',
}
def _get_edi_doc_attachments_to_export(self):
"""
To override
:return a recordset of ir.attachment to export
"""
return self.env['ir.attachment']
# -------------------------------------------------------------------------
# BUSINESS METHODS
# -------------------------------------------------------------------------
@@ -1644,5 +1644,17 @@ if records:
</field>
</record>
<record id="model_account_download_electronic_invoice" model="ir.actions.server">
<field name="name">Download Electronic Invoices</field>
<field name="model_id" ref="model_account_move"/>
<field name="binding_model_id" ref="model_account_move"/>
<field name="binding_view_types">list</field>
<field name="state">code</field>
<field name="code">
if records:
action = records._action_download_electronic_invoice()
</field>
</record>
</data>
</odoo>
-1
View File
@@ -1,5 +1,4 @@
# -*- encoding: utf-8 -*-
from . import models
from . import controller
from . import wizard
@@ -1 +0,0 @@
from . import main
-18
View File
@@ -1,18 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import http
from odoo.http import request, content_disposition
class EdiDocumentDownloadController(http.Controller):
@http.route('/account_edi/download_edi_documents', type='http', auth='user')
def download_edi_documents(self, **args):
ids = list(map(int, request.httprequest.args.getlist('ids')))
content = request.env['account.move'].browse(ids)._create_zipped()
headers = [
('Content-Type', 'zip'),
('X-Content-Type-Options', 'nosniff'),
('Content-Length', len(content)),
('Content-Disposition', content_disposition('edi_documents.zip')),
]
return request.make_response(content, headers)
+3 -21
View File
@@ -379,24 +379,6 @@ class AccountMove(models.Model):
move_result.setdefault('attachments', []).extend(edi_attachments.get('attachments', []))
return result
####################################################
# Export Electronic Document
####################################################
def _action_download_electronic_invoice(self):
if not self:
return False
return {
'type': 'ir.actions.act_url',
'url': '/account_edi/download_edi_documents?%s' % url_encode({'ids': self.filtered('edi_document_ids').ids}),
'target': 'new',
}
def _create_zipped(self):
buffer = io.BytesIO()
with zipfile.ZipFile(buffer, 'w', compression=zipfile.ZIP_DEFLATED) as zipfile_obj:
for invoice in self:
for document in invoice.edi_document_ids:
if document.state in {'sent', 'cancelled'}:
zipfile_obj.writestr(document.display_name, document.attachment_id.raw)
return buffer.getvalue()
def _get_edi_doc_attachments_to_export(self):
# EXTENDS 'account'
return super()._get_edi_doc_attachments_to_export() + self.edi_document_ids.attachment_id
@@ -142,16 +142,5 @@
</xpath>
</field>
</record>
<record id="model_account_download_electronic_invoice" model="ir.actions.server">
<field name="name">Download Electronic Invoices</field>
<field name="model_id" ref="model_account_move"/>
<field name="binding_model_id" ref="model_account_move"/>
<field name="binding_view_types">list</field>
<field name="state">code</field>
<field name="code">
if records:
action = records._action_download_electronic_invoice()
</field>
</record>
</data>
</odoo>
@@ -52,3 +52,7 @@ class AccountMove(models.Model):
return ubl_cii_xml_builder._import_invoice_ubl_cii
return super()._get_edi_decoder(file_data, new=new)
def _get_edi_doc_attachments_to_export(self):
# EXTENDS 'account'
return super()._get_edi_doc_attachments_to_export() + self.ubl_cii_xml_id