Tests and translations.

This commit refs #851
This commit is contained in:
Sergio Morillo 2015-10-13 16:47:59 +02:00
parent aba4376421
commit 326b69cce5
11 changed files with 450 additions and 24 deletions

View File

@ -3,13 +3,14 @@
from trytond.pool import Pool
from .load import (LoadOrder, LoadOrderLine,
LoadUnitLoad, LoadUnitLoadOrder,
LoadUnitLoadData)
LoadUnitLoadData, Configuration)
from .unit_load import UnitLoad
def register():
Pool.register(
UnitLoad,
Configuration,
LoadOrder,
LoadOrderLine,
LoadUnitLoadOrder,

50
load.py
View File

@ -8,16 +8,30 @@ from trytond.wizard import Wizard, StateTransition, StateView, Button
__metaclass__ = PoolMeta
__all__ = ['LoadOrder', 'LoadOrderLine', 'LoadUnitLoad',
'LoadUnitLoadOrder', 'LoadUnitLoadData']
__all__ = ['Configuration', 'LoadOrder', 'LoadOrderLine',
'LoadUnitLoad', 'LoadUnitLoadOrder', 'LoadUnitLoadData']
class Configuration:
__name__ = 'carrier.configuration'
ul_origin_restrict = fields.Boolean('Restrict UL origin',
help='Restricts origin of UL when loading in a Load order.')
@classmethod
def default_ul_origin_restrict(cls):
return True
class LoadOrder:
__name__ = 'carrier.load.order'
unit_loads = fields.Function(
fields.One2Many('stock.unit_load', None, 'ULs'),
fields.One2Many('stock.unit_load', None, 'Unit loads'),
'get_unit_loads')
ul_origin_restrict = fields.Boolean('Restrict UL origin',
states={'readonly': Eval('state') != 'draft'},
depends=['state'])
@classmethod
def __setup__(cls):
@ -36,6 +50,14 @@ class LoadOrder:
'ul_overload': 'All valid lines of load order "%s" are complete. Cannot load more ULs.',
'ul_data': 'Product data of UL "%s" does not match with any line of load order "%s".'})
@classmethod
def default_ul_origin_restrict(cls):
pool = Pool()
Configuration = pool.get('carrier.configuration')
conf = Configuration(1)
return conf.ul_origin_restrict
def get_unit_loads(self, name=None):
if not self.lines:
return []
@ -85,9 +107,13 @@ class LoadOrder:
self.rec_name))
# check it is linked to origin lines
lines = [l for l in self.lines if unit_load in l.origin.unit_loads]
lines = [l for l in self.lines if l.origin and unit_load in l.origin.unit_loads]
if not lines:
self.raise_user_error('ul_origin', unit_load.rec_name)
if self.ul_origin_restrict:
self.raise_user_error('ul_origin', unit_load.rec_name)
self.raise_user_warning('loading_ul_origin_%s' % unit_load.id, 'ul_origin',
unit_load.rec_name)
lines = self.lines
# check data matches
lines = self.check_ul_data_match(lines, unit_load)
@ -95,6 +121,7 @@ class LoadOrder:
self.raise_user_error('ul_data', (unit_load.rec_name, self.rec_name))
# check overload line qty
line = None
for _line in lines:
order_lines.setdefault(_line.id, _line.ul_quantity - len(_line.unit_loads))
if order_lines[_line.id] > 0:
@ -112,10 +139,10 @@ class LoadOrder:
def check_ul_data_match(self, lines, unit_load):
valid_lines = []
for line in lines:
product = getattr(line.origin, 'product', None)
if not product:
if not line.origin or not line.origin.product:
valid_lines.append(line)
continue
product = getattr(line.origin, 'product', None)
if product.id == unit_load.product.id:
valid_lines.append(line)
return valid_lines
@ -129,7 +156,7 @@ class LoadOrderLine:
fields.Float('Quantity per UL', digits=(16, Eval('unit_digits', 0)),
depends=['unit_digits']),
'on_change_with_quantity_per_ul')
unit_loads = fields.One2Many('stock.unit_load', 'load_line', 'ULs',
unit_loads = fields.One2Many('stock.unit_load', 'load_line', 'Unit loads',
readonly=True)
@fields.depends('quantity', 'ul_quantity', 'uom')
@ -155,6 +182,7 @@ class LoadUnitLoadOrder(ModelView):
# TODO: domain of uls_to_load: filter by in stock (storage location).
# It is verified later in add_ul, but would be fine to filter here
# TODO: configure ul_code reading by a string pattern (ex: P${code}) in carrier.configuration
# to read it with barcode scanner
class LoadUnitLoadData(ModelView):
"""Carrier load unit load"""
__name__ = 'carrier.load_uls.data'
@ -227,15 +255,15 @@ class LoadUnitLoad(Wizard):
if uls:
order.add_ul(uls)
if order.state != 'running':
order.run()
order.run([order])
return 'data'
def transition_do_(self):
pool = Pool()
Order = pool.get('carrier.load.order')
# TODO: finish load order and create sale
Order.do(self._get_load_order())
# TODO: create sale
Order.do([self._get_load_order()])
# TODO: print reports
return 'end'

View File

@ -3,6 +3,13 @@
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<!-- Configuration -->
<record model="ir.ui.view" id="carrier_configuration_view_form">
<field name="model">carrier.configuration</field>
<field name="type">form</field>
<field name="name">configuration_form</field>
<field name="inherit" ref="carrier_configuration.configuration_view_form"/>
</record>
<!-- Order -->
<record model="ir.ui.view" id="load_order_view_form">
<field name="model">carrier.load.order</field>

187
locale/es_ES.po Normal file
View File

@ -0,0 +1,187 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "error:carrier.load.order:"
msgid "All valid lines of load order \"%s\" are complete. Cannot load more ULs."
msgstr ""
"Todas las líneas válidas de la Orden de carga \"%s\" están completadas. No puede cargar más UdCs."
msgctxt "error:carrier.load.order:"
msgid "Cannot cancel load orders with loaded ULs"
msgstr "No puede cancelar Ordenes de carga con UdCs."
msgctxt "error:carrier.load.order:"
msgid "Product data of UL \"%s\" does not match with any line of load order \"%s\"."
msgstr ""
"La información de producto de la UdC \"%s\" no coincide con ninguna línea de la Orden de carga \"%s\"."
msgctxt "error:carrier.load.order:"
msgid "UL \"%s\" does not belong to any origin of this load order."
msgstr ""
"La UdC \"%s\" no pertenece a ningún origen de la Orden de carga actual."
msgctxt "error:carrier.load.order:"
msgid "UL \"%s\" is already loaded."
msgstr "La UdC \"%s\" ya ha sido cargada."
msgctxt "error:carrier.load.order:"
msgid "UL \"%s\" must be in Done state."
msgstr "La UdC \"%s\" debe estar Finalizada."
msgctxt "error:carrier.load.order:"
msgid "UL \"%s\" must be in a storage location."
msgstr "La UdC \"%s\" debe encontrarse en una ubicación de almacenamiento."
msgctxt "error:carrier.load.order:"
msgid "UL \"%s\" must be in warehouse \"%s\" to be loaded in order \"%s\"."
msgstr ""
"La UdC \"%s\" debe encontrarse en el almacén \"%s\" para ser cargada en la orden \"%s\"."
msgctxt "error:carrier.load_uls:"
msgid "Cannot find Unit load \"%s\"."
msgstr "No se ha podido encontrar la UdC \"%s\"."
msgctxt "error:carrier.load_uls:"
msgid "Must define an UL to load."
msgstr "Debe definir una UdC para cargarse."
msgctxt "error:stock.unit_load:"
msgid "Cannot unload an UdC from a Load order in Done state."
msgstr "No es posible descargar una UdC de una Orden de carga Finalizada."
msgctxt "field:carrier.configuration,ul_origin_restrict:"
msgid "Restrict UL origin"
msgstr "Restringir origen UdC"
msgctxt "help:carrier.configuration,ul_origin_restrict:"
msgid "Restricts origin of UL when loading in a Load order."
msgstr "Restringe el origen de la UdC al cargarse en una Orden de carga."
msgctxt "field:carrier.load.order,unit_loads:"
msgid "Unit loads"
msgstr "Unidades de carga"
msgctxt "field:carrier.load.order,ul_origin_restrict:"
msgid "Restrict UL origin"
msgstr "Restringir origen UdC"
msgctxt "field:carrier.load.order.line,quantity_per_ul:"
msgid "Quantity per UL"
msgstr "Cantidad por UdC"
msgctxt "field:carrier.load.order.line,ul_quantity:"
msgid "ULs"
msgstr "UdCs"
msgctxt "field:carrier.load.order.line,unit_loads:"
msgid "Unit loads"
msgstr "Unidades de carga"
msgctxt "field:carrier.load_uls.data,id:"
msgid "ID"
msgstr "Identificador"
msgctxt "field:carrier.load_uls.data,load_order:"
msgid "Order"
msgstr "Orden"
msgctxt "field:carrier.load_uls.data,loaded_uls:"
msgid "Loaded ULs"
msgstr "UdCs cargadas"
msgctxt "field:carrier.load_uls.data,ul_code:"
msgid "UL"
msgstr "UdC"
msgctxt "field:carrier.load_uls.data,uls_loaded:"
msgid "Loaded ULs"
msgstr "UdCs cargadas"
msgctxt "field:carrier.load_uls.data,uls_to_load:"
msgid "ULs to load"
msgstr "UdCs a cargar"
msgctxt "field:carrier.load_uls.order,id:"
msgid "ID"
msgstr "Identificador"
msgctxt "field:carrier.load_uls.order,load_order:"
msgid "Order"
msgstr "Orden"
msgctxt "field:stock.unit_load,load_line:"
msgid "Load line"
msgstr "Línea de carga"
msgctxt "model:carrier.load_uls.data,name:"
msgid "Carrier load unit load"
msgstr "Carga de UdC"
msgctxt "model:carrier.load_uls.order,name:"
msgid "Carrier load unit load"
msgstr "Carga de UdC"
msgctxt "model:ir.action,name:wizard_global_load_ul"
msgid "Start loading"
msgstr "Iniciar carga"
msgctxt "model:ir.action,name:wizard_load_ul"
msgid "Start loading"
msgstr "Iniciar carga"
msgctxt "model:ir.ui.menu,name:menu_start_loading"
msgid "Start loading"
msgstr "Iniciar carga"
msgctxt "wizard_button:carrier.load_uls,data,add_:"
msgid "Add"
msgstr "Añadir"
msgctxt "wizard_button:carrier.load_uls,data,do_:"
msgid "Do"
msgstr "Finalizar"
msgctxt "wizard_button:carrier.load_uls,data,end:"
msgid "Exit"
msgstr "Salir"
msgctxt "wizard_button:carrier.load_uls,order,data:"
msgid "OK"
msgstr "Aceptar"
msgctxt "wizard_button:carrier.load_uls,order,end:"
msgid "Cancel"
msgstr "Cancelar"
msgctxt "view:carrier.load.order:"
msgid "ULs"
msgstr "UdCs"
msgctxt "view:carrier.load.order:"
msgid "Start loading"
msgstr "Iniciar carga"
msgctxt "view:carrier.load_uls.data:"
msgid "UL Loading"
msgstr "Carga de UdCs"
msgctxt "view:carrier.load_uls.data:"
msgid "Loaded"
msgstr "Cargado"
msgctxt "view:carrier.load_uls.data:"
msgid "To load"
msgstr "A cargar"
msgctxt "view:carrier.load_uls.order:"
msgid "UL Loading"
msgstr "Carga de UdCs"
msgctxt "view:stock.unit_load:"
msgid "Unit loads"
msgstr "Unidades de carga"
msgctxt "view:stock.unit_load:"
msgid "Unload"
msgstr "Descargar"

193
tests/scenario_load_ul.rst Normal file
View File

@ -0,0 +1,193 @@
==============
Carrier load
==============
Imports::
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> from decimal import Decimal
>>> from trytond.modules.company.tests.tools import create_company, \
... get_company
>>> from trytond.modules.carrier_vehicle.tests.tools import create_carrier
>>> from trytond.modules.stock_unit_load.tests.tools import create_unit_load
>>> from proteus import config, Model, Wizard
>>> today = datetime.date.today()
Create database::
>>> config = config.set_trytond()
>>> config.pool.test = True
Install agro Module::
>>> Module = Model.get('ir.module.module')
>>> module, = Module.find([('name', '=', 'carrier_load_ul')])
>>> module.click('install')
>>> Wizard('ir.module.module.install_upgrade').execute('upgrade')
Create company::
>>> _ = create_company()
>>> company = get_company()
Reload the context::
>>> User = Model.get('res.user')
>>> Group = Model.get('res.group')
>>> config._context = User.get_preferences(True, config.context)
Create carrier::
>>> carrier = create_carrier(config)
Create carrier load::
>>> Load = Model.get('carrier.load')
>>> load = Load()
>>> load.company != None
True
>>> load.state
'draft'
>>> load.date == today
True
>>> load.warehouse != None
True
>>> load.warehouse_output == load.warehouse.output_location
True
>>> load.output_location = load.warehouse_output
>>> load.carrier = carrier
>>> load.vehicle != None
True
>>> load.save()
>>> load.code != None
True
Create load order::
>>> Order = Model.get('carrier.load.order')
>>> order = Order(load=load)
>>> order.state
'draft'
>>> order.ul_origin_restrict
True
>>> line = order.lines.new()
>>> line.ul_quantity = Decimal(1)
>>> order.save()
>>> order.code != None
True
>>> order.date == load.date
True
>>> order.click('wait')
>>> order.state
u'waiting'
Create unit load::
>>> Unitload = Model.get('stock.unit_load')
>>> ul = create_unit_load(config=config, do_state=False)
Starting load wizard::
>>> start_load = Wizard('carrier.load_uls', [])
>>> start_load.form.load_order = order
>>> start_load.execute('data')
>>> start_load.form.load_order == order
True
>>> len(start_load.form.uls_loaded)
0
>>> start_load.form.loaded_uls
0
>>> start_load.form.ul_code = 'X'
>>> start_load.execute('add_') # doctest:
Traceback (most recent call last):
...
UserError: ('UserError', ('Cannot find Unit load "X".', ''))
Check UL loading restrictions::
>>> start_load.form.ul_code = ul.code
>>> start_load.execute('add_') # doctest:
Traceback (most recent call last):
...
UserError: ('UserError', (u'UL "1" must be in Done state.', ''))
>>> ul.click('do')
>>> start_load.execute('add_') # doctest:
Traceback (most recent call last):
...
UserError: ('UserError', (u'UL "1" does not belong to any origin of this load order.', ''))
>>> order.ul_origin_restrict = False
>>> order.save()
>>> start_load.execute('add_') # doctest:
Traceback (most recent call last):
...
UserWarning: ('UserWarning', ('loading_ul_origin_1', u'UL "1" does not belong to any origin of this load order.', ''))
>>> Model.get('res.user.warning')(user=config.user,
... name='loading_ul_origin_1', always=True).save()
>>> start_load.execute('add_')
>>> start_load.form.loaded_uls
1
>>> order.reload()
>>> order.state
u'running'
>>> order.start_date != None
True
>>> len(order.unit_loads)
1
>>> start_load.form.ul_code = ul.code
>>> start_load.execute('add_') # doctest:
Traceback (most recent call last):
...
UserError: ('UserError', (u'UL "1" is already loaded.', ''))
Add an invalid UL::
>>> Location = Model.get('stock.location')
>>> lost_found, = Location.find([('type', '=', 'lost_found')], limit=1)
>>> ul2 = create_unit_load(do_state=False)
>>> ul2.moves[0].to_location = lost_found
>>> ul2.save()
>>> ul2.click('do')
>>> start_load.form.ul_code = ul2.code
>>> start_load.execute('add_') # doctest:
Traceback (most recent call last):
...
UserError: ('UserError', (u'UL "2" must be in a storage location.', ''))
>>> move_ul = Wizard('stock.unit_load.do_move', [ul2])
>>> move_ul.form.location = ul.location
>>> move_ul.execute('move_')
>>> ul2.reload()
>>> ul2.click('do')
>>> Model.get('res.user.warning')(user=config.user,
... name='loading_ul_origin_2', always=True).save()
>>> start_load.execute('add_') # doctest:
Traceback (most recent call last):
...
UserError: ('UserError', (u'All valid lines of load order "1" are complete. Cannot load more ULs.', ''))
Unload UL::
>>> order.lines[0].ul_quantity += 1
>>> order.save()
>>> start_load.execute('add_')
>>> start_load.execute('end')
>>> order.reload()
>>> len(order.unit_loads)
2
>>> ul2.click('unload')
>>> order.reload()
>>> len(order.unit_loads)
1
>>> ul2.load_line == None
True
Finish loading::
>>> start_load = Wizard('carrier.load_uls', [order])
>>> start_load.execute('do_')
>>> order.reload()
>>> len(order.unit_loads)
1
>>> order.state
u'done'

View File

@ -1,11 +1,10 @@
# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
import unittest
# import doctest
import doctest
import trytond.tests.test_tryton
from trytond.tests.test_tryton import ModuleTestCase
# TODO: Remove if no sceneario needed.
# from trytond.tests.test_tryton import doctest_setup, doctest_teardown
from trytond.tests.test_tryton import doctest_setup, doctest_teardown
class CarrierTestCase(ModuleTestCase):
@ -19,9 +18,8 @@ class CarrierTestCase(ModuleTestCase):
def suite():
suite = trytond.tests.test_tryton.suite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(CarrierTestCase))
# TODO: remove if no scenario needed.
# suite.addTests(doctest.DocFileSuite(
# 'scenario_load.rst',
# setUp=doctest_setup, tearDown=doctest_teardown, encoding='utf-8',
# optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
suite.addTests(doctest.DocFileSuite(
'scenario_load_ul.rst',
setUp=doctest_setup, tearDown=doctest_teardown, encoding='utf-8',
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
return suite

View File

@ -13,7 +13,6 @@ class UnitLoad:
load_line = fields.Many2One('carrier.load.order.line', 'Load line')
@classmethod
def __setup__(cls):
super(UnitLoad, cls).__setup__()

View File

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!-- The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/form" position="inside">
<label name="ul_origin_restrict"/>
<field name="ul_origin_restrict"/>
</xpath>
</data>

View File

@ -2,8 +2,12 @@
<!-- The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/form/notebook" position="before">
<label name="ul_origin_restrict"/>
<field name="ul_origin_restrict"/>
</xpath>
<xpath expr="/form/notebook" position="inside">
<page id="uls" string="Unit loads">
<page id="uls" string="ULs">
<field name="unit_loads" colspan="4"/>
</page>
</xpath>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!-- The COPYRIGHT file at the top level of this repository contains the full
copyright notices and license terms. -->
<form string="Loading" cursor="ul_code" col="2">
<form string="UL Loading" cursor="ul_code" col="2">
<label name="load_order"/>
<field name="load_order"/>
<label name="ul_code"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!-- The COPYRIGHT file at the top level of this repository contains the full
copyright notices and license terms. -->
<form string="Loading">
<form string="UL Loading">
<label name="load_order"/>
<field name="load_order"/>
</form>