135 lines
5.9 KiB
Python
135 lines
5.9 KiB
Python
from odoo import _, api, models
|
|
|
|
|
|
class AccountMoveSend(models.AbstractModel):
|
|
_inherit = 'account.move.send'
|
|
|
|
@api.model
|
|
def _is_co_edi_applicable(self, move):
|
|
return not move.invoice_pdf_report_id and move.l10n_co_dian_is_enabled
|
|
|
|
def _get_all_extra_edis(self) -> dict:
|
|
# EXTENDS 'account'
|
|
res = super()._get_all_extra_edis()
|
|
res.update({'co_dian': {'label': _("DIAN"), 'is_applicable': self._is_co_edi_applicable}})
|
|
return res
|
|
|
|
# -------------------------------------------------------------------------
|
|
# ATTACHMENTS
|
|
# -------------------------------------------------------------------------
|
|
|
|
def _l10n_co_dian_build_zip_attachment(self, move, move_data):
|
|
zip_attachment = self.env['ir.attachment']
|
|
attached_document = move_data.get('l10n_co_dian_attached_document')
|
|
if attached_document:
|
|
zip_content = (attached_document + move.invoice_pdf_report_id)._build_zip_from_attachments()
|
|
zip_attachment += self.env['ir.attachment'].create({
|
|
'name': move._l10n_co_dian_get_attached_document_filename() + ".zip",
|
|
'raw': zip_content,
|
|
'res_model': 'account.move',
|
|
'res_id': move.id,
|
|
})
|
|
attached_document.unlink()
|
|
return zip_attachment
|
|
|
|
@api.model
|
|
def _get_mail_params(self, move, move_data):
|
|
# EXTENDS 'account' to be able to zip the PDF and the Colombian xml attachment together
|
|
if not move_data.get('l10n_co_dian_attached_document'):
|
|
return super()._get_mail_params(move, move_data)
|
|
|
|
mail_attachments_widget = move_data.get('mail_attachments_widget')
|
|
seen_attachment_ids = set()
|
|
for attachment_data in mail_attachments_widget:
|
|
if attachment_data.get('skip'):
|
|
continue
|
|
|
|
try:
|
|
attachment_id = int(attachment_data['id'])
|
|
except ValueError:
|
|
continue
|
|
|
|
seen_attachment_ids.add(attachment_id)
|
|
|
|
# DIAN zip attachment
|
|
filename = move._l10n_co_dian_get_attached_document_filename() + '.zip'
|
|
placeholder = next((att for att in move_data['mail_attachments_widget'] if att.get('id') == f'placeholder_{filename}'), {})
|
|
if not placeholder.get('skip'):
|
|
zip_attachment = self._l10n_co_dian_build_zip_attachment(move, move_data)
|
|
if zip_attachment:
|
|
seen_attachment_ids.add(zip_attachment.id)
|
|
|
|
mail_attachments = [
|
|
(attachment.name, attachment.raw)
|
|
for attachment in self.env['ir.attachment'].browse(list(seen_attachment_ids)).exists()
|
|
]
|
|
|
|
return {
|
|
'author_id': move_data['author_partner_id'],
|
|
'body': move_data['mail_body'],
|
|
'subject': move_data['mail_subject'],
|
|
'partner_ids': move_data['mail_partner_ids'],
|
|
'attachments': mail_attachments,
|
|
}
|
|
|
|
def _get_placeholder_mail_attachments_data(self, move, invoice_edi_format=None, extra_edis=None, pdf_report=None):
|
|
# EXTENDS 'account'
|
|
results = super()._get_placeholder_mail_attachments_data(move, invoice_edi_format=invoice_edi_format, extra_edis=extra_edis, pdf_report=pdf_report)
|
|
|
|
if not move.l10n_co_dian_attachment_id and 'co_dian' in extra_edis:
|
|
filename = move._l10n_co_dian_get_attached_document_filename() + '.zip'
|
|
results = [{
|
|
'id': f'placeholder_{filename}',
|
|
'name': filename,
|
|
'mimetype': 'application/zip',
|
|
'placeholder': True,
|
|
}]
|
|
|
|
return results
|
|
|
|
# -------------------------------------------------------------------------
|
|
# SENDING METHODS
|
|
# -------------------------------------------------------------------------
|
|
|
|
def _call_web_service_before_invoice_pdf_render(self, invoices_data):
|
|
# EXTENDS 'account'
|
|
super()._call_web_service_before_invoice_pdf_render(invoices_data)
|
|
|
|
for invoice, invoice_data in invoices_data.items():
|
|
if 'co_dian' in invoice_data['extra_edis']:
|
|
# Render
|
|
xml, errors = self.env['account.edi.xml.ubl_dian']._export_invoice(invoice)
|
|
if errors:
|
|
invoice_data['error'] = {
|
|
'error_title': _("Error(s) when generating the UBL attachment:"),
|
|
'errors': errors,
|
|
}
|
|
continue
|
|
|
|
# 1. Build the xml representing the invoice and send it to the DIAN
|
|
doc = invoice._l10n_co_dian_send_invoice_xml(xml)
|
|
|
|
if doc.state in ('invoice_rejected', 'invoice_sending_failed'):
|
|
invoice_data['error'] = {
|
|
'error_title': _("Error(s) when sending the document to the DIAN:"),
|
|
'errors': doc.message_json.get('errors') or [doc.message_json['status']],
|
|
}
|
|
elif doc.state == 'invoice_accepted':
|
|
# 2. Call DIAN again to get the Status of the invoice and generate the Attached Document
|
|
attached_document, error_msg = doc._get_attached_document()
|
|
if error_msg:
|
|
invoice_data['error'] = {
|
|
'error_title': _("Error(s) when generating the Attached Document:"),
|
|
'errors': error_msg,
|
|
}
|
|
else:
|
|
invoice_data['l10n_co_dian_attached_document'] = self.env['ir.attachment'].create({
|
|
'raw': attached_document,
|
|
'name': invoice._l10n_co_dian_get_attached_document_filename() + ".xml",
|
|
'res_model': 'account.move',
|
|
'res_id': invoice.id,
|
|
})
|
|
|
|
if self._can_commit():
|
|
self.env.cr.commit()
|