mirror of
				https://github.com/brain-tec/account_ebics.git
				synced 2025-10-31 03:27:02 +00:00 
			
		
		
		
	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:
		
							
								
								
									
										50
									
								
								account_ebics_batch/README.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								account_ebics_batch/README.rst
									
									
									
									
									
										Normal 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]) | ||||
|  | ||||
							
								
								
									
										1
									
								
								account_ebics_batch/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								account_ebics_batch/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| from . import models | ||||
							
								
								
									
										21
									
								
								account_ebics_batch/__manifest__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								account_ebics_batch/__manifest__.py
									
									
									
									
									
										Normal 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"], | ||||
| } | ||||
							
								
								
									
										15
									
								
								account_ebics_batch/data/ir_cron_data.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								account_ebics_batch/data/ir_cron_data.xml
									
									
									
									
									
										Normal 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> | ||||
							
								
								
									
										222
									
								
								account_ebics_batch/i18n/account_ebics_batch.pot
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								account_ebics_batch/i18n/account_ebics_batch.pot
									
									
									
									
									
										Normal 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 "" | ||||
							
								
								
									
										1
									
								
								account_ebics_batch/models/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								account_ebics_batch/models/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| from . import ebics_batch_log | ||||
							
								
								
									
										207
									
								
								account_ebics_batch/models/ebics_batch_log.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								account_ebics_batch/models/ebics_batch_log.py
									
									
									
									
									
										Normal 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) | ||||
							
								
								
									
										3
									
								
								account_ebics_batch/pyproject.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								account_ebics_batch/pyproject.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| [build-system] | ||||
| requires = ["whool"] | ||||
| build-backend = "whool.buildapi" | ||||
							
								
								
									
										3
									
								
								account_ebics_batch/security/ir.model.access.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								account_ebics_batch/security/ir.model.access.csv
									
									
									
									
									
										Normal 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 | ||||
| 
 | 
							
								
								
									
										
											BIN
										
									
								
								account_ebics_batch/static/description/cover.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								account_ebics_batch/static/description/cover.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 310 KiB | 
							
								
								
									
										
											BIN
										
									
								
								account_ebics_batch/static/description/icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								account_ebics_batch/static/description/icon.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 17 KiB | 
							
								
								
									
										406
									
								
								account_ebics_batch/static/description/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										406
									
								
								account_ebics_batch/static/description/index.html
									
									
									
									
									
										Normal 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> | ||||
							
								
								
									
										117
									
								
								account_ebics_batch/views/ebics_batch_log_views.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								account_ebics_batch/views/ebics_batch_log_views.xml
									
									
									
									
									
										Normal 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> | ||||
							
								
								
									
										12
									
								
								account_ebics_batch/views/menu.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								account_ebics_batch/views/menu.xml
									
									
									
									
									
										Normal 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> | ||||
		Reference in New Issue
	
	Block a user