Extend carrier configuration to control loaded uls and/or loaded cases.
This commit refs #25499
This commit is contained in:
parent
6698047ab0
commit
e7e8b8ecec
102
load.py
102
load.py
|
@ -3,12 +3,11 @@
|
|||
from functools import partial
|
||||
from itertools import groupby
|
||||
from decimal import Decimal
|
||||
from trytond.rpc import RPC
|
||||
from sql import Null
|
||||
from sql.operators import Concat
|
||||
from trytond.model import fields, ModelView, Model, ModelSQL, Unique, Workflow
|
||||
from trytond.pool import PoolMeta, Pool
|
||||
from trytond.pyson import Eval, Bool, Id
|
||||
from trytond.pyson import Eval, Bool, Id, If, In
|
||||
from trytond.tools import reduce_ids
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.wizard import Wizard, StateTransition, StateView, Button, \
|
||||
|
@ -17,6 +16,7 @@ from trytond.exceptions import UserError, UserWarning
|
|||
from trytond.i18n import gettext
|
||||
from .exceptions import (AddUnitLoadError, AddUnitLoadWarning,
|
||||
AddUnitLoadOverloadError, AddUnitLoadOriginError, AddUnitLoadOriginWarning)
|
||||
from trytond.modules.stock_unit_load import cases_digits
|
||||
try:
|
||||
import phonenumbers
|
||||
from phonenumbers import PhoneNumberFormat, NumberParseException
|
||||
|
@ -29,11 +29,19 @@ class Configuration(metaclass=PoolMeta):
|
|||
|
||||
ul_origin_restrict = fields.Boolean('Restrict UL origin',
|
||||
help='Restricts origin of UL when loading in a Load order.')
|
||||
quantity_check = fields.MultiSelection([
|
||||
('uls', 'ULs'),
|
||||
('cases', 'Cases'),
|
||||
], "Quantity Check", sort=False)
|
||||
|
||||
@classmethod
|
||||
def default_ul_origin_restrict(cls):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def default_quantity_check(cls):
|
||||
return ['uls']
|
||||
|
||||
|
||||
class Load(metaclass=PoolMeta):
|
||||
__name__ = 'carrier.load'
|
||||
|
@ -91,6 +99,12 @@ class LoadOrder(metaclass=PoolMeta):
|
|||
'get_ul_quantity')
|
||||
loaded_uls = fields.Function(fields.Float('Loaded ULs', digits=(16, 0)),
|
||||
'get_loaded_uls')
|
||||
loaded_cases = fields.Function(
|
||||
fields.Float('Loaded Cases', digits=cases_digits),
|
||||
'get_loaded_cases')
|
||||
cases_quantity = fields.Function(
|
||||
fields.Float('Cases', digits=cases_digits),
|
||||
'get_cases_quantity')
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
|
@ -145,6 +159,16 @@ class LoadOrder(metaclass=PoolMeta):
|
|||
return 0
|
||||
return len(self.unit_loads)
|
||||
|
||||
def get_loaded_cases(self, name=None):
|
||||
if not self.unit_loads:
|
||||
return 0
|
||||
return sum(ul.cases_quantity for ul in self.unit_loads)
|
||||
|
||||
def get_cases_quantity(self, name=None):
|
||||
if not self.lines:
|
||||
return 0
|
||||
return sum(l.cases_quantity for l in self.lines)
|
||||
|
||||
@classmethod
|
||||
def set_unit_loads(cls, records, name, value):
|
||||
pass
|
||||
|
@ -414,19 +438,30 @@ class LoadOrder(metaclass=PoolMeta):
|
|||
def _check_loaded_quantity(cls, records):
|
||||
pool = Pool()
|
||||
Warning = pool.get('res.user.warning')
|
||||
Configuration = pool.get('carrier.configuration')
|
||||
|
||||
conf = Configuration(1)
|
||||
for record in records:
|
||||
if not record.unit_loads:
|
||||
raise UserError(gettext(
|
||||
'carrier_load_ul.msg_carrier_load_order_no_uls',
|
||||
order=record.rec_name))
|
||||
if record.ul_quantity > len(record.unit_loads):
|
||||
if ('uls' in conf.quantity_check
|
||||
and record.ul_quantity > record.loaded_uls):
|
||||
warning_name = 'pending_uls_%s' % record.id
|
||||
if Warning.check(warning_name):
|
||||
raise UserWarning(warning_name, gettext(
|
||||
'carrier_load_ul.msg_carrier_load_order_pending_uls',
|
||||
uls=len(record.unit_loads),
|
||||
uls=record.loaded_uls,
|
||||
ul_quantity=int(record.ul_quantity)))
|
||||
if ('cases' in conf.quantity_check
|
||||
and record.cases_quantity > record.loaded_cases):
|
||||
warning_name = 'pending_cases_%s' % record.id
|
||||
if Warning.check(warning_name):
|
||||
raise UserWarning(warning_name, gettext(
|
||||
'carrier_load_ul.msg_carrier_load_order_pending_cases',
|
||||
loaded_cases=record.loaded_cases,
|
||||
cases_quantity=record.cases_quantity))
|
||||
|
||||
@classmethod
|
||||
def _set_loaded_unit_loads(cls, records, revert=False):
|
||||
|
@ -583,14 +618,26 @@ class LoadOrder(metaclass=PoolMeta):
|
|||
order=self.rec_name))
|
||||
|
||||
def _choose_matched_line(self, lines, values, unit_load):
|
||||
pool = Pool()
|
||||
Configuration = pool.get('carrier.configuration')
|
||||
configuration = Configuration(1)
|
||||
|
||||
line = None
|
||||
for _line in lines:
|
||||
if _line.id not in values:
|
||||
values.setdefault(_line.id, set(
|
||||
ul for ul in _line.unit_loads))
|
||||
if _line.ul_quantity - len(values[_line.id]) > 0:
|
||||
line = _line
|
||||
break
|
||||
if 'uls' in configuration.quantity_check:
|
||||
if _line.ul_quantity - len(values[_line.id]) <= 0:
|
||||
continue
|
||||
if ('cases' in configuration.quantity_check
|
||||
and _line.cases_quantity):
|
||||
cases = sum(ul.cases_quantity for ul in values[_line.id])
|
||||
if round(_line.cases_quantity - cases, cases_digits[1]) <= 0:
|
||||
continue
|
||||
line = _line
|
||||
break
|
||||
|
||||
if line:
|
||||
values[line.id].add(unit_load)
|
||||
return line
|
||||
|
@ -670,9 +717,14 @@ class LoadOrder(metaclass=PoolMeta):
|
|||
class LoadOrderLine(metaclass=PoolMeta):
|
||||
__name__ = 'carrier.load.order.line'
|
||||
|
||||
quantity_check = fields.Function(
|
||||
fields.MultiSelection('_quantity_check_selection', "Quantity Check"),
|
||||
'get_quantity_check')
|
||||
ul_quantity = fields.Float('ULs', digits=(16, 0),
|
||||
domain=[('ul_quantity', '>=', Eval('loaded_uls'))],
|
||||
depends=['loaded_uls'])
|
||||
domain=[If(Eval('quantity_check', []).contains('uls'),
|
||||
('ul_quantity', '>=', Eval('loaded_uls')),
|
||||
())],
|
||||
depends=['loaded_uls', 'quantity_check'])
|
||||
quantity_per_ul = fields.Function(
|
||||
fields.Float('Quantity per UL', digits=(16, Eval('unit_digits', 0)),
|
||||
depends=['unit_digits']),
|
||||
|
@ -682,13 +734,19 @@ class LoadOrderLine(metaclass=PoolMeta):
|
|||
'invisible': Eval('order_state') == 'done'
|
||||
}, depends=['order_state'])
|
||||
loaded_uls = fields.Function(fields.Float('Loaded ULs', digits=(16, 0)),
|
||||
'get_loaded_uls')
|
||||
'get_loaded_uls')
|
||||
loaded_unit_loads = fields.Many2Many(
|
||||
'carrier.load.order.line-stock.unit_load', 'load_line', 'unit_load',
|
||||
'Loaded unit loads', readonly=True,
|
||||
states={
|
||||
'invisible': Eval('order_state') != 'done'
|
||||
}, depends=['order_state'])
|
||||
loaded_cases = fields.Function(
|
||||
fields.Float("Loaded Cases", digits=cases_digits),
|
||||
'get_loaded_cases')
|
||||
cases_quantity = fields.Function(
|
||||
fields.Float("Cases", digits=cases_digits),
|
||||
'get_cases_quantity')
|
||||
|
||||
@fields.depends('quantity', 'ul_quantity', 'uom')
|
||||
def on_change_with_quantity_per_ul(self, name=None):
|
||||
|
@ -704,6 +762,30 @@ class LoadOrderLine(metaclass=PoolMeta):
|
|||
def default_loaded_uls(cls):
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
def _quantity_check_selection(cls):
|
||||
Configuration = Pool().get('carrier.configuration')
|
||||
return Configuration.quantity_check.selection
|
||||
|
||||
def get_quantity_check(self, name=None):
|
||||
pool = Pool()
|
||||
Configuration = pool.get('carrier.configuration')
|
||||
configuration = Configuration(1)
|
||||
return configuration.quantity_check
|
||||
|
||||
def get_loaded_cases(self, name=None):
|
||||
if self.order_state == 'done':
|
||||
return sum([ul.cases_quantity for ul in self.loaded_unit_loads])
|
||||
else:
|
||||
return sum([ul.cases_quantity for ul in self.unit_loads])
|
||||
|
||||
def get_cases_quantity(self, name=None):
|
||||
ul_cases = self.origin and getattr(
|
||||
self.origin, 'ul_cases_quantity', 0) or 0
|
||||
# we use origin.ul_cases_quantity instead origin.cases_quantity
|
||||
# because we can define less ULs in load than origin
|
||||
return round(ul_cases * self.ul_quantity, cases_digits[1])
|
||||
|
||||
def get_loaded_uls(self, name=None):
|
||||
if self.order_state == 'done':
|
||||
return len(self.loaded_unit_loads or [])
|
||||
|
|
26
locale/es.po
26
locale/es.po
|
@ -83,6 +83,10 @@ msgctxt "model:ir.message,text:msg_carrier_load_order_pending_uls"
|
|||
msgid "You have loaded less ULs (%(uls)s) than expected (%(ul_quantity)s)."
|
||||
msgstr "Ha cargado menos UdCs (%(uls)s) de las esperadas (%(ul_quantity)s)."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_carrier_load_order_pending_cases"
|
||||
msgid "You have loaded less Cases (%(loaded_cases)s) than expected (%(cases_quantity)s)."
|
||||
msgstr "Ha cargado menos bultos (%(loaded_cases)s) de los esperados (%(cases_quantity)s)."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_carrier_load_order_many_ul_locations"
|
||||
msgid ""
|
||||
"Cannot set \"From location\" in Internal shipment of Load Order \"%(order)s\" because Unit loads are in different locations."
|
||||
|
@ -149,6 +153,10 @@ msgctxt "field:carrier.configuration,ul_origin_restrict:"
|
|||
msgid "Restrict UL origin"
|
||||
msgstr "Restringir origen UdC"
|
||||
|
||||
msgctxt "field:carrier.configuration,quantity_check:"
|
||||
msgid "Quantity Check"
|
||||
msgstr "Control de cantidad"
|
||||
|
||||
msgctxt "field:carrier.load,unit_loads:"
|
||||
msgid "Unit loads"
|
||||
msgstr "Unidades de carga"
|
||||
|
@ -249,6 +257,14 @@ msgctxt "field:carrier.load.order.line,loaded_uls:"
|
|||
msgid "Loaded ULs"
|
||||
msgstr "UdCs cargadas"
|
||||
|
||||
msgctxt "field:carrier.load.order.line,quantity_check:"
|
||||
msgid "Quantity Check"
|
||||
msgstr "Control de cantidad"
|
||||
|
||||
msgctxt "field:carrier.load.order.line,loaded_cases:"
|
||||
msgid "Loaded Cases"
|
||||
msgstr "Bultos cargados"
|
||||
|
||||
msgctxt "field:carrier.load.order.line,quantity_per_ul:"
|
||||
msgid "Quantity per UL"
|
||||
msgstr "Cantidad por UdC"
|
||||
|
@ -676,4 +692,12 @@ msgstr "Ordenes de carga"
|
|||
|
||||
msgctxt "model:ir.action,name:wizard_load_order_do_open"
|
||||
msgid "Do Load Order and Open form"
|
||||
msgstr "Finalizar Orden de cargay abrir formulario"
|
||||
msgstr "Finalizar Orden de cargay abrir formulario"
|
||||
|
||||
msgctxt "selection:carrier.configuration,quantity_check:"
|
||||
msgid "Cases"
|
||||
msgstr "Bultos"
|
||||
|
||||
msgctxt "selection:carrier.configuration,quantity_check:"
|
||||
msgid "ULs"
|
||||
msgstr "UdCs"
|
|
@ -64,6 +64,9 @@
|
|||
<record model="ir.message" id="msg_carrier_load_order_pending_uls">
|
||||
<field name="text">You have loaded less ULs (%(uls)s) than expected (%(ul_quantity)s).</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_carrier_load_order_pending_cases">
|
||||
<field name="text">You have loaded less Cases (%(loaded_cases)s) than expected (%(cases_quantity)s).</field>
|
||||
</record>
|
||||
|
||||
<!-- carrier.load.order.line-stock.unit_load -->
|
||||
<record model="ir.message" id="msg_carrier_load_order_line-stock_unit_load_load_line_ul_uniq">
|
||||
|
|
|
@ -70,6 +70,15 @@ Create payment term::
|
|||
>>> payment_term = create_payment_term()
|
||||
>>> payment_term.save()
|
||||
|
||||
Carrier Configuration::
|
||||
|
||||
>>> Configuration = Model.get('carrier.configuration')
|
||||
>>> configuration = Configuration(1)
|
||||
>>> configuration.quantity_check
|
||||
['uls']
|
||||
>>> configuration.quantity_check = ['uls', 'cases']
|
||||
>>> configuration.save()
|
||||
|
||||
Create carrier::
|
||||
|
||||
>>> Carrier = Model.get('carrier')
|
||||
|
@ -177,7 +186,6 @@ Create sale::
|
|||
>>> sale_line.ul_quantity = 4.0
|
||||
>>> sale_line.cases_quantity = 20
|
||||
>>> sale.click('quote')
|
||||
>>> import logging
|
||||
>>> sale.click('confirm')
|
||||
>>> sale.click('process')
|
||||
Traceback (most recent call last):
|
||||
|
@ -339,9 +347,19 @@ Finish loading::
|
|||
...
|
||||
trytond.exceptions.UserError: Cannot Process Sale "1" with ULs and undone loads. -
|
||||
>>> start_load = Wizard('carrier.load_uls', [load_order])
|
||||
>>> start_load.execute('pre_do')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
trytond.exceptions.UserWarning: You have loaded less ULs (3) than expected (4). -
|
||||
>>> Model.get('res.user.warning')(user=config.user,
|
||||
... name='pending_uls_1', always=True).save()
|
||||
>>> start_load.execute('pre_do')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
trytond.exceptions.UserWarning: You have loaded less Cases (15.0) than expected (20.0). -
|
||||
>>> Model.get('res.user.warning')(user=config.user,
|
||||
... name='pending_cases_1', always=True).save()
|
||||
>>> start_load.execute('pre_do')
|
||||
>>> load_order.reload()
|
||||
>>> len(load_order.unit_loads)
|
||||
3
|
||||
|
|
|
@ -5,5 +5,7 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<xpath expr="/form/notebook/page[@id='general']" position="inside">
|
||||
<label name="ul_origin_restrict"/>
|
||||
<field name="ul_origin_restrict"/>
|
||||
<label name="quantity_check"/>
|
||||
<field name="quantity_check"/>
|
||||
</xpath>
|
||||
</data>
|
||||
|
|
Loading…
Reference in New Issue