[IMP] Add upload state tracking on EBICS payment files

account_ebics:
- Add pain_state and ebics_order_number to ebics.file
- Set these fields after a successful upload
- Add neutralized property to api.Environment

account_ebics_batch_payment:
- Add EBICS notebook page with upload info to batch payment form
- Post chatter message with OrderID after upload

account_ebics_payment_order:
- Fix broken postprocess: replace deprecated active_model/active_id
  context keys with model/id
This commit is contained in:
Luc De Meyer committed 2026-10-24 12:01:04 +02:00
1 parent 79bfd130f0
commit 393cca3a62
5 files changed
+60 -11

No files matched your search

+22
View File
@@ -1,5 +1,8 @@
import functools
import logging import logging
from odoo import api
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
try: try:
@@ -7,3 +10,22 @@ try:
from . import wizards from . import wizards
except Exception: except Exception:
_logger.warning("Import Error, check if fintech lib has been installed") _logger.warning("Import Error, check if fintech lib has been installed")
@functools.cached_property
def neutralized(self):
return bool(
self["ir.config_parameter"].sudo().get_param("database.is_neutralized")
or self["ir.ui.view"]
.sudo()
.search_count(
[
("key", "in", ("web.neutralize_banner", "website.neutralize_ribbon")),
("active", "=", True),
]
)
)
api.Environment.neutralized = neutralized
neutralized.__set_name__(api.Environment, "neutralized")
+1 -1
View File
@@ -5,7 +5,7 @@
"name": "EBICS Banking Protocol", "name": "EBICS Banking Protocol",
"summary": "Download bank statements and upload payment " "summary": "Download bank statements and upload payment "
"files directly from Odoo, using the European EBICS standard", "files directly from Odoo, using the European EBICS standard",
"version": "19.0.1.2.0", "version": "19.0.1.3.0",
"license": "LGPL-3", "license": "LGPL-3",
"author": "Noviat", "author": "Noviat",
"website": "https://www.noviat.com/", "website": "https://www.noviat.com/",
+6
View File
@@ -70,6 +70,12 @@ class EbicsFile(models.Model):
readonly=True, readonly=True,
) )
note = fields.Text(string="Notes") note = fields.Text(string="Notes")
ebics_order_number = fields.Char(string="EBICS OrderID", readonly=True)
pain_state = fields.Selection(
[("draft", "Draft"), ("uploaded", "Uploaded"), ("error", "Error")],
default="draft",
readonly=True,
)
note_process = fields.Text( note_process = fields.Text(
string="Process Notes", string="Process Notes",
readonly=True, readonly=True,
+4
View File
@@ -135,6 +135,10 @@
string="Upload Date" string="Upload Date"
invisible="context.get('ebics_mode') == 'down'" invisible="context.get('ebics_mode') == 'down'"
/> />
<field
name="ebics_order_number"
invisible="context.get('ebics_mode') != 'up'"
/>
<field name="user_id" /> <field name="user_id" />
<field name="ebics_userid_id" /> <field name="ebics_userid_id" />
</group> </group>
+27 -10
View File
@@ -406,11 +406,9 @@ class EbicsXfer(models.TransientModel):
self.note += self.env._( self.note += self.env._(
"EBICS File has been uploaded (OrderID %s).", OrderID "EBICS File has been uploaded (OrderID %s).", OrderID
) )
ef_note = self.env._("EBICS OrderID: %s", OrderID) ef_note = ""
if self.env.context.get("origin"): if self.env.context.get("origin"):
ef_note += "\n" + self.env._( ef_note = self.env._("Origin: %s", self.env.context["origin"])
"Origin: %s", self.env.context["origin"]
)
suffix = self.format_id.suffix suffix = self.format_id.suffix
fn = self.upload_fname fn = self.upload_fname
if suffix and not fn.endswith(suffix): if suffix and not fn.endswith(suffix):
@@ -430,6 +428,9 @@ class EbicsXfer(models.TransientModel):
} }
self._update_ef_vals(ef_vals) self._update_ef_vals(ef_vals)
ebics_file = self.env["ebics.file"].create(ef_vals) ebics_file = self.env["ebics.file"].create(ef_vals)
ebics_file.write(
{"ebics_order_number": OrderID, "pain_state": "uploaded"}
)
except EbicsFunctionalError: except EbicsFunctionalError:
e = exc_info() e = exc_info()
@@ -458,16 +459,32 @@ class EbicsXfer(models.TransientModel):
OrderID = self.ebics_config_id._get_order_number() OrderID = self.ebics_config_id._get_order_number()
self.ebics_config_id.sudo()._update_order_number(OrderID) self.ebics_config_id.sudo()._update_order_number(OrderID)
ebics_file and self._payment_order_postprocess(ebics_file) ebics_file and self._payment_upload_postprocess(ebics_file)
return ebics_file return ebics_file
def _payment_order_postprocess(self, ebics_file): def _payment_upload_postprocess(self, ebics_file):
active_model = self.env.context.get("model") ctx = self.env.context
active_model = ctx.get("model")
active_id = ctx.get("id")
payment_doc = None
if active_model == "account.payment.order": if active_model == "account.payment.order":
order = self.env["account.payment.order"].browse( payment_doc = self.env["account.payment.order"].browse(active_id)
self.env.context["active_id"] payment_doc.generated2uploaded()
elif active_model == "account.batch.payment":
payment_doc = self.env["account.batch.payment"].browse(active_id)
if payment_doc:
payment_doc.ebics_file_id = ebics_file
self._payment_upload_chatter_message(payment_doc, ebics_file)
def _payment_upload_chatter_message(self, payment_doc, ebics_file):
payment_doc.message_post(
body=self.env._(
"'%(filename)s' has been uploaded via EBICS"
" (OrderID: %(order_number)s).",
filename=ebics_file.name,
order_number=ebics_file.ebics_order_number,
) )
order.generated2uploaded() )
def _setup_client(self): def _setup_client(self):
self.ebics_config_id._check_ebics_keys() self.ebics_config_id._check_ebics_keys()