Merge pull request #83 from Noviat/17.0

Syncing from upstream Noviat/account_ebics (17.0)
This commit is contained in:
braintec
2026-04-18 01:12:34 +02:00
committed by GitHub
15 changed files with 263 additions and 155 deletions

View File

@@ -15,12 +15,12 @@ Available addons
---------------- ----------------
addon | version | maintainers | summary addon | version | maintainers | summary
--- | --- | --- | --- --- | --- | --- | ---
[account_ebics](account_ebics/) | 17.0.1.2.2 | | EBICS banking protocol [account_ebics](account_ebics/) | 17.0.1.3.0 | | EBICS banking protocol
[account_ebics_batch](account_ebics_batch/) | 17.0.1.0.1 | | EBICS Files automated import and processing [account_ebics_batch](account_ebics_batch/) | 17.0.1.0.1 | | EBICS Files automated import and processing
[account_ebics_batch_payment](account_ebics_batch_payment/) | 17.0.1.0.3 | | Upload Batch Payment via EBICS [account_ebics_batch_payment](account_ebics_batch_payment/) | 17.0.1.1.0 | | Upload Batch Payment via EBICS
[account_ebics_oca_statement_import](account_ebics_oca_statement_import/) | 17.0.1.0.1 | | Use OCA Bank Statement Import with account_ebics [account_ebics_oca_statement_import](account_ebics_oca_statement_import/) | 17.0.1.0.1 | | Use OCA Bank Statement Import with account_ebics
[account_ebics_oe](account_ebics_oe/) | 17.0.1.0.0 | | Deploy account_ebics module on Odoo Enterprise [account_ebics_oe](account_ebics_oe/) | 17.0.1.0.0 | | Deploy account_ebics module on Odoo Enterprise
[account_ebics_payment_order](account_ebics_payment_order/) | 17.0.1.1.0 | | Upload Payment Order via EBICS [account_ebics_payment_order](account_ebics_payment_order/) | 17.0.1.2.0 | | Upload Payment Order via EBICS
[//]: # (end addons) [//]: # (end addons)

View File

@@ -1,9 +1,9 @@
# Copyright 2009-2025 Noviat. # Copyright 2015 Noviat.
# License LGPL-3 or later (https://www.gnu.org/licenses/lgpl). # License LGPL-3 or later (https://www.gnu.org/licenses/lgpl).
{ {
"name": "EBICS banking protocol", "name": "EBICS banking protocol",
"version": "17.0.1.2.2", "version": "17.0.1.3.0",
"license": "LGPL-3", "license": "LGPL-3",
"author": "Noviat", "author": "Noviat",
"website": "https://www.noviat.com/", "website": "https://www.noviat.com/",

View File

@@ -1,5 +1,6 @@
from . import fintech_ebics_register from . import fintech_ebics_register
from . import account_bank_statement from . import account_bank_statement
from . import account_journal
from . import ebics_config from . import ebics_config
from . import ebics_file from . import ebics_file
from . import ebics_file_format from . import ebics_file_format

View File

@@ -0,0 +1,26 @@
# Copyright 2026 Noviat.
# License LGPL-3 or later (https://www.gnu.org/licenses/lgpl).
from odoo import api, fields, models
class AccountJournal(models.Model):
_inherit = "account.journal"
ebics_config_ids = fields.Many2many(
comodel_name="ebics.config",
relation="account_journal_ebics_config_rel",
readonly=True,
)
ebics_config_id = fields.Many2one(
comodel_name="ebics.config",
compute="_compute_ebics_config_id",
compute_sudo=True,
)
@api.depends("ebics_config_ids")
def _compute_ebics_config_id(self):
for rec in self:
rec.ebics_config_id = rec.ebics_config_ids.filtered(
lambda r: r.state == "confirm"
)[:1]

View File

@@ -120,7 +120,8 @@ class EbicsConfig(models.Model):
comodel_name="res.company", comodel_name="res.company",
relation="ebics_config_res_company_rel", relation="ebics_config_res_company_rel",
string="Companies", string="Companies",
readonly=True, compute="_compute_company_ids",
store=True,
help="Companies sharing this EBICS contract.", help="Companies sharing this EBICS contract.",
) )
@@ -154,26 +155,10 @@ class EbicsConfig(models.Model):
) )
) )
def write(self, vals): @api.depends("journal_ids.company_id")
""" def _compute_company_ids(self):
Due to the multi-company nature of the EBICS config we
need to adapt the company_ids in the write method.
"""
if "journal_ids" not in vals:
return super().write(vals)
for rec in self: for rec in self:
old_company_ids = rec.journal_ids.mapped("company_id").ids rec.company_ids = rec.journal_ids.mapped("company_id")
super(EbicsConfig, rec).write(vals)
new_company_ids = rec.journal_ids.mapped("company_id").ids
updates = []
for cid in new_company_ids:
if cid in old_company_ids:
old_company_ids.remove(cid)
else:
updates += [(4, cid)]
updates += [(3, x) for x in old_company_ids]
super(EbicsConfig, rec).write({"company_ids": updates})
return True
def unlink(self): def unlink(self):
for ebics_config in self: for ebics_config in self:

View File

@@ -82,4 +82,13 @@
sequence="30" sequence="30"
/> />
<menuitem
id="ebics_xfer_menu_mark_as_downloaded"
name="Mark files as Downloaded"
parent="ebics_menu"
action="account_ebics.ebics_xfer_action_mark_as_downloaded"
groups="account_ebics.group_ebics_manager"
sequence="40"
/>
</odoo> </odoo>

View File

@@ -237,8 +237,8 @@ class EbicsXfer(models.TransientModel):
date_from = self.date_from and self.date_from.isoformat() or None date_from = self.date_from and self.date_from.isoformat() or None
date_to = self.date_to and self.date_to.isoformat() or None date_to = self.date_to and self.date_to.isoformat() or None
for df in download_formats: for df in download_formats:
try:
success = False success = False
try:
if df.order_type == "BTD": if df.order_type == "BTD":
btf = BusinessTransactionFormat( btf = BusinessTransactionFormat(
df.btf_service, df.btf_service,
@@ -263,6 +263,7 @@ class EbicsXfer(models.TransientModel):
} }
} }
data = client.download(df.order_type, params=params) data = client.download(df.order_type, params=params)
if not self.env.context.get("ebics_mark_as_downloaded"):
ebics_files += self._handle_download_data(data, df) ebics_files += self._handle_download_data(data, df)
success = True success = True
except EbicsFunctionalError: except EbicsFunctionalError:
@@ -321,8 +322,8 @@ class EbicsXfer(models.TransientModel):
order_type=df.order_type, order_type=df.order_type,
) )
tb = "".join(format_exception(*exc_info())) tb = "".join(format_exception(*exc_info()))
self.note += "\n%s" % tb self.note += f"\n{tb}"
else: finally:
# mark received data so that it is not included in further # mark received data so that it is not included in further
# downloads # downloads
trans_id = client.last_trans_id trans_id = client.last_trans_id

View File

@@ -99,7 +99,10 @@
readonly="context.get('active_model') == 'account.payment.order'" readonly="context.get('active_model') == 'account.payment.order'"
/> />
<field name="order_type" /> <field name="order_type" />
<field name="test_mode" invisible="order_type not in ('FUL', 'BTU')" /> <field
name="test_mode"
invisible="order_type not in ('FUL', 'BTU')"
/>
<field name="allowed_format_ids" invisible="1" /> <field name="allowed_format_ids" invisible="1" />
</group> </group>
<footer> <footer>
@@ -169,4 +172,77 @@
<field name="view_id" ref="ebics_xfer_view_form_upload" /> <field name="view_id" ref="ebics_xfer_view_form_upload" />
</record> </record>
<record id="ebics_xfer_view_form_mark_as_downloaded" model="ir.ui.view">
<field name="name">Mark EBICS files as Downloaded</field>
<field name="model">ebics.xfer</field>
<field name="priority">1</field>
<field name="arch" type="xml">
<form string="EBICS Mark as Downloaded">
<div class="alert alert-warning" role="alert">
The EBICS Files (Bank Statements) selected via this screen will not become available in Odoo as
EBICS files but will be marked by your bank as downloaded.
<br />
As a consequence, these Bank Statements will not be retrieved by the next 'EBICS Batch Import'
scheduled action.
</div>
<group>
<separator string="Select your bank :" colspan="2" />
<field
name="ebics_config_id"
required="1"
options="{'no_create': True, 'no_open': True}"
/>
<field
name="ebics_userid_id"
domain="[('ebics_config_id', '=', ebics_config_id), ('user_ids.id', '=', uid), ('transaction_rights', 'in', ['both', 'down'])]"
required="1"
options="{'no_create': True, 'no_open': True}"
/>
<field
name="ebics_passphrase"
password="True"
invisible="ebics_passphrase_store"
required="not ebics_passphrase_store"
/>
<field name="ebics_passphrase_store" invisible="1" />
<field name="date_from" required="1" />
<field name="date_to" required="1" />
<field
name="format_id"
required="1"
domain="[('type', '=', 'down'), ('id', 'in', allowed_format_ids)]"
/>
<field name="allowed_format_ids" invisible="1" />
</group>
<footer>
<button
name="ebics_download"
string="Mark as Downloaded"
type="object"
class="btn-primary"
data-hotkey="q"
/>
<button
string="Cancel"
class="btn-secondary"
special="cancel"
data-hotkey="z"
/>
</footer>
</form>
</field>
</record>
<record id="ebics_xfer_action_mark_as_downloaded" model="ir.actions.act_window">
<field name="name">Mark files as Downloaded</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ebics.xfer</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field
name="context"
>{'ebics_download': 1, 'ebics_mark_as_downloaded': 1}</field>
<field name="view_id" ref="ebics_xfer_view_form_mark_as_downloaded" />
</record>
</odoo> </odoo>

View File

@@ -1,9 +1,9 @@
# Copyright 2009-2024 Noviat. # Copyright 2020 Noviat.
# License LGPL-3 or later (http://www.gnu.org/licenses/lgpl). # License LGPL-3 or later (http://www.gnu.org/licenses/lgpl).
{ {
"name": "Upload Batch Payment via EBICS", "name": "Upload Batch Payment via EBICS",
"version": "17.0.1.0.3", "version": "17.0.1.1.0",
"license": "LGPL-3", "license": "LGPL-3",
"author": "Noviat", "author": "Noviat",
"website": "https://www.noviat.com/", "website": "https://www.noviat.com/",

View File

@@ -1,32 +1,38 @@
# Copyright 2009-2023 Noviat. # Copyright 2020 Noviat.
# License LGPL-3 or later (http://www.gnu.org/licenses/lgpl). # License LGPL-3 or later (http://www.gnu.org/licenses/lgpl).
from odoo import _, models from odoo import _, api, fields, models
from odoo.exceptions import UserError from odoo.exceptions import UserError
class AccountBatchPayment(models.Model): class AccountBatchPayment(models.Model):
_inherit = "account.batch.payment" _inherit = "account.batch.payment"
hide_ebics_upload = fields.Boolean(
compute="_compute_hide_ebics_upload", default=True
)
@api.depends("journal_id.ebics_config_id", "file_generation_enabled", "state")
def _compute_hide_ebics_upload(self):
for rec in self:
rec.hide_ebics_upload = (
not rec.journal_id.ebics_config_id
or not rec.file_generation_enabled
or rec.state != "sent"
)
def ebics_upload(self): def ebics_upload(self):
self.ensure_one() self.ensure_one()
ctx = self.env.context.copy() ctx = self.env.context.copy()
origin = _("Batch Payment") + ": " + self.name origin = _("Batch Payment") + ": " + self.name
ebics_config = self.env["ebics.config"].search( if not self.journal_id.ebics_config_id:
[
("journal_ids", "=", self.journal_id.id),
("state", "=", "confirm"),
]
)
if not ebics_config:
raise UserError( raise UserError(
_("No active EBICS configuration available " "for the selected bank.") _("No active EBICS configuration available for the selected bank.")
) )
if len(ebics_config) == 1:
ctx["default_ebics_config_id"] = ebics_config.id
ctx.update( ctx.update(
{ {
"default_ebics_config_id": self.journal_id.ebics_config_id.id,
"default_upload_data": self.export_file, "default_upload_data": self.export_file,
"default_upload_fname": self.export_filename, "default_upload_fname": self.export_filename,
"origin": origin, "origin": origin,
@@ -44,7 +50,6 @@ class AccountBatchPayment(models.Model):
view = self.env.ref("account_ebics.ebics_xfer_view_form_upload") view = self.env.ref("account_ebics.ebics_xfer_view_form_upload")
act = { act = {
"name": _("EBICS Upload"), "name": _("EBICS Upload"),
"view_type": "form",
"view_mode": "form", "view_mode": "form",
"res_model": "ebics.xfer", "res_model": "ebics.xfer",
"view_id": view.id, "view_id": view.id,

View File

@@ -7,10 +7,11 @@
<field name="inherit_id" ref="account_batch_payment.view_batch_payment_form" /> <field name="inherit_id" ref="account_batch_payment.view_batch_payment_form" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<button name="validate_batch_button" position="after"> <button name="validate_batch_button" position="after">
<field name="hide_ebics_upload" invisible="1" />
<button <button
name="ebics_upload" name="ebics_upload"
type="object" type="object"
invisible="not file_generation_enabled or state != 'sent'" invisible="hide_ebics_upload"
string="EBICS Upload" string="EBICS Upload"
/> />
</button> </button>

View File

@@ -1,9 +1,9 @@
# Copyright 2009-2024 Noviat. # Copyright 2015 Noviat.
# License LGPL-3 or later (http://www.gnu.org/licenses/lgpl). # License LGPL-3 or later (https://www.gnu.org/licenses/lgpl).
{ {
"name": "Upload Payment Order via EBICS", "name": "Upload Payment Order via EBICS",
"version": "17.0.1.1.0", "version": "17.0.1.2.0",
"license": "LGPL-3", "license": "LGPL-3",
"author": "Noviat", "author": "Noviat",
"website": "https://www.noviat.com/", "website": "https://www.noviat.com/",

View File

@@ -1,5 +1,5 @@
# Copyright 2009-2024 Noviat. # Copyright 2015 Noviat.
# License LGPL-3 or later (http://www.gnu.org/licenses/lpgl). # License LGPL-3 or later (https://www.gnu.org/licenses/lgpl).
from odoo import fields, models from odoo import fields, models

View File

@@ -1,13 +1,24 @@
# Copyright 2009-2024 Noviat. # Copyright 2015 Noviat.
# License LGPL-3 or later (http://www.gnu.org/licenses/lgpl). # License LGPL-3 or later (https://www.gnu.org/licenses/lgpl).
from odoo import _, models from odoo import _, api, fields, models
from odoo.exceptions import UserError from odoo.exceptions import UserError
class AccountPaymentOrder(models.Model): class AccountPaymentOrder(models.Model):
_inherit = "account.payment.order" _inherit = "account.payment.order"
hide_ebics_upload = fields.Boolean(
compute="_compute_hide_ebics_upload", default=True
)
@api.depends("journal_id.ebics_config_id", "state")
def _compute_hide_ebics_upload(self):
for rec in self:
rec.hide_ebics_upload = (
not rec.journal_id.ebics_config_id or rec.state != "generated"
)
def ebics_upload(self): def ebics_upload(self):
self.ensure_one() self.ensure_one()
ctx = self.env.context.copy() ctx = self.env.context.copy()
@@ -28,8 +39,8 @@ class AccountPaymentOrder(models.Model):
if not attach: if not attach:
raise UserError( raise UserError(
_( _(
"This payment order doesn't contains attachements." "This payment order doesn't contains attachments."
"\nPlease generate first the Payment Order file first." "\nPlease generate first the Payment Order file."
) )
) )
elif len(attach) > 1: elif len(attach) > 1:
@@ -43,23 +54,16 @@ class AccountPaymentOrder(models.Model):
) )
else: else:
origin = _("Payment Order") + ": " + self.name origin = _("Payment Order") + ": " + self.name
ebics_config = self.env["ebics.config"].search( if not self.journal_id.ebics_config_id:
[
("journal_ids", "=", self.journal_id.id),
("state", "=", "confirm"),
]
)
if not ebics_config:
raise UserError( raise UserError(
_( _(
"No active EBICS configuration available " "No active EBICS configuration available "
"for the selected bank." "for the selected bank."
) )
) )
if len(ebics_config) == 1:
ctx["default_ebics_config_id"] = ebics_config.id
ctx.update( ctx.update(
{ {
"default_ebics_config_id": self.journal_id.ebics_config_id.id,
"default_upload_data": attach.datas, "default_upload_data": attach.datas,
"default_upload_fname": attach.name, "default_upload_fname": attach.name,
"origin": origin, "origin": origin,
@@ -76,7 +80,6 @@ class AccountPaymentOrder(models.Model):
view = self.env.ref("account_ebics.ebics_xfer_view_form_upload") view = self.env.ref("account_ebics.ebics_xfer_view_form_upload")
act = { act = {
"name": _("EBICS Upload"), "name": _("EBICS Upload"),
"view_type": "form",
"view_mode": "form", "view_mode": "form",
"res_model": "ebics.xfer", "res_model": "ebics.xfer",
"view_id": view.id, "view_id": view.id,

View File

@@ -7,10 +7,11 @@
<field name="inherit_id" ref="account_payment_order.account_payment_order_form" /> <field name="inherit_id" ref="account_payment_order.account_payment_order_form" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<button name="open2generated" position="after"> <button name="open2generated" position="after">
<field name="hide_ebics_upload" invisible="1" />
<button <button
name="ebics_upload" name="ebics_upload"
type="object" type="object"
invisible="state != 'generated'" invisible="hide_ebics_upload"
string="EBICS Upload" string="EBICS Upload"
class="oe_highlight" class="oe_highlight"
/> />