Skip to content

Commit

Permalink
[IMP] shopfloor: Zone picking no packing
Browse files Browse the repository at this point in the history
Add an option to skip the packing step when processing a line into the zone picking scenario. Thanks to this option the processing of a line can be done by processing the location, set the qty and scan the destination even if the oroduct is not into a package.
  • Loading branch information
lmignon committed May 17, 2024
1 parent 912047f commit 72c4829
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 3 deletions.
2 changes: 1 addition & 1 deletion shopfloor/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{
"name": "Shopfloor",
"summary": "manage warehouse operations with barcode scanners",
"version": "16.0.2.0.0",
"version": "16.0.2.0.1",
"development_status": "Beta",
"category": "Inventory",
"website": "https://github.com/OCA/wms",
Expand Down
3 changes: 2 additions & 1 deletion shopfloor/data/shopfloor_scenario_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"multiple_move_single_pack": true,
"no_prefill_qty": true,
"scan_location_or_pack_first": true,
"allow_alternative_destination_package": true
"allow_alternative_destination_package": true,
"no_packing": true
}
</field>
</record>
Expand Down
26 changes: 26 additions & 0 deletions shopfloor/migrations/16.0.2.0.1/post-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2024 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import json
import logging

from odoo import SUPERUSER_ID, api

_logger = logging.getLogger(__name__)


def migrate(cr, version):
_logger.info("Updating scenario Zone Picking")
if not version:
return
env = api.Environment(cr, SUPERUSER_ID, {})
zone_picking_scenario = env.ref("shopfloor.scenario_zone_picking")
_update_scenario_options(zone_picking_scenario)


def _update_scenario_options(scenario):
options = scenario.options
options["no_packing"] = True
options_edit = json.dumps(options or {}, indent=4, sort_keys=True)
scenario.write({"options_edit": options_edit})
_logger.info("Option no_packing added to scenario Zone Picking")
37 changes: 37 additions & 0 deletions shopfloor/models/shopfloor_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,15 @@ class ShopfloorMenu(models.Model):
compute="_compute_allow_alternative_destination_package_is_possible"
)

no_packing = fields.Boolean(
string="No packing",
default=False,
help="If set, the user will have to scan only the source location "
"and the destination location to process a line. The unload step will be skipped.",
)

no_packing_is_possible = fields.Boolean(compute="_compute_no_packing_is_possible")

@api.onchange("unload_package_at_destination")
def _onchange_unload_package_at_destination(self):
# Uncheck pick_pack_same_time when unload_package_at_destination is set to True
Expand All @@ -243,6 +252,16 @@ def _onchange_pick_pack_same_time(self):
record.unload_package_at_destination = False
record.multiple_move_single_pack = False

@api.onchange("no_packing")
def _onchange_no_packing(self):
# no_packing is incompatible with pick_pack_same_time and unload_package_at_destination
# and multiple_move_single_pack
for record in self:
if record.no_packing:
record.pick_pack_same_time = False
record.unload_package_at_destination = False
record.multiple_move_single_pack = False

Check warning on line 263 in shopfloor/models/shopfloor_menu.py

View check run for this annotation

Codecov / codecov/patch

shopfloor/models/shopfloor_menu.py#L261-L263

Added lines #L261 - L263 were not covered by tests

@api.onchange("multiple_move_single_pack")
def _onchange_multiple_move_single_pack(self):
# multiple_move_single_pack is incompatible with pick_pack_same_time,
Expand All @@ -254,6 +273,7 @@ def _onchange_multiple_move_single_pack(self):
"unload_package_at_destination",
"pick_pack_same_time",
"multiple_move_single_pack",
"no_packing",
)
def _check_options(self):
if self.pick_pack_same_time and self.unload_package_at_destination:
Expand All @@ -270,6 +290,18 @@ def _check_options(self):
"'Multiple moves same destination package'."
)
)
elif self.no_packing and (
self.pick_pack_same_time
or self.unload_package_at_destination
or self.multiple_move_single_pack
):
raise exceptions.UserError(

Check warning on line 298 in shopfloor/models/shopfloor_menu.py

View check run for this annotation

Codecov / codecov/patch

shopfloor/models/shopfloor_menu.py#L298

Added line #L298 was not covered by tests
_(
"'No Packing' is incompatible with 'Pick and pack at the same "
"time', 'Unload package at destination' and 'Multiple moves "
"same destination package'."
)
)

@api.depends("scenario_id", "picking_type_ids")
def _compute_move_create_is_possible(self):
Expand Down Expand Up @@ -458,3 +490,8 @@ 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_no_packing_is_possible(self):
for menu in self:
menu.no_packing_is_possible = menu.scenario_id.has_option("no_packing")

Check warning on line 497 in shopfloor/models/shopfloor_menu.py

View check run for this annotation

Codecov / codecov/patch

shopfloor/models/shopfloor_menu.py#L497

Added line #L497 was not covered by tests
5 changes: 4 additions & 1 deletion shopfloor/services/zone_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ def lines_order(self):
def _pick_pack_same_time(self):
return self.work.menu.pick_pack_same_time

def _packing_required(self):
return not self.work.menu.no_packing

def _handle_complete_mix_pack(self, package):
packaging = self._actions_for("packaging")
return (
Expand Down Expand Up @@ -924,7 +927,7 @@ def _set_destination_location(
return (location_changed, response)

# If no destination package
if not move_line.result_package_id:
if self._packing_required() and not move_line.result_package_id:
response = self._response_for_set_line_destination(
move_line,
message=self.msg_store.dest_package_required(),
Expand Down
1 change: 1 addition & 0 deletions shopfloor/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
from . import test_zone_picking_unload_single
from . import test_zone_picking_unload_all
from . import test_zone_picking_unload_set_destination
from . import test_zone_picking_no_packing
from . import test_misc
from . import test_move_action_assign
from . import test_scan_anything
Expand Down
62 changes: 62 additions & 0 deletions shopfloor/tests/test_zone_picking_no_packing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from .test_zone_picking_base import ZonePickingCommonCase

# pylint: disable=missing-return


class ZonePickingNoPAcking(ZonePickingCommonCase):
"""Tests zone picking without packing steps.
* /set_destination
"""

def setUp(self):
super().setUp()
self.service.work.current_picking_type = self.picking1.picking_type_id
self.picking1.move_line_ids.result_package_id = False

def test_set_destination(self):
# when no packing is set, you can set the destination directly
# without the need to pack the product
self.service.work.menu.sudo().no_packing = False
zone_location = self.zone_location
picking_type = self.picking1.picking_type_id
move_line = self.picking1.move_line_ids[0]
response = self.service.dispatch(
"set_destination",
params={
"move_line_id": move_line.id,
"barcode": move_line.location_dest_id.barcode,
"quantity": move_line.reserved_uom_qty,
"confirmation": None,
},
)
self.assert_response_set_line_destination(
response,
zone_location,
picking_type,
move_line,
qty_done=move_line.reserved_uom_qty,
message=self.service.msg_store.dest_package_required(),
)
self.service.work.menu.sudo().no_packing = True
response = self.service.dispatch(
"set_destination",
params={
"move_line_id": move_line.id,
"barcode": move_line.location_dest_id.barcode,
"quantity": move_line.reserved_uom_qty,
"confirmation": None,
},
)
move_lines = self.service._find_location_move_lines()
move_lines = move_lines.sorted(lambda l: l.move_id.priority, reverse=True)
self.assert_response_select_line(
response,
zone_location,
picking_type,
move_lines,
message=self.service.msg_store.confirm_pack_moved(),
)
7 changes: 7 additions & 0 deletions shopfloor/views/shopfloor_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
>
<field name="ignore_no_putaway_available_is_possible" invisible="1" />
<field name="ignore_no_putaway_available" />
</group>
<group
name="no_packing"
attrs="{'invisible': [('no_packing_is_possible', '=', False)]}"
>
<field name="no_packing_is_possible" invisible="1" />
<field name="no_packing" />
</group>
<group
name="pick_pack_same_time"
Expand Down

0 comments on commit 72c4829

Please sign in to comment.