Skip to content

Commit

Permalink
Merge commit 'refs/pull/770/head' of github.com:OCA/wms into merge-br…
Browse files Browse the repository at this point in the history
…anch-2477-BSCOS-4099-99ea5643
  • Loading branch information
sebalix committed Nov 14, 2023
2 parents ec96acf + 0fcc5c4 commit 9027243
Show file tree
Hide file tree
Showing 26 changed files with 301 additions and 20 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ addon | version | maintainers | summary
[shopfloor_workstation](shopfloor_workstation/) | 14.0.1.3.1 | | Manage warehouse workstation with barcode scanners
[shopfloor_workstation_label_printer](shopfloor_workstation_label_printer/) | 14.0.1.1.0 | | Adds a label printer configuration to the user and shopfloor workstation.
[shopfloor_workstation_mobile](shopfloor_workstation_mobile/) | 14.0.1.0.1 | | Shopfloor mobile app integration for workstation
[stock_available_to_promise_release](stock_available_to_promise_release/) | 14.0.2.2.0 | | Release Operations based on available to promise
[stock_available_to_promise_release_dynamic_routing](stock_available_to_promise_release_dynamic_routing/) | 14.0.1.0.0 | | Glue between moves release and dynamic routing
[stock_available_to_promise_release](stock_available_to_promise_release/) | 14.0.2.3.0 | | Release Operations based on available to promise
[stock_available_to_promise_release_dynamic_routing](stock_available_to_promise_release_dynamic_routing/) | 14.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue between moves release and dynamic routing
[stock_checkout_sync](stock_checkout_sync/) | 14.0.1.1.0 | | Sync location for Checkout operations
[stock_dynamic_routing](stock_dynamic_routing/) | 14.0.1.1.1 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Dynamic routing of stock moves
[stock_dynamic_routing_checkout_sync](stock_dynamic_routing_checkout_sync/) | 14.0.1.0.0 | | Glue module for tests when dynamic routing and checkout sync are used
Expand Down
4 changes: 3 additions & 1 deletion shopfloor/actions/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,16 @@ def _get_picking_parser(self, record, **kw):
# Thus, we make it optional.
if "with_progress" in kw:
parser.append("progress")
if kw.get("with_priority"):
parser.append("priority")
return parser

@ensure_model("stock.picking")
def picking(self, record, **kw):
return self._jsonify(record, self._get_picking_parser(record, **kw), **kw)

def pickings(self, record, **kw):
return self.picking(record, multi=True)
return self.picking(record, multi=True, **kw)

@property
def _picking_parser(self, **kw):
Expand Down
1 change: 1 addition & 0 deletions shopfloor/actions/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def picking(self):
"scheduled_date": {"type": "string", "nullable": False, "required": True},
"progress": {"type": "float", "nullable": True},
"location_dest": self._schema_dict_of(self.location(), required=False),
"priority": {"type": "string", "nullable": True, "required": False},
}

def move_line(self, with_packaging=False, with_picking=False):
Expand Down
21 changes: 21 additions & 0 deletions shopfloor/models/shopfloor_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@
to scan a destination package.
"""

ALLOW_ORDER_PICKINGS_BY_PRIORITY_HELP = """
When listing all transfers in the scenario, display the priority number
(corresponding to the stars in each transfer in Odoo)
and order them by priority as well.
"""


class ShopfloorMenu(models.Model):
_inherit = "shopfloor.menu"
Expand Down Expand Up @@ -226,6 +232,14 @@ class ShopfloorMenu(models.Model):
allow_alternative_destination_package_is_possible = fields.Boolean(
compute="_compute_allow_alternative_destination_package_is_possible"
)
order_pickings_by_priority = fields.Boolean(
string="Order transfers by priority",
default=False,
help=ALLOW_ORDER_PICKINGS_BY_PRIORITY_HELP,
)
order_pickings_by_priority_is_possible = fields.Boolean(
compute="_compute_order_pickings_by_priority_is_possible"
)

@api.onchange("unload_package_at_destination")
def _onchange_unload_package_at_destination(self):
Expand Down Expand Up @@ -455,3 +469,10 @@ def _compute_allow_alternative_destination_package_is_possible(self):
menu.allow_alternative_destination_package_is_possible = (
menu.scenario_id.has_option("allow_alternative_destination_package")
)

@api.depends("scenario_id")
def _compute_order_pickings_by_priority_is_possible(self):
for menu in self:
menu.order_pickings_by_priority_is_possible = menu.scenario_id.has_option(
"order_pickings_by_priority"
)
10 changes: 8 additions & 2 deletions shopfloor/services/checkout.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ def _response_for_manual_selection(self, message=None):
self._domain_for_list_stock_picking(),
order=self._order_for_list_stock_picking(),
)
data = {"pickings": self.data.pickings(pickings)}
order_by_priority = self.work.menu.order_pickings_by_priority
data = {
"pickings": self.data.pickings(pickings, with_priority=order_by_priority)
}
return self._response(next_state="manual_selection", data=data, message=message)

def _response_for_select_package(self, picking, lines, message=None):
Expand Down Expand Up @@ -365,7 +368,10 @@ def _domain_for_list_stock_picking(self):
]

def _order_for_list_stock_picking(self):
return "scheduled_date asc, id asc"
base_order = "scheduled_date asc, id asc"
if self.work.menu.order_pickings_by_priority:
return "priority desc, " + base_order
return base_order

def list_stock_picking(self):
"""List stock.picking records available
Expand Down
4 changes: 2 additions & 2 deletions shopfloor/tests/test_checkout_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ def _stock_locations_data(self, locations, **kw):
return self.service._data_for_locations(locations, **kw)

# we test the methods that structure data in test_actions_data.py
def _picking_summary_data(self, picking):
return self.data.picking(picking)
def _picking_summary_data(self, picking, **kw):
return self.data.picking(picking, **kw)

def _move_line_data(self, move_line):
return self.data.move_line(move_line)
Expand Down
27 changes: 27 additions & 0 deletions shopfloor/tests/test_checkout_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,33 @@ def test_list_stock_picking(self):

self.assert_response(response, next_state="manual_selection", data=expected)

def test_list_stock_picking_order_by_priority(self):
self.menu.sudo().order_pickings_by_priority = True
# Pickings should be ordered by priority,
# and they should also return their priority number to the frontend.
picking1 = self._create_picking()
picking1.priority = "0"
picking2 = self._create_picking()
picking2.priority = "1"
picking3 = self._create_picking()
picking3.priority = "1"
picking4 = self._create_picking()
picking4.priority = "0"
to_assign = picking1 | picking2 | picking3 | picking4
self._fill_stock_for_moves(to_assign.move_lines, in_package=True)
to_assign.action_assign()
response = self.service.dispatch("list_stock_picking", params={})
expected = {
"pickings": [
self._picking_summary_data(picking2, with_priority=True),
self._picking_summary_data(picking3, with_priority=True),
self._picking_summary_data(picking1, with_priority=True),
self._picking_summary_data(picking4, with_priority=True),
]
}

self.assert_response(response, next_state="manual_selection", data=expected)


class CheckoutSelectCase(CheckoutCommonCase):
@classmethod
Expand Down
13 changes: 12 additions & 1 deletion shopfloor/views/shopfloor_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
name="scan_location_or_pack_first"
attrs="{'invisible': [('scan_location_or_pack_first_is_possible', '=', False)]}"
>
<field name="scenario_key" invisible="1" />
<field name="scan_location_or_pack_first_is_possible" invisible="1" />
<field name="scan_location_or_pack_first" />
<div
Expand Down Expand Up @@ -167,7 +168,17 @@
invisible="1"
/>
<field name="allow_alternative_destination_package" />
</group>
</group>
<group
name="order_pickings_by_priority"
attrs="{'invisible': [('order_pickings_by_priority_is_possible', '=', False)]}"
>
<field
name="order_pickings_by_priority_is_possible"
invisible="1"
/>
<field name="order_pickings_by_priority" />
</group>
</group>
</field>
</record>
Expand Down
1 change: 1 addition & 0 deletions shopfloor_mobile/static/wms/src/scenario/checkout.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ const Checkout = {
{path: "origin"},
{path: "carrier.name", label: "Carrier"},
{path: "move_line_count", label: "Lines"},
{path: "priority", label: "Priority"},
],
},
};
Expand Down
2 changes: 1 addition & 1 deletion stock_available_to_promise_release/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Stock Available to Promise Release
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:fce8e84ad2954ae45e70c0d921e9a4e689378b265045b0477e2ab31264ce96b4
!! source digest: sha256:2309ceaa3005c7fdf6d7a5d4d199d02942de918334d3586cedb8968f9c2593de
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down
2 changes: 1 addition & 1 deletion stock_available_to_promise_release/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

{
"name": "Stock Available to Promise Release",
"version": "14.0.2.2.0",
"version": "14.0.2.3.0",
"summary": "Release Operations based on available to promise",
"author": "Camptocamp, BCIM, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/wms",
Expand Down
19 changes: 14 additions & 5 deletions stock_available_to_promise_release/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,10 +471,10 @@ def _run_stock_rule(self):
)
self.env["procurement.group"].run_defer(procurement_requests)

released_moves._after_release_assign_moves()
released_moves._after_release_update_chain()
assigned_moves = released_moves._after_release_assign_moves()
assigned_moves._after_release_update_chain()

return released_moves
return assigned_moves

def _before_release(self):
"""Hook that aims to be overridden."""
Expand All @@ -495,8 +495,12 @@ def _after_release_update_chain(self):
def _after_release_assign_moves(self):
move_ids = []
for origin_moves in self._get_chained_moves_iterator("move_orig_ids"):
move_ids += origin_moves.ids
self.env["stock.move"].browse(move_ids)._action_assign()
move_ids += origin_moves.filtered(
lambda m: m.state not in ("cancel", "done")
).ids
moves = self.browse(move_ids)
moves._action_assign()
return moves

def _release_split(self, remaining_qty):
"""Split move and put remaining_qty to a backorder move."""
Expand Down Expand Up @@ -584,6 +588,8 @@ def _split_origins(self, origins):
"""
self.ensure_one()
qty = self.product_qty
# Unreserve goods before the split
origins._do_unreserve()
rounding = self.product_uom.rounding
new_origin_moves = self.env["stock.move"]
while float_compare(qty, 0, precision_rounding=rounding) > 0 and origins:
Expand All @@ -596,6 +602,9 @@ def _split_origins(self, origins):
new_origin_moves |= self.create(new_move_vals)
break
origins -= origin
# And then do the reservation again
origins._action_assign()
new_origin_moves._action_assign()
return new_origin_moves

def _search_picking_for_assignation_domain(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ <h1 class="title">Stock Available to Promise Release</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:fce8e84ad2954ae45e70c0d921e9a4e689378b265045b0477e2ab31264ce96b4
!! source digest: sha256:2309ceaa3005c7fdf6d7a5d4d199d02942de918334d3586cedb8968f9c2593de
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/wms/tree/14.0/stock_available_to_promise_release"><img alt="OCA/wms" src="https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/wms-14-0/wms-14-0-stock_available_to_promise_release"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/wms&amp;target_branch=14.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Currently the reservation is performed by adding reserved quantities on quants,
Expand Down
1 change: 1 addition & 0 deletions stock_available_to_promise_release/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
from . import test_unrelease
from . import test_unrelease_2steps
from . import test_unrelease_3steps
from . import test_unrelease_merged_moves
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2023 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from datetime import datetime

from .common import PromiseReleaseCommonCase


class TestAvailableToPromiseRelease(PromiseReleaseCommonCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
delivery_pick_rule = cls.wh.delivery_route_id.rule_ids.filtered(
lambda r: r.location_src_id == cls.loc_stock
)
delivery_pick_rule.group_propagation_option = "fixed"
cls.pc1 = cls._create_picking_chain(
cls.wh, [(cls.product1, 2)], date=datetime(2019, 9, 2, 16, 0)
)
cls.shipping1 = cls._out_picking(cls.pc1)
cls.pc2 = cls._create_picking_chain(
cls.wh, [(cls.product1, 3)], date=datetime(2019, 9, 2, 16, 0)
)
cls.shipping2 = cls._out_picking(cls.pc2)
cls._update_qty_in_location(cls.loc_bin1, cls.product1, 15.0)
cls.wh.delivery_route_id.write(
{
"available_to_promise_defer_pull": True,
}
)
shippings = cls.shipping1 | cls.shipping2
shippings.release_available_to_promise()
cls.picking1 = cls._prev_picking(cls.shipping1)
cls.picking1.action_assign()
cls.picking2 = cls._prev_picking(cls.shipping2)
cls.picking2.action_assign()

@classmethod
def _out_picking(cls, pickings):
return pickings.filtered(lambda r: r.picking_type_code == "outgoing")

@classmethod
def _prev_picking(cls, picking):
return picking.move_lines.move_orig_ids.picking_id

def test_unrelease_merged_move(self):
self.assertEqual(self.picking1, self.picking2)
moves = self.picking1.move_lines.filtered(lambda m: m.state == "assigned")
self.assertEqual(sum(moves.mapped("product_uom_qty")), 5.0)
self.shipping2.unrelease()
move = self.picking1.move_lines.filtered(lambda m: m.state == "assigned")
line = move.move_line_ids
self.assertEqual(move.product_uom_qty, 2.0)
self.assertEqual(line.product_uom_qty, 2.0)
12 changes: 11 additions & 1 deletion stock_available_to_promise_release_dynamic_routing/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Available to Promise Release - Dynamic Routing
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:6acf3b31d72d9fb1a24f1bf47f79e5bafc6ec4e41f7590ad28e35096ae1e85aa
!! source digest: sha256:aead33fabdb3ae0f3970ffc2be1cfc29fccd1926d059460081fff13eccac24d7
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
Expand Down Expand Up @@ -61,10 +61,12 @@ Authors
~~~~~~~

* Camptocamp
* BCIM

Contributors
~~~~~~~~~~~~

* Jacques-Etienne Baudoux (BCIM) <[email protected]>
* Guewen Baconnier <[email protected]>
* `Trobz <https://trobz.com>`_:
* Dung Tran <[email protected]>
Expand All @@ -88,6 +90,14 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-jbaudoux| image:: https://github.com/jbaudoux.png?size=40px
:target: https://github.com/jbaudoux
:alt: jbaudoux

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-jbaudoux|

This module is part of the `OCA/wms <https://github.com/OCA/wms/tree/14.0/stock_available_to_promise_release_dynamic_routing>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
{
"name": "Available to Promise Release - Dynamic Routing",
"summary": "Glue between moves release and dynamic routing",
"author": "Camptocamp, Odoo Community Association (OCA)",
"author": "Camptocamp,BCIM,Odoo Community Association (OCA)",
"maintainers": ["jbaudoux"],
"website": "https://github.com/OCA/wms",
"category": "Warehouse Management",
"version": "14.0.1.0.0",
"version": "14.0.1.1.0",
"license": "AGPL-3",
"depends": ["stock_available_to_promise_release", "stock_dynamic_routing"],
"demo": [],
Expand Down
19 changes: 19 additions & 0 deletions stock_available_to_promise_release_dynamic_routing/i18n/es_AR.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#. module: stock_available_to_promise_release_dynamic_routing
#: model:ir.model.fields,field_description:stock_available_to_promise_release_dynamic_routing.field_stock_move__display_name
msgid "Display Name"
msgstr ""

#. module: stock_available_to_promise_release_dynamic_routing
#: model:ir.model.fields,field_description:stock_available_to_promise_release_dynamic_routing.field_stock_move__id
msgid "ID"
msgstr ""

#. module: stock_available_to_promise_release_dynamic_routing
#: model:ir.model.fields,field_description:stock_available_to_promise_release_dynamic_routing.field_stock_move____last_update
msgid "Last Modified on"
msgstr ""

#. module: stock_available_to_promise_release_dynamic_routing
#: model:ir.model,name:stock_available_to_promise_release_dynamic_routing.model_stock_move
msgid "Stock Move"
msgstr ""
Loading

0 comments on commit 9027243

Please sign in to comment.