Deleted references. Added export mixin
This commit is contained in:
parent
99de3536fa
commit
ad49a33983
13
__init__.py
13
__init__.py
|
@ -19,9 +19,16 @@ def register():
|
||||||
party.PartyIdentifier,
|
party.PartyIdentifier,
|
||||||
stock.Configuration,
|
stock.Configuration,
|
||||||
stock.ConfigurationEDIOutputPath,
|
stock.ConfigurationEDIOutputPath,
|
||||||
stock.UnitLoad,
|
|
||||||
incoterm.Rule,
|
|
||||||
product.Template,
|
product.Template,
|
||||||
product.Product,
|
product.Product,
|
||||||
product.Reference,
|
|
||||||
module='edocument_edifact', type_='model')
|
module='edocument_edifact', type_='model')
|
||||||
|
|
||||||
|
Pool.register(
|
||||||
|
incoterm.Rule,
|
||||||
|
module='edocument_edifact', type_='model',
|
||||||
|
depends=['incoterm'])
|
||||||
|
|
||||||
|
Pool.register(
|
||||||
|
product.Reference,
|
||||||
|
module='edocument_edifact', type_='model',
|
||||||
|
depends=['product_cross_reference'])
|
||||||
|
|
93
edocument.py
93
edocument.py
|
@ -1,10 +1,12 @@
|
||||||
# The COPYRIGHT file at the top level of
|
# The COPYRIGHT file at the top level of
|
||||||
# this repository contains the full copyright notices and license terms.
|
# this repository contains the full copyright notices and license terms.
|
||||||
|
from datetime import datetime
|
||||||
from trytond.model import ModelSQL, ModelView, fields, Exclude
|
from trytond.model import ModelSQL, ModelView, fields, Exclude
|
||||||
from sql.conditionals import Coalesce
|
from sql.conditionals import Coalesce
|
||||||
from sql.operators import Equal as SqlEqual
|
from sql.operators import Equal as SqlEqual
|
||||||
from trytond.pool import Pool
|
from trytond.pool import Pool
|
||||||
from trytond.transaction import Transaction
|
from trytond.transaction import Transaction
|
||||||
|
from genshi.template import TextTemplate
|
||||||
from io import open
|
from io import open
|
||||||
import oyaml as yaml
|
import oyaml as yaml
|
||||||
import os
|
import os
|
||||||
|
@ -228,3 +230,94 @@ class EdocumentFileManager(object):
|
||||||
def _handle_imported(cls, imported):
|
def _handle_imported(cls, imported):
|
||||||
for file in imported:
|
for file in imported:
|
||||||
os.remove(file)
|
os.remove(file)
|
||||||
|
|
||||||
|
|
||||||
|
class EdocumentExportMixin(object):
|
||||||
|
|
||||||
|
def _write_file(self, file_path, file, encoding='utf-8'):
|
||||||
|
edi_file = open(file_path, 'w+', encoding=encoding)
|
||||||
|
edi_file.write(file)
|
||||||
|
edi_file.close()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def __setup__(cls):
|
||||||
|
super(cls).__setup__()
|
||||||
|
cls._error_messages.update({
|
||||||
|
'company_unique': ('Cannot send invoices from more than '
|
||||||
|
'1 company.'),
|
||||||
|
'EDI_sender': 'Company %s lacks EDI sender identifier.',
|
||||||
|
'EDI_sequence':
|
||||||
|
'EDI Sequence must be defined in Edocument Configuration.',
|
||||||
|
'EDI_receiver': 'Party %s lacks EDI receiver identifier.',
|
||||||
|
'EDI_export_path':
|
||||||
|
'EDI export path is not defined in Edocument Configuration'})
|
||||||
|
|
||||||
|
def _edi_template(self, message_type, party):
|
||||||
|
pool = Pool()
|
||||||
|
EdocumentTemplate = pool.get('edocument.template')
|
||||||
|
templates = EdocumentTemplate.search([
|
||||||
|
('message_type', '=', message_type),
|
||||||
|
('party', '=', party)])
|
||||||
|
if templates:
|
||||||
|
return templates[0].template, templates[0].encoding
|
||||||
|
else:
|
||||||
|
template_path = os.path.join(os.path.dirname(__file__),
|
||||||
|
'template', message_type.lower() + '.txt')
|
||||||
|
with open(template_path) as file:
|
||||||
|
template = file.read()
|
||||||
|
return template, 'utf-8'
|
||||||
|
|
||||||
|
def generate_message(self, message_type, export_again=False):
|
||||||
|
pool = Pool()
|
||||||
|
_model_name = Transaction().context['active_model']
|
||||||
|
ActiveModel = pool.get(_model_name)
|
||||||
|
Message = pool.get('edocument.message')
|
||||||
|
domain = [('id', 'in', Transaction().context['active_ids'])]
|
||||||
|
if not export_again:
|
||||||
|
domain.append(('edocument_processed', '=', False))
|
||||||
|
records = ActiveModel.search(domain)
|
||||||
|
if not records:
|
||||||
|
return None, None
|
||||||
|
companies = set(x.company for x in records)
|
||||||
|
if len(companies) > 1:
|
||||||
|
self.raise_user_error('company_unique')
|
||||||
|
company, = companies
|
||||||
|
edifact_sender = [x for x in company.party.identifiers
|
||||||
|
if x.type == 'EDI_sender']
|
||||||
|
if not edifact_sender:
|
||||||
|
self.raise_user_error('EDI_sender', company.party.name)
|
||||||
|
parties = set(x.party for x in records)
|
||||||
|
party, = parties
|
||||||
|
edifact_receiver = [x for x in party.identifiers
|
||||||
|
if x.type == 'EDI_receiver']
|
||||||
|
if not edifact_receiver:
|
||||||
|
self.raise_user_error('EDI_receiver', party.name)
|
||||||
|
template, encoding = self._edi_template(message_type, party)
|
||||||
|
loader = TextTemplate(template)
|
||||||
|
for record in records:
|
||||||
|
message = Message()
|
||||||
|
message.origin = record
|
||||||
|
message.save()
|
||||||
|
data = {
|
||||||
|
"message": message,
|
||||||
|
"sender": edifact_sender[0].code,
|
||||||
|
"receiver": edifact_receiver[0].code,
|
||||||
|
"records": [[message.rec_name, record]],
|
||||||
|
"date": message.create_date.strftime("%y%m%d"),
|
||||||
|
"time": message.create_date.strftime("%H%M")
|
||||||
|
}
|
||||||
|
message.message = loader.generate(
|
||||||
|
data=data, items=[1, 2, 3]).render()
|
||||||
|
message.save()
|
||||||
|
record.save()
|
||||||
|
conf = Pool().get('edocument.configuration')(0)
|
||||||
|
if conf.export_path:
|
||||||
|
chars = ['.', ' ', '-', ':']
|
||||||
|
f_name = ''.join(
|
||||||
|
[c for c in str(datetime.now()) if c not in chars])
|
||||||
|
name = 'EDI' + f_name + ".edi"
|
||||||
|
file_name = os.path.join(conf.export_path, name)
|
||||||
|
self._write_file(file_name, message.message, encoding=encoding)
|
||||||
|
if not message.code:
|
||||||
|
self.raise_user_error('EDI_sequence')
|
||||||
|
return message.message, message_type + message.code + '.EDI'
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<tryton>
|
<tryton>
|
||||||
<data>
|
<data>
|
||||||
<record model="ir.sequence.type" id="sequence_type_edocument">
|
<record model="ir.sequence.type" id="sequence_type_edocument">
|
||||||
|
<field name="code">edocument</field>
|
||||||
<field name="name">Electronic Document</field>
|
<field name="name">Electronic Document</field>
|
||||||
</record>
|
</record>
|
||||||
<record model="ir.sequence.type-res.group"
|
<record model="ir.sequence.type-res.group"
|
||||||
|
@ -13,7 +14,7 @@
|
||||||
</record>
|
</record>
|
||||||
<record model="ir.sequence" id="sequence_edocument">
|
<record model="ir.sequence" id="sequence_edocument">
|
||||||
<field name="name">Electronic Document sequence</field>
|
<field name="name">Electronic Document sequence</field>
|
||||||
<field name="sequence_type" ref="sequence_type_edocument"/>
|
<field name="code">edocument</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- Edocument Template -->
|
<!-- Edocument Template -->
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<!-- The COPYRIGHT file at the top level of this repository contains the full
|
<!-- The COPYRIGHT file at the top level of this repository contains the full
|
||||||
copyright notices and license terms. -->
|
copyright notices and license terms. -->
|
||||||
<tryton>
|
<tryton>
|
||||||
<data>
|
<data depends="incoterm">
|
||||||
<record model="ir.ui.view" id="rule_view_form">
|
<record model="ir.ui.view" id="rule_view_form">
|
||||||
<field name="model">incoterm.rule</field>
|
<field name="model">incoterm.rule</field>
|
||||||
<field name="inherit" ref="incoterm.rule_view_form"/>
|
<field name="inherit" ref="incoterm.rule_view_form"/>
|
||||||
|
|
18
stock.py
18
stock.py
|
@ -5,7 +5,6 @@ from trytond.pool import PoolMeta, Pool
|
||||||
from trytond.pyson import Id
|
from trytond.pyson import Id
|
||||||
from trytond.tools.multivalue import migrate_property
|
from trytond.tools.multivalue import migrate_property
|
||||||
from trytond.modules.company.model import CompanyValueMixin
|
from trytond.modules.company.model import CompanyValueMixin
|
||||||
from trytond.modules.product_ean.tools import get_control_digit
|
|
||||||
from trytond import backend
|
from trytond import backend
|
||||||
|
|
||||||
__all__ = ['Configuration', 'ConfigurationSequence', 'UnitLoad',
|
__all__ = ['Configuration', 'ConfigurationSequence', 'UnitLoad',
|
||||||
|
@ -100,20 +99,3 @@ class ConfigurationEDIOutputPath(ModelSQL, CompanyValueMixin):
|
||||||
fields.append('company')
|
fields.append('company')
|
||||||
migrate_property('stock.configuration',
|
migrate_property('stock.configuration',
|
||||||
field_names, cls, value_names, fields=fields)
|
field_names, cls, value_names, fields=fields)
|
||||||
|
|
||||||
|
|
||||||
class UnitLoad(metaclass=PoolMeta):
|
|
||||||
__name__ = 'stock.unit_load'
|
|
||||||
|
|
||||||
def get_sscc(self):
|
|
||||||
if self.shipment and self.shipment.__name__ == 'stock.shipment.out':
|
|
||||||
edi_codes = [identifier.code for identifier in
|
|
||||||
self.shipment.company.party.identifiers
|
|
||||||
if identifier.type == 'EDI_sender']
|
|
||||||
edi_code = edi_codes[0][:6] if edi_codes else '000000'
|
|
||||||
code = '00' + edi_code + self.code[-9:].zfill(len(self.code[-9:])-9)
|
|
||||||
return code + get_control_digit(code)
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def get_grai(self):
|
|
||||||
return ''
|
|
||||||
|
|
|
@ -6,10 +6,10 @@ depends:
|
||||||
party
|
party
|
||||||
stock
|
stock
|
||||||
product
|
product
|
||||||
incoterm
|
|
||||||
stock_unit_load
|
|
||||||
product_ean
|
|
||||||
party_edi
|
party_edi
|
||||||
|
|
||||||
|
extras_depends:
|
||||||
|
incoterm
|
||||||
product_cross_reference
|
product_cross_reference
|
||||||
|
|
||||||
xml:
|
xml:
|
||||||
|
|
Loading…
Reference in New Issue