diff --git a/setup/shopfloor_single_product_transfer_mobile/odoo/addons/shopfloor_single_product_transfer_mobile b/setup/shopfloor_single_product_transfer_mobile/odoo/addons/shopfloor_single_product_transfer_mobile new file mode 120000 index 00000000000..b7c27cf6414 --- /dev/null +++ b/setup/shopfloor_single_product_transfer_mobile/odoo/addons/shopfloor_single_product_transfer_mobile @@ -0,0 +1 @@ +../../../../shopfloor_single_product_transfer_mobile \ No newline at end of file diff --git a/setup/shopfloor_single_product_transfer_mobile/setup.py b/setup/shopfloor_single_product_transfer_mobile/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/shopfloor_single_product_transfer_mobile/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/shopfloor_single_product_transfer_mobile/README.rst b/shopfloor_single_product_transfer_mobile/README.rst new file mode 100644 index 00000000000..d4a8202ab11 --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/README.rst @@ -0,0 +1,100 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +======================================== +Shopfloor single product transfer mobile +======================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:39010ee9b8915238c90002b46515c302bdd44e6e757ab6fbefe3e13a5ee9aa58 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/16.0/shopfloor_single_product_transfer_mobile + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_single_product_transfer_mobile + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Frontend for the single_product_transfer scenario in shopfloor. + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Camptocamp +* BCIM + +Contributors +------------ + +- Juan Miguel Sánchez Arce + +Design +~~~~~~ + +- Jacques-Etienne Baudoux + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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 +.. |maintainer-TDu| image:: https://github.com/TDu.png?size=40px + :target: https://github.com/TDu + :alt: TDu +.. |maintainer-mmequignon| image:: https://github.com/mmequignon.png?size=40px + :target: https://github.com/mmequignon + :alt: mmequignon + +Current `maintainers `__: + +|maintainer-jbaudoux| |maintainer-TDu| |maintainer-mmequignon| + +This module is part of the `OCA/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/shopfloor_single_product_transfer_mobile/__init__.py b/shopfloor_single_product_transfer_mobile/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/shopfloor_single_product_transfer_mobile/__manifest__.py b/shopfloor_single_product_transfer_mobile/__manifest__.py new file mode 100644 index 00000000000..59683000aa9 --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2022 Camptocamp SA (http://www.camptocamp.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +{ + "name": "Shopfloor single product transfer mobile", + "summary": "Mobile frontend for single product transfer scenario", + "version": "16.0.1.0.0", + "development_status": "Beta", + "depends": ["shopfloor_mobile", "shopfloor_single_product_transfer"], + "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", + "maintainers": ["jbaudoux", "TDu", "mmequignon"], + "website": "https://github.com/OCA/wms", + "category": "Warehouse Management", + "license": "AGPL-3", + "installable": True, + "data": ["templates/assets.xml"], +} diff --git a/shopfloor_single_product_transfer_mobile/i18n/it.po b/shopfloor_single_product_transfer_mobile/i18n/it.po new file mode 100644 index 00000000000..e69de29bb2d diff --git a/shopfloor_single_product_transfer_mobile/i18n/shopfloor_single_product_transfer_mobile.pot b/shopfloor_single_product_transfer_mobile/i18n/shopfloor_single_product_transfer_mobile.pot new file mode 100644 index 00000000000..aadee09bfed --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/i18n/shopfloor_single_product_transfer_mobile.pot @@ -0,0 +1,13 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" diff --git a/shopfloor_single_product_transfer_mobile/readme/CONTRIBUTORS.md b/shopfloor_single_product_transfer_mobile/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..fa83f53ca8b --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/readme/CONTRIBUTORS.md @@ -0,0 +1,5 @@ +- Juan Miguel Sánchez Arce \ + +## Design + +- Jacques-Etienne Baudoux \<\> diff --git a/shopfloor_single_product_transfer_mobile/readme/DESCRIPTION.md b/shopfloor_single_product_transfer_mobile/readme/DESCRIPTION.md new file mode 100644 index 00000000000..6ada7953992 --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Frontend for the single_product_transfer scenario in shopfloor. diff --git a/shopfloor_single_product_transfer_mobile/static/description/icon.png b/shopfloor_single_product_transfer_mobile/static/description/icon.png new file mode 100644 index 00000000000..1dcc49c24f3 Binary files /dev/null and b/shopfloor_single_product_transfer_mobile/static/description/icon.png differ diff --git a/shopfloor_single_product_transfer_mobile/static/description/index.html b/shopfloor_single_product_transfer_mobile/static/description/index.html new file mode 100644 index 00000000000..0af58769ebf --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/static/description/index.html @@ -0,0 +1,441 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Shopfloor single product transfer mobile

+ +

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Frontend for the single_product_transfer scenario in shopfloor.

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp
  • +
  • BCIM
  • +
+
+
+

Contributors

+ +
+

Design

+ +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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.

+

Current maintainers:

+

jbaudoux TDu mmequignon

+

This module is part of the OCA/wms project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+
+ + diff --git a/shopfloor_single_product_transfer_mobile/static/src/demo/demo.single_product_transfer.esm.js b/shopfloor_single_product_transfer_mobile/static/src/demo/demo.single_product_transfer.esm.js new file mode 100644 index 00000000000..7c116a2f010 --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/static/src/demo/demo.single_product_transfer.esm.js @@ -0,0 +1,110 @@ +/** + * Copyright 2022 Camptocamp SA (http://www.camptocamp.com) + * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + */ + +import {demotools} from "/shopfloor_mobile_base/static/src/demo/demo.core.esm.js"; + +const location_src = demotools.makeLocation(); +const picking = demotools.makePicking( + {}, + {lines_count: 2, line_random_pack: true, line_random_dest: true} +); +const selected_move_line = picking.move_lines[0]; + +const single_product_transfer_menu_case = demotools.addAppMenu( + { + name: "Single product transfer", + scenario: "single_product_transfer", + picking_types: [{id: 27, name: "Random type"}], + }, + "sprt_1" +); + +const DEMO_SINGLE_PRODUCT_TRANSFER = { + start: { + next_state: "select_location_or_package", + data: { + select_location_or_package: { + location: location_src, + }, + }, + }, + scan_location_or_package: { + next_state: "select_product", + data: { + select_product: { + location: location_src, + }, + }, + }, + scan_location: { + next_state: "select_product", + data: { + select_product: { + location: location_src, + }, + }, + }, + scan_product: { + next_state: "set_quantity", + data: { + set_quantity: { + picking, + move_line: selected_move_line, + }, + }, + }, + scan_product__action_cancel: { + next_state: "set_quantity", + data: { + set_quantity: { + picking, + move_line: selected_move_line, + }, + }, + }, + set_quantity: function (scanned) { + // Different behaviour depending on the first letter of the scanned barcode: + // - P: Scanned product, increase qty_done and stay in the same screen. + // - L: Scanned location, go to screen 1. + // - Else: Display warning message. + const barcode = scanned.barcode; + if (barcode[0] === "P") { + selected_move_line.qty_done++; + return { + next_state: "set_quantity", + data: { + set_quantity: { + picking, + selected_move_line, + }, + }, + }; + } else if (barcode[0] === "L") { + return { + next_state: "show_completion_info", + data: {}, + }; + } + return { + next_state: "set_quantity", + data: { + set_quantity: { + picking, + selected_move_line, + }, + }, + message: { + message_type: "warning", + body: "Barcode is wrong", + }, + }; + }, +}; + +demotools.add_case( + "single_product_transfer", + single_product_transfer_menu_case, + DEMO_SINGLE_PRODUCT_TRANSFER +); diff --git a/shopfloor_single_product_transfer_mobile/static/src/i18n/en.json b/shopfloor_single_product_transfer_mobile/static/src/i18n/en.json new file mode 100644 index 00000000000..b5a449fe5e0 --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/static/src/i18n/en.json @@ -0,0 +1,14 @@ +{ + "single_product_transfer.start_line.title": "Start by scanning something", + "single_product_transfer.start_line.scan_placeholder": "Scan location / pack / product / lot", + "single_product_transfer.start_line.scan_placeholder_location_pack": "Scan a location or a package", + "single_product_transfer.start_line.scan_placeholder_product_lot_pack": "Scan a product, lot, or package", + "single_product_transfer.select_location_or_package.title": "Scan a location or a package", + "single_product_transfer.select_location_or_package.scan_placeholder": "Scan location / package", + "single_product_transfer.select_product.title": "Select a product", + "single_product_transfer.select_product.scan_placeholder": "Scan product / lot", + "single_product_transfer.set_quantity.title": "Set quantity", + "single_product_transfer.set_quantity.scan_placeholder": "Scan product / packaging / lot / location / package", + "single_product_transfer.set_location.title": "Set location", + "single_product_transfer.set_location.scan_placeholder": "Scan location" +} diff --git a/shopfloor_single_product_transfer_mobile/static/src/i18n/fr.json b/shopfloor_single_product_transfer_mobile/static/src/i18n/fr.json new file mode 100644 index 00000000000..807ec40f55f --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/static/src/i18n/fr.json @@ -0,0 +1,14 @@ +{ + "single_product_transfer.start_line.title": "Commencez par scanner quelque chose", + "single_product_transfer.start_line.scan_placeholder": "Scanner l'emplacement / le paquet / le produit / le lot", + "single_product_transfer.start_line.scan_placeholder_location_pack": "Scanner un emplacement ou un paquet", + "single_product_transfer.start_line.scan_placeholder_product_lot_pack": "Scanner un produit, un lot ou un paquet", + "single_product_transfer.select_location_or_package.title": "Scanner un emplacement ou un paquet", + "single_product_transfer.select_location_or_package.scan_placeholder": "Scanner l'emplacement / le paquet", + "single_product_transfer.select_product.title": "Sélectionner un produit", + "single_product_transfer.select_product.scan_placeholder": "Scanner le produit / le lot", + "single_product_transfer.set_quantity.title": "Définir la quantité", + "single_product_transfer.set_quantity.scan_placeholder": "Scanner le produit / l'emballage / le lot / l'emplacement / le paquet", + "single_product_transfer.set_location.title": "Définir l'emplacement", + "single_product_transfer.set_location.scan_placeholder": "Scanner l'emplacement" +} diff --git a/shopfloor_single_product_transfer_mobile/static/src/scenario/single_product_transfer.esm.js b/shopfloor_single_product_transfer_mobile/static/src/scenario/single_product_transfer.esm.js new file mode 100644 index 00000000000..ad5b1ea9e3c --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/static/src/scenario/single_product_transfer.esm.js @@ -0,0 +1,361 @@ +/** + * Copyright 2022 Camptocamp SA (http://www.camptocamp.com) + * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + */ + +import {ScenarioBaseMixin} from "/shopfloor_mobile_base/static/wms/src/scenario/mixins.js"; +import {process_registry} from "/shopfloor_mobile_base/static/wms/src/services/process_registry.js"; + +const SingleProductTransfer = { + mixins: [ScenarioBaseMixin], + template: ` + + + + + + + + + + +
+ + + + + +
+ +
+ `, + methods: { + screen_title: function () { + if (_.isEmpty(this.current_doc()) || this.state_is("select_document")) { + return this.menu_item().name; + } + const title = this.current_doc().record.name; + return title; + }, + current_doc: function () { + const data = this.state_get_data("set_quantity"); + if (_.isEmpty(data)) { + return null; + } + return { + record: data.move_line.product, + identifier: data.move_line.product.name, + }; + }, + current_location: function () { + const data = this.state_get_data("select_product"); + if (_.isEmpty(data) || _.isEmpty(data.location)) { + return {}; + } + return data.location; + }, + current_location_msg: function () { + if (this.current_location().id) { + return {title: "Working from location " + this.current_location().name}; + } + return {}; + }, + current_package: function () { + const data = this.state_get_data("select_product"); + if (_.isEmpty(data) || _.isEmpty(data.package)) { + return {}; + } + return data.package; + }, + current_package_msg: function () { + if (this.current_package().id) { + return {title: "Working on package " + this.current_package().name}; + } + return {}; + }, + product_detail_options_for_set_quantity: function () { + return { + title_action_field: {action_val_path: "product.barcode"}, + key_title: "product.display_name", + fields: [{path: "lot.name", label: "Lot", action_val_path: "lot.name"}], + }; + }, + move_line_options_for_set_location: function () { + return { + key_title: "product.display_name", + loud_labels: true, + fields: [{path: "location_src.name", label: "Source Location"}], + }; + }, + linear_progress_options_for_select_product: function () { + return { + done_label: "Ongoing", + todo_label: "Available", + color: "lime", + }; + }, + get_select_product_scan_params: function (scanned) { + const params = { + barcode: scanned.text, + }; + const state_location = _.result(this.state.data, "location", false); + params.location_id = state_location.id; + const state_package = _.result(this.state.data, "package", false); + params.package_id = state_package.id; + return params; + }, + get_select_product_package_or_location_data: function () { + if (this.state.data.package) { + return this.state.data.package; + } + return this.state.data.location; + }, + display_operations_progress: function () { + const operation_progress = this._get_operation_progress_data(); + if (operation_progress) { + return operation_progress.to_do > 0; + } + }, + _get_operation_progress_data: function () { + return _.result( + this.get_select_product_package_or_location_data(), + "operation_progress", + false + ); + }, + }, + data: function () { + return { + usage: "single_product_transfer", + initial_state_key: "select_location_or_package", + states: { + init: { + enter: () => { + this.wait_call(this.odoo.call("start")); + }, + }, + get_work: { + /* eslint-disable no-unused-vars */ + on_get_work: (evt) => { + this.wait_call(this.odoo.call("find_work")); + }, + /* eslint-disable no-unused-vars */ + on_manual_selection: (evt) => { + this.state_to("select_location_or_package"); + }, + }, + start_line: { + display_info: { + title: this.$t("single_product_transfer.start_line.title"), + scan_placeholder: () => { + const selected_location_id = + this.state.data.selected_location_id; + const selected_package_id = + this.state.data.selected_package_id; + if ( + this.state.data.scan_location_or_pack_first && + !selected_location_id && + !selected_package_id + ) { + return this.$t( + "single_product_transfer.start_line.scan_placeholder_location_pack" + ); + } + if (selected_package_id || selected_location_id) { + return this.$t( + "single_product_transfer.start_line.scan_placeholder_product_lot_pack" + ); + } + return this.$t( + "single_product_transfer.start_line.scan_placeholder" + ); + }, + }, + on_scan: (scanned) => { + const data = { + selected_line_id: this.state.data.move_line.id, + barcode: scanned.text, + }; + if (this.state.data.selected_location_id) { + data.selected_location_id = + this.state.data.selected_location_id; + } + if (this.state.data.selected_package_id) { + data.selected_package_id = + this.state.data.selected_package_id; + } + this.wait_call(this.odoo.call("confirm_start_line", data)); + }, + }, + select_location_or_package: { + display_info: { + title: this.$t( + "single_product_transfer.select_location_or_package.title" + ), + scan_placeholder: this.$t( + "single_product_transfer.select_location_or_package.scan_placeholder" + ), + }, + on_scan: (scanned) => { + this.wait_call( + this.odoo.call("scan_location_or_package", { + barcode: scanned.text, + }) + ); + }, + }, + select_product: { + display_info: { + title: this.$t("single_product_transfer.select_product.title"), + scan_placeholder: this.$t( + "single_product_transfer.select_product.scan_placeholder" + ), + }, + on_scan: (scanned) => { + const params = this.get_select_product_scan_params(scanned); + this.wait_call(this.odoo.call("scan_product", params)); + }, + on_cancel: () => { + this.wait_call(this.odoo.call("scan_product__action_cancel")); + }, + }, + set_quantity: { + display_info: { + title: this.$t("single_product_transfer.set_quantity.title"), + scan_placeholder: this.$t( + "single_product_transfer.set_quantity.scan_placeholder" + ), + }, + events: { + qty_edit: "on_qty_update", + }, + on_qty_update: (qty) => { + this.state.data.quantity = qty; + }, + on_scan: (scanned) => { + const confirmation = this.state.data.asking_confirmation || ""; + this.wait_call( + this.odoo.call("set_quantity", { + selected_line_id: this.state.data.move_line.id, + barcode: scanned.text, + quantity: this.state.data.quantity, + confirmation, + }) + ); + }, + on_cancel: () => { + this.wait_call( + this.odoo.call("set_quantity__action_cancel", { + selected_line_id: this.state.data.move_line.id, + }) + ); + }, + }, + set_location: { + display_info: { + title: "Set location", + scan_placeholder: "Scan location", + }, + on_scan: (scanned) => { + this.wait_call( + this.odoo.call("set_location", { + selected_line_id: this.state.data.move_line.id, + package_id: this.state.data.package.id, + barcode: scanned.text, + }) + ); + }, + on_back: () => { + this.state_to("set_quantity"); + this.reset_notification(); + }, + }, + show_completion_info: { + on_confirm: () => { + this.state_to("select_location_or_package"); + }, + }, + }, + }; + }, +}; + +process_registry.add("single_product_transfer", SingleProductTransfer); + +export default SingleProductTransfer; diff --git a/shopfloor_single_product_transfer_mobile/static/src/translation_registry.esm.js b/shopfloor_single_product_transfer_mobile/static/src/translation_registry.esm.js new file mode 100644 index 00000000000..f8035503a4f --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/static/src/translation_registry.esm.js @@ -0,0 +1,10 @@ +import {translation_registry} from "/shopfloor_mobile_base/static/wms/src/services/translation_registry.js"; + +translation_registry.load( + "fr-FR", + "/shopfloor_single_product_transfer_mobile/static/src/i18n/fr.json" +); +translation_registry.load( + "en-US", + "/shopfloor_single_product_transfer_mobile/static/src/i18n/en.json" +); diff --git a/shopfloor_single_product_transfer_mobile/templates/assets.xml b/shopfloor_single_product_transfer_mobile/templates/assets.xml new file mode 100644 index 00000000000..f2fd2e1252b --- /dev/null +++ b/shopfloor_single_product_transfer_mobile/templates/assets.xml @@ -0,0 +1,47 @@ + + + + +