[IMP] account_ebics: pre-commit

This commit is contained in:
Luc De Meyer 2022-10-27 23:48:16 +02:00
parent c17100ee23
commit 0f3169e375
15 changed files with 233 additions and 226 deletions

View File

@ -17,7 +17,7 @@ rebel_module_groups: []
repo_description: 'EBICS support for Odoo' repo_description: 'EBICS support for Odoo'
repo_name: account_ebics repo_name: account_ebics
repo_slug: account_ebics repo_slug: account_ebics
repo_website: https://github.com/Noviat/account_ebics repo_website: https://www.noviat.com
travis_apt_packages: [] travis_apt_packages: []
travis_apt_sources: [] travis_apt_sources: []

View File

@ -36,7 +36,7 @@ repos:
# update the NOT INSTALLABLE ADDONS section above # update the NOT INSTALLABLE ADDONS section above
- id: oca-update-pre-commit-excluded-addons - id: oca-update-pre-commit-excluded-addons
- id: oca-fix-manifest-website - id: oca-fix-manifest-website
args: ["https://www.noviat.com/"] args: ["https://www.noviat.com"]
- repo: https://github.com/myint/autoflake - repo: https://github.com/myint/autoflake
rev: v1.7.7 rev: v1.7.7
hooks: hooks:

View File

@ -3,10 +3,10 @@
{ {
"name": "EBICS banking protocol", "name": "EBICS banking protocol",
"version": "14.0.1.0.5", "version": "15.0.1.0.0",
"license": "LGPL-3", "license": "LGPL-3",
"author": "Noviat", "author": "Noviat",
"website": "https://github.com/Noviat/account_ebics", "website": "https://www.noviat.com",
"category": "Accounting & Finance", "category": "Accounting & Finance",
"depends": ["account"], "depends": ["account"],
"data": [ "data": [

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo noupdate="1">
<data noupdate="1">
<!-- Download formats --> <!-- Download formats -->
@ -9,9 +8,7 @@
<field name="type">down</field> <field name="type">down</field>
<field name="order_type">C52</field> <field name="order_type">C52</field>
<field name="download_process_method">camt.052</field> <field name="download_process_method">camt.052</field>
<field <field name="description">bank to customer account report in format camt.052</field>
name="description"
>bank to customer account report in format camt.052</field>
<field name="suffix">c52.xml</field> <field name="suffix">c52.xml</field>
</record> </record>
@ -20,9 +17,7 @@
<field name="type">down</field> <field name="type">down</field>
<field name="order_type">Z52</field> <field name="order_type">Z52</field>
<field name="download_process_method">camt.052</field> <field name="download_process_method">camt.052</field>
<field <field name="description">bank to customer account report in format camt.052</field>
name="description"
>bank to customer account report in format camt.052</field>
<field name="suffix">c52.xml</field> <field name="suffix">c52.xml</field>
</record> </record>
@ -176,5 +171,4 @@
<field name="suffix">xml</field> <field name="suffix">xml</field>
</record> </record>
</data>
</odoo> </odoo>

View File

@ -1,4 +1,4 @@
# Copyright 2009-2020 Noviat. # Copyright 2009-2022 Noviat.
# License LGPL-3 or later (http://www.gnu.org/licenses/lpgl). # License LGPL-3 or later (http://www.gnu.org/licenses/lpgl).
from odoo import fields, models from odoo import fields, models

View File

@ -22,7 +22,6 @@ class EbicsConfig(models.Model):
_order = "name" _order = "name"
name = fields.Char( name = fields.Char(
string="Name",
readonly=True, readonly=True,
states={"draft": [("readonly", False)]}, states={"draft": [("readonly", False)]},
required=True, required=True,
@ -131,7 +130,6 @@ class EbicsConfig(models.Model):
) )
state = fields.Selection( state = fields.Selection(
[("draft", "Draft"), ("confirm", "Confirmed")], [("draft", "Draft"), ("confirm", "Confirmed")],
string="State",
default="draft", default="draft",
required=True, required=True,
readonly=True, readonly=True,
@ -144,7 +142,7 @@ class EbicsConfig(models.Model):
"\nThis number should match the following pattern : " "\nThis number should match the following pattern : "
"[A-Z]{1}[A-Z0-9]{3}", "[A-Z]{1}[A-Z0-9]{3}",
) )
active = fields.Boolean(string="Active", default=True) active = fields.Boolean(default=True)
company_ids = fields.Many2many( company_ids = fields.Many2many(
comodel_name="res.company", comodel_name="res.company",
string="Companies", string="Companies",

View File

@ -46,7 +46,6 @@ class EbicsFile(models.Model):
) )
state = fields.Selection( state = fields.Selection(
[("draft", "Draft"), ("done", "Done")], [("draft", "Draft"), ("done", "Done")],
string="State",
default="draft", default="draft",
required=True, required=True,
readonly=True, readonly=True,
@ -93,8 +92,7 @@ class EbicsFile(models.Model):
def process(self): def process(self):
self.ensure_one() self.ensure_one()
ctx = dict(self.env.context, allowed_company_ids=self.env.user.company_ids.ids) self = self.with_context(allowed_company_ids=self.env.user.company_ids.ids)
self = self.with_context(ctx)
self.note_process = "" self.note_process = ""
ff_methods = self._file_format_methods() ff_methods = self._file_format_methods()
ff = self.format_id.download_process_method ff = self.format_id.download_process_method
@ -159,11 +157,12 @@ class EbicsFile(models.Model):
if raise_if_not_found: if raise_if_not_found:
raise UserError( raise UserError(
_( _(
"The module to process the '%s' format is not installed " "The module to process the '%(ebics_format)s' format is not installed "
"on your system. " "on your system. "
"\nPlease install module '%s'" "\nPlease install module '%(module)s'",
ebics_format=self.format_id.name,
module=module,
) )
% (self.format_id.name, module)
) )
return False return False
return True return True
@ -288,9 +287,12 @@ class EbicsFile(models.Model):
"notifications": [], "notifications": [],
}, },
} }
wiz_ctx = dict(self.env.context, active_model="ebics.file")
for i, wiz_vals in enumerate(wiz_vals_list, start=1): for i, wiz_vals in enumerate(wiz_vals_list, start=1):
wiz = self.env[wiz_model].with_context(wiz_ctx).create(wiz_vals) wiz = (
self.env[wiz_model]
.with_context(active_model="ebics.file")
.create(wiz_vals)
)
res = wiz.import_file_button() res = wiz.import_file_button()
ctx = res.get("context") ctx = res.get("context")
if res.get("res_model") == "account.bank.statement.import.journal.creation": if res.get("res_model") == "account.bank.statement.import.journal.creation":
@ -360,11 +362,12 @@ class EbicsFile(models.Model):
if not found: if not found:
raise UserError( raise UserError(
_( _(
"The module to process the '%s' format is not installed " "The module to process the '%(ebics_format)s' format is "
"on your system. " "not installed on your system. "
"\nPlease install one of the following modules: \n%s." "\nPlease install one of the following modules: \n%(modules)s.",
ebics_format=self.format_id.name,
modules=", ".join([x[1] for x in modules]),
) )
% (self.format_id.name, ", ".join([x[1] for x in modules]))
) )
if _src == "oca": if _src == "oca":
self._process_camt053_oca() self._process_camt053_oca()
@ -386,8 +389,9 @@ class EbicsFile(models.Model):
"notifications": [], "notifications": [],
}, },
} }
wiz_ctx = dict(self.env.context, active_model="ebics.file") wiz = (
wiz = self.env[wiz_model].with_context(wiz_ctx).create(wiz_vals) self.env[wiz_model].with_context(active_model="ebics.file").create(wiz_vals)
)
res = wiz.import_file_button() res = wiz.import_file_button()
ctx = res.get("context") ctx = res.get("context")
if res.get("res_model") == "account.bank.statement.import.journal.creation": if res.get("res_model") == "account.bank.statement.import.journal.creation":
@ -418,8 +422,9 @@ class EbicsFile(models.Model):
) )
] ]
} }
ctx = dict(self.env.context, active_model="ebics.file") wiz = (
wiz = self.env[wiz_model].with_context(ctx).create(wiz_vals) self.env[wiz_model].with_context(active_model="ebics.file").create(wiz_vals)
)
res = wiz.import_file() res = wiz.import_file()
if res.get("res_model") == "account.bank.statement.import.journal.creation": if res.get("res_model") == "account.bank.statement.import.journal.creation":
if res.get("context"): if res.get("context"):

View File

@ -1,4 +1,4 @@
# Copyright 2009-2020 Noviat. # Copyright 2009-2022 Noviat.
# License LGPL-3 or later (http://www.gnu.org/licenses/lpgl). # License LGPL-3 or later (http://www.gnu.org/licenses/lpgl).
from odoo import api, fields, models from odoo import api, fields, models
@ -22,7 +22,6 @@ class EbicsFileFormat(models.Model):
selection=[("down", "Download"), ("up", "Upload")], required=True selection=[("down", "Download"), ("up", "Upload")], required=True
) )
order_type = fields.Char( order_type = fields.Char(
string="Order Type",
required=True, required=True,
help="E.g. C53 (check your EBICS contract).\n" help="E.g. C53 (check your EBICS contract).\n"
"For most banks in France you should use the " "For most banks in France you should use the "
@ -40,7 +39,6 @@ class EbicsFileFormat(models.Model):
# move signature_class parameter so that it can be set per EBICS config # move signature_class parameter so that it can be set per EBICS config
signature_class = fields.Selection( signature_class = fields.Selection(
selection=[("E", "Single signature"), ("T", "Transport signature")], selection=[("E", "Single signature"), ("T", "Transport signature")],
string="Signature Class",
help="Please doublecheck the security of your Odoo " help="Please doublecheck the security of your Odoo "
"ERP system when using class 'E' to prevent unauthorised " "ERP system when using class 'E' to prevent unauthorised "
"users to make supplier payments." "users to make supplier payments."

View File

@ -1,4 +1,4 @@
# Copyright 2009-2020 Noviat. # Copyright 2009-2022 Noviat.
# License LGPL-3 or later (http://www.gnu.org/licenses/lpgl). # License LGPL-3 or later (http://www.gnu.org/licenses/lpgl).
import base64 import base64
@ -75,7 +75,6 @@ class EbicsUserID(models.Model):
# Classes A and B are not yet supported. # Classes A and B are not yet supported.
signature_class = fields.Selection( signature_class = fields.Selection(
selection=[("E", "Single signature"), ("T", "Transport signature")], selection=[("E", "Single signature"), ("T", "Transport signature")],
string="Signature Class",
required=True, required=True,
default="T", default="T",
readonly=True, readonly=True,
@ -157,12 +156,11 @@ class EbicsUserID(models.Model):
("to_verify", "Verification"), ("to_verify", "Verification"),
("active_keys", "Active Keys"), ("active_keys", "Active Keys"),
], ],
string="State",
default="draft", default="draft",
required=True, required=True,
readonly=True, readonly=True,
) )
active = fields.Boolean(string="Active", default=True) active = fields.Boolean(default=True)
company_ids = fields.Many2many( company_ids = fields.Many2many(
comodel_name="res.company", comodel_name="res.company",
string="Companies", string="Companies",
@ -243,11 +241,11 @@ class EbicsUserID(models.Model):
partnerid=self.ebics_config_id.ebics_partner, partnerid=self.ebics_config_id.ebics_partner,
userid=self.name, userid=self.name,
) )
except Exception: except Exception as err:
exctype, value = exc_info()[:2] exctype, value = exc_info()[:2]
error = _("EBICS Initialisation Error:") error = _("EBICS Initialisation Error:")
error += "\n" + str(exctype) + "\n" + str(value) error += "\n" + str(exctype) + "\n" + str(value)
raise UserError(error) raise UserError(error) from err
self.ebics_config_id._check_ebics_keys() self.ebics_config_id._check_ebics_keys()
if not os.path.isfile(self.ebics_keys_fn): if not os.path.isfile(self.ebics_keys_fn):
@ -265,11 +263,11 @@ class EbicsUserID(models.Model):
keyversion=self.ebics_config_id.ebics_key_version, keyversion=self.ebics_config_id.ebics_key_version,
bitlength=self.ebics_config_id.ebics_key_bitlength, bitlength=self.ebics_config_id.ebics_key_bitlength,
) )
except Exception: except Exception as err:
exctype, value = exc_info()[:2] exctype, value = exc_info()[:2]
error = _("EBICS Initialisation Error:") error = _("EBICS Initialisation Error:")
error += "\n" + str(exctype) + "\n" + str(value) error += "\n" + str(exctype) + "\n" + str(value)
raise UserError(error) raise UserError(error) from err
if self.swift_3skey and not self.ebics_key_x509: if self.swift_3skey and not self.ebics_key_x509:
raise UserError( raise UserError(
@ -314,7 +312,7 @@ class EbicsUserID(models.Model):
_logger.info("%s, EBICS INI command, OrderID=%s", self._name, OrderID) _logger.info("%s, EBICS INI command, OrderID=%s", self._name, OrderID)
if ebics_version == "H003": if ebics_version == "H003":
self.ebics_config_id._update_order_number(OrderID) self.ebics_config_id._update_order_number(OrderID)
except URLError: except URLError as err:
exctype, value = exc_info()[:2] exctype, value = exc_info()[:2]
tb = "".join(format_exception(*exc_info())) tb = "".join(format_exception(*exc_info()))
_logger.error( _logger.error(
@ -323,21 +321,22 @@ class EbicsUserID(models.Model):
tb, tb,
) )
raise UserError( raise UserError(
_("urlopen error:\n url '%s' - %s") _("urlopen error:\n url '%(url)s' - %(val)s"),
% (self.ebics_config_id.ebics_url, str(value)) url=self.ebics_config_id.ebics_url,
) val=str(value),
except EbicsFunctionalError: ) from err
except EbicsFunctionalError as err:
e = exc_info() e = exc_info()
error = _("EBICS Functional Error:") error = _("EBICS Functional Error:")
error += "\n" error += "\n"
error += "{} (code: {})".format(e[1].message, e[1].code) error += "{} (code: {})".format(e[1].message, e[1].code)
raise UserError(error) raise UserError(error) from err
except EbicsTechnicalError: except EbicsTechnicalError as err:
e = exc_info() e = exc_info()
error = _("EBICS Technical Error:") error = _("EBICS Technical Error:")
error += "\n" error += "\n"
error += "{} (code: {})".format(e[1].message, e[1].code) error += "{} (code: {})".format(e[1].message, e[1].code)
raise UserError(error) raise UserError(error) from err
# Send the public authentication and encryption keys to the bank. # Send the public authentication and encryption keys to the bank.
if ebics_version == "H003": if ebics_version == "H003":
@ -411,25 +410,25 @@ class EbicsUserID(models.Model):
userid=self.name, userid=self.name,
) )
client = EbicsClient(bank, user, version=self.ebics_config_id.ebics_version) client = EbicsClient(bank, user, version=self.ebics_config_id.ebics_version)
except Exception: except Exception as err:
exctype, value = exc_info()[:2] exctype, value = exc_info()[:2]
error = _("EBICS Initialisation Error:") error = _("EBICS Initialisation Error:")
error += "\n" + str(exctype) + "\n" + str(value) error += "\n" + str(exctype) + "\n" + str(value)
raise UserError(error) raise UserError(error) from err
try: try:
public_bank_keys = client.HPB() public_bank_keys = client.HPB()
except EbicsFunctionalError: except EbicsFunctionalError as err:
e = exc_info() e = exc_info()
error = _("EBICS Functional Error:") error = _("EBICS Functional Error:")
error += "\n" error += "\n"
error += "{} (code: {})".format(e[1].message, e[1].code) error += "{} (code: {})".format(e[1].message, e[1].code)
raise UserError(error) raise UserError(error) from err
except Exception: except Exception as err:
exctype, value = exc_info()[:2] exctype, value = exc_info()[:2]
error = _("EBICS Initialisation Error:") error = _("EBICS Initialisation Error:")
error += "\n" + str(exctype) + "\n" + str(value) error += "\n" + str(exctype) + "\n" + str(value)
raise UserError(error) raise UserError(error) from err
public_bank_keys = public_bank_keys.encode() public_bank_keys = public_bank_keys.encode()
tmp_dir = os.path.normpath(self.ebics_config_id.ebics_files + "/tmp") tmp_dir = os.path.normpath(self.ebics_config_id.ebics_files + "/tmp")

View File

@ -5,7 +5,7 @@
<field name="name">ebics.config.tree</field> <field name="name">ebics.config.tree</field>
<field name="model">ebics.config</field> <field name="model">ebics.config</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="EBICS Configuration" decoration-muted="state == 'draft'"> <tree decoration-muted="state == 'draft'">
<field name="name" /> <field name="name" />
<field name="ebics_host" /> <field name="ebics_host" />
<field name="state" /> <field name="state" />

View File

@ -5,7 +5,7 @@
<field name="name">ebics.file.format.tree</field> <field name="name">ebics.file.format.tree</field>
<field name="model">ebics.file.format</field> <field name="model">ebics.file.format</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="EBICS File Formats"> <tree>
<field name="type" /> <field name="type" />
<field name="order_type" /> <field name="order_type" />
<field name="signature_class" /> <field name="signature_class" />

View File

@ -38,7 +38,7 @@
<field name="name">ebics.file.tree</field> <field name="name">ebics.file.tree</field>
<field name="model">ebics.file</field> <field name="model">ebics.file</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="EBICS Files" decoration-muted="state=='draft'" create="false"> <tree decoration-muted="state=='draft'" create="false">
<field name="date" string="Download Date" /> <field name="date" string="Download Date" />
<field name="name" /> <field name="name" />
<field name="date_from" /> <field name="date_from" />
@ -169,7 +169,7 @@
<field name="name">ebics.file.tree</field> <field name="name">ebics.file.tree</field>
<field name="model">ebics.file</field> <field name="model">ebics.file</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="EBICS Files" decoration-muted="state=='draft'" create="false"> <tree decoration-muted="state=='draft'" create="false">
<field name="date" string="Upload Date" /> <field name="date" string="Upload Date" />
<field name="name" /> <field name="name" />
<field name="user_id" /> <field name="user_id" />

View File

@ -5,7 +5,7 @@
<field name="name">ebics.userid.tree</field> <field name="name">ebics.userid.tree</field>
<field name="model">ebics.userid</field> <field name="model">ebics.userid</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="EBICS UserID" decoration-muted="state != 'active_keys'"> <tree decoration-muted="state != 'active_keys'">
<field name="name" /> <field name="name" />
<field name="signature_class" /> <field name="signature_class" />
<field name="state" /> <field name="state" />

View File

@ -1,4 +1,4 @@
# Copyright 2009-2020 Noviat. # Copyright 2009-2022 Noviat.
# License LGPL-3 or later (http://www.gnu.org/licenses/lpgl). # License LGPL-3 or later (http://www.gnu.org/licenses/lpgl).
import logging import logging
@ -43,8 +43,8 @@ class EbicsChangePassphrase(models.TransientModel):
passphrase=self.ebics_userid_id.ebics_passphrase, passphrase=self.ebics_userid_id.ebics_passphrase,
) )
keyring.change_passphrase(self.new_pass) keyring.change_passphrase(self.new_pass)
except ValueError as e: except ValueError as err:
raise UserError(str(e)) raise UserError(str(err)) from err
self.ebics_userid.ebics_passphrase = self.new_pass self.ebics_userid.ebics_passphrase = self.new_pass
self.note = "The EBICS Passphrase has been changed." self.note = "The EBICS Passphrase has been changed."

View File

@ -86,7 +86,6 @@ class EbicsXfer(models.TransientModel):
"and 'FDL' for download.", "and 'FDL' for download.",
) )
test_mode = fields.Boolean( test_mode = fields.Boolean(
string="Test Mode",
help="Select this option to test if the syntax of " help="Select this option to test if the syntax of "
"the upload file is correct." "the upload file is correct."
"\nThis option is only available for " "\nThis option is only available for "
@ -222,8 +221,11 @@ class EbicsXfer(models.TransientModel):
e = exc_info() e = exc_info()
self.note += "\n" self.note += "\n"
self.note += _( self.note += _(
"EBICS Functional Error during download of File Format %s (%s):" "EBICS Functional Error during download of "
) % (df.name, df.order_type) "File Format %(name)s (%(order_type)s):",
name=df.name,
order_type=df.order_type,
)
self.note += "\n" self.note += "\n"
self.note += "{} (code: {})".format(e[1].message, e[1].code) self.note += "{} (code: {})".format(e[1].message, e[1].code)
except EbicsTechnicalError: except EbicsTechnicalError:
@ -231,8 +233,11 @@ class EbicsXfer(models.TransientModel):
e = exc_info() e = exc_info()
self.note += "\n" self.note += "\n"
self.note += _( self.note += _(
"EBICS Technical Error during download of File Format %s (%s):" "EBICS Technical Error during download of "
) % (df.name, df.order_type) "File Format %(name)s (%(order_type)s):",
name=df.name,
order_type=df.order_type,
)
self.note += "\n" self.note += "\n"
self.note += "{} (code: {})".format(e[1].message, e[1].code) self.note += "{} (code: {})".format(e[1].message, e[1].code)
except EbicsVerificationError: except EbicsVerificationError:
@ -240,23 +245,31 @@ class EbicsXfer(models.TransientModel):
self.note += "\n" self.note += "\n"
self.note += _( self.note += _(
"EBICS Verification Error during download of " "EBICS Verification Error during download of "
"File Format %s (%s):" "File Format %(name)s (%(order_type)s):",
) % (df.name, df.order_type) name=df.name,
order_type=df.order_type,
)
self.note += "\n" self.note += "\n"
self.note += _("The EBICS response could not be verified.") self.note += _("The EBICS response could not be verified.")
except UserError as e: except UserError as e:
self.note += "\n" self.note += "\n"
self.note += _( self.note += _(
"Warning during download of File Format %s (%s):" "Warning during download of "
) % (df.name, df.order_type) "File Format %(name)s (%(order_type)s):",
name=df.name,
order_type=df.order_type,
)
self.note += "\n" self.note += "\n"
self.note += e.name self.note += e.name
except Exception: except Exception:
err_cnt += 1 err_cnt += 1
self.note += "\n" self.note += "\n"
self.note += _( self.note += _(
"Unknown Error during download of File Format %s (%s):" "Unknown Error during download of "
) % (df.name, df.order_type) "File Format %(name)s (%(order_type)s):",
name=df.name,
order_type=df.order_type,
)
tb = "".join(format_exception(*exc_info())) tb = "".join(format_exception(*exc_info()))
self.note += "\n%s" % tb self.note += "\n%s" % tb
else: else: