diff options
| author | Benjamin Frantzen (bfr) <bfr@odoo.com> | 2021-01-21 14:35:24 +0000 |
|---|---|---|
| committer | Benjamin Frantzen (bfr) <bfr@odoo.com> | 2021-01-22 12:54:08 +0000 |
| commit | 8d0c25f359f92533eb25f2990d6e2aceef33b77a (patch) | |
| tree | b6858c043c8f8923f0396319ccb604cec83da8e0 /addons/account_edi | |
| parent | e452d30f739db39a088248a3109c8c49cff9d49f (diff) | |
[FIX] account_edi: better locking of documents and other models when processing EDI
- On account_edi_document, lock the documents successively instead of all at once.
- Lock account_move that should be cancelled. Before, cancelling the invoice after cancelling it on the web-service could fail.
- Lock ir_attachment that might be unlinked. Before, attachments that weren't attached to any model could become unreachable but still present in the database when an invoice was cancelled or a new attachment was produced.
closes odoo/odoo#64870
Signed-off-by: Quentin De Paoli (qdp) <qdp@openerp.com>
Diffstat (limited to 'addons/account_edi')
| -rw-r--r-- | addons/account_edi/models/account_edi_document.py | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/addons/account_edi/models/account_edi_document.py b/addons/account_edi/models/account_edi_document.py index b1bd59193cd..c5dc475e238 100644 --- a/addons/account_edi/models/account_edi_document.py +++ b/addons/account_edi/models/account_edi_document.py @@ -141,10 +141,25 @@ class AccountEdiDocument(models.Model): continue # payments are processed after invoices for documents in batches: + move_to_cancel = documents.filtered(lambda doc: doc.edi_format_id._needs_web_services() \ + and doc.attachment_id \ + and doc.state == 'to_cancel' \ + and doc.move_id.is_invoice(include_receipts=True) \ + and doc.edi_format_id._is_required_for_invoice(doc.move_id)).move_id + attachments_potential_unlink = documents.attachment_id.filtered(lambda a: not a.res_model and not a.res_id) + try: with self.env.cr.savepoint(): # Locks the documents in DB. Avoid sending an invoice twice (the documents can be processed by the CRON but also manually). - self._cr.execute('SELECT * FROM account_edi_document WHERE id IN %s FOR UPDATE NOWAIT', [tuple(self.ids)]) + self._cr.execute('SELECT * FROM account_edi_document WHERE id IN %s FOR UPDATE NOWAIT', [tuple(documents.ids)]) + + # Locks the move that will be cancelled. + if move_to_cancel: + self._cr.execute('SELECT * FROM account_move WHERE id IN %s FOR UPDATE NOWAIT', [tuple(move_to_cancel.ids)]) + + # Locks the attachments that might be unlinked + if attachments_potential_unlink: + self._cr.execute('SELECT * FROM ir_attachment WHERE id IN %s FOR UPDATE NOWAIT', [tuple(attachments_potential_unlink.ids)]) if state == 'to_send': edi_result = edi_format._post_invoice_edi(documents.move_id, test_mode=test_mode) |
