parent
e1d0c4cdfb
commit
9796367b1e
|
@ -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,
|
||||
|
|
175
edocument.py
175
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 = ''
|
||||
|
||||
|
|
|
@ -192,5 +192,12 @@
|
|||
<field name="type">form</field>
|
||||
<field name="name">export_params_form</field>
|
||||
</record>
|
||||
|
||||
<!-- Import views -->
|
||||
<record model="ir.ui.view" id="import_result_view_form">
|
||||
<field name="model">edifact_import.result</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">import_result_form</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
14
locale/es.po
14
locale/es.po
|
@ -400,4 +400,16 @@ msgstr "Mensajes de Documentación Electrónica"
|
|||
|
||||
msgctxt "model:ir.ui.menu,name:menu_edocument_message"
|
||||
msgid "Messages"
|
||||
msgstr "Mensajes"
|
||||
msgstr "Mensajes"
|
||||
|
||||
msgctxt "model:edifact_import.result,name:"
|
||||
msgid "Import EDIFACT Result"
|
||||
msgstr "Resultado importar EDIFACT"
|
||||
|
||||
msgctxt "field:edifact_import.result,error_file:"
|
||||
msgid "Errors"
|
||||
msgstr "Errores"
|
||||
|
||||
msgctxt "view:edifact_import.result:"
|
||||
msgid "The import of EDI files has encountered the following errors:"
|
||||
msgstr "La importación de ficheros EDI ha encontrado los siguientes errores:"
|
11
party.py
11
party.py
|
@ -29,15 +29,16 @@ class Party(metaclass=PoolMeta):
|
|||
], 'Assigned Code')
|
||||
|
||||
|
||||
class PartyIdentifier(metaclass=PoolMeta):
|
||||
__name__ = 'party.identifier'
|
||||
class PartyConfiguration(metaclass=PoolMeta):
|
||||
__name__ = 'party.configuration'
|
||||
|
||||
@classmethod
|
||||
def get_types(cls):
|
||||
return super().get_types() + [
|
||||
def __setup__(cls):
|
||||
super().__setup__()
|
||||
cls.identifier_types.selection.extend([
|
||||
('EDI_sender', 'EDI Sender'),
|
||||
('EDI_receiver', 'EDI Receiver'),
|
||||
('EDI_supplier', 'EDI Supplier'),
|
||||
('EDI_payer', 'EDI Payer'),
|
||||
('EDI_buyer', 'EDI Buyer'),
|
||||
('EDI_invoice', 'EDI Invoice')]
|
||||
('EDI_invoice', 'EDI Invoice')])
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- The COPYRIGHT file at the top level of this repository contains the full
|
||||
copyright notices and license terms. -->
|
||||
<form col="2">
|
||||
<image name="tryton-warning" xexpand="0" xfill="0"/>
|
||||
<label string="The import of EDI files has encountered the following errors:"
|
||||
id="process" yalign="0.5" xalign="0.0" xexpand="1"/>
|
||||
<newline/>
|
||||
<label name="error_file"/>
|
||||
<field name="error_file" filename="error_filename"/>
|
||||
<field name="message" colspan="2"/>
|
||||
<field name="error_filename" invisible="1" colspan="2"/>
|
||||
</form>
|
Loading…
Reference in New Issue