trytond-stock_unit_load/stock.py

144 lines
4.2 KiB
Python

# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from functools import wraps
from trytond.pool import PoolMeta, Pool
from trytond.model import fields, Workflow
from trytond.pyson import Bool, Eval, Or
from trytond.exceptions import UserError
from trytond.i18n import gettext
from trytond.transaction import Transaction
from itertools import groupby
def set_unit_load_shipment(func):
@wraps(func)
def wrapper(cls, moves):
pool = Pool()
UnitLoad = pool.get('stock.unit_load')
uls_to_save = list(set([move.unit_load for move in moves
if move.unit_load]))
func(cls, moves)
if uls_to_save and not Transaction().context.get(
'skip_set_unit_load', False):
UnitLoad.set_state(uls_to_save)
UnitLoad.set_shipment(uls_to_save)
return wrapper
def set_unit_load_state(func):
@wraps(func)
def wrapper(cls, moves):
pool = Pool()
UnitLoad = pool.get('stock.unit_load')
uls_to_save = list(set([move.unit_load for move in moves
if move.unit_load]))
func(cls, moves)
if uls_to_save and not Transaction().context.get(
'skip_set_unit_load', False):
UnitLoad.set_state(uls_to_save)
return wrapper
class Move(metaclass=PoolMeta):
__name__ = 'stock.move'
unit_load = fields.Many2One('stock.unit_load', 'Unit load',
ondelete='RESTRICT', select=True, states={
'readonly': Bool(True)
})
@classmethod
def __setup__(cls):
super().__setup__()
for button in ['draft', 'cancel', 'assign', 'do']:
if cls._buttons[button].get('readonly'):
cls._buttons[button]['readonly'] |= Bool(Eval('unit_load'))
else:
cls._buttons[button]['readonly'] = Bool(Eval('unit_load'))
cls._buttons[button]['depends'].append('unit_load')
@classmethod
def validate(cls, records):
super(Move, cls).validate(records)
for record in records:
if record.unit_load and record.time_ is None:
raise UserError(gettext(
'stock_unit_load.msg_stock_move_ul_time_required'))
@classmethod
@set_unit_load_state
def draft(cls, moves):
# Save unit-load moves effective_date
ul_moves = [m for m in moves if m.effective_date and m.unit_load]
ul_moves.sort(key=lambda x: x.effective_date)
to_update = []
for ef_date, ef_moves in groupby(ul_moves, lambda x: x.effective_date):
to_update.extend([list(ef_moves), {'effective_date': ef_date}])
super().draft(moves)
if to_update:
cls.write(*to_update)
@classmethod
@set_unit_load_shipment
@Workflow.transition('assigned')
def assign(cls, moves):
super().assign(moves)
@classmethod
@set_unit_load_shipment
@Workflow.transition('done')
def do(cls, moves):
super().do(moves)
@classmethod
@set_unit_load_shipment
@Workflow.transition('cancelled')
def cancel(cls, moves):
super().cancel(moves)
@classmethod
@set_unit_load_shipment
def delete(cls, moves):
super().delete(moves)
@classmethod
def _get_origin(cls):
origins = super()._get_origin()
return origins + ['stock.unit_load']
@classmethod
def create(cls, vlist):
moves = super().create(vlist)
uls = list(set([move.unit_load for move in moves if move.unit_load]))
if uls:
UnitLoad = Pool().get('stock.unit_load')
UnitLoad.set_state(uls)
return moves
@classmethod
def init_end_date(cls):
pool = Pool()
Configuration = pool.get('production.configuration')
conf = Configuration(1)
if conf.propose_drop_end_date == 'last_drop':
return False
return super().init_end_date()
class Move2(metaclass=PoolMeta):
__name__ = 'stock.move'
@fields.depends('state', 'origin', 'shipment', 'unit_load',
'_parent_unit_load.id')
def on_change_with_cancelation_allowed(self, name=None):
res = super(Move, self).on_change_with_cancelation_allowed(name=name)
return res and not self.unit_load