[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:
@@ -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)
|
||||
@@ -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,5 +1,4 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from . import models
|
||||
from . import controller
|
||||
from . import wizard
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
from . import main
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user