diff --git a/__init__.py b/__init__.py
index 9f60d0c..e11b51d 100644
--- a/__init__.py
+++ b/__init__.py
@@ -18,8 +18,9 @@ def register():
edocument.EdocumentTemplate,
edocument.EdocumentExportParams,
edocument.EdocumentExportFile,
+ edocument.EDocumentImportResult,
party.Party,
- party.PartyIdentifier,
+ party.PartyConfiguration,
stock.Configuration,
stock.ConfigurationSequence,
product.Template,
diff --git a/edocument.py b/edocument.py
index b2cafdf..2910c28 100644
--- a/edocument.py
+++ b/edocument.py
@@ -5,6 +5,7 @@ from trytond.model import ModelSQL, ModelView, fields, Exclude
from sql.conditionals import Coalesce
from sql.operators import Equal as SqlEqual
from trytond.pool import Pool
+from trytond.pyson import PYSONEncoder
from trytond.transaction import Transaction
from trytond.i18n import gettext
from trytond.exceptions import UserError
@@ -86,11 +87,11 @@ class EdocumentMessage(ModelView, ModelSQL):
default_company = Transaction().context.get('company', None)
vlist = [x.copy() for x in vlist]
for values in vlist:
- if config.edocument_sequence:
+ if not values.get('code') and config.edocument_sequence:
values['code'] = config.get_multivalue(
'edocument_sequence',
company=values.get('company', default_company)).get()
- return super(EdocumentMessage, cls).create(vlist)
+ return super().create(vlist)
class EdocumentMixin(object):
@@ -134,25 +135,20 @@ class EdocumentMixin(object):
return message.rec_name
-class EdocumentImportMixin(EdocumentMixin):
+class EdocumentImportMixin(object):
+ _edi_message_type = ''
@classmethod
def _get_template_name(cls):
pass
@classmethod
- def create_from_edi(cls, edi_info, template):
+ def create_object_from_edi(cls, edi_content, template):
pass
@classmethod
- def postprocess(cls, objects):
- pass
-
- @classmethod
- def _get_path(cls, message_type):
- pool = Pool()
- Configuration = pool.get('edocument.configuration.path')
- return Configuration._get_path(message_type)
+ def _postprocess(cls, objects):
+ return objects
@classmethod
def _template(cls):
@@ -165,56 +161,58 @@ class EdocumentImportMixin(EdocumentMixin):
return EdocumentFileManager()
@classmethod
- def _create_objects_from_edi(
- cls, source_uri, error_uri, template=None, target_model=None):
+ def _create_objects_from_edi(cls, template=None):
"""
Get objects from edi files
"""
pool = Pool()
- if not target_model:
- target_model = cls.__name__
- Object = pool.get(target_model)
+ Configuration = pool.get('edocument.configuration.path')
+ ObjectModel = pool.get(cls.__name__)
Message = pool.get('edocument.message')
+
+ paths = Configuration._get_path(cls._edi_message_type)
+ source_uri, error_uri = paths.path, paths.error_path
+
if not template:
template = cls._template()
- objects = []
+ records = []
+ error_files = []
messages = []
- imported = []
+ to_delete = []
manager = cls._get_document_manager()
for name, info in manager._get_messages(source_uri, error_uri).items():
- created, errors = cls.create_from_edi(info, template)
- if created:
- message = Message(code=info)
- messages.append(message)
- imported.append(name)
- for value in created:
- if 'id' in value:
- new_object = Object(value['id'])
- else:
- new_object = Object()
- for k, v in value.items():
- setattr(new_object, k, v)
- new_object.message = message
- message.origin = new_object
- objects.append(new_object)
- if imported:
- manager._handle_imported(imported)
- if errors:
- manager._handle_errors(name, errors, error_uri)
- Message.save(messages)
- Object.save(objects)
- return objects
+ try:
+ record, errors = cls.create_object_from_edi(info, template)
+ except RuntimeError:
+ continue
+ else:
+ if errors:
+ error_files.append(manager._handle_errors(
+ name, errors, error_uri))
+ else:
+ if record:
+ message = Message(
+ code=os.path.basename(os.path.splitext(name)[0]),
+ message=info,
+ origin=record)
+ messages.append(message)
+ records.append(record)
+ to_delete.append(name)
+
+ ObjectModel.save(records)
+ if messages:
+ Message.save(messages)
+
+ records = cls._postprocess(records)
+
+ if to_delete:
+ manager._handle_imported(to_delete)
+
+ return records, error_files
@classmethod
- def get_objects_from_edi(cls, message_type, target_model=None):
- '''Get objects from edi'''
- conf = cls._get_path(message_type)
- results = cls._create_objects_from_edi(
- conf.path,
- conf.error_path,
- target_model=target_model)
- cls.postprocess(results)
- return results
+ def get_objects_from_edi(cls):
+ return cls._create_objects_from_edi()
class EdocumentFileManager(object):
@@ -222,7 +220,7 @@ class EdocumentFileManager(object):
@classmethod
def _read_file(cls, filename):
- with open(filename, encoding='utf-8') as file:
+ with open(filename, 'r', encoding='cp1252') as file:
return file.read()
@classmethod
@@ -240,6 +238,7 @@ class EdocumentFileManager(object):
os.path.splitext(os.path.basename(fname))[0]))
with open(error_fname, 'w') as fp:
fp.write('\n'.join(errors))
+ return error_fname
@classmethod
def _handle_imported(cls, imported):
@@ -247,6 +246,80 @@ class EdocumentFileManager(object):
os.remove(file)
+class EDocumentImportResult(ModelView):
+ """Import EDIFACT Result"""
+ __name__ = 'edifact_import.result'
+
+ error_file = fields.Binary('Errors', filename='error_filename',
+ readonly=True)
+ error_filename = fields.Char('Filename')
+ message = fields.Text('Message', readonly=True)
+
+
+def import_edocument_mixin(model_name, result_field):
+
+ class ImportEDocumentMixin(object):
+
+ start = StateTransition()
+ errors = StateView('edifact_import.result',
+ 'edocument_edifact.import_result_view_form', [
+ Button('OK', 'pre_open', 'tryton-ok', default=True),
+ ])
+ pre_open = StateTransition()
+
+ @property
+ def result_records(self):
+ return getattr(self.errors, result_field, [])
+
+ @result_records.setter
+ def result_records(self, value):
+ setattr(self.errors, result_field, [s.id for s in (value or [])])
+
+ def transition_start(self):
+ pool = Pool()
+ ActiveModel = pool.get(model_name)
+ Configuration = pool.get('edocument.configuration.path')
+
+ paths = Configuration._get_path(ActiveModel._edi_message_type)
+
+ results, error_files = ActiveModel.get_objects_from_edi()
+ self.result_records = results
+ if error_files:
+ error_file = os.path.join(paths.error_path, 'error_file')
+ with open(error_file, 'w') as ef:
+ for file in error_files:
+ ef.write('%s:\n' % file.split('/')[-1].split('error_')[-1])
+ with open(file, 'r') as f:
+ for line in f:
+ ef.write('\t- %s' % line)
+ ef.write('\n')
+ with open(error_file, mode='r') as f:
+ self.errors.error_file = f.read()
+ return 'errors'
+ return 'pre_open'
+
+ def default_errors(self, fields):
+ return {
+ 'error_file': self.errors.error_file,
+ 'error_filename': 'EDI_error.txt',
+ 'message': self.errors.error_file,
+ result_field: [r.id for r in self.result_records]
+ }
+
+ def transition_pre_open(self):
+ return 'open_'
+
+ def do_open_(self, action):
+ if not self.result_records:
+ return
+ action['pyson_domain'] = PYSONEncoder().encode([
+ ('id', 'in', [s.id for s in self.result_records])
+ ])
+ return action, {}
+
+ return ImportEDocumentMixin
+
+
class EdocumentExportMixin(object):
_message_type = ''
diff --git a/edocument.xml b/edocument.xml
index 68e7da1..5a310ba 100644
--- a/edocument.xml
+++ b/edocument.xml
@@ -192,5 +192,12 @@