odoo/odoo · error · UserError

You can't edit the following journal entry %s because an ele

Error message

You can't edit the following journal entry %s because an electronic document has already been sent. Please use the 'Request EDI Cancellation' button instead.

What it means

Raised by account_edi's override of account.move.button_draft(). For each move, if _edi_allow_button_draft() is False — which happens when edi_show_cancel_button is True, i.e. an EDI document has already been sent through a webservice — resetting to draft is refused. The already-transmitted electronic document cannot be silently altered; you must request an EDI cancellation instead.

Source

Thrown at addons/account_edi/models/account_move.py:295

        # Set the electronic document to be canceled and cancel immediately for synchronous formats.
        res = super().button_cancel()

        self.edi_document_ids.filtered(lambda doc: doc.state != 'sent').write({'state': 'cancelled', 'error': False, 'blocking_level': False})
        self.edi_document_ids.filtered(lambda doc: doc.state == 'sent').write({'state': 'to_cancel', 'error': False, 'blocking_level': False})
        self.edi_document_ids._process_documents_no_web_services()
        self.env.ref('account_edi.ir_cron_edi_network')._trigger()

        return res

    def _edi_allow_button_draft(self):
        self.ensure_one()
        return not self.edi_show_cancel_button

    def button_draft(self):
        # OVERRIDE
        for move in self:
            if not move._edi_allow_button_draft():
                raise UserError(_(
                    "You can't edit the following journal entry %s because an electronic document has already been "
                    "sent. Please use the 'Request EDI Cancellation' button instead.",
                    move.display_name))

        res = super().button_draft()

        self.edi_document_ids.write({'error': False, 'blocking_level': False})
        self.edi_document_ids.filtered(lambda doc: doc.state == 'to_send').unlink()

        return res

    def button_cancel_posted_moves(self):
        '''Mark the edi.document related to this move to be canceled.
        '''
        to_cancel_documents = self.env['account.edi.document']
        for move in self:
            move._check_fiscal_lock_dates()
            is_move_marked = False

View on GitHub (pinned to 1e661df964)

Solutions

  1. Use the 'Request EDI Cancellation' button on the invoice: it asks the webservice to cancel the transmitted document and, once accepted, lets you reset/edit the move.
  2. If the service already rejected/failed cancellation, follow the format's cancellation workflow (some services require issuing a credit note instead).
  3. For non-webservice EDI formats (or docs never sent), _edi_allow_button_draft() returns True — verify edi_document_ids states if you believe no document was actually sent.
  4. In scripts, skip moves where not move._edi_allow_button_draft() and route them to the cancellation flow instead of button_draft().

Example fix

# before
for move in moves:
    move.button_draft()  # raises for sent EDI documents

# after
for move in moves:
    if move._edi_allow_button_draft():
        move.button_draft()
    else:
        # route to the EDI cancellation workflow instead
        move.message_log(body='EDI cancellation required before resetting to draft')
Defensive patterns

Strategy: validation

Validate before calling

blocked = moves.filtered(lambda m: not m._edi_allow_button_draft())
if blocked:
    route_to_edi_cancellation(blocked)  # do not call button_draft on these

Type guard

def can_reset_to_draft(move) -> bool:
    return not move.edi_show_cancel_button

Try / catch

from odoo.exceptions import UserError
for move in moves:
    try:
        move.button_draft()
    except UserError as e:
        if 'Request EDI Cancellation' in str(e):
            continue  # handle via cancellation flow
        raise

Prevention

When it happens

Trigger: Calling button_draft() (the 'Reset to Draft' action) on a posted invoice whose EDI document has state 'sent' for a webservice format and which therefore exposes edi_show_cancel_button (Request EDI Cancellation).

Common situations: User wants to correct an invoice that was already submitted to a government/e-invoicing network (Peppol, national portals); automation scripts that bulk reset posted invoices to draft and hit sent EDI documents; double-entry workflows unaware of EDI states.

Related errors


AI-assisted analysis of odoo/odoo@1e661df964 (2026-08-15). Data as JSON: /api/errors/cac16a7861105c9e. Report an issue: GitHub.