From 1231f2b95b79bbcd63c392514c8d155efd362b9e Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 5 Oct 2020 11:04:31 +0200 Subject: [PATCH 01/11] shopfloor: zone_picking rename empty_location_src -> location_will_be_empty --- shopfloor/services/zone_picking.py | 9 +++++++-- shopfloor/tests/test_zone_picking_base.py | 2 +- shopfloor/tests/test_zone_picking_select_line.py | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/shopfloor/services/zone_picking.py b/shopfloor/services/zone_picking.py index d36e5ffd09..602e387cfc 100644 --- a/shopfloor/services/zone_picking.py +++ b/shopfloor/services/zone_picking.py @@ -226,9 +226,14 @@ def _data_for_move_lines(self, zone_location, picking_type, move_lines): "move_lines": self.data.move_lines(move_lines, with_picking=True), } for data_move_line in data["move_lines"]: + # TODO: this could be expensive, think about a better way + # to retrieve if location will be empty. + # Maybe group lines by location and compute only once. move_line = self.env["stock.move.line"].browse(data_move_line["id"]) + # `location_will_be_empty` flag states if, by processing this move line + # and picking the product, the location will be emptied. data_move_line[ - "empty_location_src" + "location_will_be_empty" ] = move_line.location_id.planned_qty_in_location_is_empty(move_line) return data @@ -1557,7 +1562,7 @@ def _schema_for_move_lines(self): @property def _schema_for_move_lines_empty_location(self): schema = self._schema_for_move_lines - schema["move_lines"]["schema"]["schema"]["empty_location_src"] = { + schema["move_lines"]["schema"]["schema"]["location_will_be_empty"] = { "type": "boolean", "nullable": False, "required": True, diff --git a/shopfloor/tests/test_zone_picking_base.py b/shopfloor/tests/test_zone_picking_base.py index f2cb932382..948ec31161 100644 --- a/shopfloor/tests/test_zone_picking_base.py +++ b/shopfloor/tests/test_zone_picking_base.py @@ -224,7 +224,7 @@ def _assert_response_select_line( for data_move_line in data["move_lines"]: move_line = self.env["stock.move.line"].browse(data_move_line["id"]) data_move_line[ - "empty_location_src" + "location_will_be_empty" ] = move_line.location_id.planned_qty_in_location_is_empty(move_line) self.assert_response( response, next_state=state, data=data, message=message, popup=popup, diff --git a/shopfloor/tests/test_zone_picking_select_line.py b/shopfloor/tests/test_zone_picking_select_line.py index ba02eac993..614cd6a3ff 100644 --- a/shopfloor/tests/test_zone_picking_select_line.py +++ b/shopfloor/tests/test_zone_picking_select_line.py @@ -422,7 +422,7 @@ def test_list_move_lines_empty_location(self): for m in data_move_lines if m["location_src"]["barcode"] == "ZONE_SUBLOCATION_1" ][0] - self.assertTrue(data_move_line["empty_location_src"]) + self.assertTrue(data_move_line["location_will_be_empty"]) # Same check with the internal method move_line = self.env["stock.move.line"].browse(data_move_line["id"]) location_src = move_line.location_id From 81f1bb500b0957fef31f05f46df02e997df30146 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 5 Oct 2020 11:39:25 +0200 Subject: [PATCH 02/11] shopfloor_mobile: list/select add card_klass option Allow to provide custom class for the v-card wrapping the list. --- shopfloor_mobile/static/wms/src/components/list.js | 2 +- shopfloor_mobile/static/wms/src/components/manual_select.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shopfloor_mobile/static/wms/src/components/list.js b/shopfloor_mobile/static/wms/src/components/list.js index d4a9534d3a..8d8de02fa8 100644 --- a/shopfloor_mobile/static/wms/src/components/list.js +++ b/shopfloor_mobile/static/wms/src/components/list.js @@ -95,7 +95,7 @@ Vue.component("list", { }, template: `
- {{ group.title }} diff --git a/shopfloor_mobile/static/wms/src/components/manual_select.js b/shopfloor_mobile/static/wms/src/components/manual_select.js index d166704558..d331652a98 100644 --- a/shopfloor_mobile/static/wms/src/components/manual_select.js +++ b/shopfloor_mobile/static/wms/src/components/manual_select.js @@ -232,7 +232,7 @@ Vue.component("manual-select", { }, template: `
- From 1cea4e6af227c9b51dad0b5a36776923499ace51 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 5 Oct 2020 11:40:36 +0200 Subject: [PATCH 03/11] shopfloor_mobile: zone_picking make line detail labels bold --- shopfloor_mobile/static/wms/src/css/main.css | 1 + shopfloor_mobile/static/wms/src/scenario/zone_picking.js | 1 + 2 files changed, 2 insertions(+) diff --git a/shopfloor_mobile/static/wms/src/css/main.css b/shopfloor_mobile/static/wms/src/css/main.css index 4a3f1ca560..f3c026b19e 100644 --- a/shopfloor_mobile/static/wms/src/css/main.css +++ b/shopfloor_mobile/static/wms/src/css/main.css @@ -113,6 +113,7 @@ ul.packaging span:first-child { font-size: 1.3em; line-height: 1.4em; } +.v-card.loud-labels .label, .detail.item-detail-card .field-detail.loud-label .label, .detail.item-detail-card.loud-labels .v-card__text.details .label, .detail.item-detail-card.loud .v-card__text.details .label { diff --git a/shopfloor_mobile/static/wms/src/scenario/zone_picking.js b/shopfloor_mobile/static/wms/src/scenario/zone_picking.js index bd02040c44..cabf1c3cdc 100644 --- a/shopfloor_mobile/static/wms/src/scenario/zone_picking.js +++ b/shopfloor_mobile/static/wms/src/scenario/zone_picking.js @@ -262,6 +262,7 @@ const ZonePicking = { let options = { key_title: "location_src.name", group_color: this.utils.colors.color_for("screen_step_todo"), + card_klass: "loud-labels", title_action_field: {action_val_path: "product.barcode"}, showActions: false, list_item_options: { From c70dcf7572f8ac30a785f7742df927f5c75e0e99 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 5 Oct 2020 11:41:59 +0200 Subject: [PATCH 04/11] shopfloor_mobile: zone_picking table mode use priority widget --- shopfloor_mobile/static/wms/src/scenario/zone_picking.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shopfloor_mobile/static/wms/src/scenario/zone_picking.js b/shopfloor_mobile/static/wms/src/scenario/zone_picking.js index cabf1c3cdc..3042b41178 100644 --- a/shopfloor_mobile/static/wms/src/scenario/zone_picking.js +++ b/shopfloor_mobile/static/wms/src/scenario/zone_picking.js @@ -41,6 +41,10 @@ const template_mobile = ` :items="select_line_table_items()" :key="make_state_component_key(['data-table'])" class="elevation-1"> + +
From 3ee08c1e7046fa8403f51415fd90b4852bdf8906 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 5 Oct 2020 11:44:27 +0200 Subject: [PATCH 05/11] shopfloor_mobile: zone_picking show special icon for location_will_be_empty --- shopfloor_mobile/static/wms/src/components/misc.js | 7 +++++++ shopfloor_mobile/static/wms/src/css/main.css | 6 ++++++ .../static/wms/src/demo/demo.zone_picking.js | 4 ++++ .../static/wms/src/scenario/zone_picking.js | 13 +++++++++++++ 4 files changed, 30 insertions(+) diff --git a/shopfloor_mobile/static/wms/src/components/misc.js b/shopfloor_mobile/static/wms/src/components/misc.js index 338ade9dfc..585b6879a3 100644 --- a/shopfloor_mobile/static/wms/src/components/misc.js +++ b/shopfloor_mobile/static/wms/src/components/misc.js @@ -439,3 +439,10 @@ Vue.component("btn-fullscreen", { }, template: `{{ btn_label }}`, }); + +Vue.component("empty-location-icon", { + mixins: [ItemDetailMixin], + template: ` + mdi-alert-rhombus-outline + `, +}); diff --git a/shopfloor_mobile/static/wms/src/css/main.css b/shopfloor_mobile/static/wms/src/css/main.css index f3c026b19e..3daa67d6de 100644 --- a/shopfloor_mobile/static/wms/src/css/main.css +++ b/shopfloor_mobile/static/wms/src/css/main.css @@ -520,6 +520,12 @@ I tested only w/ checkout/select_package for now margin-right: 1.2em; } +.v-list-item.location-will-be-empty .field-detail.location_will_be_empty { + position: absolute; + top: 5px; + right: 5px; +} + @media screen and (max-width: 320px) { #app header.has-main-doc .app-bar-actions { display: none; diff --git a/shopfloor_mobile/static/wms/src/demo/demo.zone_picking.js b/shopfloor_mobile/static/wms/src/demo/demo.zone_picking.js index 580da90ac2..f36ad99285 100644 --- a/shopfloor_mobile/static/wms/src/demo/demo.zone_picking.js +++ b/shopfloor_mobile/static/wms/src/demo/demo.zone_picking.js @@ -44,6 +44,10 @@ const move_lines = demotools.makePickingLines( {lines_count: 30, line_random_pack: true, picking_auto: true} ); const select_line_move_lines = _.orderBy(move_lines, ["priority"], ["desc"]); +_.forEach(select_line_move_lines, function(line, i) { + // Simulate random flag + line.location_will_be_empty = i % 3 == 0; +}); const list_move_lines = { next_state: "select_line", diff --git a/shopfloor_mobile/static/wms/src/scenario/zone_picking.js b/shopfloor_mobile/static/wms/src/scenario/zone_picking.js index 3042b41178..1efb55e307 100644 --- a/shopfloor_mobile/static/wms/src/scenario/zone_picking.js +++ b/shopfloor_mobile/static/wms/src/scenario/zone_picking.js @@ -45,6 +45,9 @@ const template_mobile = ` +
@@ -272,6 +275,11 @@ const ZonePicking = { list_item_options: { bold_title: true, fields: this.move_line_list_fields(), + list_item_klass_maker: function(rec) { + return rec.location_will_be_empty + ? "location-will-be-empty" + : ""; + }, }, }; return options; @@ -298,6 +306,11 @@ const ZonePicking = { return {priority: parseInt(record.priority || "0", 10)}; }, }, + { + path: "location_will_be_empty", + render_component: "empty-location-icon", + display_no_value: true, + }, ]; if (table_mode) { fields.unshift({path: "location_src.name", label: "Location"}); From 5ba62cf7ffae3142bb5bce36d3195aa96bf75e98 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 5 Oct 2020 12:03:55 +0200 Subject: [PATCH 06/11] shopfloor_mobile: zone_picking show qty picker --- .../static/wms/src/scenario/zone_picking.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/shopfloor_mobile/static/wms/src/scenario/zone_picking.js b/shopfloor_mobile/static/wms/src/scenario/zone_picking.js index 1efb55e307..326369ab1c 100644 --- a/shopfloor_mobile/static/wms/src/scenario/zone_picking.js +++ b/shopfloor_mobile/static/wms/src/scenario/zone_picking.js @@ -42,6 +42,11 @@ const template_mobile = ` :key="make_state_component_key(['data-table'])" class="elevation-1"> + @@ -261,6 +266,7 @@ const ZonePicking = { item_data[field.path] = field.renderer(record, field); } }); + item_data["_origin"] = record; return item_data; }); return items; @@ -290,6 +296,14 @@ const ZonePicking = { {path: "product.display_name", label: table_mode ? "Product" : null}, {path: "package_src.name", label: "Pack"}, {path: "lot.name", label: "Lot"}, + { + path: "quantity", + label: "Qty", + render_component: "packaging-qty-picker-display", + render_options: function(record) { + return self.utils.misc.move_line_qty_picker_options(record); + }, + }, {path: "package_src.weight", label: "Weight"}, { path: "picking.scheduled_date", From 3e9902b85cb4243eb056a2bbe8ed2bcdea225228 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 5 Oct 2020 12:05:06 +0200 Subject: [PATCH 07/11] shopfloor_mobile: manual-select support list_item_klass_maker --- shopfloor_mobile/static/wms/src/components/manual_select.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shopfloor_mobile/static/wms/src/components/manual_select.js b/shopfloor_mobile/static/wms/src/components/manual_select.js index d331652a98..011d2643d7 100644 --- a/shopfloor_mobile/static/wms/src/components/manual_select.js +++ b/shopfloor_mobile/static/wms/src/components/manual_select.js @@ -239,7 +239,8 @@ Vue.component("manual-select", { {{ group.title }}
- + Date: Mon, 5 Oct 2020 12:06:41 +0200 Subject: [PATCH 08/11] shopfloor_mobile: priority-widget no need for record prop --- shopfloor_mobile/static/wms/src/components/priority-widget.js | 1 - 1 file changed, 1 deletion(-) diff --git a/shopfloor_mobile/static/wms/src/components/priority-widget.js b/shopfloor_mobile/static/wms/src/components/priority-widget.js index 24ed857ffd..d3cb43d6ff 100644 --- a/shopfloor_mobile/static/wms/src/components/priority-widget.js +++ b/shopfloor_mobile/static/wms/src/components/priority-widget.js @@ -6,7 +6,6 @@ export var PriorityWidget = Vue.component("priority-widget", { props: { - record: Object, options: Object, }, computed: { From 6882dc94f3b251ca1b0603f6c00d3df7578082f9 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 5 Oct 2020 12:07:10 +0200 Subject: [PATCH 09/11] shopfloor_mobile: update roadmap --- shopfloor_mobile/readme/ROADMAP.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/shopfloor_mobile/readme/ROADMAP.rst b/shopfloor_mobile/readme/ROADMAP.rst index ae1f65bd45..ebc46793cf 100644 --- a/shopfloor_mobile/readme/ROADMAP.rst +++ b/shopfloor_mobile/readme/ROADMAP.rst @@ -4,3 +4,4 @@ * Document demo mode * Find / create a nice icon * Finish base translations (move all UI strings to translatable terms) +* Use SCSS From 43378ee0920b981a24335e9354e56660ad387833 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 5 Oct 2020 12:10:02 +0200 Subject: [PATCH 10/11] shopfloor_mobile: add fullscreen toggle icons --- shopfloor_mobile/static/wms/src/components/misc.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shopfloor_mobile/static/wms/src/components/misc.js b/shopfloor_mobile/static/wms/src/components/misc.js index 585b6879a3..729df7c5e8 100644 --- a/shopfloor_mobile/static/wms/src/components/misc.js +++ b/shopfloor_mobile/static/wms/src/components/misc.js @@ -437,7 +437,11 @@ Vue.component("btn-fullscreen", { this.fullscreen_on = false; }, }, - template: `{{ btn_label }}`, + template: ` + + {{ fullscreen_on ? 'mdi-fullscreen-exit' : 'mdi-fullscreen' }} {{ btn_label }} + + `, }); Vue.component("empty-location-icon", { From b9df51c33de39ca0dba90d10b8b2f72fcc201848 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 5 Oct 2020 14:08:05 +0200 Subject: [PATCH 11/11] shopfloor_mobile: zone_picking table save space --- .../static/wms/src/scenario/zone_picking.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/shopfloor_mobile/static/wms/src/scenario/zone_picking.js b/shopfloor_mobile/static/wms/src/scenario/zone_picking.js index 326369ab1c..617251f816 100644 --- a/shopfloor_mobile/static/wms/src/scenario/zone_picking.js +++ b/shopfloor_mobile/static/wms/src/scenario/zone_picking.js @@ -294,8 +294,15 @@ const ZonePicking = { const self = this; let fields = [ {path: "product.display_name", label: table_mode ? "Product" : null}, - {path: "package_src.name", label: "Pack"}, - {path: "lot.name", label: "Lot"}, + { + path: "package_src.name", + label: "Pack / Lot", + renderer: function(rec, field) { + const pkg = _.result(rec, "package_src.name", ""); + const lot = _.result(rec, "lot.name", ""); + return lot ? pkg + "\n" + lot : pkg; + }, + }, { path: "quantity", label: "Qty",