diff --git a/README.md b/README.md
index 5406a0b2f..8cb915bcf 100644
--- a/README.md
+++ b/README.md
@@ -44,7 +44,7 @@ addon | version | maintainers | summary
[edi_sale_ubl_output_oca](edi_sale_ubl_output_oca/) | 18.0.1.0.1 | | Configuration and special behaviors for EDI on sales.
[edi_state_oca](edi_state_oca/) | 18.0.1.0.3 |
| Allow to assign specific EDI states to related records.
[edi_stock_oca](edi_stock_oca/) | 18.0.1.0.1 | | Define EDI Configuration for Stock
-[edi_storage_oca](edi_storage_oca/) | 18.0.1.0.2 | | Base module to allow exchanging files via storage backend (eg: SFTP).
+[edi_storage_oca](edi_storage_oca/) | 18.0.1.0.4 | | Base module to allow exchanging files via storage backend (eg: SFTP).
[edi_storage_queue_oca](edi_storage_queue_oca/) | 18.0.1.0.0 | | Integrates EDI Storage with Queue
[edi_ubl_oca](edi_ubl_oca/) | 18.0.1.0.1 |
| Define EDI backend type for UBL.
[edi_webservice_oca](edi_webservice_oca/) | 18.0.1.0.2 |
| Defines webservice integration from EDI Exchange records
diff --git a/edi_storage_oca/README.rst b/edi_storage_oca/README.rst
index 52b9f7ece..f880503b3 100644
--- a/edi_storage_oca/README.rst
+++ b/edi_storage_oca/README.rst
@@ -11,7 +11,7 @@ EDI Storage backend support
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !! source digest: sha256:ae52c0238c8bab278e4e2d6a48d86d4222672b893df1f171be046f3b7a3c58ae
+ !! source digest: sha256:ca9c4e0d1ecd9744b5cfa517900a5dace2a206007360ce2c1299dc1da5910bfa
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
diff --git a/edi_storage_oca/__manifest__.py b/edi_storage_oca/__manifest__.py
index 39f47e247..87b4c5f92 100644
--- a/edi_storage_oca/__manifest__.py
+++ b/edi_storage_oca/__manifest__.py
@@ -7,7 +7,7 @@
"summary": """
Base module to allow exchanging files via storage backend (eg: SFTP).
""",
- "version": "18.0.1.0.2",
+ "version": "18.0.1.0.4",
"development_status": "Beta",
"license": "LGPL-3",
"website": "https://github.com/OCA/edi-framework",
diff --git a/edi_storage_oca/i18n/edi_storage_oca.pot b/edi_storage_oca/i18n/edi_storage_oca.pot
index cba90f769..7b3703040 100644
--- a/edi_storage_oca/i18n/edi_storage_oca.pot
+++ b/edi_storage_oca/i18n/edi_storage_oca.pot
@@ -114,6 +114,12 @@ msgstr ""
msgid "Storage Handler for EDI"
msgstr ""
+#. module: edi_storage_oca
+#. odoo-python
+#: code:addons/edi_storage_oca/models/edi_oca_storage_handler.py:0
+msgid "Storage error while reading %(path)s: %(error)s"
+msgstr ""
+
#. module: edi_storage_oca
#: model:ir.model.fields,help:edi_storage_oca.field_edi_backend__storage_id
msgid "Storage for in-out files"
diff --git a/edi_storage_oca/i18n/it.po b/edi_storage_oca/i18n/it.po
index e35011ab4..ce7ead09f 100644
--- a/edi_storage_oca/i18n/it.po
+++ b/edi_storage_oca/i18n/it.po
@@ -28,7 +28,6 @@ msgstr "Tipo scambio EDI"
#. module: edi_storage_oca
#: model:ir.actions.server,name:edi_storage_oca.cron_check_storage_pending_input_ir_actions_server
-#: model:ir.cron,cron_name:edi_storage_oca.cron_check_storage_pending_input
msgid "EDI backend storage check pending input"
msgstr "Controllo ingressi in attesa deposito backend EDI"
@@ -51,8 +50,13 @@ msgstr "Deposito FS"
#. module: edi_storage_oca
#: model:ir.model.fields,help:edi_storage_oca.field_edi_exchange_type__exchange_filename_pattern
msgid ""
-"For output exchange types this should be a formatting string with the following variables available (to be used between brackets, `{}`): `exchange_record`, `record_name`, `type` and `dt`. For instance, a valid string would be {record_name}-{type.code}-{dt}\n"
-"For input exchange types related to storage backends it should be a regex expression to filter the files to be fetched from the pending directory in the related storage. E.g: `.*my-type-[0-9]*.\\.csv`"
+"For output exchange types this should be a formatting string with the "
+"following variables available (to be used between brackets, `{}`): "
+"`exchange_record`, `record_name`, `type` and `dt`. For instance, a valid "
+"string would be {record_name}-{type.code}-{dt}\n"
+"For input exchange types related to storage backends it should be a regex "
+"expression to filter the files to be fetched from the pending directory in "
+"the related storage. E.g: `.*my-type-[0-9]*.\\.csv`"
msgstr ""
"Per i tipi di scambio in uscita questo dovrebbe essere una stringa di "
"formattazione con le seguenti variabili disponibili (da utilizzare tra "
@@ -120,6 +124,17 @@ msgstr "Record creato da un file trovato nel deposito FS"
msgid "Storage"
msgstr "Deposito"
+#. module: edi_storage_oca
+#: model:ir.model,name:edi_storage_oca.model_edi_oca_storage_handler
+msgid "Storage Handler for EDI"
+msgstr ""
+
+#. module: edi_storage_oca
+#. odoo-python
+#: code:addons/edi_storage_oca/models/edi_oca_storage_handler.py:0
+msgid "Storage error while reading %(path)s: %(error)s"
+msgstr ""
+
#. module: edi_storage_oca
#: model:ir.model.fields,help:edi_storage_oca.field_edi_backend__storage_id
msgid "Storage for in-out files"
diff --git a/edi_storage_oca/models/edi_oca_storage_handler.py b/edi_storage_oca/models/edi_oca_storage_handler.py
index ce0f7682f..3e2a3d938 100644
--- a/edi_storage_oca/models/edi_oca_storage_handler.py
+++ b/edi_storage_oca/models/edi_oca_storage_handler.py
@@ -9,6 +9,7 @@
from pathlib import PurePath
from odoo import models
+from odoo.exceptions import UserError
from .. import utils
@@ -34,7 +35,9 @@ def send(self, exchange_record):
utils.add_file(exchange_record.backend_id.storage_id, path.as_posix(), filedata)
def receive(self, exchange_record):
- return self._get_remote_file(exchange_record, "pending", binary=True)
+ return self._get_remote_file(
+ exchange_record, "pending", binary=True, raise_if_missing=True
+ )
def _dir_by_state(self, backend, direction, state):
"""Return remote directory path by direction and state.
@@ -61,11 +64,21 @@ def _get_remote_file_path(self, exchange_record, state, filename=None):
)
return path
- def _get_remote_file(self, exchange_record, state, filename=None, binary=False):
+ def _get_remote_file(
+ self,
+ exchange_record,
+ state,
+ filename=None,
+ binary=False,
+ raise_if_missing=False,
+ ):
"""Get file for current exchange_record in the given destination state.
:param state: string ("pending", "done", "error")
:param filename: custom file name, exchange_record filename used by default
+ :param raise_if_missing: when True, storage errors are re-raised as
+ swallable exceptions so the caller transitions the record to an
+ error state instead of treating "no content" as a successful read.
:return: remote file content as string
"""
path = self._get_remote_file_path(exchange_record, state, filename=filename)
@@ -84,14 +97,25 @@ def _get_remote_file(self, exchange_record, state, filename=None, binary=False):
path,
state,
)
+ if raise_if_missing:
+ raise
return None
- except OSError:
- _logger.info(
- "Ignored OSError when trying to get file %s into path %s for state %s",
+ except OSError as err:
+ _logger.warning(
+ "OSError when trying to get file %s into path %s for state %s: %s",
filename,
path,
state,
+ err,
)
+ if raise_if_missing:
+ raise UserError(
+ self.env._(
+ "Storage error while reading %(path)s: %(error)s",
+ path=path.as_posix(),
+ error=str(err),
+ )
+ ) from err
return None
def check(self, exchange_record):
diff --git a/edi_storage_oca/static/description/index.html b/edi_storage_oca/static/description/index.html
index 87b66f49d..fe56fe211 100644
--- a/edi_storage_oca/static/description/index.html
+++ b/edi_storage_oca/static/description/index.html
@@ -372,7 +372,7 @@
Allow exchange files using storage backends from OCA/storage.
diff --git a/edi_storage_oca/utils.py b/edi_storage_oca/utils.py index 0b93e5da0..0b791c09b 100644 --- a/edi_storage_oca/utils.py +++ b/edi_storage_oca/utils.py @@ -48,6 +48,8 @@ def list_files(storage, relative_path="", pattern=False): if pattern: relative_path = fs.sep.join([relative_path, pattern]) return fs.glob(relative_path) + if fs.protocol == "ftp" and fs.ftp: + return fs.ftp.nlst(relative_path) return fs.ls(relative_path, detail=False)