Add unit loads to internal shipment.

This commit is contained in:
Sergio Morillo 2016-09-05 18:18:08 +02:00
parent e1dfb7b701
commit 8f72f35be7
7 changed files with 287 additions and 3 deletions

View File

@ -8,7 +8,7 @@ from .unit_load import (UnitLoad, UnitLoadMove, MoveUnitLoad,
BatchDropUnitLoad, BatchDropUnitLoadData, BatchDropUnitLoadConfirm)
from .stock import (Move, UnitLoadsByLocations,
UnitLoadsByLocationsStart)
from .shipment import ShipmentOut
from .shipment import ShipmentOut, ShipmentInternal
def register():
@ -23,6 +23,7 @@ def register():
DropUnitLoadFailedProduct,
UnitLoadsByLocationsStart,
ShipmentOut,
ShipmentInternal,
BatchDropUnitLoadData,
BatchDropUnitLoadConfirm,
module='stock_unit_load', type_='model')

View File

@ -538,10 +538,22 @@ msgctxt "view:stock.unit_loads_by_locations.start:"
msgid "Unit loads by Locations"
msgstr "Unidades de carga por ubicación"
msgctxt "field:stock.shipment.out,unit_loads:"
msgid "Unit loads"
msgstr "Unidades de carga"
msgctxt "view:stock.shipment.out:"
msgid "ULs"
msgstr "UdCs"
msgctxt "field:stock.shipment.internal,unit_loads:"
msgid "Unit loads"
msgstr "Unidades de carga"
msgctxt "view:stock.shipment.internal:"
msgid "ULs"
msgstr "UdCs"
msgctxt "view:stock.unit_load.move:"
msgid "Start Time"
msgstr "Hora inicio"

View File

@ -5,7 +5,7 @@ from trytond.model import fields
from trytond.pool import PoolMeta, Pool
from trytond.pyson import Eval
__all__ = ['ShipmentOut']
__all__ = ['ShipmentOut', 'ShipmentInternal']
class ShipmentOut:
@ -69,4 +69,61 @@ class ShipmentOut:
location = move.unit_load.get_location([move.unit_load], type='storage')[move.unit_load.id]
res.from_location = location
res.unit_load = move.unit_load
return res
return res
class ShipmentInternal:
__name__ = 'stock.shipment.internal'
__metaclass__ = PoolMeta
unit_loads = fields.Function(
fields.One2Many('stock.unit_load', None, 'Unit loads',
states={'readonly': Eval('state') != 'draft'},
depends=['state']),
'get_unit_loads', setter='set_unit_loads', searcher='search_unit_loads')
@classmethod
def __setup__(cls):
super(ShipmentInternal, cls).__setup__()
for _field_name in ('moves', ):
_field = getattr(cls, _field_name)
if _field.states.get('readonly'):
_field.states['readonly'] |= Eval('unit_loads')
else:
_field.states['readonly'] = Eval('unit_loads')
if 'unit_loads' not in _field.depends:
_field.depends.append('unit_loads')
def get_unit_loads(self, name=None):
if not self.moves:
return []
uls = set(m.unit_load.id for m in self.moves if m.unit_load)
return list(uls)
@classmethod
def set_unit_loads(cls, records, name, value):
pass
@classmethod
def search_unit_loads(cls, name, clause):
_field = 'moves.unit_load'
if '.' in name:
_field += '.%s' % name[10:]
return [(_field,) + tuple(clause[1:])]
@fields.depends('unit_loads', 'moves', 'date_time_',
'from_location', 'to_location')
def on_change_unit_loads(self):
moves = []
ul_ids = [ul.id for ul in self.unit_loads]
if self.moves:
moves.extend(
[m for m in self.moves if m.unit_load.id in ul_ids])
for ul in self.unit_loads:
if ul.id in [m.unit_load.id for m in moves]:
continue
new_moves = ul._move(self.to_location,
self.date_time_,
from_location=self.from_location)
moves.extend(new_moves)
self.moves = moves

View File

@ -10,6 +10,13 @@ this repository contains the full copyright notices and license terms. -->
<field name="inherit" ref="stock.shipment_out_view_form"/>
</record>
<!-- Shipment internal -->
<record model="ir.ui.view" id="shipment_internal_view_form">
<field name="model">stock.shipment.internal</field>
<field name="name">shipment_internal_form</field>
<field name="inherit" ref="stock.shipment_internal_view_form"/>
</record>
<!-- form relate -->
<record model="ir.action.act_window" id="act_unit_loads_shipment_out">
<field name="name">Shipment Out</field>

View File

@ -0,0 +1,188 @@
========================
Check unit load creation
========================
Imports::
>>> import datetime
>>> from proteus import config, Model, Wizard, Report
>>> from dateutil.relativedelta import relativedelta
>>> from decimal import Decimal
>>> from trytond.modules.company.tests.tools import create_company, \
... get_company
>>> today = datetime.date.today()
>>> tomorrow = today + relativedelta(days=1)
>>> time_ = datetime.datetime.now().time()
>>> time_ = time_.replace(microsecond=0)
Create database::
>>> config = config.set_trytond()
>>> config.pool.test = True
Install unit load Module::
>>> Module = Model.get('ir.module')
>>> module, = Module.find([('name', '=', 'stock_unit_load')])
>>> module.click('install')
>>> Wizard('ir.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 product::
>>> ProductUom = Model.get('product.uom')
>>> ProductTemplate = Model.get('product.template')
>>> Product = Model.get('product.product')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> product = Product()
>>> template = ProductTemplate()
>>> template.name = 'Product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.list_price = Decimal('20')
>>> template.cost_price = Decimal('8')
>>> template.save()
>>> product.template = template
>>> product.save()
Get stock locations::
>>> Location = Model.get('stock.location')
>>> production_loc, = Location.find([('type', '=', 'production')])
>>> warehouse_loc, = Location.find([('code', '=', 'WH')])
>>> storage_loc, = Location.find([('code', '=', 'STO')])
>>> output_loc, = Location.find([('code', '=', 'OUT')])
>>> wh2, = warehouse_loc.duplicate()
>>> wh2.name = 'Warehouse 2'
>>> wh2.code = 'WH2'
>>> wh2.save()
Create an unit load::
>>> UnitLoad = Model.get('stock.unit_load')
>>> unit_load = UnitLoad()
>>> unit_load.company != None
True
>>> unit_load.start_date != None
True
>>> unit_load.end_date != None
True
>>> unit_load.end_date = unit_load.start_date + relativedelta(minutes=5)
>>> unit_load.production_type = 'location'
>>> unit_load.production_location = output_loc
>>> unit_load.product = product
>>> unit_load.cases_quantity = 5
>>> len(unit_load.production_moves)
0
>>> unit_load.save() # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
UserError: ...
>>> unit_load.production_location = production_loc
>>> unit_load.save()
>>> unit_load.code != None
True
Add moves::
>>> unit_load.production_state
'running'
>>> unit_load.quantity = Decimal('35.0')
>>> len(unit_load.production_moves)
1
>>> move = unit_load.production_moves[0]
>>> move.planned_date == today
True
>>> move.product == unit_load.product
True
>>> move.quantity
35.0
>>> move.from_location == production_loc
True
>>> not move.to_location
True
>>> move.to_location = storage_loc
>>> move.currency == unit_load.company.currency
True
>>> unit_load.save()
>>> unit_load.state
u'draft'
>>> unit_load.production_state
'running'
>>> len(unit_load.moves)
1
>>> len(unit_load.production_moves)
1
>>> unit_load.production_moves[0].state
u'draft'
>>> unit_load.internal_quantity
35.0
>>> unit_load.quantity_per_case
7.0
Check computed fields::
>>> unit_load.location.code
u'STO'
>>> len(unit_load.last_moves) == 1
True
>>> unit_load.click('assign')
>>> unit_load.state
u'assigned'
>>> unit_load.moves[0].state
u'assigned'
>>> unit_load.production_state
'running'
>>> len(unit_load.ul_moves)
1
>>> unit_load.uom.rec_name
u'Unit'
>>> unit_load.save()
>>> unit_load.click('do')
Create a shipment internal::
>>> ShipmentInternal = Model.get('stock.shipment.internal')
>>> shipment_internal = ShipmentInternal()
>>> shipment_internal.company = company
>>> shipment_internal.date_time_ = datetime.datetime.now() + relativedelta(minutes=10)
>>> shipment_internal.from_location = unit_load.location
>>> shipment_internal.to_location = wh2.storage_location
Add Unit load::
>>> shipment_internal.unit_loads.append(unit_load)
>>> len(shipment_internal.moves)
1
>>> shipment_internal.moves[0].unit_load.id == unit_load.id
True
>>> shipment_internal.save()
>>> shipment_internal.click('wait')
>>> len(shipment_internal.moves)
1
>>> shipment_internal.moves[0].unit_load.id == unit_load.id
True
>>> shipment_internal.click('assign_try')
True
>>> shipment_internal.click('done')
Check unit load state::
>>> unit_load.reload()
>>> len(unit_load.ul_moves)
2
>>> unit_load.state
u'done'
>>> unit_load.location.id == wh2.storage_location.id
True

View File

@ -30,5 +30,9 @@ def suite():
'scenario_batch_drop.rst',
setUp=doctest_setup, tearDown=doctest_teardown, encoding='utf-8',
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
suite.addTests(doctest.DocFileSuite(
'scenario_shipment_internal.rst',
setUp=doctest_setup, tearDown=doctest_teardown, encoding='utf-8',
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
# TODO: uls by locations wizard
return suite

View File

@ -0,0 +1,15 @@
<?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/field[@name='moves']" position="replace">
<notebook>
<page id="uls" string="ULs">
<field name="unit_loads" colspan="4" widget="many2many"/>
</page>
<page id="moves" string="Moves">
<field name="moves" colspan="4"/>
</page>
</notebook>
</xpath>
</data>