Allow shipments to be automatically assigned
issue9513 review318011002
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
* Allow shipments to be automatically assigned
|
||||
* Rename inventory count quantity_added to quantity
|
||||
* Add document source on move of product quantities by warehouse
|
||||
* Add relate from assigned shipment to products quantities by warehouse
|
||||
|
||||
@@ -18,4 +18,8 @@ class Cron(metaclass=PoolMeta):
|
||||
"Reschedule Supplier Return Shipments"),
|
||||
('stock.shipment.internal|reschedule',
|
||||
"Reschedule Internal Shipments"),
|
||||
('stock.shipment.out|assign_cron',
|
||||
"Assign Customer Shipments"),
|
||||
('stock.shipment.internal|assign_cron',
|
||||
"Assign Internal Shipments"),
|
||||
])
|
||||
|
||||
@@ -301,7 +301,8 @@ class Move(Workflow, ModelSQL, ModelView):
|
||||
'on_change_with_cost_price_required')
|
||||
assignation_required = fields.Function(
|
||||
fields.Boolean('Assignation Required'),
|
||||
'on_change_with_assignation_required')
|
||||
'on_change_with_assignation_required',
|
||||
searcher='search_assignation_required')
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
@@ -488,6 +489,29 @@ class Move(Workflow, ModelSQL, ModelView):
|
||||
self.quantity
|
||||
and self.from_location.type in {'storage', 'view'})
|
||||
|
||||
@classmethod
|
||||
def search_assignation_required(cls, name, clause):
|
||||
operators = {
|
||||
'=': 'in',
|
||||
'!=': 'not in',
|
||||
}
|
||||
reverse = {
|
||||
'=': '!=',
|
||||
'!=': '=',
|
||||
}
|
||||
if clause[1] in operators:
|
||||
if not clause[2]:
|
||||
operator = reverse[clause[1]]
|
||||
else:
|
||||
operator = clause[1]
|
||||
return [
|
||||
('quantity', '!=', 0),
|
||||
('from_location.type', operators[operator], [
|
||||
'storage', 'view']),
|
||||
]
|
||||
else:
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def _get_shipment():
|
||||
'Return list of Model names for shipment Reference'
|
||||
|
||||
+53
-5
@@ -30,6 +30,12 @@ class ShipmentMixin:
|
||||
|
||||
|
||||
class ShipmentAssignMixin(ShipmentMixin):
|
||||
_assign_moves_field = None
|
||||
|
||||
partially_assigned = fields.Function(
|
||||
fields.Boolean("Partially Assigned"),
|
||||
'get_partially_assigned',
|
||||
searcher='search_partially_assigned')
|
||||
|
||||
@classmethod
|
||||
def assign_wizard(cls, shipments):
|
||||
@@ -37,7 +43,7 @@ class ShipmentAssignMixin(ShipmentMixin):
|
||||
|
||||
@property
|
||||
def assign_moves(self):
|
||||
raise NotImplementedError
|
||||
return getattr(self, self._assign_moves_field)
|
||||
|
||||
@dualmethod
|
||||
@ModelView.button
|
||||
@@ -65,6 +71,48 @@ class ShipmentAssignMixin(ShipmentMixin):
|
||||
})
|
||||
cls.assign(shipments)
|
||||
|
||||
@classmethod
|
||||
def _get_assign_domain(cls):
|
||||
pool = Pool()
|
||||
Date = pool.get('ir.date')
|
||||
return [
|
||||
('state', '=', 'waiting'),
|
||||
('planned_date', '=', Date.today()),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def assign_cron(cls):
|
||||
shipments = cls.search(cls._get_assign_domain())
|
||||
cls.assign_try(shipments)
|
||||
|
||||
def get_partially_assigned(self, name):
|
||||
return any(m.state == 'assigned' for m in self.assign_moves
|
||||
if m.assignation_required)
|
||||
|
||||
@classmethod
|
||||
def search_partially_assigned(cls, name, clause):
|
||||
operators = {
|
||||
'=': 'where',
|
||||
'!=': 'not where',
|
||||
}
|
||||
reverse = {
|
||||
'=': '!=',
|
||||
'!=': '=',
|
||||
}
|
||||
if clause[1] in operators:
|
||||
if not clause[2]:
|
||||
operator = reverse[clause[1]]
|
||||
else:
|
||||
operator = clause[1]
|
||||
return [
|
||||
(cls._assign_moves_field, operators[operator], [
|
||||
('state', '=', 'assigned'),
|
||||
('assignation_required', '=', True),
|
||||
]),
|
||||
]
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
class ShipmentIn(ShipmentMixin, Workflow, ModelSQL, ModelView):
|
||||
"Supplier Shipment"
|
||||
@@ -515,6 +563,8 @@ class ShipmentInReturn(ShipmentAssignMixin, Workflow, ModelSQL, ModelView):
|
||||
"Supplier Return Shipment"
|
||||
__name__ = 'stock.shipment.in.return'
|
||||
_rec_name = 'number'
|
||||
_assign_moves_field = 'moves'
|
||||
|
||||
effective_date = fields.Date('Effective Date',
|
||||
states={
|
||||
'readonly': Eval('state').in_(['cancelled', 'done']),
|
||||
@@ -830,10 +880,6 @@ class ShipmentInReturn(ShipmentAssignMixin, Workflow, ModelSQL, ModelView):
|
||||
def assign_wizard(cls, shipments):
|
||||
pass
|
||||
|
||||
@property
|
||||
def assign_moves(self):
|
||||
return self.moves
|
||||
|
||||
@dualmethod
|
||||
@ModelView.button
|
||||
def assign_try(cls, shipments, with_childs=None):
|
||||
@@ -880,6 +926,7 @@ class ShipmentOut(ShipmentAssignMixin, Workflow, ModelSQL, ModelView):
|
||||
"Customer Shipment"
|
||||
__name__ = 'stock.shipment.out'
|
||||
_rec_name = 'number'
|
||||
_assign_moves_field = 'moves'
|
||||
effective_date = fields.Date('Effective Date',
|
||||
states={
|
||||
'readonly': Eval('state').in_(['cancelled', 'done']),
|
||||
@@ -1934,6 +1981,7 @@ class ShipmentInternal(ShipmentAssignMixin, Workflow, ModelSQL, ModelView):
|
||||
"Internal Shipment"
|
||||
__name__ = 'stock.shipment.internal'
|
||||
_rec_name = 'number'
|
||||
_assign_moves_field = 'moves'
|
||||
effective_date = fields.Date('Effective Date',
|
||||
states={
|
||||
'readonly': Eval('state').in_(['cancelled', 'done']),
|
||||
|
||||
+36
-13
@@ -92,14 +92,6 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_in_return_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_shipment_in_return_form_domain_assigned">
|
||||
<field name="name">Assigned</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain" eval="[('state', '=', 'assigned')]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_in_return_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_shipment_in_return_form_domain_waiting">
|
||||
<field name="name">Waiting</field>
|
||||
@@ -108,6 +100,22 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_in_return_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_shipment_in_return_form_domain_available">
|
||||
<field name="name">Partially Assigned</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain" eval="[('partially_assigned', '=', 'True')]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_in_return_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_shipment_in_return_form_domain_assigned">
|
||||
<field name="name">Assigned</field>
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="domain" eval="[('state', '=', 'assigned')]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_in_return_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_shipment_in_return_form_domain_all">
|
||||
<field name="name">All</field>
|
||||
@@ -163,23 +171,30 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_out_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_shipment_out_form_domain_available">
|
||||
<field name="name">Partially Assigned</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain" eval="[('partially_assigned', '=', True)]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_out_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_shipment_out_form_domain_assigned">
|
||||
<field name="name">Assigned</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="domain" eval="[('state', '=', 'assigned')]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_out_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_shipment_out_form_domain_picked">
|
||||
<field name="name">Picked</field>
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="sequence" eval="50"/>
|
||||
<field name="domain" eval="[('state', '=', 'picked')]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_out_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_shipment_out_form_domain_packed">
|
||||
<field name="name">Packed</field>
|
||||
<field name="sequence" eval="50"/>
|
||||
<field name="sequence" eval="60"/>
|
||||
<field name="domain" eval="[('state', '=', 'packed')]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_out_form"/>
|
||||
@@ -247,10 +262,18 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_internal_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_shipment_internal_form_domain_available">
|
||||
<field name="name">Partially Assigned</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain" eval="[('partially_assigned', '=', True)]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_internal_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_shipment_internal_form_domain_assigned">
|
||||
<field name="name">Assigned</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="domain" eval="[('state', '=', 'assigned')]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_shipment_internal_form"/>
|
||||
@@ -258,7 +281,7 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_shipment_internal_form_domain_shipped">
|
||||
<field name="name">Shipped</field>
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="sequence" eval="50"/>
|
||||
<field name="domain" eval="[('state', '=', 'shipped')]" pyson="1"/>
|
||||
<field name="act_window" ref="act_shipment_internal_form"/>
|
||||
</record>
|
||||
|
||||
Reference in New Issue
Block a user