Merge branch '18.0-mig-account_ebics_batch' into '18.0'

[MIG] account_ebics_batch: Migration to 18.0

See merge request Noviat/Noviat_Generic/accounting-ebics!73
This commit is contained in:
Luc De Meyer 2024-12-25 16:16:46 +00:00
commit 54a6ea14dc
14 changed files with 1058 additions and 0 deletions

View File

@ -0,0 +1,50 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: https://www.gnu.org/licenses/agpl
:alt: License: AGPL-3
============================================
Module to enable batch import of EBICS files
============================================
This module adds a cron job for the automated import of EBICS files.
|
A Log is created during the import in order to document import errors.
If errors have been detected, the Batch Import Log state is set to 'error'.
When all EBICS Files have been imported correctly, the Batch Import Log state is set to 'done'.
|
The user can reprocess the imported EBICS files in status 'draft' via the Log object 'REPROCESS' button until all errors have been cleared.
As an alternative, the user can force the Batch Import Log state to 'done'
(e.g. when the errors have been circumvented via manual encoding or the reprocessing of a single EBICS file).
|
Configuration
=============
Adapt the 'EBICS Batch Import' ir.cron job created during the module installation.
The cron job calls the following python method:
|
.. code-block:: python
_batch_import()
The EBICS download will be performed on all confirmed EBICS connections.
You can limit the automated operation to a subset of your EBICS connections via the ebics_config_ids parameter, e.g.
|
.. code-block:: python
_batch_import(ebics_config_ids=[1,3])

View File

@ -0,0 +1 @@
from . import models

View File

@ -0,0 +1,21 @@
# Copyright 2009-2024 Noviat.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "EBICS Files batch import",
"version": "18.0.1.0.0",
"license": "AGPL-3",
"author": "Noviat",
"website": "https://www.noviat.com",
"category": "Accounting & Finance",
"summary": "EBICS Files automated import and processing",
"depends": ["account_ebics"],
"data": [
"security/ir.model.access.csv",
"data/ir_cron_data.xml",
"views/ebics_batch_log_views.xml",
"views/menu.xml",
],
"installable": True,
"images": ["static/description/cover.png"],
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo noupdate="1">
<record id="ir_cron_ebics_batch_import" model="ir.cron">
<field name="name">EBICS Batch Import</field>
<field name="model_id" ref="model_ebics_batch_log" />
<field name="state">code</field>
<field name="code">model._batch_import()</field>
<field name="user_id" ref="base.user_root" />
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="active" eval="False" />
</record>
</odoo>

View File

@ -0,0 +1,222 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_ebics_batch
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 17.0+e\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__file_ids
msgid "Batch Import EBICS Files"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log_item__note
#: model_terms:ir.ui.view,arch_db:account_ebics_batch.ebics_batch_log_view_form
msgid "Batch Import Log"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__log_ids
msgid "Batch Import Log Items"
msgstr ""
#. module: account_ebics_batch
#: model_terms:ir.ui.view,arch_db:account_ebics_batch.ebics_batch_log_view_form
msgid "Batch Import Logs"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log_item__log_id
msgid "Batch Object"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__create_uid
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log_item__create_uid
msgid "Created by"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__create_date
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log_item__create_date
msgid "Created on"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__date_from
msgid "Date From"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__date_to
msgid "Date To"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__display_name
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log_item__display_name
msgid "Display Name"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields.selection,name:account_ebics_batch.selection__ebics_batch_log__state__done
#: model:ir.model.fields.selection,name:account_ebics_batch.selection__ebics_batch_log_item__state__done
msgid "Done"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields.selection,name:account_ebics_batch.selection__ebics_batch_log__state__draft
#: model:ir.model.fields.selection,name:account_ebics_batch.selection__ebics_batch_log_item__state__draft
msgid "Draft"
msgstr ""
#. module: account_ebics_batch
#: model:ir.actions.server,name:account_ebics_batch.ir_cron_ebics_batch_import_ir_actions_server
msgid "EBICS Batch Import"
msgstr ""
#. module: account_ebics_batch
#: model_terms:ir.ui.view,arch_db:account_ebics_batch.ebics_batch_log_view_form
msgid "EBICS Batch Import Log"
msgstr ""
#. module: account_ebics_batch
#: model:ir.actions.act_window,name:account_ebics_batch.ebics_batch_log_action
#: model:ir.ui.menu,name:account_ebics_batch.ebics_batch_log_menu
msgid "EBICS Batch Import Logs"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__ebics_config_ids
msgid "EBICS Configurations"
msgstr ""
#. module: account_ebics_batch
#: model_terms:ir.ui.view,arch_db:account_ebics_batch.ebics_batch_log_view_form
msgid "EBICS Files"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__file_count
msgid "EBICS Files Count"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields.selection,name:account_ebics_batch.selection__ebics_batch_log__state__error
#: model:ir.model.fields.selection,name:account_ebics_batch.selection__ebics_batch_log_item__state__error
msgid "Error"
msgstr ""
#. module: account_ebics_batch
#. odoo-python
#: code:addons/account_ebics_batch/models/ebics_batch_log.py:0
#, python-format
msgid "Error while processing EBICS connection '%s' :\n"
msgstr ""
#. module: account_ebics_batch
#: model_terms:ir.ui.view,arch_db:account_ebics_batch.ebics_batch_log_view_search
msgid "Group By"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__has_draft_files
msgid "Has Draft Files"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__id
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log_item__id
msgid "ID"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__write_uid
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log_item__write_uid
msgid "Last Updated by"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__write_date
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log_item__write_date
msgid "Last Updated on"
msgstr ""
#. module: account_ebics_batch
#: model_terms:ir.ui.view,arch_db:account_ebics_batch.ebics_batch_log_view_form
msgid "Mark Done"
msgstr ""
#. module: account_ebics_batch
#. odoo-python
#: code:addons/account_ebics_batch/models/ebics_batch_log.py:0
#, python-format
msgid ""
"No EBICS UserID with stored passphrase found.\n"
"You should configure such a UserID for automated downloads."
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log_item__error_count
msgid "Number of Errors"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model,name:account_ebics_batch.model_ebics_batch_log_item
msgid "Object to store EBICS Batch Import Log Items"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model,name:account_ebics_batch.model_ebics_batch_log
msgid "Object to store EBICS Batch Import Logs"
msgstr ""
#. module: account_ebics_batch
#. odoo-python
#: code:addons/account_ebics_batch/models/ebics_batch_log.py:0
#, python-format
msgid "Only log objects in state 'draft' can be deleted !"
msgstr ""
#. module: account_ebics_batch
#. odoo-python
#: code:addons/account_ebics_batch/models/ebics_batch_log.py:0
#, python-format
msgid "Please set state to 'Confirm' and Reprocess this EBICS Import Log."
msgstr ""
#. module: account_ebics_batch
#: model_terms:ir.ui.view,arch_db:account_ebics_batch.ebics_batch_log_view_form
msgid "Reprocess"
msgstr ""
#. module: account_ebics_batch
#: model_terms:ir.ui.view,arch_db:account_ebics_batch.ebics_batch_log_view_form
msgid "Reprocess 'draft' EBICS Files"
msgstr ""
#. module: account_ebics_batch
#: model_terms:ir.ui.view,arch_db:account_ebics_batch.ebics_batch_log_view_search
msgid "Search EBICS Batch Import Log Files"
msgstr ""
#. module: account_ebics_batch
#: model_terms:ir.ui.view,arch_db:account_ebics_batch.ebics_batch_log_view_form
msgid "Set to Draft"
msgstr ""
#. module: account_ebics_batch
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log__state
#: model:ir.model.fields,field_description:account_ebics_batch.field_ebics_batch_log_item__state
#: model_terms:ir.ui.view,arch_db:account_ebics_batch.ebics_batch_log_view_search
msgid "State"
msgstr ""

View File

@ -0,0 +1 @@
from . import ebics_batch_log

View File

@ -0,0 +1,207 @@
# Copyright 2009-2024 Noviat.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from sys import exc_info
from traceback import format_exception
from odoo import api, fields, models
from odoo.exceptions import UserError
class EbicsBatchLog(models.Model):
_name = "ebics.batch.log"
_description = "Object to store EBICS Batch Import Logs"
_order = "create_date desc"
date_from = fields.Date()
date_to = fields.Date()
ebics_config_ids = fields.Many2many(
comodel_name="ebics.config", string="EBICS Configurations"
)
log_ids = fields.One2many(
comodel_name="ebics.batch.log.item",
inverse_name="log_id",
string="Batch Import Log Items",
readonly=True,
)
file_ids = fields.Many2many(
comodel_name="ebics.file",
string="Batch Import EBICS Files",
readonly=True,
)
file_count = fields.Integer(
string="EBICS Files Count", compute="_compute_ebics_files_fields", readonly=True
)
has_draft_files = fields.Boolean(compute="_compute_ebics_files_fields")
state = fields.Selection(
selection=[("draft", "Draft"), ("error", "Error"), ("done", "Done")],
required=True,
readonly=True,
default="draft",
)
@api.depends("file_ids")
def _compute_ebics_files_fields(self):
for rec in self:
rec.has_draft_files = "draft" in rec.file_ids.mapped("state")
rec.file_count = len(rec.file_ids)
def unlink(self):
for log in self:
if log.state != "draft":
raise UserError(
self.env._("Only log objects in state 'draft' can be deleted !")
)
return super().unlink()
def button_draft(self):
self.state = "draft"
def button_done(self):
self.state = "done"
def reprocess(self):
import_dict = {"errors": []}
self._ebics_process(import_dict)
self._finalise_processing(import_dict)
def view_ebics_files(self):
action = self.env["ir.actions.actions"]._for_xml_id(
"account_ebics.ebics_file_action_download"
)
action["domain"] = [("id", "in", self.file_ids.ids)]
return action
def _batch_import(self, ebics_config_ids=None, date_from=None, date_to=None):
"""
Call this method from a cron job to automate the EBICS import.
"""
log_model = self.env["ebics.batch.log"]
import_dict = {"errors": []}
configs = self.env["ebics.config"].browse(ebics_config_ids) or self.env[
"ebics.config"
].search(
[
("company_ids", "in", self.env.user.company_ids.ids),
("state", "=", "confirm"),
]
)
log = log_model.create(
{
"ebics_config_ids": [(6, 0, configs.ids)],
"date_from": date_from,
"date_to": date_to,
}
)
ebics_file_ids = []
for config in configs:
err_msg = (
self.env._("Error while processing EBICS connection '%s' :\n")
% config.name
)
if config.state == "draft":
import_dict["errors"].append(
err_msg
+ self.env._(
"Please set state to 'Confirm' and "
"Reprocess this EBICS Import Log."
)
)
continue
if not any(config.mapped("ebics_userid_ids.ebics_passphrase_store")):
import_dict["errors"].append(
err_msg
+ self.env._(
"No EBICS UserID with stored passphrase found.\n"
"You should configure such a UserID for automated downloads."
)
)
continue
try:
with self.env.cr.savepoint():
ebics_file_ids += self._ebics_import(
config, date_from, date_to, import_dict
)
except UserError as e:
import_dict["errors"].append(err_msg + " ".join(e.args))
except Exception:
tb = "".join(format_exception(*exc_info()))
import_dict["errors"].append(err_msg + tb)
log.file_ids = [(6, 0, ebics_file_ids)]
try:
log._ebics_process(import_dict)
except UserError as e:
import_dict["errors"].append(err_msg + " ".join(e.args))
except Exception:
tb = "".join(format_exception(*exc_info()))
import_dict["errors"].append(err_msg + tb)
log._finalise_processing(import_dict)
def _finalise_processing(self, import_dict):
log_item_model = self.env["ebics.batch.log.item"]
state = self.has_draft_files and "draft" or "done"
note = ""
error_count = 0
if import_dict["errors"]:
state = "error"
note = "\n\n".join(import_dict["errors"])
error_count = len(import_dict["errors"])
log_item_model.create(
{
"log_id": self.id,
"state": state,
"note": note,
"error_count": error_count,
}
)
self.state = state
def _ebics_import(self, config, date_from, date_to, import_dict):
ebics_userids = config.ebics_userid_ids.filtered(
lambda r: r.ebics_passphrase_store
)
t_userids = ebics_userids.filtered(lambda r: r.signature_class == "T")
ebics_userid = t_userids and t_userids[0] or ebics_userids[0]
xfer_wiz = (
self.env["ebics.xfer"]
.with_context(ebics_download=True)
.create(
{
"ebics_config_id": config.id,
"date_from": date_from,
"date_to": date_to,
}
)
)
xfer_wiz._onchange_ebics_config_id()
xfer_wiz.ebics_userid_id = ebics_userid
res = xfer_wiz.ebics_download()
file_ids = res["context"].get("ebics_file_ids", [])
if res["context"]["err_cnt"]:
import_dict["errors"].append(xfer_wiz.note)
return file_ids
def _ebics_process(self, import_dict):
to_process = self.file_ids.filtered(lambda r: r.state == "draft")
for ebics_file in to_process:
ebics_file.process()
class EbicsBatchLogItem(models.Model):
_name = "ebics.batch.log.item"
_description = "Object to store EBICS Batch Import Log Items"
_order = "create_date desc"
log_id = fields.Many2one(
comodel_name="ebics.batch.log",
string="Batch Object",
ondelete="cascade",
readonly=True,
)
state = fields.Selection(
selection=[("draft", "Draft"), ("error", "Error"), ("done", "Done")],
required=True,
readonly=True,
)
note = fields.Text(string="Batch Import Log", readonly=True)
error_count = fields.Integer(string="Number of Errors", required=True, default=0)

View File

@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_ebics_batch_log,ebics.batch.log,model_ebics_batch_log,account.group_account_invoice,1,1,1,1
access_ebics_batch_log_item,ebics.batch.log.item,model_ebics_batch_log_item,account.group_account_invoice,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_ebics_batch_log ebics.batch.log model_ebics_batch_log account.group_account_invoice 1 1 1 1
3 access_ebics_batch_log_item ebics.batch.log.item model_ebics_batch_log_item account.group_account_invoice 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -0,0 +1,406 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.20.1: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document">
<a class="reference external image-reference" href="https://www.gnu.org/licenses/agpl"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a>
<div class="section" id="module-to-enable-batch-import-of-ebics-files">
<h1>Module to enable batch import of EBICS files</h1>
<p>This module adds a cron job for the automated import of EBICS files.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<p>A Log is created during the import in order to document import errors.
If errors have been detected, the Batch Import Log state is set to 'error'.</p>
<p>When all EBICS Files have been imported correctly, the Batch Import Log state is set to 'done'.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<p>The user can reprocess the imported EBICS files in status 'draft' via the Log object 'REPROCESS' button until all errors have been cleared.</p>
<p>As an alternative, the user can force the Batch Import Log state to 'done'
(e.g. when the errors have been circumvented via manual encoding or the reprocessing of a single EBICS file).</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<div class="section" id="configuration">
<h2>Configuration</h2>
<p>Adapt the 'EBICS Batch Import' ir.cron job created during the module installation.</p>
<p>The cron job calls the following python method:</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<pre class="code python literal-block">
<span class="name">_batch_import</span><span class="punctuation">()</span>
</pre>
<p>The EBICS download will be performed on all confirmed EBICS connections.</p>
<p>You can limit the automated operation to a subset of your EBICS connections via the ebics_config_ids parameter, e.g.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<pre class="code python literal-block">
<span class="name">_batch_import</span><span class="punctuation">(</span><span class="name">ebics_config_ids</span><span class="operator">=</span><span class="punctuation">[</span><span class="literal number integer">1</span><span class="punctuation">,</span><span class="literal number integer">3</span><span class="punctuation">])</span>
</pre>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,117 @@
<?xml version="1.0" ?>
<odoo>
<record id="ebics_batch_log_view_search" model="ir.ui.view">
<field name="name">ebics.batch.log.search</field>
<field name="model">ebics.batch.log</field>
<field name="arch" type="xml">
<search string="Search EBICS Batch Import Log Files">
<group col="10" colspan="4">
<field name="create_date" />
<field name="state" />
</group>
<newline />
<group expand="0" string="Group By">
<filter name="group_by_state" string="State" context="{'group_by':'state'}" />
</group>
</search>
</field>
</record>
<record id="ebics_batch_log_view_list" model="ir.ui.view">
<field name="name">ebics.batch.log.list</field>
<field name="model">ebics.batch.log</field>
<field name="arch" type="xml">
<list create="false">
<field name="create_date" />
<field name="file_count" />
<field name="state" />
</list>
</field>
</record>
<record id="ebics_batch_log_view_form" model="ir.ui.view">
<field name="name">ebics.batch.log.form</field>
<field name="model">ebics.batch.log</field>
<field name="arch" type="xml">
<form string="EBICS Batch Import Log" create="false">
<header>
<button
name="button_draft"
invisible="state not in ('done', 'error')"
string="Set to Draft"
type="object"
/>
<button
name="reprocess"
string="Reprocess"
help="Reprocess 'draft' EBICS Files"
type="object"
class="oe_highlight"
invisible="state, '=', 'done' or not has_draft_files"
/>
<button
name="button_done"
invisible="state not in ('done', 'error')"
string="Mark Done"
type="object"
/>
<field
name="state"
widget="statusbar"
statusbar_visible="draft,done"
statusbar_colors="{'error':'red'}"
/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button
name="view_ebics_files"
type="object"
class="oe_stat_button"
icon="fa-pencil-square-o"
invisible="file_count == 0"
>
<field name="file_count" widget="statinfo" string="EBICS Files" />
</button>
</div>
<group colspan="4" col="4">
<field name="create_date" />
<field name="ebics_config_ids" widget="many2many_tags" />
</group>
<notebook colspan="4">
<page string="Batch Import Logs">
<field name="log_ids" nolabel="1">
<list>
<field name="create_date" />
<field name="state" />
<field name="error_count" />
</list>
<form string="Batch Import Log">
<group colspan="4" col="6">
<field name="create_date" />
<field name="error_count" />
</group>
<group invisible="not note">
<separator colspan="4" />
<field name="note" nolabel="1" colspan="4" height="360" />
</group>
</form>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="ebics_batch_log_action" model="ir.actions.act_window">
<field name="name">EBICS Batch Import Logs</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ebics.batch.log</field>
<field name="view_mode">list,form</field>
<field name="view_id" ref="ebics_batch_log_view_list" />
<field name="search_view_id" ref="ebics_batch_log_view_search" />
</record>
</odoo>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" ?>
<odoo>
<menuitem
id="ebics_batch_log_menu"
name="EBICS Batch Import Logs"
parent="account_ebics.ebics_processing_menu"
action="ebics_batch_log_action"
sequence="100"
/>
</odoo>