Skip to content

Commit

Permalink
Merge PR #82 into 13.0
Browse files Browse the repository at this point in the history
Signed-off-by simahawk
  • Loading branch information
OCA-git-bot committed Dec 1, 2020
2 parents ca10b47 + a2e9d21 commit 6d4e1eb
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 23 deletions.
3 changes: 2 additions & 1 deletion shopfloor/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
"depends": [
"stock",
"stock_picking_batch",
"base_rest",
"base_jsonify",
"base_rest",
"base_sparse_field",
"auth_api_key",
# OCA / stock-logistics-warehouse
"stock_picking_completion_info",
Expand Down
13 changes: 13 additions & 0 deletions shopfloor/models/shopfloor_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, api, exceptions, fields, models

from odoo.addons.base_sparse_field.models.fields import Serialized


class ShopfloorMenu(models.Model):
_name = "shopfloor.menu"
Expand Down Expand Up @@ -33,6 +35,17 @@ class ShopfloorMenu(models.Model):
)

scenario = fields.Selection(selection="_selection_scenario", required=True)
# TODO: `options` field allows to provide custom options for the scenario,
# (or for any other kind of service).
# Developers should probably have a way to register scenario and their options
# which will be computed in this field at the end.
# This would allow to get rid of hardcoded settings like
# `_scenario_allowing_create_moves` or `_scenario_allowing_unreserve_other_moves`.
# For now is not included in any view as it should be customizable by scenario.
# Maybe we can have a wizard accessible via a button on the menu tree view.
# There's no automation here. Developers are responsible for their usage
# and/or their exposure to the scenario api.
options = Serialized(default={})

move_create_is_possible = fields.Boolean(compute="_compute_move_create_is_possible")
# only available for some scenarios, move_create_is_possible defines if the option
Expand Down
13 changes: 13 additions & 0 deletions shopfloor/services/checkout.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from werkzeug.exceptions import BadRequest

from odoo import _

from odoo.addons.base_rest.components.service import to_int
Expand Down Expand Up @@ -73,6 +76,9 @@ def _response_for_select_package(self, picking, lines, message=None):
"selected_move_lines": self._data_for_move_lines(lines.sorted()),
"picking": self.data.picking(picking),
"packing_info": self._data_for_packing_info(picking),
"no_package_enabled": not self.options.get(
"checkout:disable_no_package"
),
},
message=message,
)
Expand Down Expand Up @@ -758,6 +764,8 @@ def no_package(self, picking_id, selected_line_ids):
Transitions:
* select_line: goes back to selection of lines to work on next lines
"""
if self.options.get("checkout:disable_no_package"):
raise BadRequest("`checkout.no_package` endpoint is not enabled")
picking = self.env["stock.picking"].browse(picking_id)
message = self._check_picking_status(picking)
if message:
Expand Down Expand Up @@ -1180,6 +1188,11 @@ def _states(self):
"select_package": dict(
self._schema_selected_lines,
packing_info={"type": "string", "nullable": True},
no_package_enabled={
"type": "boolean",
"nullable": True,
"required": False,
},
),
"change_quantity": self._schema_selected_lines,
"select_dest_package": self._schema_select_package,
Expand Down
18 changes: 18 additions & 0 deletions shopfloor/services/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,24 @@ def _work_ctx_get_menu_id(self, rec_id):
def _work_ctx_get_profile_id(self, rec_id):
return "profile", self.env["shopfloor.profile"].browse(rec_id).exists()

_options = {}

@property
def options(self):
"""Compute options for current service.
If the service has a menu, options coming from the menu are injected.
"""
if self._options:
return self._options

options = {}
if self._requires_header_menu and getattr(self.work, "menu", None):
options = self.work.menu.options or {}
options.update(getattr(self.work, "options", {}))
self._options = options
return self._options


class BaseShopfloorProcess(AbstractComponent):
"""Base class for process rest service"""
Expand Down
47 changes: 33 additions & 14 deletions shopfloor/tests/test_checkout_no_package.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,44 @@
# Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import werkzeug

from .test_checkout_base import CheckoutCommonCase
from .test_checkout_select_package_base import CheckoutSelectPackageMixin


class CheckoutNoPackageCase(CheckoutCommonCase, CheckoutSelectPackageMixin):
def test_no_package_ok(self):
picking = self._create_picking(
@classmethod
def setUpClassBaseData(cls):
super().setUpClassBaseData()
cls.picking = picking = cls._create_picking(
lines=[
(self.product_a, 10),
(self.product_b, 10),
(self.product_c, 10),
(self.product_d, 10),
(cls.product_a, 10),
(cls.product_b, 10),
(cls.product_c, 10),
(cls.product_d, 10),
]
)
pack1_moves = picking.move_lines[:3]
pack2_moves = picking.move_lines[3:]
cls.pack1_moves = pack1_moves = picking.move_lines[:3]
cls.pack2_moves = pack2_moves = picking.move_lines[3:]
# put in 2 packs, for this test, we'll work on pack1
self._fill_stock_for_moves(pack1_moves)
self._fill_stock_for_moves(pack2_moves)
cls._fill_stock_for_moves(pack1_moves)
cls._fill_stock_for_moves(pack2_moves)
picking.action_assign()

move_line1, move_line2, move_line3 = pack1_moves.move_line_ids
def test_no_package_ok(self):
move_line1, move_line2, move_line3 = self.pack1_moves.move_line_ids
selected_lines = move_line1 + move_line2

# we'll put only the first 2 lines (product A and B) w/ no package
move_line1.qty_done = move_line1.product_uom_qty
move_line2.qty_done = move_line2.product_uom_qty
move_line3.qty_done = 0

response = self.service.dispatch(
"no_package",
params={"picking_id": picking.id, "selected_line_ids": selected_lines.ids},
params={
"picking_id": self.picking.id,
"selected_line_ids": selected_lines.ids,
},
)

self.assertRecordValues(
Expand All @@ -48,9 +55,21 @@ def test_no_package_ok(self):
response,
# go pack to the screen to select lines to put in packages
next_state="select_line",
data={"picking": self._stock_picking_data(picking)},
data={"picking": self._stock_picking_data(self.picking)},
message={
"message_type": "success",
"body": "Product(s) processed as raw product(s)",
},
)

def test_no_package_disabled(self):
self.service.work.options = {"checkout:disable_no_package": True}
with self.assertRaises(werkzeug.exceptions.BadRequest) as err:
self.service.dispatch(
"no_package",
params={
"picking_id": self.picking.id,
"selected_line_ids": self.pack1_moves.move_line_ids.ids,
},
)
self.assertEqual(err.name, "`checkout.no_package` endpoint is not enabled")
12 changes: 12 additions & 0 deletions shopfloor/tests/test_checkout_select_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ def test_select_line_package_ok(self):
)
self._assert_selected(response, selected_lines)

def test_select_line_no_package_disabled(self):
selected_lines = self.moves_pack.move_line_ids
self.service.work.options = {"checkout:disable_no_package": True}
response = self.service.dispatch(
"select_line",
params={
"picking_id": self.picking.id,
"package_id": selected_lines.package_id.id,
},
)
self._assert_selected(response, selected_lines, no_package_enabled=False)

def test_select_line_move_line_package_ok(self):
selected_lines = self.moves_pack.move_line_ids
# When we select a single line but the line is part of a package,
Expand Down
16 changes: 9 additions & 7 deletions shopfloor/tests/test_checkout_select_package_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@

class CheckoutSelectPackageMixin:
def _assert_selected_response(
self, response, selected_lines, message=None, packing_info=False
self,
response,
selected_lines,
message=None,
packing_info=False,
no_package_enabled=True,
):
picking = selected_lines.mapped("picking_id")
self.assert_response(
Expand All @@ -16,6 +21,7 @@ def _assert_selected_response(
],
"picking": self._picking_summary_data(picking),
"packing_info": picking.shopfloor_packing_info if packing_info else "",
"no_package_enabled": no_package_enabled,
},
message=message,
)
Expand All @@ -41,9 +47,7 @@ def _assert_selected_qties(
response, selected_lines, message=message, packing_info=packing_info
)

def _assert_selected(
self, response, selected_lines, message=None, packing_info=False
):
def _assert_selected(self, response, selected_lines, message=None, **kw):
picking = selected_lines.mapped("picking_id")
unselected_lines = picking.move_line_ids - selected_lines
for line in selected_lines:
Expand All @@ -54,6 +58,4 @@ def _assert_selected(
)
for line in unselected_lines:
self.assertEqual(line.qty_done, 0)
self._assert_selected_response(
response, selected_lines, message=message, packing_info=packing_info
)
self._assert_selected_response(response, selected_lines, message=message, **kw)
2 changes: 1 addition & 1 deletion shopfloor_mobile/static/wms/src/scenario/checkout.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const Checkout = {
>New pack</btn-action>
</v-col>
</v-row>
<v-row align="center">
<v-row align="center" v-if="state.data.no_package_enabled">
<v-col class="text-center" cols="12">
<btn-action
@click="state.on_without_pack"
Expand Down

0 comments on commit 6d4e1eb

Please sign in to comment.