diff --git a/__init__.py b/__init__.py index c37e409..4f8083b 100644 --- a/__init__.py +++ b/__init__.py @@ -6,21 +6,27 @@ from . import systemlogics from . import location from . import product from . import stock +from . import configuration def register(): Pool.register( systemlogics.SystemLogicsModula, systemlogics.SystemLogicsModulaEXPOrdiniFile, + systemlogics.SystemLogicsModulaImportEXPOrdiniFileStart, location.Location, product.Product, stock.ShipmentIn, stock.ShipmentOut, stock.ShipmentOutReturn, stock.ShipmentOutSystemlogicsModulaExportStart, + stock.ShipmentOutSystemlogicsModulaCheckStart, stock.ShipmentInternal, product.SystemlogicsModulaArticoliResult, + configuration.Configuration, module='systemlogics_modula', type_='model') Pool.register( + systemlogics.SystemLogicsModulaImportEXPOrdiniFile, stock.ShipmentOutSystemlogicsModulaExport, + stock.ShipmentOutSystemlogicsModulaCheck, product.SystemlogicsModulaArticoli, module='systemlogics_modula', type_='wizard') diff --git a/configuration.py b/configuration.py new file mode 100644 index 0000000..7627a86 --- /dev/null +++ b/configuration.py @@ -0,0 +1,26 @@ +# The COPYRIGHT file at the top level of this repository contains the full +# copyright notices and license terms. +from trytond.model import fields +from trytond.pool import PoolMeta + +__all__ = ['Configuration'] + + +class Configuration(metaclass=PoolMeta): + __name__ = 'stock.configuration' + + try_generate_systemlogics_modula = fields.Boolean( + 'Try Generate SystemLogic Modula', + help="Try generate SystemLogic Modula files") + slice_systemlogics_modula = fields.Integer( + 'Cron Slice SystemLogics Modula', + help=("Number of blocs of shipments to generate the systemlogics " + "modula file. If 0 or null it will be all.")) + + @staticmethod + def default_try_generate_systemlogics_modula(): + return True + + @staticmethod + def default_slice_systemlogics_modula(): + return 100 diff --git a/configuration.xml b/configuration.xml new file mode 100644 index 0000000..e56d95a --- /dev/null +++ b/configuration.xml @@ -0,0 +1,13 @@ + + + + + + stock.configuration + + configuration_form + + + diff --git a/locale/ca_ES.po b/locale/ca.po similarity index 95% rename from locale/ca_ES.po rename to locale/ca.po index 4f2d45b..1378ed1 100644 --- a/locale/ca_ES.po +++ b/locale/ca.po @@ -162,6 +162,10 @@ msgctxt "model:ir.action,name:wizard_shipment_out_export" msgid "Export Systemlogics Modula" msgstr "Exporta Systemlogics Modula" +msgctxt "model:ir.action,name:wizard_shipment_out_check" +msgid "Check Systemlogics Modula" +msgstr "Comprovar Systemlogics Modula" + msgctxt "model:ir.action,name:wizard_systemlogics_modula_articoli" msgid "Export Products Modula" msgstr "Exporta productes Modula" @@ -262,6 +266,10 @@ msgctxt "view:stock.shipment.out.systemlogics.modula.export.start:" msgid "Export Shipments Out to Modula" msgstr "Exporta albarans client a Modula" +msgctxt "view:stock.shipment.out.systemlogics.modula.check.start:" +msgid "Check Shipments Out to Modula" +msgstr "Comprovar albarans client a Modula" + msgctxt "view:systemlogics.modula.articoli.result:" msgid "Export Product XML Modula" msgstr "Exportar XML productes Modula" @@ -288,6 +296,11 @@ msgctxt "" msgid "Export" msgstr "Exporta" +msgctxt "" +"wizard_button:stock.shipment.out.systemlogics.modula.check,start,check:" +msgid "Check" +msgstr "Comprova" + msgctxt "wizard_button:systemlogics.modula.articoli,result,end:" msgid "Close" msgstr "Tanca" diff --git a/locale/es_ES.po b/locale/es.po similarity index 95% rename from locale/es_ES.po rename to locale/es.po index aecff26..f4f3de5 100644 --- a/locale/es_ES.po +++ b/locale/es.po @@ -162,6 +162,10 @@ msgctxt "model:ir.action,name:wizard_shipment_out_export" msgid "Export Systemlogics Modula" msgstr "Exportar Systemlogics Modula" +msgctxt "model:ir.action,name:wizard_shipment_out_check" +msgid "Check Systemlogics Modula" +msgstr "Comprobar Systemlogics Modula" + msgctxt "model:ir.action,name:wizard_systemlogics_modula_articoli" msgid "Export Products Modula" msgstr "Exportar productos Modula" @@ -262,6 +266,10 @@ msgctxt "view:stock.shipment.out.systemlogics.modula.export.start:" msgid "Export Shipments Out to Modula" msgstr "Exportar albaranes cliente a Modula" +msgctxt "view:stock.shipment.out.systemlogics.modula.check.start:" +msgid "Check Shipments Out to Modula" +msgstr "Comprobar albaranes cliente a Modula" + msgctxt "view:systemlogics.modula.articoli.result:" msgid "Export Product XML Modula" msgstr "Exportar productos XML Modula" @@ -288,6 +296,11 @@ msgctxt "" msgid "Export" msgstr "Exportar" +msgctxt "" +"wizard_button:stock.shipment.out.systemlogics.modula.check,start,check:" +msgid "Check" +msgstr "Comprobar" + msgctxt "wizard_button:systemlogics.modula.articoli,result,end:" msgid "Close" msgstr "Cerrar" diff --git a/shipment.xml b/shipment.xml index 84f3eab..61ae4df 100644 --- a/shipment.xml +++ b/shipment.xml @@ -39,5 +39,90 @@ The COPYRIGHT file at the top level of this repository contains the full copyrig + + + + stock.shipment.out.systemlogics.modula.check.start + form + shipment_out_check_form + + + + Check Systemlogics Modula + stock.shipment.out.systemlogics.modula.check + stock.shipment.out + + + form_action + stock.shipment.out,-1 + + + + + + + + + + user_stock_check_systemlogics_modula + Cron Check SystemLogics Modula + + + + + + + + + + + + + Check SystemLogic Modula for Out Shipments + + + + + minutes + + + stock.shipment.out + check_systemlogics_modula_scheduler + + + + + user_stock_generate_systemlogics_modula + Cron Generate SystemLogics Modula + + + + + + + + + + + + + Generate SystemLogic Modula for Out Shipments + + + + + hours + + + stock.shipment.out + generate_systemlogics_modula_scheduler + + + + stock.shipment.out + + shipment_out_tree + diff --git a/stock.py b/stock.py index 08ecf31..13e148b 100644 --- a/stock.py +++ b/stock.py @@ -6,9 +6,14 @@ from trytond.model import ModelView, fields from trytond.transaction import Transaction from trytond.pyson import Eval from trytond.wizard import Wizard, StateView, Button, StateTransition +from trytond.tools import grouped_slice +import logging __all__ = ['ShipmentIn', 'ShipmentOut', 'ShipmentOutReturn', 'ShipmentInternal', - 'ShipmentOutSystemlogicsModulaExportStart', 'ShipmentOutSystemlogicsModulaExport'] + 'ShipmentOutSystemlogicsModulaExportStart', 'ShipmentOutSystemlogicsModulaExport', + 'ShipmentOutSystemlogicsModulaCheckStart', 'ShipmentOutSystemlogicsModulaCheck'] + +logger = logging.getLogger(__name__) class ShipmentIn(metaclass=PoolMeta): @@ -75,72 +80,193 @@ class ShipmentOut(metaclass=PoolMeta): systemlogics_modula = fields.Boolean('SystemLogics Modula') systemlogics_modula_completed = fields.Boolean( 'SystemLogics Modula Completed') + systemlogics_modula_sended = fields.Boolean('SystemLogics Modula Sended') + ship_create_date = fields.Function(fields.DateTime('Create Date'), + 'get_ship_create_date') @staticmethod def default_systemlogics_modula(): return False + @staticmethod + def default_systemlogics_modula_completed(): + return False + + @staticmethod + def default_systemlogics_modula_sended(): + return False + + def get_ship_create_date(self, name): + return self.create_date + @classmethod def copy(cls, shipments, default=None): if default is None: default = {} default = default.copy() - default['systemlogics_modula'] = None - default['systemlogics_modula_completed'] = None + default['systemlogics_modula'] = False + default['systemlogics_modula_completed'] = False + default['systemlogics_modula_sended'] = False return super(ShipmentOut, cls).copy(shipments, default=default) @classmethod - def generate_systemlogics_modula(cls, shipments): - '''Active System Logics process when a move from location is systemlogics marked''' + def generate_systemlogics_modula_file(cls, shipments): SystemLogicsModula = Pool().get('systemlogics.modula') - s_completed = [] # shipments completed - s_incompleted = [] # shipments incompleted - for s in shipments: - if hasattr(s, 'review'): - if s.review: + # Force not get a rollback to generate XML file + shipment_ids = [s.id for s in shipments] + Transaction().commit() + + # Search shipment ID to sure not have a rollback + shipments = cls.search([ + ('id', 'in', shipment_ids), + ], order=[('systemlogics_modula_completed', 'DESC')]) + SystemLogicsModula.imp_ordini( + shipments, template='IMP_ORDINI_OUT', type_='P') + + @classmethod + def check_systemlogics_modula(cls, shipments): + pool = Pool() + Configuration = pool.get('stock.configuration') + + config = Configuration(1) + if not (Transaction().context.get('generate_systemlogics_modula', + config.try_generate_systemlogics_modula)): + return + + to_write = [] + values = { + 'systemlogics_modula': True + } + for shipment in shipments: + if hasattr(shipment, 'review'): + if shipment.review: continue systemLogics = False completed = True - for move in s.inventory_moves: + for move in shipment.inventory_moves: if move.from_location.systemlogics_modula: systemLogics = True else: completed = False if systemLogics: + values = values.copy() if completed: - s_completed.append(s) + values['systemlogics_modula_completed'] = True else: - s_incompleted.append(s) + values['systemlogics_modula_completed'] = False + to_write.extend(([shipment], values)) + if to_write: + cls.write(*to_write) - if s_completed or s_incompleted: - if s_completed: - cls.write(s_completed, { - 'systemlogics_modula': True, - 'systemlogics_modula_completed': True, - }) - if s_incompleted: - cls.write(s_incompleted, { - 'systemlogics_modula': True, - 'systemlogics_modula_completed': False, - }) + @classmethod + def generate_systemlogics_modula(cls, shipments): + '''Generate SystemLogics Modula''' + Configuration = Pool().get('stock.configuration') - # Force not get a rollback to generate XML file - shipment_ids = [s.id for s in (s_completed + s_incompleted)] - Transaction().commit() - # Search shipment ID to sure not have a rollback - shipments = cls.search([ - ('id', 'in', shipment_ids), - ], order=[('systemlogics_modula_completed', 'DESC')]) - SystemLogicsModula.imp_ordini( - shipments, template='IMP_ORDINI_OUT', type_='P') + config = Configuration(1) + if not (Transaction().context.get('generate_systemlogics_modula', + config.try_generate_systemlogics_modula)): + return + + to_write = [] + shipments_modula = [] + value = { + 'systemlogics_modula_sended': True + } + for shipment in shipments: + if hasattr(shipment, 'review'): + if shipment.review: + continue + shipments_modula.append(shipment) + to_write.extend(([shipment], value)) + + if shipments_modula: + cls.write(*to_write) + cls.generate_systemlogics_modula_file(shipments_modula) @classmethod def assign(cls, shipments): super(ShipmentOut, cls).assign(shipments) - # control generate systemlogics module with context - if Transaction().context.get('generate_systemlogics_modula', True): - cls.generate_systemlogics_modula(shipments) + assigned = [s for s in shipments if s.state == 'assigned'] + cls.check_systemlogics_modula(assigned) + cls.generate_systemlogics_modula(assigned) + + @classmethod + def check_systemlogics_modula_scheduler(cls, args=None): + ''' + This method is intended to be called from ir.cron + args: warehouse ids [ids] + ''' + pool = Pool() + Configuration = pool.get('stock.configuration') + config = Configuration(1) + + domain = [ + ('state', '=', 'assigned'), + ] + if args: + domain.append( + ('warehouse', 'in', args), + ) + shipments = cls.search(domain) + + len_ships = len(shipments) + logger.info( + 'Scheduler Try Check Systemlogics Modula. Total: %s' % ( + len_ships)) + if len_ships: + blocs = 1 + slice_systemlogics_modula = (config.slice_systemlogics_modula or + len_ships) + with Transaction().set_context(generate_systemlogics_modula=True): + for sub_shipments in grouped_slice(shipments, + slice_systemlogics_modula): + logger.info('Start bloc %s of %s.' % ( + blocs, len_ships/slice_systemlogics_modula)) + cls.check_systemlogics_modula(list(sub_shipments)) + logger.info('End bloc %s.' % blocs) + blocs += 1 + logger.info('End Scheduler Try Check Systemlogics Modula.') + + @classmethod + def generate_systemlogics_modula_scheduler(cls, args=None): + ''' + This method is intended to be called from ir.cron + args: warehouse ids [ids] + ''' + pool = Pool() + Configuration = pool.get('stock.configuration') + config = Configuration(1) + + domain = [ + ('state', '=', 'assigned'), + ('systemlogics_modula', '=', True), + ('systemlogics_modula_sended', '=', False), + ] + if args: + domain.append( + ('warehouse', 'in', args), + ) + shipments = cls.search(domain) + + len_ships = len(shipments) + logger.info( + 'Scheduler Try generate Systemlogics Modula. Total: %s' % ( + len_ships)) + if len_ships: + blocs = 1 + slice_systemlogics_modula = (config.slice_systemlogics_modula or + len_ships) + with Transaction().set_context(generate_systemlogics_modula=True): + for sub_shipments in grouped_slice(shipments, + slice_systemlogics_modula): + logger.info('Start bloc %s of %s.' % ( + blocs, len_ships/slice_systemlogics_modula)) + cls.generate_systemlogics_modula(list(sub_shipments)) + logger.info('End bloc %s.' % blocs) + blocs += 1 + logger.info('End Scheduler Try generate Systemlogics Modula.') class ShipmentOutReturn(metaclass=PoolMeta): @@ -245,7 +371,7 @@ class ShipmentInternal(metaclass=PoolMeta): ('id', 'in', extract_shipments_ids), ]) SystemLogicsModula.imp_ordini( - ext_shipments, template='IMP_ORDINI_IN', type_='P') + ext_shipments, template='IMP_ORDINI_INTERNAL', type_='P') if deposit_shipments_ids: # Search shipment ID to sure not have a rollback dep_shipments = cls.search([ @@ -264,23 +390,25 @@ class ShipmentOutSystemlogicsModulaExportStart(ModelView): 'Customer shipments export Systemlogics Modula Start' __name__ = 'stock.shipment.out.systemlogics.modula.export.start' shipments = fields.Many2Many('stock.shipment.out', None, None, 'Shipments', - domain=[ - ('state', 'in', ['assigned']), + required=True, domain=[ + ('state', '=', 'assigned'), + ('systemlogics_modula', '=', True), + ('systemlogics_modula_sended', '=', False), ], - states={ - 'required': True, - }, help='Assigned customer shipments to export Systemlogics Modula.') - @staticmethod - def default_shipments(): + @classmethod + def default_shipments(cls): ShipmentOut = Pool().get('stock.shipment.out') active_ids = Transaction().context.get('active_ids', []) - shipments = ShipmentOut.search([ - ('id', 'in', active_ids), - ('state', 'in', ['assigned']), - ]) + domain = [] + domain.extend(cls.shipments.domain) + if active_ids: + domain.append( + ('id', 'in', active_ids) + ) + shipments = ShipmentOut.search(domain) return [s.id for s in shipments] @@ -298,7 +426,54 @@ class ShipmentOutSystemlogicsModulaExport(Wizard): def transition_export(self): ShipmentOut = Pool().get('stock.shipment.out') - shipments = self.start.shipments + shipments = list(self.start.shipments) if shipments: - ShipmentOut.generate_systemlogics_modula(shipments) + with Transaction().set_context(generate_systemlogics_modula=True): + ShipmentOut.generate_systemlogics_modula(shipments) + return 'end' + + +class ShipmentOutSystemlogicsModulaCheckStart(ModelView): + 'Customer shipments check Systemlogics Modula Start' + __name__ = 'stock.shipment.out.systemlogics.modula.check.start' + shipments = fields.Many2Many('stock.shipment.out', None, None, 'Shipments', + required=True, domain=[ + ('state', '=', 'assigned'), + ], + help='Assigned customer shipments to check Systemlogics Modula.') + + @staticmethod + def default_shipments(): + ShipmentOut = Pool().get('stock.shipment.out') + + active_ids = Transaction().context.get('active_ids', []) + domain = [ + ('state', '=', 'assigned'), + ] + if active_ids: + domain.append( + ('id', 'in', active_ids) + ) + shipments = ShipmentOut.search(domain) + return [s.id for s in shipments] + + +class ShipmentOutSystemlogicsModulaCheck(Wizard): + 'Customer shipments check Systemlogics Modula' + __name__ = 'stock.shipment.out.systemlogics.modula.check' + + start = StateView('stock.shipment.out.systemlogics.modula.check.start', + 'systemlogics_modula.shipment_out_check_form', [ + Button('Cancel', 'end', 'tryton-cancel'), + Button('Check', 'check', 'tryton-ok', True), + ]) + check = StateTransition() + + def transition_check(self): + ShipmentOut = Pool().get('stock.shipment.out') + + shipments = list(self.start.shipments) + if shipments: + with Transaction().set_context(generate_systemlogics_modula=True): + ShipmentOut.check_systemlogics_modula(shipments) return 'end' diff --git a/systemlogics.py b/systemlogics.py index f998d3b..8ed0fdf 100644 --- a/systemlogics.py +++ b/systemlogics.py @@ -2,7 +2,8 @@ #The COPYRIGHT file at the top level of this repository contains #the full copyright notices and license terms. from trytond.pool import Pool -from trytond.model import ModelView, ModelSQL, fields +from trytond.model import ModelView, ModelSQL, fields, Unique +from trytond.wizard import Wizard, StateTransition, StateView, Button from trytond.pyson import Eval from trytond.transaction import Transaction from trytond.rpc import RPC @@ -16,7 +17,9 @@ import logging import datetime import tempfile -__all__ = ['SystemLogicsModula', 'SystemLogicsModulaEXPOrdiniFile'] +__all__ = ['SystemLogicsModula', 'SystemLogicsModulaEXPOrdiniFile', + 'SystemLogicsModulaImportEXPOrdiniFile', + 'SystemLogicsModulaImportEXPOrdiniFileStart'] loader = genshi.template.TemplateLoader( os.path.join(os.path.dirname(__file__), 'template'), @@ -224,31 +227,25 @@ class SystemLogicsModula(ModelSQL, ModelView): EXPOrdiniFile = Pool().get('systemlogics.modula.exp.ordini.file') logger.info('Start read SystemLogics Module files') - - modulas = cls.search([ - ('name', '=', 'EXP_ORDINI'), - ]) - vlist = [] - to_delete = [] - for modula in modulas: + to_process = [] + for modula in cls.search([('name', '=', 'EXP_ORDINI')]): try: filenames = os.listdir(modula.path) - except OSError: + except OSError as e: logger.warning('Error reading path: %s' % e) continue + exp_ordini_files = [f.name for f in EXPOrdiniFile.search([ + ('name', 'in', filenames)])] for filename in filenames: fullname = '%s/%s' % (modula.path, filename) values = {} - exp_ordini_file = EXPOrdiniFile.search([ - ('name', '=', filename) - ]) - if exp_ordini_file: - to_delete.append(fullname) + if filename in exp_ordini_files: + to_process.append(fullname) continue try: content = open(fullname, 'r').read() - except IOError: + except IOError as e: logger.warning('Error reading file %s: %s' % (fullname, e)) continue values['name'] = filename @@ -256,15 +253,18 @@ class SystemLogicsModula(ModelSQL, ModelView): values['content'] = content values['state'] = 'pending' vlist.append(values) - to_delete.append(fullname) + to_process.append(fullname) + ordini_files = EXPOrdiniFile.create(vlist) EXPOrdiniFile.process_export_ordini(ordini_files) - for filename in to_delete: + Transaction().commit() + + for filename in to_process: try: os.remove(filename) except OSError: pass - logger.info('Loaded SystemLogics Module %s files' % (len(to_delete))) + logger.info('Loaded SystemLogics Module %s files' % (len(to_process))) class SystemLogicsModulaEXPOrdiniFile(ModelSQL, ModelView): @@ -284,14 +284,15 @@ class SystemLogicsModulaEXPOrdiniFile(ModelSQL, ModelView): @classmethod def __setup__(cls): super(SystemLogicsModulaEXPOrdiniFile, cls).__setup__() - cls._sql_constraints += [ - ('name_uniq', 'UNIQUE(name)', 'Name must be unique.'), + t = cls.__table__() + cls._sql_constraints = [ + ('name_uniq', Unique(t, t.name), 'Name must be unique.'), ] cls._buttons.update({ - 'process_export_ordini': { - 'invisible': ~Eval('state').in_(['pending', 'failed']), - }, - }) + 'process_export_ordini': { + 'invisible': ~Eval('state').in_(['pending', 'failed']), + }, + }) @classmethod def default_state(cls): @@ -325,20 +326,20 @@ class SystemLogicsModulaEXPOrdiniFile(ModelSQL, ModelView): continue quantities = {} - moves = [] + move_ids = [] for o in dom.getElementsByTagName('EXP_ORDINI_RIGHE'): - move = {} - id_ = (o.getElementsByTagName('RIG_HOSTINF')[0] - .firstChild.data) - moves.append(id_) + id_ = int(o.getElementsByTagName( + 'RIG_HOSTINF')[0].firstChild.data) + move_ids.append(id_) quantities[int(id_)] = float( o.getElementsByTagName('RIG_QTAE') [0].firstChild.data.replace(',', '.')) - moves = Move.search([ - ('id', 'in', moves) - ]) - for move in moves: + for move in Move.search([('id', 'in', move_ids)]): + # TODO process shipment out and internal + if (not move.shipment + or move.shipment.__name__ != 'stock.shipment.out'): + continue if (quantities[move.id] == move.quantity and move.shipment.state == 'assigned'): to_do.append(move) @@ -368,3 +369,24 @@ class SystemLogicsModulaEXPOrdiniFile(ModelSQL, ModelView): cls.write(done_ordini_files, {'state': 'done'}) if fail_ordini_files: cls.write(fail_ordini_files, {'state': 'failed'}) + + +class SystemLogicsModulaImportEXPOrdiniFileStart(ModelView): + 'SystemLogcics Modula Import EXP Ordini File Start' + __name__ = 'systemlogics.modula.import.exp.ordini.file.start' + + +class SystemLogicsModulaImportEXPOrdiniFile(Wizard): + 'SystemLogics Modula Import EXP Ordini File' + __name__ = "systemlogics.modula.import.exp.ordini.file" + start = StateView('systemlogics.modula.import.exp.ordini.file.start', + 'systemlogics_modula.systemlogics_modula_import_exp_ordini_file_start', [ + Button('Cancel', 'end', 'tryton-cancel'), + Button('Import', 'import_', 'tryton-ok', default=True), + ]) + import_ = StateTransition() + + def transition_import_(self): + SystemLogicsModula = Pool().get('systemlogics.modula') + SystemLogicsModula.export_ordini_file() + return 'end' diff --git a/systemlogics.xml b/systemlogics.xml index 2b6f017..b0be93d 100644 --- a/systemlogics.xml +++ b/systemlogics.xml @@ -19,6 +19,22 @@ The COPYRIGHT file at the top level of this repository contains the full copyrig + + + user_cron_internal_systemlogics_modula + Cron SystemLogics Modula + + + + + + + + + + + + @@ -110,17 +126,37 @@ The COPYRIGHT file at the top level of this repository contains the full copyrig - + + + + + + + + + systemlogics.modula.import.exp.ordini.file.start + form + systemlogics_modula_import_exp_ordini_file_start + + + + Import EXP Ordini File + systemlogics.modula.import.exp.ordini.file + + + + + + Export Ordini Files - + 1 days @@ -201,14 +237,6 @@ The COPYRIGHT file at the top level of this repository contains the full copyrig - - - - - - - - diff --git a/template/IMP_ORDINI_INTERNAL.xml b/template/IMP_ORDINI_INTERNAL.xml index 568b663..69e3a32 100644 --- a/template/IMP_ORDINI_INTERNAL.xml +++ b/template/IMP_ORDINI_INTERNAL.xml @@ -8,7 +8,8 @@ - + + ${shipment.number} ${move.product.code or move.product.rec_name} @@ -20,5 +21,6 @@ 0 + diff --git a/template/IMP_ORDINI_OUT.xml b/template/IMP_ORDINI_OUT.xml index fd3f40d..9bbc6c4 100644 --- a/template/IMP_ORDINI_OUT.xml +++ b/template/IMP_ORDINI_OUT.xml @@ -1,7 +1,7 @@ - ${shipment.number} + ${shipment.code} ${shipment.reference and shipment.reference[:50]} ${type_} ${datetime.datetime.now().strftime("%Y%m%d%H%M%s")[:16]} @@ -10,7 +10,7 @@ - ${shipment.number} + ${shipment.code} ${move.product.code or move.product.rec_name} @@ -23,7 +23,7 @@ - ${shipment.number} + ${shipment.code} ${systemlogic.not_completed or'Not completed'} diff --git a/tests/exp_ordini.xml b/tests/exp_ordini.xml new file mode 100644 index 0000000..0483a52 --- /dev/null +++ b/tests/exp_ordini.xml @@ -0,0 +1,23 @@ + + + + 2 + + P + + 2 + P2 + + + + + 6 + 1,000 + 1,000 + + + + + + + diff --git a/tests/scenario_systemlogics_modula.rst b/tests/scenario_systemlogics_modula.rst index aa9aa1b..62222d2 100644 --- a/tests/scenario_systemlogics_modula.rst +++ b/tests/scenario_systemlogics_modula.rst @@ -5,16 +5,19 @@ Systemlogics Modula Scenario Imports:: >>> import datetime + >>> import os >>> from dateutil.relativedelta import relativedelta >>> from decimal import Decimal >>> from proteus import config, Model, Wizard >>> from trytond.tests.tools import activate_modules >>> from trytond.modules.company.tests.tools import create_company, \ ... get_company + >>> from trytond.modules.systemlogics_modula.tests.tools \ + ... import read_file >>> today = datetime.date.today() >>> yesterday = today - relativedelta(days=1) -Install SystemLogics Modula Module:: +Install stock Module:: >>> config = activate_modules('systemlogics_modula') @@ -52,6 +55,10 @@ Create product:: >>> template.list_price = Decimal('20') >>> template.save() >>> product, = template.products + >>> product.code = 'P1' + >>> product.cost_price = Decimal('8') + >>> product.code = 'P1' + >>> product.save() >>> product2 = Product() >>> template = ProductTemplate() @@ -62,6 +69,9 @@ Create product:: >>> template.list_price = Decimal('20') >>> template.save() >>> product2, = template.products + >>> product2.cost_price = Decimal('8') + >>> product2.code = 'P2' + >>> product2.save() Get stock locations:: @@ -169,13 +179,13 @@ Create Shipment Out:: >>> shipment_out.systemlogics_modula == False True - >>> shipment_out = ShipmentOut() - >>> shipment_out.planned_date = today - >>> shipment_out.customer = customer - >>> shipment_out.warehouse = warehouse_loc - >>> shipment_out.company = company - >>> shipment_out.outgoing_moves.extend([StockMove()]) - >>> for move in shipment_out.outgoing_moves: + >>> shipment_out2 = ShipmentOut() + >>> shipment_out2.planned_date = today + >>> shipment_out2.customer = customer + >>> shipment_out2.warehouse = warehouse_loc + >>> shipment_out2.company = company + >>> shipment_out2.outgoing_moves.extend([StockMove()]) + >>> for move in shipment_out2.outgoing_moves: ... move.product = product2 ... move.uom = unit ... move.quantity = 1 @@ -184,15 +194,15 @@ Create Shipment Out:: ... move.company = company ... move.unit_price = Decimal('1') ... move.currency = company.currency - >>> shipment_out.save() - >>> shipment_out.click('wait') - >>> inventory_move, = shipment_out.inventory_moves + >>> shipment_out2.save() + >>> shipment_out2.click('wait') + >>> inventory_move, = shipment_out2.inventory_moves >>> inventory_move.from_location = modula_loc >>> inventory_move.save() - >>> shipment_out.reload() - >>> shipment_out.click('assign_try') + >>> shipment_out2.reload() + >>> shipment_out2.click('assign_try') True - >>> shipment_out.systemlogics_modula == True + >>> shipment_out2.systemlogics_modula == True True Create Shipment Out Return:: @@ -270,3 +280,19 @@ Create Shipment Internal:: >>> shipment_internal.reload() >>> shipment_internal.systemlogics_modula == True True + +Import EXP Ordini:: + + >>> EXPOrdiniFile = Model.get('systemlogics.modula.exp.ordini.file') + >>> ordine_file = os.path.join(os.path.dirname(__file__), 'exp_ordini.xml') + >>> exp_ordini_file = EXPOrdiniFile() + >>> exp_ordini_file.name = 'EXP_ORDINI1.XML' + >>> exp_ordini_file.modula = sm_exp_ordini + >>> exp_ordini_file.content = read_file(ordine_file).decode('utf-8') + >>> exp_ordini_file.save() + >>> exp_ordini_file.click('process_export_ordini') + >>> exp_ordini_file.state == 'done' + True + >>> shipment_out2.reload() + >>> shipment_out2.state == 'packed' + True diff --git a/tests/tools.py b/tests/tools.py new file mode 100644 index 0000000..c908dce --- /dev/null +++ b/tests/tools.py @@ -0,0 +1,13 @@ +# The COPYRIGHT file at the top level of this repository contains the full +# copyright notices and license terms. + +__all__ = ['read_file'] + + +def read_file(filename): + with open(filename) as f: + data = f.read() + # On python3 we must cast to bytes with valid encoding + if bytes != str: + data = bytes(data, encoding=f.encoding) + return data diff --git a/tryton.cfg b/tryton.cfg index 36df377..99335cc 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -13,3 +13,4 @@ xml: location.xml product.xml shipment.xml + configuration.xml diff --git a/view/configuration_form.xml b/view/configuration_form.xml new file mode 100644 index 0000000..78f2963 --- /dev/null +++ b/view/configuration_form.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/view/shipment_out_check_form.xml b/view/shipment_out_check_form.xml new file mode 100644 index 0000000..a973821 --- /dev/null +++ b/view/shipment_out_check_form.xml @@ -0,0 +1,6 @@ + + +
+ + diff --git a/view/shipment_out_tree.xml b/view/shipment_out_tree.xml new file mode 100644 index 0000000..74271f3 --- /dev/null +++ b/view/shipment_out_tree.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + diff --git a/view/systemlogics_modula_exp_ordini_file_form.xml b/view/systemlogics_modula_exp_ordini_file_form.xml index 6ea10a6..98cf1eb 100644 --- a/view/systemlogics_modula_exp_ordini_file_form.xml +++ b/view/systemlogics_modula_exp_ordini_file_form.xml @@ -12,6 +12,6 @@ The COPYRIGHT file at the top level of this repository contains the full copyrig