Implement task.

This commit refs #857
This commit is contained in:
Sergio Morillo 2015-10-20 19:27:57 +02:00
parent feb2269f59
commit e32064d5f3
9 changed files with 135 additions and 9 deletions

View File

@ -6,6 +6,7 @@ from .unit_load import (UnitLoad, UnitLoadMove, MoveUnitLoad,
MoveUnitLoadStart)
from .stock import (Move, UnitLoadsByLocations,
UnitLoadsByLocationsStart)
from .shipment import ShipmentOut
def register():
@ -16,6 +17,7 @@ def register():
Move,
MoveUnitLoadStart,
UnitLoadsByLocationsStart,
ShipmentOut,
module='stock_unit_load', type_='model')
Pool.register(
MoveUnitLoad,

View File

@ -338,4 +338,8 @@ msgstr "Abrir"
msgctxt "view:stock.unit_loads_by_locations.start:"
msgid "Unit loads by Locations"
msgstr "Unidades de carga por ubicación"
msgstr "Unidades de carga por ubicación"
msgctxt "view:stock.shipment.out:"
msgid "ULs"
msgstr "UdCs"

69
shipment.py Normal file
View File

@ -0,0 +1,69 @@
# 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, Pool
from trytond.pyson import Eval
__metaclass__ = PoolMeta
__all__ = ['ShipmentOut']
class ShipmentOut:
__name__ = 'stock.shipment.out'
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(ShipmentOut, cls).__setup__()
for _field_name in ('inventory_moves', 'outgoing_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.outgoing_moves:
return []
uls = set(m.unit_load.id for m in self.outgoing_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', 'outgoing_moves')
def on_change_unit_loads(self):
moves = []
ul_ids = [ul.id for ul in self.unit_loads]
if self.outgoing_moves:
moves.extend([m for m in self.outgoing_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._get_new_moves({'from_location': self.warehouse_output.id,
'to_location': self.customer_location.id,
'planned_date': self.planned_date,
'effective_date': self.effective_date})
moves.extend(new_moves)
self.outgoing_moves = moves
def _get_inventory_move(self, move):
res = super(ShipmentOut, self)._get_inventory_move(move)
res.unit_load = move.unit_load
return res

14
shipment.xml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<!-- The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<!-- Shipment out -->
<record model="ir.ui.view" id="shipment_out_view_form">
<field name="model">stock.shipment.out</field>
<field name="type">form</field>
<field name="name">shipment_out_form</field>
<field name="inherit" ref="stock.shipment_out_view_form"/>
</record>
</data>
</tryton>

View File

@ -17,7 +17,8 @@ class Move:
__name__ = 'stock.move'
unit_load = fields.Many2One('stock.unit_load', 'Unit load',
ondelete='RESTRICT', select=True)
ondelete='RESTRICT', select=True,
readonly=True)
class UnitLoadsByLocationsStart(ModelView):

View File

@ -9,3 +9,4 @@ xml:
configuration.xml
unit_load.xml
stock.xml
shipment.xml

View File

@ -1,6 +1,8 @@
# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
import datetime
from functools import partial
from itertools import groupby
from sql import Literal, Null
from sql.aggregate import Max
from sql.conditionals import Coalesce
@ -105,6 +107,10 @@ class UnitLoad(ModelView, ModelSQL):
def get_code_readonly(self, name):
return True
@classmethod
def default_state(cls):
return 'draft'
@classmethod
def create(cls, vlist):
model_sequence = Pool().get('ir.sequence')
@ -381,17 +387,36 @@ class UnitLoad(ModelView, ModelSQL):
cls.raise_user_error('wrong_move_location', (record.rec_name, to_location.rec_name))
if max(m.planned_date or m.effective_date for m in record.last_moves) > at_date:
cls.raise_user_error('wrong_move_date', (record.rec_name, at_date))
new_moves = Move.copy(record.last_moves, {'origin': None,
'shipment': None,
'from_location': from_location.id,
'to_location': to_location.id,
'planned_date': at_date,
'effective_date': at_date})
new_moves = record._get_new_moves({'from_location': from_location.id,
'to_location': to_location.id,
'planned_date': at_date})
to_create.extend(new_moves)
if to_create:
Move.save(to_create)
return Move.browse(map(int, to_create))
def _get_new_moves(self, default_values={}):
pool = Pool()
Move = pool.get('stock.move')
Uom = pool.get('product.uom')
default_values.update({'origin': None,
'shipment': None,
'effective_date': default_values.get('planned_date') or None}
)
moves = []
keyfunc = partial(self._get_group_move_key, self.last_moves)
data = sorted(self.last_moves, key=keyfunc)
for key, grouped_moves in groupby(data, key=keyfunc):
_grouped_moves = list(grouped_moves)
move, = Move.copy([_grouped_moves[0]], default_values)
move.quantity = sum(Uom.compute_qty(m.uom, m.quantity, move.uom) for m in _grouped_moves)
moves.append(move)
return moves
def _get_group_move_key(self, moves, move):
return (move.to_location.id, move.product.id)
def get_state(self, name=None):
pool = Pool()
Move = pool.get('stock.move')

View File

@ -2,7 +2,7 @@
<!-- The COPYRIGHT file at the top level of this repository contains the full
copyright notices and license terms. -->
<data>
<xpath expr="/form" position="inside">
<xpath expr="/form/field[@name='effective_date']" position="after">
<label name="unit_load"/>
<field name="unit_load"/>
</xpath>

View File

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