diff --git a/requirements.txt b/requirements.txt index a0eac5b6..97245be3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,5 +3,6 @@ astor cryptography odoo_test_helper openpyxl +python-barcode xlrd xlsxwriter diff --git a/setup/stock_barcodes/odoo/addons/stock_barcodes b/setup/stock_barcodes/odoo/addons/stock_barcodes new file mode 120000 index 00000000..7172e5ad --- /dev/null +++ b/setup/stock_barcodes/odoo/addons/stock_barcodes @@ -0,0 +1 @@ +../../../../stock_barcodes \ No newline at end of file diff --git a/setup/stock_barcodes/setup.py b/setup/stock_barcodes/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/stock_barcodes/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/setup/stock_picking_product_barcode_report/odoo/addons/stock_picking_product_barcode_report b/setup/stock_picking_product_barcode_report/odoo/addons/stock_picking_product_barcode_report new file mode 120000 index 00000000..b0b7439a --- /dev/null +++ b/setup/stock_picking_product_barcode_report/odoo/addons/stock_picking_product_barcode_report @@ -0,0 +1 @@ +../../../../stock_picking_product_barcode_report \ No newline at end of file diff --git a/setup/stock_picking_product_barcode_report/setup.py b/setup/stock_picking_product_barcode_report/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/stock_picking_product_barcode_report/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/setup/web_widget_numeric_step/odoo/addons/web_widget_numeric_step b/setup/web_widget_numeric_step/odoo/addons/web_widget_numeric_step new file mode 120000 index 00000000..13aab738 --- /dev/null +++ b/setup/web_widget_numeric_step/odoo/addons/web_widget_numeric_step @@ -0,0 +1 @@ +../../../../web_widget_numeric_step \ No newline at end of file diff --git a/setup/web_widget_numeric_step/setup.py b/setup/web_widget_numeric_step/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/web_widget_numeric_step/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_barcodes/README.rst b/stock_barcodes/README.rst new file mode 100644 index 00000000..5e70d8ba --- /dev/null +++ b/stock_barcodes/README.rst @@ -0,0 +1,420 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +============== +Stock Barcodes +============== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:e0efe6d44d3d0fa81c0abcf6e0a89a1dfc6512a6011a92e322cb0f0194ef79c5 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fstock--logistics--barcode-lightgray.png?logo=github + :target: https://github.com/OCA/stock-logistics-barcode/tree/16.0/stock_barcodes + :alt: OCA/stock-logistics-barcode +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/stock-logistics-barcode-16-0/stock-logistics-barcode-16-0-stock_barcodes + :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/stock-logistics-barcode&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module provides a barcode reader interface for stock module. + +This module contains a base wizard read barcode that can be extended by +other modules. + +This module also makes use of this wizard for providing barcode support for +doing inventories and picking operations. + +This module provides configuring barcodes for barcode actions. + + + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Barcode interface for inventory operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Option 1: To use the barcode interface on inventory + + #. Go to *Inventory > operations > Inventory Adjustments*. + #. Create new inventory with "Select products manually" option. + #. Start inventory. + #. Click to "Scan barcodes" smart button. + #. Start reading barcodes. + +Option 2: Use the barcode interface inventory directly from the Barcodes application + #. Go to *Barcodes*. + #. Select the *Inventory* option. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/inventory_barcode_action.png + :height: 100 + :width: 200 + :alt: Inventory barcode action + + #. Start scanning barcodes. + +Actions + # Press the *+ Product* button to display the form for the new item. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/add_product.png + :height: 100 + :width: 200 + :alt: Add product + + # When you select a product, a numeric field is displayed to add the quantity. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/form_add_product_quantity.png + :height: 100 + :width: 200 + :alt: Add quantity product + + # When you press the button with the trash can icon, the values of the form are reset (except for the location) without closing it. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/form_add_product_reset.png + :height: 100 + :width: 200 + :alt: Reset data form + + # When you press the *Clean values* button, all fields are reset and the form is closed. + # When you press the *Confirm* button, the new item is added and the form is closed. + # When the eye icon is closed, the created items greater than zero are displayed, and if not, those less than or equal to zero. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/list_items.png + :height: 100 + :width: 200 + :alt: Reset data form + + # In the list, the trash can icon allows you to reset the quantity to zero and the edit icon allows you to change the item values. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/list_action_items.png + :height: 100 + :width: 200 + :alt: Reset data form + + # The *Apply* button is only displayed if there are items with quantities greater than zero, regardless of whether they were scanned or entered manually; If you press all the defined quantities will be processed after defining the reason for the inventory adjustment and then the main barcode menu will be displayed. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/apply_inventory.png + :height: 100 + :width: 200 + :alt: Apply inventory + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/apply_inventory_reason.png + :height: 100 + :width: 200 + :alt: Apply inventory reason + + +Barcode interface for picking operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You can use the barcode interface in a picking or an operation type, the main +difference is that if you open the barcode interface from a picking, this +picking is locked and you read products for it. + +To use the barcode interface on picking operations: + +#. Go to *Inventory*. +#. Click on scanner button on any operation type. +#. Start reading barcodes. + +Option 1: To use the barcode interface on a picking: + + #. Go to *Inventory > Transfers*. + #. Click to "Scan barcodes" smart button. + #. Start reading barcodes. + +Option 2: Use the barcode interface picking directly from the Barcodes application + #. Go to *Barcodes*. + #. Select the option *OPERATIONS*. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/inventory_barcode_action.png + :height: 100 + :width: 200 + :alt: Operation barcode action + + # Select the type of picking. + # The pickings in ready status are displayed, select the one you want to start scanning. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/list_picking.png + :height: 100 + :width: 200 + :alt: List picking + + #. Start scanning barcodes. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/barcode_interface_picking.png + :height: 100 + :width: 200 + :alt: List picking + +Actions + # All the items that have been configured for the selected picking are listed. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/list_items_picking.png + :height: 100 + :width: 200 + :alt: List picking + + # The edit icon in the list allows you to modify the data. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/list_items_picking_edit.png + :height: 100 + :width: 200 + :alt: Edit picking + + # The button that contains a *+120* (in this case), allows you to define all the + remaining quantities. Once defined, this button disappears and if you want to change the + quantities, press the edit button. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/list_items_picking_quantity.png + :height: 100 + :width: 200 + :alt: Quantity picking + + # If there is at least one item with a quantity already defined, an eye icon is displayed, + which if closed shows the items and their quantities already scanned. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/list_items_picking_scanned.png + :height: 100 + :width: 200 + :alt: Picking scanned + + # When you press the *Validate* button, a wizard will be displayed to confirm the action. + If everything is correct, it is validated and you return to the picking list mentioned above. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/confirm_items_picking.png + :height: 100 + :width: 200 + :alt: Picking scanned + + # If there is an item whose quantity is zero, a wizard will be displayed after the one mentioned + above, to confirm if you want to process all the quantities. If positive, you will proceed + and be directed to the list mentioned above in the previous point. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/confirm_all_quantity_items_picking.png + :height: 100 + :width: 200 + :alt: Picking scanned + + # Press the *+ Product* button to display the form for the new item. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/add_product.png + :height: 100 + :width: 200 + :alt: Add product + + # When you select a product, a numeric field is displayed to add the quantity. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/form_add_product_quantity.png + :height: 100 + :width: 200 + :alt: Add quantity product + + # When you press the button with the trash can icon, the values of the form are reset (except for the location) without closing it. + + .. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/form_add_product_reset.png + :height: 100 + :width: 200 + :alt: Reset data form + + # When you press the *Clean values* button, all fields are reset and the form is closed. + # When you press the *Confirm* button, the new item is added and the form is closed. + # When adding the new item all the quantities are assigned to it, if you want to modify it, press the edit icon. + +The barcode scanner interface has two operation modes. In both of them user +can scan: + +#. Warehouse locations with barcode. +#. Product packaging with barcode. +#. Product with barcode. +#. Product Lots (The barcode is name field in this case). + + +Automatic operation mode +~~~~~~~~~~~~~~~~~~~~~~~~ + +This is the default mode, all screen controls are locked to avoid scan into +fields. + +The user only has to scan barcode in physical warehouse locations with a +scanner hardward, the interface read the barcode and do operations in this +order: + +#. Try search a product, if found, is assigned to product_id field and creates + or update inventory line with 1.0 unit. (If product has tracking by lots + the interface wait for a lot to be scanned). +#. Try search a product packaging, if found, the product_id related is set, + product quantities are updated and create or update inventory line with + product quantities defined in the product packaging. +#. Try search a lot (The product is mandatory in this case so you first scan a + product and then scann a lot), this lot field is not erased until that + product change, so for each product scann the interface add or update a + inventory line with this lot. +#. Try to search a location, if found the field location is set and next scan + action will be done with this warehouse location. + +If barcode has not found, when message is displayed you can create this lot +scanning the product. + +Manual entry mode +~~~~~~~~~~~~~~~~~ + +You can change to "manual entry" to allow to select data without scanner +hardware, but hardward scanner still active on, so a use case would be when +user wants set quantities manually instead increment 1.0 unit peer scan action. + +Scan logs +~~~~~~~~~ + +All scanned barcodes are saved into model. +Barcode scanning interface display 10 last records linked to model, the goal of +this log is show to user other reads with the same product and location done +by other users. +User can remove the last read scan. + +Barcode interface for barcode actions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To use the barcode interface for actions: + +#. Go to *Inventory > Configuration > Barcode Actions*. +#. Create a new barcode action and configure the barcode. + +.. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/create_barcode_action.png + :height: 100 + :width: 200 + :alt: Print barcodes + +#. Select the barcode actions you want to use, a button (PRINT BARCODES) will appear that allows you to print the configured barcodes to PDF. + +.. image:: https://raw.githubusercontent.com/OCA/stock-logistics-barcode/16.0/stock_barcodes/static/src/img/print_barcodes.png + :height: 100 + :width: 200 + :alt: Print barcodes + +#. Go to *Barcodes*. +#. Start scanning barcodes from actions. + +Known issues / Roadmap +====================== + +* Excute action_done() method outside onchange environment. +* Allow create product when a barcode has not been found. +* Allow to select picking reading its barcode. +* Allow to select multiple pickings to process scanned products. + +Changelog +========= + +11.0.1.1.0 (2019-09-24) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [ADD] New feature. + User can uses barcode interface in picking operations. + +13.0.1.1.1 (2021-02-06) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [ADD] New feature. + Add option to get lots automatically based on removal strategy in inventory. + +14.0.1.0.0 (2021-04-05) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [ADD] New feature. + Add security for users. + +16.0.1.0.0 (2025-01-23) +~~~~~~~~~~~~~~~~~~~~~~~ +* [IMP] + Improved views to optimize navigation and functionality. + Intuitive and mobile-friendly views. + Visual improvement of the main view accessed from the Barcodes menu. + +* [ADD] New feature. + Barcode reading to barcode actions. + Generate PDF document for the barcodes of the selected barcode actions. + + +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 +~~~~~~~ + +* Tecnativa + +Contributors +~~~~~~~~~~~~ + + +* `Tecnativa `_: + + * Sergio Teruel + * Carlos Dauden + * Pedro M. Baeza + * Alexandre D. Díaz + +* `Onestein `_: + + * Andrea Stirpe + +* `InitOS `_: + + * Foram Shah + +* `ForgeFlow `_: + + * Lois Rilo + +* Enric Tobella + +* `Binhex `_: + + * Edilio Escalona Almira + +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. + +This module is part of the `OCA/stock-logistics-barcode `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_barcodes/__init__.py b/stock_barcodes/__init__.py new file mode 100644 index 00000000..7ed583d8 --- /dev/null +++ b/stock_barcodes/__init__.py @@ -0,0 +1,7 @@ +# Copyright 2019 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models +from . import wizard +from . import reports +from .hooks import pre_init_hook diff --git a/stock_barcodes/__manifest__.py b/stock_barcodes/__manifest__.py new file mode 100644 index 00000000..6c8f4a86 --- /dev/null +++ b/stock_barcodes/__manifest__.py @@ -0,0 +1,47 @@ +# Copyright 2019 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Stock Barcodes", + "summary": "It provides read barcode on stock operations.", + "version": "16.0.2.2.4", + "author": "Tecnativa, " "Odoo Community Association (OCA)", + "website": "https://github.com/OCA/stock-logistics-barcode", + "license": "AGPL-3", + "category": "Extra Tools", + "depends": ["barcodes", "stock", "web_widget_numeric_step", "web", "mail"], + "data": [ + "security/ir.model.access.csv", + "views/stock_barcodes_action_view.xml", + "views/stock_barcodes_option_view.xml", + "views/stock_location_views.xml", + "views/stock_picking_views.xml", + "wizard/stock_production_lot_views.xml", + "wizard/stock_barcodes_read_views.xml", + "wizard/stock_barcodes_read_picking_views.xml", + "wizard/stock_barcodes_read_todo_view.xml", + "wizard/stock_barcodes_read_inventory_views.xml", + # Keep order + "data/stock_barcodes_action.xml", + "data/stock_barcodes_option.xml", + "views/stock_barcodes_menu.xml", + # Reports + "reports/barcode_actions_report.xml", + "reports/reports.xml", + ], + "assets": { + "web.assets_backend": [ + "/stock_barcodes/static/src/**/*.esm.js", + ( + "after", + "/web_widget_numeric_step/static/src/numeric_step.xml", + "/stock_barcodes/static/src/widgets/numeric_step.xml", + ), + "/stock_barcodes/static/src/views/kanban/stock_barcodes_kanban.xml", + "/stock_barcodes/static/src/widgets/view_button.xml", + "/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.xml", + "/stock_barcodes/static/src/**/*.scss", + ], + }, + "installable": True, + "pre_init_hook": "pre_init_hook", +} diff --git a/stock_barcodes/data/stock_barcodes_action.xml b/stock_barcodes/data/stock_barcodes_action.xml new file mode 100644 index 00000000..0dee6947 --- /dev/null +++ b/stock_barcodes/data/stock_barcodes_action.xml @@ -0,0 +1,50 @@ + + + + + Picking IN + 10 + + 1 + {'search_default_code': 'incoming', 'search_default_barcode_options': 1} + + + Picking INTERNAL + 30 + + 3 + {'search_default_code': 'internal', 'search_default_barcode_options': 1} + + + Picking OUT + 20 + + 2 + {'search_default_code': 'outgoing', 'search_default_barcode_options': 1} + + + + Inventory + 40 + + 8 + {'inventory_mode': True} + + + + Operations + 40 + + 9 + {'operations_mode': True} + + diff --git a/stock_barcodes/data/stock_barcodes_option.xml b/stock_barcodes/data/stock_barcodes_option.xml new file mode 100644 index 00000000..9a344ba4 --- /dev/null +++ b/stock_barcodes/data/stock_barcodes_option.xml @@ -0,0 +1,635 @@ + + + + Picking OUT options + OUT + True + True + guided + True + True + move_ids + True + + + Package + 1 + 10 + package_id + True + False + False + True + False + + + + Product + 1 + 20 + product_id + False + False + True + True + True + + + + Lot + 1 + 30 + lot_id + False + False + False + True + True + + + + Source + 2 + 40 + location_id + False + True + True + False + True + + + + Qty. + 3 + 50 + product_qty + False + False + False + True + True + + + + + Picking IN options + IN + True + False + False + + True + False + move_line_ids + False + + + Dest. + 1 + 10 + location_dest_id + True + True + False + False + False + + + + Product + 20 + product_id + True + True + True + + + + Lot + 30 + lot_id + True + False + True + + + + Product Qty + 40 + product_qty + True + + + + + Picking Internal options + INT + guided + False + False + True + True + True + move_line_ids + True + + + Source + 1 + 10 + location_id + False + True + True + False + True + + + + Prod. + 2 + 20 + product_id + False + False + True + False + True + + + + Package + 2 + 30 + package_id + True + False + False + True + False + + + + Lot + 2 + 30 + lot_id + False + False + False + True + True + + + + Dest. + 3 + 50 + location_dest_id + True + False + False + True + True + + + + Qty + 4 + 60 + product_qty + False + False + False + True + True + + + + + Picking relocation options + REL + + False + False + True + True + False + False + move_line_ids + True + + + Source + 0 + 10 + location_id + False + False + False + True + True + + + + Product + 1 + 20 + product_id + False + False + False + True + True + + + + Package + 1 + 25 + package_id + False + False + True + True + + + + Lot + 1 + 30 + lot_id + False + False + False + True + True + + + + Package Dest. + 2 + 35 + result_package_id + False + False + True + True + + + + Dest. + 2 + 40 + location_dest_id + False + False + True + True + True + + + + Product Qty + 3 + 50 + product_qty + False + False + False + True + True + + + + + Inventory options + INV + + + + Location + 1 + 10 + location_id + True + False + False + True + False + + + + Packaging + 2 + 10 + packaging_id + False + False + True + False + True + + + + Product + 2 + 20 + product_id + False + False + True + True + True + + + + Lot + 2 + 30 + lot_id + False + False + True + True + True + + + + Product Qty + 3 + 50 + product_qty + False + False + False + True + True + + + + + + + Operation options + OPE + + + + Location + 1 + 10 + location_id + True + False + False + True + False + + + + Packaging + 2 + 10 + packaging_id + False + False + True + False + True + + + + Product + 2 + 20 + product_id + False + False + True + True + True + + + + Lot + 2 + 30 + lot_id + False + False + True + True + True + + + + Product Qty + 3 + 50 + product_qty + False + False + False + True + True + + + + diff --git a/stock_barcodes/hooks.py b/stock_barcodes/hooks.py new file mode 100644 index 00000000..d718c63c --- /dev/null +++ b/stock_barcodes/hooks.py @@ -0,0 +1,20 @@ +# Copyright 2021 Tecnativa - Sergio Teruel +# Copyright 2024 Tecnativa - Carlos Dauden +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + + +def pre_init_hook(cr): + cr.execute( + """ + ALTER TABLE stock_move_line + ADD COLUMN IF NOT EXISTS barcode_scan_state VARCHAR DEFAULT 'pending'; + ALTER TABLE stock_move_line ALTER COLUMN barcode_scan_state DROP DEFAULT; + """, + ) + cr.execute( + """ + ALTER TABLE stock_move + ADD COLUMN IF NOT EXISTS barcode_backorder_action VARCHAR DEFAULT 'pending'; + ALTER TABLE stock_move ALTER COLUMN barcode_backorder_action DROP DEFAULT; + """, + ) diff --git a/stock_barcodes/i18n/es.po b/stock_barcodes/i18n/es.po new file mode 100644 index 00000000..9a3bc8c5 --- /dev/null +++ b/stock_barcodes/i18n/es.po @@ -0,0 +1,2422 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_barcodes +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-02-06 20:07+0000\n" +"PO-Revision-Date: 2023-10-30 21:36+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_wiz_candidate_picking__state +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking__picking_state +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_todo__picking_state +msgid "" +" * Draft: The transfer is not confirmed yet. Reservation doesn't apply.\n" +" * Waiting another operation: This transfer is waiting for another operation " +"before being ready.\n" +" * Waiting: The transfer is waiting for the availability of some products.\n" +"(a) The shipping policy is \"As soon as possible\": no product could be " +"reserved.\n" +"(b) The shipping policy is \"When all products are ready\": not all the " +"products could be reserved.\n" +" * Ready: The transfer is ready to be processed.\n" +"(a) The shipping policy is \"As soon as possible\": at least one product has " +"been reserved.\n" +"(b) The shipping policy is \"When all products are ready\": all product have " +"been reserved.\n" +" * Done: The transfer has been processed.\n" +" * Cancelled: The transfer has been cancelled." +msgstr "" +" * Borrador: La transferencia no ha sido confirmada. No se realizan " +"reservas.\n" +" * Esperando otra operación: La transferencia espera otra operación antes de " +"estar preparada.\n" +" * Esperando: La transferencia está esperando disponibilidad de algunos " +"productos.\n" +"(a) La política de envío es \"Tan pronto como sea posible\" ningún producto " +"pudo ser reservado.\n" +"(b) La política de envío es \"Cuando todos los productos estén listos\": no " +"todos los productos pueden reservarse.\n" +" * Preparado: La transferencia está lista para ser procesada.\n" +"(a) La política de envío es \"Tan pronto como sea posible\": por lo menos un " +"producto se ha reservado.\n" +"(b) La política de envío es \"Cuando todos los productos estén listos\": " +"todos los productos han sido reservados.\n" +" * Hecho: la transferencia ha sido procesada.\n" +" * Cancelado: la transferencia ha sido cancelada." + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/models/stock_barcodes_action.py:0 +#, python-format +msgid " Barcode has already been assigned to the action(s): {}." +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/models/stock_barcodes_action.py:0 +#, python-format +msgid "" +" The barcode {} is not correct.Use numbers, letters and dashes, without " +"spaces.E.g. 15753, BC-5789,er-56 " +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "%(barcode)s (%(message)s)" +msgstr "%(barcode)s (%(message)s)" + +#. module: stock_barcodes +#: model:ir.actions.report,print_report_name:stock_barcodes.action_report_barcode_actions +msgid "'Barcodes - %s' % (object.name)" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_new_lot +msgid "1 - Scan or input product barcode" +msgstr "1 - Escanea o introduce el código de barras del producto" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_new_lot +msgid "2 - Scan or input product lot barcode" +msgstr "2 - Escanea o introduce el código de barras del lote" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.stock_picking_type_kanban +msgid "" +msgstr "" +"" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.stock_picking_type_kanban +msgid "" +"\n" +" New" +msgstr "" +"\n" +" Nuevo" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "" +"" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +msgstr "" +"" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.stock_picking_type_kanban +msgid "" +"\n" +" New" +msgstr "" +"\n" +" Nouveau" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "" +"" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Clean Values" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Confirm" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Product" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_picking_form +msgid "Scan barcodes" +msgstr "Scan codes-barres" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "" +"Dest. Location\n" +" " +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "" +"Source Location\n" +" \n" +" " +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "" +"Lot S/N\n" +" " +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +msgid "" +"Package\n" +" " +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "" +"Product\n" +" " +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "" +"Source Package -> Result Package\n" +" \n" +" " +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "" +"Total Qty\n" +" " +msgstr "" +"Qté totale\n" +" " + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "ADD PRODUCT" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__accumulate_read_quantity +msgid "Accumulate Read Quantity" +msgstr "Accumuler les quantités lues" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__action_ids +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__action_ids +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__action_ids +msgid "Action" +msgstr "Action" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__action_window_id +msgid "Action window" +msgstr "Fenêtre d'action" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_stock_barcodes_action +msgid "Actions for barcode interface" +msgstr "Actions de l'interface code-barres" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__active +msgid "Active" +msgstr "Actif" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__allow_negative_quant +msgid "Allow Negative Quant" +msgstr "Autoriser quantité négative" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__create_lot +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__create_lot +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__create_lot +msgid "Allow create lot" +msgstr "Autoriser création de lot" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "Are you sure to validate the picking ?" +msgstr "Le transfert sera validé. Continuer ?" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "Assign Serial Numbers" +msgstr "Assigner des numéros de série" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__auto_put_in_pack +msgid "Auto put in pack" +msgstr "Mise en colis auto" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__auto_put_in_pack +msgid "Auto put in pack before picking validation" +msgstr "Mise en colis auto avant validation du transfert" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_move__barcode_backorder_action +msgid "Backorder action" +msgstr "Action reliquat" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__barcode +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__barcode +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__barcode +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__barcode +#: model_terms:ir.ui.view,arch_db:stock_barcodes.stock_location_form_inherit +msgid "Barcode" +msgstr "Code-barres" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_barcodes_barcode_events_mixin +msgid "Barcode Event Mixin" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_picking_type__barcode_option_group_id +msgid "Barcode Option Group" +msgstr "Code-barres - Groupe d'options" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/models/stock_picking.py:0 +#, python-format +msgid "" +"Barcode Option Group is not configured on Operation Type '%(pick_type)s'." +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_pickingtype_filter +msgid "Barcode Options" +msgstr "Code-barres - Options" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_quant___barcode_scanned +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_new_lot___barcode_scanned +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read___barcode_scanned +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory___barcode_scanned +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking___barcode_scanned +msgid "Barcode Scanned" +msgstr "Code-barres scanné" + +#. module: stock_barcodes +#. odoo-javascript +#: code:addons/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.xml:0 +#, python-format +msgid "Barcode Scanner" +msgstr "" + +#. module: stock_barcodes +#: model:ir.ui.menu,name:stock_barcodes.menu_action_stock_barcodes +msgid "Barcode actions" +msgstr "Code-barres - Actions" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__barcode_image +msgid "Barcode image" +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Barcode not found" +msgstr "Code-barres introuvable" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Barcode not found or field already filled" +msgstr "Code-barres introuvable ou déjà renseigné" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Barcode not found with this screen values" +msgstr "Code-barres introuvable avec les valeurs sur cet écran" + +#. module: stock_barcodes +#: model:ir.ui.menu,name:stock_barcodes.menu_action_stock_barcodes_option_group +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_option_group_form +msgid "Barcode options" +msgstr "Code-barres - Options" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read__message_type__success +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_inventory__message_type__success +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_picking__message_type__success +msgid "Barcode read correctly" +msgstr "Le code-barres a bien été lu" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read__message_type__info +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_inventory__message_type__info +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_picking__message_type__info +msgid "Barcode read with additional info" +msgstr "Code-barres lu avec infos additionnelles" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read_picking.py:0 +#, python-format +msgid "Barcode reader" +msgstr "Lecteur de codes-barres" + +#. module: stock_barcodes +#: model:ir.actions.act_window,name:stock_barcodes.action_stock_barcodes_action_kanban +#: model:ir.actions.client,name:stock_barcodes.action_stock_barcodes_action_client +#: model:ir.ui.menu,name:stock_barcodes.stock_barcodes_root +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_picking_type_form +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Barcodes" +msgstr "Codes-barres" + +#. module: stock_barcodes +#: model:ir.actions.report,name:stock_barcodes.action_report_barcode_actions +msgid "Barcodes (PDF)" +msgstr "" + +#. module: stock_barcodes +#: model:ir.actions.act_window,name:stock_barcodes.action_stock_barcodes_read +#: model:ir.actions.act_window,name:stock_barcodes.action_stock_barcodes_read_inventory +#: model:ir.actions.act_window,name:stock_barcodes.action_stock_barcodes_read_picking +msgid "Barcodes Read" +msgstr "Lecture de codes-barres" + +#. module: stock_barcodes +#: model:ir.actions.act_window,name:stock_barcodes.action_stock_barcodes +#: model:ir.actions.act_window,name:stock_barcodes.action_stock_barcodes_action +msgid "Barcodes actions" +msgstr "Codes-barres - Actions" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form_manual_qty +msgid "Barcodes manual quantities" +msgstr "Codes-barres - Quantités manuelles" + +#. module: stock_barcodes +#: model:ir.actions.act_window,name:stock_barcodes.action_stock_barcodes_menu +msgid "Barcodes menu" +msgstr "Codes-barres - Menu" + +#. module: stock_barcodes +#: model:ir.actions.act_window,name:stock_barcodes.action_stock_barcodes_option +msgid "Barcodes options" +msgstr "Codes-barres - Options" + +#. module: stock_barcodes +#: model:ir.actions.act_window,name:stock_barcodes.action_stock_barcodes_option_group +msgid "Barcodes options groups" +msgstr "Codes-barres - Groupes d'options" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_option_group_form +msgid "Behavior settings" +msgstr "Options de l'interface" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_new_lot +msgid "Cancel" +msgstr "Annuler" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__name +msgid "Candidate Picking" +msgstr "Transfert suggéré" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__candidate_picking_ids +msgid "Candidate pickings" +msgstr "Transferts suggérés" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_wiz_candidate_picking +msgid "Candidate pickings for barcode interface" +msgstr "Transferts suggérés pour l'interface codes-barres" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__candidate_picking_id +msgid "Candidate stock picking" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "Clean" +msgstr "Vider" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__clean_after_done +msgid "Clean After Done" +msgstr "Vider après ajout" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Clean Values" +msgstr "Vider les valeurs" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Clean lot" +msgstr "Vider le lot" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Clean package info" +msgstr "Vider les infos du colis" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Clean product" +msgstr "Vider le produit" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read_picking.py:0 +#, python-format +msgid "Click on picking pushpin to lock it" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__code +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_pickingtype_filter +msgid "Code" +msgstr "Code" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__company_id +msgid "Company" +msgstr "Société" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_new_lot +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Confirm" +msgstr "Confirmer" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__confirmed_moves +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__confirmed_moves +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__confirmed_moves +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__confirmed_moves +msgid "Confirmed moves" +msgstr "Mouvements confirmés" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__partner_id +msgid "Contact" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__context +msgid "Context" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__count_elements +msgid "Count Elements" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__count_inventory_quants +msgid "Count Inventory Quants" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__stock_move__barcode_backorder_action__create_backorder +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "Create Backorder" +msgstr "Créer un reliquat" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Create lot" +msgstr "Créer un lot" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__create_lot +msgid "Create lots if not match" +msgstr "Créer les lots manquants" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Create new lot" +msgstr "Créer un nouveau lot" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Create new package" +msgstr "Créer un nouveau colis" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_report_stock_barcodes_report_barcode_actions__create_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__create_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__create_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__create_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__create_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_new_lot__create_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__create_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__create_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_report_stock_barcodes_report_barcode_actions__create_date +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__create_date +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__create_date +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__create_date +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__create_date +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_new_lot__create_date +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__create_date +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__create_date +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__create_date +msgid "Created on" +msgstr "Créé le" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__date +msgid "Creation Date" +msgstr "Date de création" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_wiz_candidate_picking__date +msgid "Creation Date, usually the time of the order" +msgstr "Date de création, en général la date de la commande" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_picking__picking_type_code__outgoing +msgid "Customers" +msgstr "Clients" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__manual_entry +msgid "Default value when open scan interface" +msgstr "Valeur par défaut à l'ouverture de l'interface de scan" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__product_uom_qty +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__product_uom_qty +msgid "Demand" +msgstr "Demande" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__location_dest_name +msgid "Destinatino Name" +msgstr "Nom de la destination" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__picking_location_dest_id +#: model:ir.model.fields.selection,name:stock_barcodes.selection__stock_barcodes_option_group__location_field_to_sort__location_dest_id +msgid "Destination Location" +msgstr "Emplacement de destination" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__stock_barcodes_option_group__source_pending_moves__move_line_ids +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "Detailed operations" +msgstr "Opérations détaillées" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__display_assign_serial +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__display_assign_serial +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__display_assign_serial +msgid "Display Assign Serial" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__display_menu +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__display_menu +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__display_menu +msgid "Display Menu" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_report_stock_barcodes_report_barcode_actions__display_name +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__display_name +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__display_name +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__display_name +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__display_name +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_new_lot__display_name +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__display_name +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__display_name +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__display_name +msgid "Display Name" +msgstr "Nom d'affichage" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__display_notification +msgid "Display Odoo notifications" +msgstr "Afficher les notifications Odoo" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__no_increase_qty_done +msgid "Do not increase qty done on each scan" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__product_qty_done +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__qty_done +#: model:ir.model.fields.selection,name:stock_barcodes.selection__stock_move_line__barcode_scan_state__done +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_todo__state__done +msgid "Done" +msgstr "Fait" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__stock_move_line__barcode_scan_state__done_forced +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_todo__state__done_forced +msgid "Done forced" +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Empty field" +msgstr "Champ non renseigné" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__enable_add_product +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__enable_add_product +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__enable_add_product +msgid "Enable Add Product" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read__product_tracking +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_inventory__product_tracking +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking__product_tracking +msgid "Ensure the traceability of a storable product in your warehouse." +msgstr "Assurer la traçabilité d'un produit stockable dans votre entrepôt." + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read__manual_entry +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_inventory__manual_entry +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking__manual_entry +msgid "Entry manual data" +msgstr "Saisir les données manuellement" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__field_name +msgid "Field Name" +msgstr "Nom de champ" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__fill_fields_from_lot +msgid "Fill Fields From Lot" +msgstr "Renseigner les champs à partir du lot" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__filled_default +msgid "Filled Default" +msgstr "Renseigné par défaut" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Force done" +msgstr "Forcer en fait" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__forced +msgid "Forced" +msgstr "Forcé" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__forced_todo_key +msgid "Forced Todo Key" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__auto_lot +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__auto_lot +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__auto_lot +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__auto_lot +msgid "Get lots automatically" +msgstr "Obtenir les lots automatiquement" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read__product_packaging_ids +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_inventory__product_packaging_ids +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking__product_packaging_ids +msgid "Gives the different ways to package the same product." +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__group_key_for_todo_records +msgid "Group Key For Todo Records" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__stock_barcodes_option_group__barcode_guided_mode__guided +msgid "Guided" +msgstr "Guidé" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__guided_location_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__guided_location_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__guided_location_id +msgid "Guided Location" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__guided_location_dest_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__guided_location_dest_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__guided_location_dest_id +msgid "Guided Location Dest" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__guided_lot_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__guided_lot_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__guided_lot_id +msgid "Guided Lot" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__guided_product_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__guided_product_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__guided_product_id +msgid "Guided Product" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_report_stock_barcodes_report_barcode_actions__id +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__id +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__id +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_new_lot__id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__id +msgid "ID" +msgstr "ID" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__icon_class +msgid "Icon Class" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__accumulate_read_quantity +msgid "" +"If checked quantity will be accumulated to the existing record instead of " +"overwrite it with the new quantity value" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__auto_lot +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read__auto_lot +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_inventory__auto_lot +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking__auto_lot +msgid "" +"If checked the lot will be set automatically with the same removal startegy" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__create_lot +msgid "" +"If checked the lot will created automatically with the scanned barcode if " +"not exists " +msgstr "" +"Si coché, un lot sera créé automatiquement avec le code-barres scanné " +"lorsqu'aucun lot n'existe déjà " + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__show_detailed_operations +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking__show_detailed_operations +msgid "If checked the picking detailed operations are displayed" +msgstr "Si coché, les opérations de transfert détaillées seront affichées" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__keep_screen_values +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking__keep_screen_values +msgid "" +"If checked the wizard values are kept until the pending move is completed" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__fill_fields_from_lot +msgid "" +"If checked, the fields in the interface will be filled from the scanned lot" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__is_manual_qty +msgid "" +"If it is checked, it always shows the product quantity field in edit mode" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__allow_negative_quant +msgid "" +"If it is checked, it will allow the creation of movements that generate " +"negative stock" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__ignore_quant_location +msgid "" +"If it is checked, quant location will be ignored when reading lot/package" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__is_manual_confirm +msgid "If it is marked, the movement must always be confirmed from a button" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "If locked keep result package" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__ignore_quant_location +msgid "Ignore Quant Location" +msgstr "Ignorer quantité en stock" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__ignore_filled_fields +msgid "Ignore filled fields" +msgstr "Ignorer champs renseignés" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "Ignore rest" +msgstr "Ignorer le reste" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read__message_type__info_page +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_inventory__message_type__info_page +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_picking__message_type__info_page +msgid "Info page" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_picking__picking_type_code__internal +msgid "Internal" +msgstr "Interne" + +#. module: stock_barcodes +#: model:stock.barcodes.action,name:stock_barcodes.stock_barcodes_action_inventory +msgid "Inventory" +msgstr "Inventaire" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__inventory_quant_ids +msgid "Inventory Quant" +msgstr "Quantité inventaire" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read_inventory.py:0 +#, python-format +msgid "Inventory line with more than one unit in serial tracked product" +msgstr "Plusieurs unités trouvées avec le même numéro de série" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__inventory_product_qty +msgid "Inventory quantities" +msgstr "Quantités inventaire" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +msgid "Inventory quants" +msgstr "Quantités inventaire" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__todo_line_is_extra_line +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__is_extra_line +msgid "Is Extra Line" +msgstr "Ligne additionnelle" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__is_manual_confirm +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__is_manual_confirm +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__is_manual_confirm +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__is_manual_confirm +msgid "Is Manual Confirm" +msgstr "Confirmation manuelle" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__is_manual_qty +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__is_manual_qty +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__is_manual_qty +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__is_manual_qty +msgid "Is Manual Qty" +msgstr "Quantité manuelle" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__is_pending +msgid "Is Pending" +msgstr "En attente" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__is_stock_move_line_origin +msgid "Is Stock Move Line Origin" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__confirmed_moves +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read__confirmed_moves +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_inventory__confirmed_moves +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking__confirmed_moves +msgid "" +"It allows to work with movements without reservation (Without detailed " +"operations)" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__keep_result_package +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__keep_result_package +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__keep_result_package +msgid "Keep Result Package" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__keep_screen_values +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__keep_screen_values +msgid "Keep Screen Values" +msgstr "Conserver les valeurs à l'écran" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__key_char_shortcut +msgid "Key Char Shortcut" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__key_shortcut +msgid "Key Shortcut" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_report_stock_barcodes_report_barcode_actions____last_update +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action____last_update +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option____last_update +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group____last_update +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking____last_update +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_new_lot____last_update +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory____last_update +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking____last_update +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_report_stock_barcodes_report_barcode_actions__write_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__write_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__write_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__write_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__write_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_new_lot__write_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__write_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__write_uid +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__write_uid +msgid "Last Updated by" +msgstr "Dernière mise à jour par" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_report_stock_barcodes_report_barcode_actions__write_date +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__write_date +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__write_date +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__write_date +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__write_date +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_new_lot__write_date +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__write_date +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__write_date +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__write_date +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__line_ids +msgid "Line" +msgstr "Ligne" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__location_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__location_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__location_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__location_id +msgid "Location" +msgstr "Emplacement" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__location_dest_id +msgid "Location Dest" +msgstr "Emplacement dest" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__location_field_to_sort +msgid "Location Field To Sort" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__location_name +msgid "Location Name" +msgstr "Nom de l'emplacement" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__location_dest_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__location_dest_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__location_dest_id +msgid "Location dest." +msgstr "Emplacement dest." + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__lot_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__lot_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__lot_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__lot_id +msgid "Lot" +msgstr "Lot" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +msgid "Lot S/N:" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_new_lot__lot_name +msgid "Lot name" +msgstr "Nom du lot" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__lot_name +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__lot_name +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__lot_name +msgid "Lot/Serial Number Name" +msgstr "Nom du lot / n° de série" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "Lot:" +msgstr "Lot :" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__manual_entry +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__manual_entry +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__manual_entry +msgid "Manual" +msgstr "Manuel" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__manual_entry_field_focus +msgid "Manual Entry Field Focus" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__manual_entry +msgid "Manual entry" +msgstr "Entrée manuelle" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Manual entry OK" +msgstr "Entrée manuelle OK" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__message +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__message +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__message +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__message +msgid "Message" +msgstr "Message" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__message_step +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__message_step +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__message_step +msgid "Message Step" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__message_type +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__message_type +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__message_type +msgid "Message Type" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__barcode_guided_mode +msgid "Mode" +msgstr "Mode" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "" +"More than one lot found\n" +"Scan product before" +msgstr "" +"Plusieurs lots ont été trouvés\n" +"Veuillez scanner le produit en premier" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read__message_type__more_match +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_inventory__message_type__more_match +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_picking__message_type__more_match +msgid "More than one matches found" +msgstr "Plusieurs correspondances trouvées" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "More than one package found" +msgstr "Plusieurs colis trouvés" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "More than one product found" +msgstr "Plusieurs produits trouvés" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__move_line_ids +msgid "Move Line" +msgstr "Ligne de mouvement" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "NOT AVAILABLE" +msgstr "NON DISPONIBLE" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__name +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__name +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__name +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__name +msgid "Name" +msgstr "Nom" + +#. module: stock_barcodes +#: model:ir.actions.act_window,name:stock_barcodes.action_stock_barcodes_new_lot +msgid "New Lot" +msgstr "Nouveau lot" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read_picking.py:0 +#, python-format +msgid "New Move:" +msgstr "Nouveau mouvement :" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_picking_type__new_picking_barcode_option_group_id +msgid "New Picking Barcode Option Group" +msgstr "Code-barres - Groupe d'options pour nouveau transfert" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "Next" +msgstr "Suivant" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__stock_move__barcode_backorder_action__skip_backorder +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "No Backorder" +msgstr "Pas de reliquat" + +#. module: stock_barcodes +#. odoo-javascript +#: code:addons/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.esm.js:0 +#, python-format +msgid "No action found with barcode: " +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read__message_type__not_found +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_inventory__message_type__not_found +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_picking__message_type__not_found +msgid "No barcode found" +msgstr "Code-barres introuvable" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read_picking.py:0 +#, python-format +msgid "No pending lines for this product" +msgstr "Aucune ligne en attente pour ce produit" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "No stock available for this lot with screen values" +msgstr "Aucun stock n'est disponible pour ce lot avec les valeurs à l'écran" + +#. module: stock_barcodes +#: model_terms:ir.actions.act_window,help:stock_barcodes.stock_barcodes_action_picking_tree_ready +msgid "No transfer found. Let's create one!" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__note +msgid "Notes" +msgstr "Notes" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "OK" +msgstr "OK" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "Odoo will not create a backorder for this move. Are you sure?" +msgstr "Odoo ne va pas créer de reliquat pour ce mouvement. Êtes-vous sûr ?" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "Open actions" +msgstr "" + +#. module: stock_barcodes +#: model:ir.actions.act_window,name:stock_barcodes.stock_barcodes_action_picking_tree_ready +#: model:ir.model.fields.selection,name:stock_barcodes.selection__stock_barcodes_option_group__source_pending_moves__move_ids +#: model:stock.barcodes.action,name:stock_barcodes.stock_barcodes_action_barcode_operations +msgid "Operations" +msgstr "Opérations" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__option_ids +msgid "Option" +msgstr "Option" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__option_group_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__option_group_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__option_group_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__option_group_id +msgid "Option Group" +msgstr "Groupe d'options" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_stock_barcodes_option +msgid "Options for barcode interface" +msgstr "Codes-barres - Options" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_stock_barcodes_option_group +msgid "Options group for barcode interface" +msgstr "Codes-barres - Groupe d'options" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__stock_barcodes_option_group__location_field_to_sort__location_id +msgid "Origin Location" +msgstr "Emplacement d'origine" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__source_pending_moves +msgid "Origin of the data to generate the movements to process" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__owner_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__owner_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__owner_id +msgid "Owner" +msgstr "Propriétaire" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__package_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__package_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__package_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__package_id +msgid "Package" +msgstr "Colis" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__package_product_qty +msgid "Package Product Qty" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__packaging_qty +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__packaging_qty +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__packaging_qty +msgid "Package Qty" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "Package:" +msgstr "Colis :" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__packaging_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__packaging_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__packaging_id +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_packaging_form +msgid "Packaging" +msgstr "Conditionnement" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__partner_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__partner_id +msgid "Partner" +msgstr "Partenaire" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__stock_move__barcode_backorder_action__pending +#: model:ir.model.fields.selection,name:stock_barcodes.selection__stock_move_line__barcode_scan_state__pending +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_todo__state__pending +msgid "Pending" +msgstr "En attente" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__pending_move_ids +msgid "Pending Move" +msgstr "Mouvement en attente" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "Pending moves" +msgstr "Mouvements en attente" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__picking_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__picking_id +msgid "Picking" +msgstr "Transfert" + +#. module: stock_barcodes +#: model:stock.barcodes.action,name:stock_barcodes.stock_barcodes_action_picking_in +msgid "Picking IN" +msgstr "Réception (entrée)" + +#. module: stock_barcodes +#: model:stock.barcodes.action,name:stock_barcodes.stock_barcodes_action_picking_int +msgid "Picking INTERNAL" +msgstr "Transfert interne" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__picking_mode +msgid "Picking Mode" +msgstr "" + +#. module: stock_barcodes +#: model:stock.barcodes.action,name:stock_barcodes.stock_barcodes_action_picking_out +msgid "Picking OUT" +msgstr "Livraison (sortie)" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_stock_picking_type +msgid "Picking Type" +msgstr "Type de transfert" + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_picking__picking_mode__picking +msgid "Picking mode" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__picking_product_qty +msgid "Picking quantities" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__picking_ids +msgid "Pickings" +msgstr "Transferts" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__position_index +msgid "Position Index" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "Previous" +msgstr "Précédent" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_action_tree +msgid "Print barcodes" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_report_stock_barcodes_report_barcode_actions +msgid "Print barcodes from barcode actions" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_new_lot__product_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__product_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__product_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__product_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__product_id +msgid "Product" +msgstr "Produit" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__total_product_uom_qty +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__total_product_uom_qty +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__total_product_uom_qty +msgid "Product Demand" +msgstr "Demande de produit" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "Mouvements de produit (Ligne de mouvement de stock)" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__product_packaging_ids +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__product_packaging_ids +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__product_packaging_ids +msgid "Product Packages" +msgstr "Colis des produits" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__product_qty +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__product_qty +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__product_qty +msgid "Product Qty" +msgstr "Qté produit" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__total_product_qty_done +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__total_product_qty_done +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__total_product_qty_done +msgid "Product Qty. Done" +msgstr "Qté produit faite" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__product_uom_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__product_uom_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__product_uom_id +msgid "Product Uom" +msgstr "UdM produit" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "Put in Pack" +msgstr "Mettre en colis" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "Put in pack" +msgstr "Mettre en colis" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__qty_available +msgid "Qty Available" +msgstr "Qté disponible" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__qty_done_rest +msgid "Qty Done Rest" +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read_picking.py:0 +#, python-format +msgid "Quantities not available in location" +msgstr "Quantités non disponibles dans l'emplacement" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read_picking.py:0 +#, python-format +msgid "Quantities scanned are higher than necessary" +msgstr "Les quantités scannées dépassent la prévision" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_stock_quant +msgid "Quants" +msgstr "Quants" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "Range" +msgstr "Assigner n°" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__display_read_quant +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +msgid "Read items" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__display_read_quant +msgid "Read items on inventory mode" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form_manual_qty +msgid "Reopen" +msgstr "Ré-ouvrir" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__required +msgid "Required" +msgstr "Requis" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__res_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__res_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__res_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__res_ids +msgid "Res" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__res_model_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__res_model_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__res_model_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__res_model_id +msgid "Res Model" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__product_qty_reserved +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__product_qty_reserved +msgid "Reserved" +msgstr "Réservé" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "Restore to pending" +msgstr "Remettre à en attente" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__result_package_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__result_package_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__result_package_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__result_package_id +msgid "Result Package" +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Review and confirm" +msgstr "Vérifier et confirmer" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read_picking.py:0 +#, python-format +msgid "S/N Already in picking" +msgstr "Le n° de série est déjà dans le transfert" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read_picking.py:0 +#, python-format +msgid "S/N already created" +msgstr "Le n° de série a déjà été créé" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__scan_count +msgid "Scan Count" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_move_line__barcode_scan_state +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__state +msgid "Scan State" +msgstr "État du scan" + +#. module: stock_barcodes +#. odoo-javascript +#: code:addons/stock_barcodes/static/src/views/kanban/stock_barcodes_kanban.xml:0 +#, python-format +msgid "Scan a" +msgstr "" + +#. module: stock_barcodes +#. odoo-javascript +#: code:addons/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.xml:0 +#, python-format +msgid "Scan a barcode actions" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.report_barcode_actions +msgid "Scan your actions and streamline your actions." +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Scan {}" +msgstr "Scan {}" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__selected_pending_move_id +msgid "Selected Pending Move" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_action__sequence +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__sequence +msgid "Sequence" +msgstr "Séquence" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__manual_entry_field_focus +msgid "Set field to set focus when manual entry mode is enabled" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__show_detailed_operations +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__show_detailed_operations +msgid "Show Detailed Operations" +msgstr "Afficher les opérations détaillées" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__show_form_scan +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__show_form_scan +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__show_form_scan +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__show_form_scan +msgid "Show Form Scan" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read__create_lot +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_inventory__create_lot +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking__create_lot +msgid "Show lot name field" +msgstr "Afficher le champ Nom du lot" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__show_pending_moves +msgid "Show pending moves" +msgstr "Afficher les mouvements en attente" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__show_pending_moves +msgid "Shows a list of movements to process" +msgstr "Afficher une liste des mouvements à traiter" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__picking_location_id +msgid "Source Location" +msgstr "Emplacement d'origine" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__source_pending_moves +msgid "Source Pending Moves" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_picking_form +msgid "Start barcode interface" +msgstr "Démarrer l'interface de scan de codes-barres" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__state +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__picking_state +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__picking_state +msgid "Status" +msgstr "Statut" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__step +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__step +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__step +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__step +msgid "Step" +msgstr "Étape" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_option_group_form +msgid "Steps to scan" +msgstr "Étapes du scan" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_stock_move +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__stock_move_ids +msgid "Stock Move" +msgstr "Mouvement de stock" + +#. module: stock_barcodes +#. odoo-javascript +#: code:addons/stock_barcodes/static/src/views/views.esm.js:0 +#, python-format +msgid "The inventory adjustment has been validated" +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "The product type is not allowed" +msgstr "Le type de produit n'est pas autorisé" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "The quantity is huge" +msgstr "La quantité est très grande" + +#. module: stock_barcodes +#. odoo-javascript +#: code:addons/stock_barcodes/static/src/views/views.esm.js:0 +#, python-format +msgid "The transfer has been validated" +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/models/stock_barcodes_action.py:0 +#, python-format +msgid "There can be no spaces at the beginning or end." +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_picking_type__new_picking_barcode_option_group_id +msgid "" +"This Barcode Option Group will be selected when clicking the 'New' button in " +"an operation type. It will be used to create a non planned picking." +msgstr "" +"Ce groupe d'options CB sera sélectionné à partir du bouton 'Nouveau' pour ce " +"type d'opération - pour enregistrer un transfert non planifié." + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "This move will be set to pending. Are you sure?" +msgstr "Ce mouvement sera mis en état en attente. Êtes-vous sûr ?" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__todo_line_ids +msgid "To Do Lines" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option__to_scan +msgid "To Scan" +msgstr "À scanner" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__todo_line_id +msgid "Todo Line" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__todo_line_display_ids +msgid "Todo Line Display" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__product_tracking +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__product_tracking +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__product_tracking +msgid "Tracking" +msgstr "Suivi" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_stock_picking +msgid "Transfer" +msgstr "Transfert" + +#. module: stock_barcodes +#: model_terms:ir.actions.act_window,help:stock_barcodes.stock_barcodes_action_picking_tree_ready +msgid "Transfers allow you to move products from one location to another." +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__picking_type_code +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__picking_code +msgid "Type of Operation" +msgstr "Type d'opération" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_pickingtype_filter +msgid "Type of operation" +msgstr "Type d'opération" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__uom_id +msgid "Uom" +msgstr "UdM" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_stock_barcodes_option_group__use_location_dest_putaway +msgid "Use location dest. putaway" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_quant___barcode_scanned +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_new_lot___barcode_scanned +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read___barcode_scanned +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_inventory___barcode_scanned +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking___barcode_scanned +msgid "Value of the last barcode scanned." +msgstr "Valeur du dernier code-barres scanné." + +#. module: stock_barcodes +#: model:ir.model.fields.selection,name:stock_barcodes.selection__wiz_stock_barcodes_read_picking__picking_type_code__incoming +msgid "Vendors" +msgstr "Fournisseurs" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read__visible_force_done +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_inventory__visible_force_done +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_picking__visible_force_done +msgid "Visible Force Done" +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Waiting location" +msgstr "En attente de l'emplacement" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Waiting lot" +msgstr "En attente du lot" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Waiting product" +msgstr "En attente du produit" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Waiting quantities" +msgstr "En attente des quantités" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__barcode_guided_mode +msgid "" +"When guided mode is selected, information will appear with the movement to " +"be processed" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__wiz_barcode_id +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_stock_barcodes_read_todo__wiz_barcode_id +msgid "Wiz Barcode" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model.fields,field_description:stock_barcodes.field_wiz_candidate_picking__wiz_picking_id +msgid "Wizard Picking" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_wiz_stock_barcodes_new_lot +msgid "Wizard to create new lot from barcode scanner" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_wiz_stock_barcodes_read +msgid "Wizard to read barcode" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_wiz_stock_barcodes_read_inventory +msgid "Wizard to read barcode on inventory" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_wiz_stock_barcodes_read_picking +msgid "Wizard to read barcode on picking batch" +msgstr "" + +#. module: stock_barcodes +#: model:ir.model,name:stock_barcodes.model_wiz_stock_barcodes_read_todo +msgid "Wizard to read barcode todo" +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Wrong location" +msgstr "Emplacement invalide" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Wrong location dest" +msgstr "Emplacement de dest invalide" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "Wrong lot" +msgstr "Lot invalide" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#: code:addons/stock_barcodes/wizard/stock_barcodes_read_picking.py:0 +#, python-format +msgid "Wrong product" +msgstr "Produit invalide" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_stock_barcodes_option_group__group_key_for_todo_records +msgid "" +"You can establish a list of fields that will act as a grouping key to " +"generate the movements to be process.\n" +"The object variable is used to refer to the source record\n" +"For example, object.location_id,object.product_id,object.lot_id" +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read_picking.py:0 +#, python-format +msgid "You can not add extra moves if you have not set a picking" +msgstr "" +"Vous ne pouvez pas ajouter de mouvements additionnels sans avoir au " +"préalable défini le transfert qui doit les contenir" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_todo_kanban +msgid "" +"You have not set any quantity to this operation and it will be removed from " +"pending moves. Are you sure?" +msgstr "" +"Vous n'avez pas défini de quantité pour cette opération ; elle sera " +"supprimée des mouvements en attente. Êtes-vous sûr ?" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "lock picking" +msgstr "bloquer le transfert" + +#. module: stock_barcodes +#. odoo-javascript +#: code:addons/stock_barcodes/static/src/views/kanban/stock_barcodes_kanban.xml:0 +#, python-format +msgid "lot" +msgstr "" + +#. module: stock_barcodes +#. odoo-javascript +#: code:addons/stock_barcodes/static/src/views/kanban/stock_barcodes_kanban.xml:0 +#, python-format +msgid "or a" +msgstr "" + +#. module: stock_barcodes +#. odoo-javascript +#: code:addons/stock_barcodes/static/src/views/kanban/stock_barcodes_kanban.xml:0 +#, python-format +msgid "product" +msgstr "" + +#. module: stock_barcodes +#. odoo-javascript +#: code:addons/stock_barcodes/static/src/views/kanban/stock_barcodes_kanban.xml:0 +#, python-format +msgid "to filter your records" +msgstr "" + +#. module: stock_barcodes +#. odoo-javascript +#: code:addons/stock_barcodes/static/src/views/kanban/stock_barcodes_kanban.xml:0 +#, python-format +msgid "transfer" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "unlock picking" +msgstr "débloquer le transfert" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "{name} is required" +msgstr "{name} est requis" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "Apply" +#~ msgstr "Appliquer" + +#~ msgid "" +#~ "Dest. Location\n" +#~ " " +#~ msgstr "" +#~ "Empl. dest.\n" +#~ " " + +#~ msgid "" +#~ "Source Location\n" +#~ " " +#~ msgstr "" +#~ "Empl. origine\n" +#~ " " + +#~ msgid "" +#~ "Lot S/N\n" +#~ " " +#~ msgstr "" +#~ "N° série lot\n" +#~ " " + +#~ msgid "" +#~ "Package\n" +#~ " " +#~ msgstr "" +#~ "Colis\n" +#~ " " + +#~ msgid "" +#~ "Product\n" +#~ " " +#~ msgstr "" +#~ "Produit\n" +#~ " " + +#~ msgid "Back" +#~ msgstr "Retour" + +#~ msgid "Clean message" +#~ msgstr "Retirer le message" + +#~ msgid "Edit" +#~ msgstr "Modifier" + +#~ msgid "Loc:" +#~ msgstr "Empl :" + +#~ msgid "Open" +#~ msgstr "Ouvrir" + +#~ msgid "Options" +#~ msgstr "Options" + +#~ msgid "Remove detailed operation" +#~ msgstr "Supprimer l'opération détaillée" + +#~ msgid "Remove quant" +#~ msgstr "Supprimer quantité" + +#~ msgid "Reset inventory quantity" +#~ msgstr "Remettre quantité inventaire à 0" + +#~ msgid "Validate" +#~ msgstr "Valider" diff --git a/stock_barcodes/i18n/it.po b/stock_barcodes/i18n/it.po new file mode 100644 index 00000000..2e20c242 --- /dev/null +++ b/stock_barcodes/i18n/it.po @@ -0,0 +1,2439 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_barcodes +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2026-04-20 15:45+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.15.2\n" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_wiz_candidate_picking__state +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking__picking_state +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_todo__picking_state +msgid "" +" * Draft: The transfer is not confirmed yet. Reservation doesn't apply.\n" +" * Waiting another operation: This transfer is waiting for another operation " +"before being ready.\n" +" * Waiting: The transfer is waiting for the availability of some products.\n" +"(a) The shipping policy is \"As soon as possible\": no product could be " +"reserved.\n" +"(b) The shipping policy is \"When all products are ready\": not all the " +"products could be reserved.\n" +" * Ready: The transfer is ready to be processed.\n" +"(a) The shipping policy is \"As soon as possible\": at least one product has " +"been reserved.\n" +"(b) The shipping policy is \"When all products are ready\": all product have " +"been reserved.\n" +" * Done: The transfer has been processed.\n" +" * Cancelled: The transfer has been cancelled." +msgstr "" +" * Bozza: Il trasferimento non è ancora confermato. Non è possibile " +"riservare.\n" +" * Attesa altra operazione: questo trasferimento è in attesa di un'altra " +"operazione prima di essere pronto.\n" +" * In attesa: il trasferimento è in attesa della disponibilità di alcuni " +"prodotti.\n" +"(a) La politica di spedizione è \"Il prima possibile\": non è stato " +"possibile riservare alcun prodotto.\n" +"(b) La politica di spedizione è \"Quando tutti i prodotti sono pronti\": non " +"è stato possibile riservare tutti i prodotti.\n" +" * Pronto: il trasferimento è pronto per essere completato.\n" +"(a) La politica di spedizione è \"Il prima possibile\": almeno un prodotto è " +"stato riservato.\n" +"(b) La politica di spedizione è \"Quando tutti i prodotti sono pronti\": " +"tutti i prodotti sono stati riservati.\n" +" * Fatto: il trasferimento è stato completato.\n" +" * Annullato: il trasferimento è stato annullato." + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/models/stock_barcodes_action.py:0 +#, python-format +msgid " Barcode has already been assigned to the action(s): {}." +msgstr " Il codice a barre è già stato assegnato all'azione: {}." + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/models/stock_barcodes_action.py:0 +#, python-format +msgid "" +" The barcode {} is not correct.Use numbers, letters and dashes, without " +"spaces.E.g. 15753, BC-5789,er-56 " +msgstr "" +" il codice a barre {} non è corretto. Usare numeri, lettere, e trattini " +"senza spazi. Es. 15753, BC-5789,er-56 " + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "%(barcode)s (%(message)s)" +msgstr "%(barcode)s (%(message)s)" + +#. module: stock_barcodes +#: model:ir.actions.report,print_report_name:stock_barcodes.action_report_barcode_actions +msgid "'Barcodes - %s' % (object.name)" +msgstr "'Codici a barre - %s' % (object.name)" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_new_lot +msgid "1 - Scan or input product barcode" +msgstr "1 - Scansionare o inserire il codice a barre del prodotto" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_new_lot +msgid "2 - Scan or input product lot barcode" +msgstr "2 - Scansionare o inserire il codice a barre del lotto del prodotto" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.stock_picking_type_kanban +msgid "" +msgstr "" +"" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.stock_picking_type_kanban +msgid "" +"\n" +" New" +msgstr "" +"\n" +" Nuovo" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "" +"" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.stock_picking_type_kanban +msgid "" +"\n" +" New" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "" +"\n" +"Language-Team: none\n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" + +#. module: stock_barcodes +#: model:ir.model.fields,help:stock_barcodes.field_wiz_candidate_picking__state +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_picking__picking_state +#: model:ir.model.fields,help:stock_barcodes.field_wiz_stock_barcodes_read_todo__picking_state +msgid "" +" * Draft: The transfer is not confirmed yet. Reservation doesn't apply.\n" +" * Waiting another operation: This transfer is waiting for another operation " +"before being ready.\n" +" * Waiting: The transfer is waiting for the availability of some products.\n" +"(a) The shipping policy is \"As soon as possible\": no product could be " +"reserved.\n" +"(b) The shipping policy is \"When all products are ready\": not all the " +"products could be reserved.\n" +" * Ready: The transfer is ready to be processed.\n" +"(a) The shipping policy is \"As soon as possible\": at least one product has " +"been reserved.\n" +"(b) The shipping policy is \"When all products are ready\": all product have " +"been reserved.\n" +" * Done: The transfer has been processed.\n" +" * Cancelled: The transfer has been cancelled." +msgstr "" +" * Taslak: Transfer henüz onaylanmadı. Rezervasyon geçerli değildir.\n" +" * Başka bir işlem bekleniyor: Bu transfer hazır olmadan önce başka bir " +"işlemi bekliyor.\n" +" * Bekliyor: Transfer bazı ürünlerin kullanılabilirliğini bekliyor.\n" +"(a) Gönderim politikası \"Mümkün olan en kısa sürede\" şeklindedir: hiçbir " +"ürün rezerve edilemez.\n" +"(b) Gönderim politikası \"Tüm ürünler hazır olduğunda\" şeklindedir: tüm " +"ürünler rezerve edilemez.\n" +" * Hazır: Aktarım işlenmeye hazır.\n" +"(a) Gönderim politikası \"Mümkün olan en kısa sürede\" şeklindedir: en az " +"bir ürün rezerve edilmiştir.\n" +"(b) Gönderim politikası \"Tüm ürünler hazır olduğunda\" şeklindedir: tüm " +"ürünler rezerve edilmiştir.\n" +" * Bitti: Aktarım işlendi.\n" +" * İptal Edildi: Transfer iptal edildi." + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/models/stock_barcodes_action.py:0 +#, python-format +msgid " Barcode has already been assigned to the action(s): {}." +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/models/stock_barcodes_action.py:0 +#, python-format +msgid "" +" The barcode {} is not correct.Use numbers, letters and dashes, without " +"spaces.E.g. 15753, BC-5789,er-56 " +msgstr "" + +#. module: stock_barcodes +#. odoo-python +#: code:addons/stock_barcodes/wizard/stock_barcodes_read.py:0 +#, python-format +msgid "%(barcode)s (%(message)s)" +msgstr "%(barcode)s (%(message)s)" + +#. module: stock_barcodes +#: model:ir.actions.report,print_report_name:stock_barcodes.action_report_barcode_actions +msgid "'Barcodes - %s' % (object.name)" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_new_lot +msgid "1 - Scan or input product barcode" +msgstr "1 - Ürün barkodunu tarayın veya girin" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_new_lot +msgid "2 - Scan or input product lot barcode" +msgstr "2 - Ürün lot barkodunu tarayın veya girin" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.stock_picking_type_kanban +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.stock_picking_type_kanban +msgid "" +"\n" +" New" +msgstr "" +"\n" +" Yeni" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_picking_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_inventory_form +msgid "" +msgstr "" + +#. module: stock_barcodes +#: model_terms:ir.ui.view,arch_db:stock_barcodes.view_stock_barcodes_read_form +msgid "" +"" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +#~ msgstr "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ " +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import fields, models + + +class StockBarcodesOptionGroup(models.Model): + _name = "stock.barcodes.option.group" + _description = "Options group for barcode interface" + + name = fields.Char() + code = fields.Char() + option_ids = fields.One2many( + comodel_name="stock.barcodes.option", inverse_name="option_group_id", copy=True + ) + barcode_guided_mode = fields.Selection( + [("guided", "Guided")], + string="Mode", + help="When guided mode is selected, information will appear with the " + "movement to be processed", + ) + manual_entry = fields.Boolean( + string="Manual entry", + help="Default value when open scan interface", + ) + manual_entry_field_focus = fields.Char( + help="Set field to set focus when manual entry mode is enabled", + default="location_id", + ) + confirmed_moves = fields.Boolean( + string="Confirmed moves", + help="It allows to work with movements without reservation " + "(Without detailed operations)", + ) + show_pending_moves = fields.Boolean( + string="Show pending moves", help="Shows a list of movements to process" + ) + source_pending_moves = fields.Selection( + [("move_line_ids", "Detailed operations"), ("move_ids", "Operations")], + default="move_line_ids", + help="Origin of the data to generate the movements to process", + ) + ignore_filled_fields = fields.Boolean( + string="Ignore filled fields", + ) + auto_put_in_pack = fields.Boolean( + string="Auto put in pack", help="Auto put in pack before picking validation" + ) + is_manual_qty = fields.Boolean( + help="If it is checked, it always shows the product quantity field in edit mode" + ) + is_manual_confirm = fields.Boolean( + help="If it is marked, the movement must always be confirmed from a button" + ) + allow_negative_quant = fields.Boolean( + help="If it is checked, it will allow the creation of movements that " + "generate negative stock" + ) + fill_fields_from_lot = fields.Boolean( + help="If checked, the fields in the interface will be filled from " + "the scanned lot" + ) + ignore_quant_location = fields.Boolean( + help="If it is checked, quant location will be ignored when reading lot/package", + ) + group_key_for_todo_records = fields.Char( + help="You can establish a list of fields that will act as a grouping " + "key to generate the movements to be process.\n" + "The object variable is used to refer to the source record\n" + "For example, object.location_id,object.product_id,object.lot_id" + ) + auto_lot = fields.Boolean( + string="Get lots automatically", + help="If checked the lot will be set automatically with the same " + "removal startegy", + ) + create_lot = fields.Boolean( + string="Create lots if not match", + help="If checked the lot will created automatically with the scanned barcode " + "if not exists ", + ) + show_detailed_operations = fields.Boolean( + help="If checked the picking detailed operations are displayed", + ) + keep_screen_values = fields.Boolean( + help="If checked the wizard values are kept until the pending move is completed", + ) + accumulate_read_quantity = fields.Boolean( + help="If checked quantity will be accumulated to the existing record instead of " + "overwrite it with the new quantity value", + ) + display_notification = fields.Boolean( + string="Display Odoo notifications", + ) + use_location_dest_putaway = fields.Boolean( + string="Use location dest. putaway", + ) + location_field_to_sort = fields.Selection( + selection=[ + ("location_id", "Origin Location"), + ("location_dest_id", "Destination Location"), + ] + ) + display_read_quant = fields.Boolean(string="Read items on inventory mode") + no_increase_qty_done = fields.Boolean( + string="Do not increase qty done on each scan", + ) + show_form_scan = fields.Boolean(default=True) + + def get_option_value(self, field_name, attribute): + option = self.option_ids.filtered(lambda op: op.field_name == field_name)[:1] + return option[attribute] + + +class StockBarcodesOption(models.Model): + _name = "stock.barcodes.option" + _description = "Options for barcode interface" + _order = "step, sequence, id" + + sequence = fields.Integer(default=100) + name = fields.Char() + option_group_id = fields.Many2one( + comodel_name="stock.barcodes.option.group", ondelete="cascade" + ) + field_name = fields.Char() + filled_default = fields.Boolean() + forced = fields.Boolean() + to_scan = fields.Boolean() + required = fields.Boolean() + clean_after_done = fields.Boolean() + message = fields.Char() + step = fields.Integer() diff --git a/stock_barcodes/models/stock_move.py b/stock_barcodes/models/stock_move.py new file mode 100644 index 00000000..4d5ad452 --- /dev/null +++ b/stock_barcodes/models/stock_move.py @@ -0,0 +1,37 @@ +# Copyright 2024 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class StockMove(models.Model): + _inherit = "stock.move" + + barcode_backorder_action = fields.Selection( + [ + ("pending", "Pending"), + ("create_backorder", "Create Backorder"), + ("skip_backorder", "No Backorder"), + ], + string="Backorder action", + default="pending", + ) + + def _action_done(self, cancel_backorder=False): + moves_cancel_backorder = self.browse() + if not cancel_backorder: + moves_cancel_backorder = self.filtered( + lambda sm: sm.barcode_backorder_action == "skip_backorder" + ) + super(StockMove, moves_cancel_backorder)._action_done(cancel_backorder=True) + moves_backorder = self - moves_cancel_backorder + moves_backorder.barcode_backorder_action = "pending" + return super(StockMove, moves_backorder)._action_done( + cancel_backorder=cancel_backorder + ) + + def copy_data(self, default=None): + vals_list = super().copy_data(default=default) + for vals in vals_list: + vals.pop("barcode_backorder_action", None) + return vals_list diff --git a/stock_barcodes/models/stock_move_line.py b/stock_barcodes/models/stock_move_line.py new file mode 100644 index 00000000..3d042506 --- /dev/null +++ b/stock_barcodes/models/stock_move_line.py @@ -0,0 +1,40 @@ +# Copyright 2019 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import api, fields, models + + +class StockMoveLine(models.Model): + _inherit = "stock.move.line" + + barcode_scan_state = fields.Selection( + [("pending", "Pending"), ("done", "Done"), ("done_forced", "Done forced")], + string="Scan State", + default="pending", + compute="_compute_barcode_scan_state", + readonly=False, + store=True, + ) + + @api.depends("qty_done", "reserved_uom_qty") + def _compute_barcode_scan_state(self): + for line in self: + if line.qty_done >= line.reserved_uom_qty: + line.barcode_scan_state = "done" + else: + line.barcode_scan_state = "pending" + + def _barcodes_process_line_to_unlink(self): + self.qty_done = 0.0 + + def action_barcode_detailed_operation_unlink(self): + for sml in self: + stock_move = sml.move_id + stock_move.barcode_backorder_action = "pending" + sml.unlink() + # HACK: To force refresh wizard values + wiz_barcode = self.env["wiz.stock.barcodes.read.picking"].browse( + self.env.context.get("wiz_barcode_id", False) + ) + stock_move._action_assign() + wiz_barcode.fill_todo_records() + wiz_barcode.determine_todo_action() diff --git a/stock_barcodes/models/stock_picking.py b/stock_barcodes/models/stock_picking.py new file mode 100644 index 00000000..c0810184 --- /dev/null +++ b/stock_barcodes/models/stock_picking.py @@ -0,0 +1,78 @@ +# Copyright 2019 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import _, models +from odoo.exceptions import UserError + + +class StockPicking(models.Model): + _inherit = "stock.picking" + + def _prepare_barcode_wiz_vals(self, option_group): + vals = { + "picking_id": self.id, + "res_model_id": self.env.ref("stock.model_stock_picking").id, + "res_id": self.id, + "picking_type_code": self.picking_type_code, + "option_group_id": option_group.id, + "manual_entry": option_group.manual_entry, + "picking_mode": "picking", + } + if self.picking_type_id.code == "outgoing": + vals["location_dest_id"] = self.location_dest_id.id + elif self.picking_type_id.code == "incoming": + vals["location_id"] = self.location_id.id + + if option_group.get_option_value("location_id", "filled_default"): + vals["location_id"] = self.location_id.id + if option_group.get_option_value("location_dest_id", "filled_default"): + vals["location_dest_id"] = self.location_dest_id.id + return vals + + def action_barcode_scan(self, option_group=False): + option_group = ( + option_group + or self.picking_type_id.barcode_option_group_id + or self.env.ref("stock_barcodes.stock_barcodes_option_group_operation") + ) + if not option_group: + raise UserError( + _( + "Barcode Option Group is not configured on " + "Operation Type '%(pick_type)s'.", + pick_type=self.picking_type_id.display_name, + ) + ) + wiz = self.env["wiz.stock.barcodes.read.picking"].create( + self._prepare_barcode_wiz_vals(option_group) + ) + wiz.fill_pending_moves() + wiz.determine_todo_action() + action = self.env["ir.actions.actions"]._for_xml_id( + "stock_barcodes.action_stock_barcodes_read_picking" + ) + action["res_id"] = wiz.id + return action + + def button_validate(self): + put_in_pack_picks = self.filtered( + lambda p: p.picking_type_id.barcode_option_group_id.auto_put_in_pack + and not p.move_line_ids.result_package_id + ) + if put_in_pack_picks: + put_in_pack_picks.action_put_in_pack() + if self.env.context.get("stock_barcodes_validate_picking", False): + res = super( + StockPicking, self.with_context(skip_backorder=True) + ).button_validate() + else: + res = super().button_validate() + if res is True and self.env.context.get("show_picking_type_action_tree", False): + res = self[:1].picking_type_id.get_action_picking_tree_ready() + + if self.env.context.get("stock_barcodes_validate_picking", False) and all( + p.state == "done" for p in self + ): + self.env["bus.bus"]._sendone( + "stock_barcodes_scan", "actions_barcode", {"valid_picking": True} + ) + return res diff --git a/stock_barcodes/models/stock_picking_type.py b/stock_barcodes/models/stock_picking_type.py new file mode 100644 index 00000000..5dc256be --- /dev/null +++ b/stock_barcodes/models/stock_picking_type.py @@ -0,0 +1,104 @@ +# Copyright 2019 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from ast import literal_eval + +from odoo import fields, models + + +class StockPickingType(models.Model): + _inherit = "stock.picking.type" + + barcode_option_group_id = fields.Many2one( + comodel_name="stock.barcodes.option.group" + ) + + new_picking_barcode_option_group_id = fields.Many2one( + comodel_name="stock.barcodes.option.group", + help="This Barcode Option Group will be selected when clicking the 'New' button" + " in an operation type. It will be used to create a non planned picking.", + ) + + def action_barcode_scan(self): + vals = { + "res_model_id": self.env.ref("stock.model_stock_picking_type").id, + "res_id": self.id, + "picking_type_code": self.code, + "option_group_id": self.barcode_option_group_id.id, + "manual_entry": self.barcode_option_group_id.manual_entry, + "picking_mode": "picking", + } + if self.code == "outgoing": + vals["location_dest_id"] = ( + self.default_location_dest_id.id + or self.env.ref("stock.stock_location_customers").id + ) + elif self.code == "incoming": + vals["location_id"] = ( + self.default_location_src_id.id + or self.env.ref("stock.stock_location_suppliers").id + ) + if self.barcode_option_group_id.get_option_value( + "location_id", "filled_default" + ): + vals["location_id"] = self.default_location_src_id.id + if self.barcode_option_group_id.get_option_value( + "location_dest_id", "filled_default" + ): + vals["location_dest_id"] = self.default_location_dest_id.id + wiz = self.env["wiz.stock.barcodes.read.picking"].create(vals) + wiz.fill_pending_moves() + wiz.determine_todo_action() + action = self.env["ir.actions.actions"]._for_xml_id( + "stock_barcodes.action_stock_barcodes_read_picking" + ) + action["res_id"] = wiz.id + return action + + def action_barcode_new_picking(self): + self.ensure_one() + picking = ( + self.env["stock.picking"] + .with_context(default_immediate_transfer=True) + .create( + { + "picking_type_id": self.id, + "location_id": self.default_location_src_id.id, + "location_dest_id": self.default_location_dest_id.id, + } + ) + ) + option_group = self.new_picking_barcode_option_group_id + return picking.action_barcode_scan(option_group=option_group) + + def get_action_picking_tree_ready(self): + context = dict(self.env.context) + if context.get("operations_mode", False): + return self._get_action( + "stock_barcodes.stock_barcodes_action_picking_tree_ready" + ) + return super().get_action_picking_tree_ready() + + def _get_action(self, action_xmlid): + action = self.env["ir.actions.actions"]._for_xml_id(action_xmlid) + if self: + action["display_name"] = self.display_name + + default_immediate_tranfer = True + if ( + self.env["ir.config_parameter"] + .sudo() + .get_param("stock.no_default_immediate_tranfer") + ): + default_immediate_tranfer = False + + context = { + "search_default_picking_type_id": [self.id], + "default_picking_type_id": self.id, + "default_immediate_transfer": default_immediate_tranfer, + "default_company_id": self.company_id.id, + } + + action_context = literal_eval(action["context"].strip()) + context = {**action_context, **context} + action["context"] = context + return action diff --git a/stock_barcodes/models/stock_quant.py b/stock_barcodes/models/stock_quant.py new file mode 100644 index 00000000..eea8b9bc --- /dev/null +++ b/stock_barcodes/models/stock_quant.py @@ -0,0 +1,80 @@ +# Copyright 2023 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from odoo import models + +MODEL_UPDATE_INVENTORY = ["wiz.stock.barcodes.read.inventory"] + + +class StockQuant(models.Model): + _name = "stock.quant" + _inherit = ["stock.quant", "barcodes.barcode_events_mixin"] + + def action_barcode_inventory_quant_unlink(self): + self.with_context(inventory_mode=True).action_set_inventory_quantity_to_zero() + context = dict(self.env.context) + params = context.get("params", {}) + res_model = params.get("model", False) + res_id = params.get("id", False) + if res_id and res_model in MODEL_UPDATE_INVENTORY: + wiz_id = self.env[params["model"]].browse(params["id"]) + wiz_id._compute_count_inventory_quants() + wiz_id.send_bus_done( + "stock_barcodes_form_update", + "count_apply_inventory", + {"count": wiz_id.count_inventory_quants}, + ) + + def _get_fields_to_edit(self): + return [ + "location_id", + "product_id", + "product_uom_id", + "lot_id", + "package_id", + ] + + def action_barcode_inventory_quant_edit(self): + wiz_barcode_id = self.env.context.get("wiz_barcode_id", False) + wiz_barcode = self.env["wiz.stock.barcodes.read.inventory"].browse( + wiz_barcode_id + ) + for quant in self: + # Try to assign fields with the same name between quant and the scan wizard + for fname in self._get_fields_to_edit(): + wiz_barcode[fname] = quant[fname] + wiz_barcode.product_qty = quant.inventory_quantity + + wiz_barcode.manual_entry = True + self.send_bus_done( + "stock_barcodes_scan", + "stock_barcodes_edit_manual", + { + "manual_entry": True, + }, + ) + + def enable_current_operations(self): + self.send_bus_done( + "stock_barcodes_kanban_update", + "enable_operations", + { + "id": self.id, + }, + ) + + def operation_quantities_rest(self): + self.write({"inventory_quantity": self.inventory_quantity - 1}) + self.enable_current_operations() + + def operation_quantities(self): + self.write({"inventory_quantity": self.inventory_quantity + 1}) + self.enable_current_operations() + + def action_apply_inventory(self): + res = super().action_apply_inventory() + self.send_bus_done( + "stock_barcodes_scan", + "actions_barcode", + {"apply_inventory": True}, + ) + return res diff --git a/stock_barcodes/readme/CONTRIBUTORS.rst b/stock_barcodes/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..ab346ae1 --- /dev/null +++ b/stock_barcodes/readme/CONTRIBUTORS.rst @@ -0,0 +1,25 @@ + +* `Tecnativa `_: + + * Sergio Teruel + * Carlos Dauden + * Pedro M. Baeza + * Alexandre D. Díaz + +* `Onestein `_: + + * Andrea Stirpe + +* `InitOS `_: + + * Foram Shah + +* `ForgeFlow `_: + + * Lois Rilo + +* Enric Tobella + +* `Binhex `_: + + * Edilio Escalona Almira diff --git a/stock_barcodes/readme/DESCRIPTION.rst b/stock_barcodes/readme/DESCRIPTION.rst new file mode 100644 index 00000000..06862318 --- /dev/null +++ b/stock_barcodes/readme/DESCRIPTION.rst @@ -0,0 +1,11 @@ +This module provides a barcode reader interface for stock module. + +This module contains a base wizard read barcode that can be extended by +other modules. + +This module also makes use of this wizard for providing barcode support for +doing inventories and picking operations. + +This module provides configuring barcodes for barcode actions. + + diff --git a/stock_barcodes/readme/HISTORY.rst b/stock_barcodes/readme/HISTORY.rst new file mode 100644 index 00000000..50f772b9 --- /dev/null +++ b/stock_barcodes/readme/HISTORY.rst @@ -0,0 +1,29 @@ +11.0.1.1.0 (2019-09-24) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [ADD] New feature. + User can uses barcode interface in picking operations. + +13.0.1.1.1 (2021-02-06) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [ADD] New feature. + Add option to get lots automatically based on removal strategy in inventory. + +14.0.1.0.0 (2021-04-05) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [ADD] New feature. + Add security for users. + +16.0.1.0.0 (2025-01-23) +~~~~~~~~~~~~~~~~~~~~~~~ +* [IMP] + Improved views to optimize navigation and functionality. + Intuitive and mobile-friendly views. + Visual improvement of the main view accessed from the Barcodes menu. + +* [ADD] New feature. + Barcode reading to barcode actions. + Generate PDF document for the barcodes of the selected barcode actions. + diff --git a/stock_barcodes/readme/ROADMAP.rst b/stock_barcodes/readme/ROADMAP.rst new file mode 100644 index 00000000..c69cbaa9 --- /dev/null +++ b/stock_barcodes/readme/ROADMAP.rst @@ -0,0 +1,4 @@ +* Excute action_done() method outside onchange environment. +* Allow create product when a barcode has not been found. +* Allow to select picking reading its barcode. +* Allow to select multiple pickings to process scanned products. diff --git a/stock_barcodes/readme/USAGE.rst b/stock_barcodes/readme/USAGE.rst new file mode 100644 index 00000000..51618733 --- /dev/null +++ b/stock_barcodes/readme/USAGE.rst @@ -0,0 +1,261 @@ +Barcode interface for inventory operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Option 1: To use the barcode interface on inventory + + #. Go to *Inventory > operations > Inventory Adjustments*. + #. Create new inventory with "Select products manually" option. + #. Start inventory. + #. Click to "Scan barcodes" smart button. + #. Start reading barcodes. + +Option 2: Use the barcode interface inventory directly from the Barcodes application + #. Go to *Barcodes*. + #. Select the *Inventory* option. + + .. image:: ../static/src/img/inventory_barcode_action.png + :height: 100 + :width: 200 + :alt: Inventory barcode action + + #. Start scanning barcodes. + +Actions + # Press the *+ Product* button to display the form for the new item. + + .. image:: ../static/src/img/add_product.png + :height: 100 + :width: 200 + :alt: Add product + + # When you select a product, a numeric field is displayed to add the quantity. + + .. image:: ../static/src/img/form_add_product_quantity.png + :height: 100 + :width: 200 + :alt: Add quantity product + + # When you press the button with the trash can icon, the values of the form are reset (except for the location) without closing it. + + .. image:: ../static/src/img/form_add_product_reset.png + :height: 100 + :width: 200 + :alt: Reset data form + + # When you press the *Clean values* button, all fields are reset and the form is closed. + # When you press the *Confirm* button, the new item is added and the form is closed. + # When the eye icon is closed, the created items greater than zero are displayed, and if not, those less than or equal to zero. + + .. image:: ../static/src/img/list_items.png + :height: 100 + :width: 200 + :alt: Reset data form + + # In the list, the trash can icon allows you to reset the quantity to zero and the edit icon allows you to change the item values. + + .. image:: ../static/src/img/list_action_items.png + :height: 100 + :width: 200 + :alt: Reset data form + + # The *Apply* button is only displayed if there are items with quantities greater than zero, regardless of whether they were scanned or entered manually; If you press all the defined quantities will be processed after defining the reason for the inventory adjustment and then the main barcode menu will be displayed. + + .. image:: ../static/src/img/apply_inventory.png + :height: 100 + :width: 200 + :alt: Apply inventory + + .. image:: ../static/src/img/apply_inventory_reason.png + :height: 100 + :width: 200 + :alt: Apply inventory reason + + +Barcode interface for picking operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You can use the barcode interface in a picking or an operation type, the main +difference is that if you open the barcode interface from a picking, this +picking is locked and you read products for it. + +To use the barcode interface on picking operations: + +#. Go to *Inventory*. +#. Click on scanner button on any operation type. +#. Start reading barcodes. + +Option 1: To use the barcode interface on a picking: + + #. Go to *Inventory > Transfers*. + #. Click to "Scan barcodes" smart button. + #. Start reading barcodes. + +Option 2: Use the barcode interface picking directly from the Barcodes application + #. Go to *Barcodes*. + #. Select the option *OPERATIONS*. + + .. image:: ../static/src/img/inventory_barcode_action.png + :height: 100 + :width: 200 + :alt: Operation barcode action + + # Select the type of picking. + # The pickings in ready status are displayed, select the one you want to start scanning. + + .. image:: ../static/src/img/list_picking.png + :height: 100 + :width: 200 + :alt: List picking + + #. Start scanning barcodes. + + .. image:: ../static/src/img/barcode_interface_picking.png + :height: 100 + :width: 200 + :alt: List picking + +Actions + # All the items that have been configured for the selected picking are listed. + + .. image:: ../static/src/img/list_items_picking.png + :height: 100 + :width: 200 + :alt: List picking + + # The edit icon in the list allows you to modify the data. + + .. image:: ../static/src/img/list_items_picking_edit.png + :height: 100 + :width: 200 + :alt: Edit picking + + # The button that contains a *+120* (in this case), allows you to define all the + remaining quantities. Once defined, this button disappears and if you want to change the + quantities, press the edit button. + + .. image:: ../static/src/img/list_items_picking_quantity.png + :height: 100 + :width: 200 + :alt: Quantity picking + + # If there is at least one item with a quantity already defined, an eye icon is displayed, + which if closed shows the items and their quantities already scanned. + + .. image:: ../static/src/img/list_items_picking_scanned.png + :height: 100 + :width: 200 + :alt: Picking scanned + + # When you press the *Validate* button, a wizard will be displayed to confirm the action. + If everything is correct, it is validated and you return to the picking list mentioned above. + + .. image:: ../static/src/img/confirm_items_picking.png + :height: 100 + :width: 200 + :alt: Picking scanned + + # If there is an item whose quantity is zero, a wizard will be displayed after the one mentioned + above, to confirm if you want to process all the quantities. If positive, you will proceed + and be directed to the list mentioned above in the previous point. + + .. image:: ../static/src/img/confirm_all_quantity_items_picking.png + :height: 100 + :width: 200 + :alt: Picking scanned + + # Press the *+ Product* button to display the form for the new item. + + .. image:: ../static/src/img/add_product.png + :height: 100 + :width: 200 + :alt: Add product + + # When you select a product, a numeric field is displayed to add the quantity. + + .. image:: ../static/src/img/form_add_product_quantity.png + :height: 100 + :width: 200 + :alt: Add quantity product + + # When you press the button with the trash can icon, the values of the form are reset (except for the location) without closing it. + + .. image:: ../static/src/img/form_add_product_reset.png + :height: 100 + :width: 200 + :alt: Reset data form + + # When you press the *Clean values* button, all fields are reset and the form is closed. + # When you press the *Confirm* button, the new item is added and the form is closed. + # When adding the new item all the quantities are assigned to it, if you want to modify it, press the edit icon. + +The barcode scanner interface has two operation modes. In both of them user +can scan: + +#. Warehouse locations with barcode. +#. Product packaging with barcode. +#. Product with barcode. +#. Product Lots (The barcode is name field in this case). + + +Automatic operation mode +~~~~~~~~~~~~~~~~~~~~~~~~ + +This is the default mode, all screen controls are locked to avoid scan into +fields. + +The user only has to scan barcode in physical warehouse locations with a +scanner hardward, the interface read the barcode and do operations in this +order: + +#. Try search a product, if found, is assigned to product_id field and creates + or update inventory line with 1.0 unit. (If product has tracking by lots + the interface wait for a lot to be scanned). +#. Try search a product packaging, if found, the product_id related is set, + product quantities are updated and create or update inventory line with + product quantities defined in the product packaging. +#. Try search a lot (The product is mandatory in this case so you first scan a + product and then scann a lot), this lot field is not erased until that + product change, so for each product scann the interface add or update a + inventory line with this lot. +#. Try to search a location, if found the field location is set and next scan + action will be done with this warehouse location. + +If barcode has not found, when message is displayed you can create this lot +scanning the product. + +Manual entry mode +~~~~~~~~~~~~~~~~~ + +You can change to "manual entry" to allow to select data without scanner +hardware, but hardward scanner still active on, so a use case would be when +user wants set quantities manually instead increment 1.0 unit peer scan action. + +Scan logs +~~~~~~~~~ + +All scanned barcodes are saved into model. +Barcode scanning interface display 10 last records linked to model, the goal of +this log is show to user other reads with the same product and location done +by other users. +User can remove the last read scan. + +Barcode interface for barcode actions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To use the barcode interface for actions: + +#. Go to *Inventory > Configuration > Barcode Actions*. +#. Create a new barcode action and configure the barcode. + +.. image:: ../static/src/img/create_barcode_action.png + :height: 100 + :width: 200 + :alt: Print barcodes + +#. Select the barcode actions you want to use, a button (PRINT BARCODES) will appear that allows you to print the configured barcodes to PDF. + +.. image:: ../static/src/img/print_barcodes.png + :height: 100 + :width: 200 + :alt: Print barcodes + +#. Go to *Barcodes*. +#. Start scanning barcodes from actions. diff --git a/stock_barcodes/reports/__init__.py b/stock_barcodes/reports/__init__.py new file mode 100644 index 00000000..84df5b6e --- /dev/null +++ b/stock_barcodes/reports/__init__.py @@ -0,0 +1 @@ +from . import barcode_actions_report diff --git a/stock_barcodes/reports/barcode_actions_report.py b/stock_barcodes/reports/barcode_actions_report.py new file mode 100644 index 00000000..792a013b --- /dev/null +++ b/stock_barcodes/reports/barcode_actions_report.py @@ -0,0 +1,16 @@ +from odoo import api, models + + +class ReportStockBarcodesBarcodeActions(models.Model): + _name = "report.stock_barcodes.report_barcode_actions" + _description = "Print barcodes from barcode actions" + + @api.model + def _get_report_values(self, docids, data=None): + datas = self.env["stock.barcodes.action"].search_read( + [("id", "in", docids), ("barcode", "!=", False)], + ["name", "barcode", "barcode_image"], + ) + return { + "barcodes": datas, + } diff --git a/stock_barcodes/reports/barcode_actions_report.xml b/stock_barcodes/reports/barcode_actions_report.xml new file mode 100644 index 00000000..d8c872da --- /dev/null +++ b/stock_barcodes/reports/barcode_actions_report.xml @@ -0,0 +1,25 @@ + + + diff --git a/stock_barcodes/reports/reports.xml b/stock_barcodes/reports/reports.xml new file mode 100644 index 00000000..274e3226 --- /dev/null +++ b/stock_barcodes/reports/reports.xml @@ -0,0 +1,28 @@ + + + A4 + + A4 + 0 + 0 + Portrait + 30 + 5 + 7 + 7 + + 5 + 90 + + + + Barcodes (PDF) + stock.barcodes.action + qweb-pdf + stock_barcodes.report_barcode_actions + stock_barcodes.report_barcode_actions + 'Barcodes - %s' % (object.name) + report + + + diff --git a/stock_barcodes/security/ir.model.access.csv b/stock_barcodes/security/ir.model.access.csv new file mode 100644 index 00000000..0297e235 --- /dev/null +++ b/stock_barcodes/security/ir.model.access.csv @@ -0,0 +1,13 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_wiz_stock_barcodes_read_picking,access_wiz_stock_barcodes_read_picking,model_wiz_stock_barcodes_read_picking,stock.group_stock_user,1,1,1,1 +access_wiz_candidate_picking,access_wiz_candidate_picking,model_wiz_candidate_picking,stock.group_stock_user,1,1,1,1 +access_wiz_stock_barcodes_new_lot,access_wiz_stock_barcodes_new_lot,model_wiz_stock_barcodes_new_lot,stock.group_stock_user,1,1,1,1 +access_stock_barcodes_action_manager,access_stock_barcodes_action_manager,model_stock_barcodes_action,stock.group_stock_manager,1,1,1,1 +access_stock_barcodes_action,access_stock_barcodes_action,model_stock_barcodes_action,stock.group_stock_user,1,0,0,0 +access_stock_barcodes_option_group,access_stock_barcodes_option_group,model_stock_barcodes_option_group,stock.group_stock_user,1,1,1,1 +access_stock_barcodes_option,access_stock_barcodes_option,model_stock_barcodes_option,stock.group_stock_user,1,1,1,1 +access_stock_barcodes_read_picking,access_stock_barcodes_read_picking,model_wiz_stock_barcodes_read_picking,stock.group_stock_user,1,1,1,1 +access_wiz_stock_barcodes_read_todo,access_wiz_stock_barcodes_read_todo,model_wiz_stock_barcodes_read_todo,stock.group_stock_user,1,1,1,1 +access_wiz_stock_barcodes_read_inventory,access_wiz_stock_barcodes_read_inventory,model_wiz_stock_barcodes_read_inventory,stock.group_stock_user,1,1,1,1 +access_report_stock_barcodes_report_barcode_actions_manager,access_report_stock_barcodes_report_barcode_actions_manager,model_report_stock_barcodes_report_barcode_actions,stock.group_stock_manager,1,1,1,1 +access_report_stock_barcodes_report_barcode_actions,access_report_stock_barcodes_report_barcode_actions,model_report_stock_barcodes_report_barcode_actions,stock.group_stock_user,1,0,0,0 diff --git a/stock_barcodes/static/description/icon.png b/stock_barcodes/static/description/icon.png new file mode 100755 index 00000000..c6ef19d3 Binary files /dev/null and b/stock_barcodes/static/description/icon.png differ diff --git a/stock_barcodes/static/description/icon.svg b/stock_barcodes/static/description/icon.svg new file mode 100644 index 00000000..7014a875 --- /dev/null +++ b/stock_barcodes/static/description/icon.svg @@ -0,0 +1,1041 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stock_barcodes/static/description/index.html b/stock_barcodes/static/description/index.html new file mode 100644 index 00000000..35f26601 --- /dev/null +++ b/stock_barcodes/static/description/index.html @@ -0,0 +1,728 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Stock Barcodes

+ +

Beta License: AGPL-3 OCA/stock-logistics-barcode Translate me on Weblate Try me on Runboat

+

This module provides a barcode reader interface for stock module.

+

This module contains a base wizard read barcode that can be extended by +other modules.

+

This module also makes use of this wizard for providing barcode support for +doing inventories and picking operations.

+

This module provides configuring barcodes for barcode actions.

+

Table of contents

+ +
+

Usage

+
+

Barcode interface for inventory operations

+

Option 1: To use the barcode interface on inventory

+
+
    +
  1. Go to Inventory > operations > Inventory Adjustments.
  2. +
  3. Create new inventory with “Select products manually” option.
  4. +
  5. Start inventory.
  6. +
  7. Click to “Scan barcodes” smart button.
  8. +
  9. Start reading barcodes.
  10. +
+
+
+
Option 2: Use the barcode interface inventory directly from the Barcodes application
+
    +
  1. Go to Barcodes.
  2. +
  3. Select the Inventory option.
  4. +
+
+Inventory barcode action +
+
    +
  1. Start scanning barcodes.
  2. +
+
+
Actions
+

# Press the + Product button to display the form for the new item.

+
+Add product +
+

# When you select a product, a numeric field is displayed to add the quantity.

+
+Add quantity product +
+

# When you press the button with the trash can icon, the values of the form are reset (except for the location) without closing it.

+
+Reset data form +
+

# When you press the Clean values button, all fields are reset and the form is closed. +# When you press the Confirm button, the new item is added and the form is closed. +# When the eye icon is closed, the created items greater than zero are displayed, and if not, those less than or equal to zero.

+
+Reset data form +
+

# In the list, the trash can icon allows you to reset the quantity to zero and the edit icon allows you to change the item values.

+
+Reset data form +
+

# The Apply button is only displayed if there are items with quantities greater than zero, regardless of whether they were scanned or entered manually; If you press all the defined quantities will be processed after defining the reason for the inventory adjustment and then the main barcode menu will be displayed.

+
+Apply inventory +Apply inventory reason +
+
+
+
+
+

Barcode interface for picking operations

+

You can use the barcode interface in a picking or an operation type, the main +difference is that if you open the barcode interface from a picking, this +picking is locked and you read products for it.

+

To use the barcode interface on picking operations:

+
    +
  1. Go to Inventory.
  2. +
  3. Click on scanner button on any operation type.
  4. +
  5. Start reading barcodes.
  6. +
+

Option 1: To use the barcode interface on a picking:

+
+
    +
  1. Go to Inventory > Transfers.
  2. +
  3. Click to “Scan barcodes” smart button.
  4. +
  5. Start reading barcodes.
  6. +
+
+
+
Option 2: Use the barcode interface picking directly from the Barcodes application
+
    +
  1. Go to Barcodes.
  2. +
  3. Select the option OPERATIONS.
  4. +
+
+Operation barcode action +
+

# Select the type of picking. +# The pickings in ready status are displayed, select the one you want to start scanning.

+
+List picking +
+
    +
  1. Start scanning barcodes.
  2. +
+
+List picking +
+
+
Actions
+

# All the items that have been configured for the selected picking are listed.

+
+List picking +
+

# The edit icon in the list allows you to modify the data.

+
+Edit picking +
+
+
# The button that contains a +120 (in this case), allows you to define all the
+

remaining quantities. Once defined, this button disappears and if you want to change the +quantities, press the edit button.

+Quantity picking +
+
# If there is at least one item with a quantity already defined, an eye icon is displayed,
+

which if closed shows the items and their quantities already scanned.

+Picking scanned +
+
# When you press the Validate button, a wizard will be displayed to confirm the action.
+

If everything is correct, it is validated and you return to the picking list mentioned above.

+Picking scanned +
+
# If there is an item whose quantity is zero, a wizard will be displayed after the one mentioned
+

above, to confirm if you want to process all the quantities. If positive, you will proceed +and be directed to the list mentioned above in the previous point.

+Picking scanned +
+
+

# Press the + Product button to display the form for the new item.

+
+Add product +
+

# When you select a product, a numeric field is displayed to add the quantity.

+
+Add quantity product +
+

# When you press the button with the trash can icon, the values of the form are reset (except for the location) without closing it.

+
+Reset data form +
+

# When you press the Clean values button, all fields are reset and the form is closed. +# When you press the Confirm button, the new item is added and the form is closed. +# When adding the new item all the quantities are assigned to it, if you want to modify it, press the edit icon.

+
+
+

The barcode scanner interface has two operation modes. In both of them user +can scan:

+
    +
  1. Warehouse locations with barcode.
  2. +
  3. Product packaging with barcode.
  4. +
  5. Product with barcode.
  6. +
  7. Product Lots (The barcode is name field in this case).
  8. +
+
+
+

Automatic operation mode

+

This is the default mode, all screen controls are locked to avoid scan into +fields.

+

The user only has to scan barcode in physical warehouse locations with a +scanner hardward, the interface read the barcode and do operations in this +order:

+
    +
  1. Try search a product, if found, is assigned to product_id field and creates +or update inventory line with 1.0 unit. (If product has tracking by lots +the interface wait for a lot to be scanned).
  2. +
  3. Try search a product packaging, if found, the product_id related is set, +product quantities are updated and create or update inventory line with +product quantities defined in the product packaging.
  4. +
  5. Try search a lot (The product is mandatory in this case so you first scan a +product and then scann a lot), this lot field is not erased until that +product change, so for each product scann the interface add or update a +inventory line with this lot.
  6. +
  7. Try to search a location, if found the field location is set and next scan +action will be done with this warehouse location.
  8. +
+

If barcode has not found, when message is displayed you can create this lot +scanning the product.

+
+
+

Manual entry mode

+

You can change to “manual entry” to allow to select data without scanner +hardware, but hardward scanner still active on, so a use case would be when +user wants set quantities manually instead increment 1.0 unit peer scan action.

+
+
+

Scan logs

+

All scanned barcodes are saved into model. +Barcode scanning interface display 10 last records linked to model, the goal of +this log is show to user other reads with the same product and location done +by other users. +User can remove the last read scan.

+
+
+

Barcode interface for barcode actions

+

To use the barcode interface for actions:

+
    +
  1. Go to Inventory > Configuration > Barcode Actions.
  2. +
  3. Create a new barcode action and configure the barcode.
  4. +
+Print barcodes +
    +
  1. Select the barcode actions you want to use, a button (PRINT BARCODES) will appear that allows you to print the configured barcodes to PDF.
  2. +
+Print barcodes +
    +
  1. Go to Barcodes.
  2. +
  3. Start scanning barcodes from actions.
  4. +
+
+
+
+

Known issues / Roadmap

+
    +
  • Excute action_done() method outside onchange environment.
  • +
  • Allow create product when a barcode has not been found.
  • +
  • Allow to select picking reading its barcode.
  • +
  • Allow to select multiple pickings to process scanned products.
  • +
+
+
+

Changelog

+
+

11.0.1.1.0 (2019-09-24)

+
    +
  • [ADD] New feature. +User can uses barcode interface in picking operations.
  • +
+
+
+

13.0.1.1.1 (2021-02-06)

+
    +
  • [ADD] New feature. +Add option to get lots automatically based on removal strategy in inventory.
  • +
+
+
+

14.0.1.0.0 (2021-04-05)

+
    +
  • [ADD] New feature. +Add security for users.
  • +
+
+
+

16.0.1.0.0 (2025-01-23)

+
    +
  • [IMP] +Improved views to optimize navigation and functionality. +Intuitive and mobile-friendly views. +Visual improvement of the main view accessed from the Barcodes menu.
  • +
  • [ADD] New feature. +Barcode reading to barcode actions. +Generate PDF document for the barcodes of the selected barcode actions.
  • +
+
+
+
+

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

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+
    +
  • Tecnativa:
      +
    • Sergio Teruel
    • +
    • Carlos Dauden
    • +
    • Pedro M. Baeza
    • +
    • Alexandre D. Díaz
    • +
    +
  • +
  • Onestein:
      +
    • Andrea Stirpe
    • +
    +
  • +
  • InitOS:
      +
    • Foram Shah
    • +
    +
  • +
  • ForgeFlow:
      +
    • Lois Rilo
    • +
    +
  • +
  • Enric Tobella
  • +
  • Binhex:
      +
    • Edilio Escalona Almira
    • +
    +
  • +
+
+
+

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.

+

This module is part of the OCA/stock-logistics-barcode project on GitHub.

+

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

+
+
+
+
+ + diff --git a/stock_barcodes/static/src/docs/barcodes_actions.pdf b/stock_barcodes/static/src/docs/barcodes_actions.pdf new file mode 100644 index 00000000..caca3f7f Binary files /dev/null and b/stock_barcodes/static/src/docs/barcodes_actions.pdf differ diff --git a/stock_barcodes/static/src/docs/barcodes_demo.pdf b/stock_barcodes/static/src/docs/barcodes_demo.pdf new file mode 100644 index 00000000..efa79893 Binary files /dev/null and b/stock_barcodes/static/src/docs/barcodes_demo.pdf differ diff --git a/stock_barcodes/static/src/img/add_product.png b/stock_barcodes/static/src/img/add_product.png new file mode 100644 index 00000000..298c5143 Binary files /dev/null and b/stock_barcodes/static/src/img/add_product.png differ diff --git a/stock_barcodes/static/src/img/apply_inventory.png b/stock_barcodes/static/src/img/apply_inventory.png new file mode 100644 index 00000000..9e3e0e8a Binary files /dev/null and b/stock_barcodes/static/src/img/apply_inventory.png differ diff --git a/stock_barcodes/static/src/img/apply_inventory_reason.png b/stock_barcodes/static/src/img/apply_inventory_reason.png new file mode 100644 index 00000000..6b434b2c Binary files /dev/null and b/stock_barcodes/static/src/img/apply_inventory_reason.png differ diff --git a/stock_barcodes/static/src/img/barcode_interface_picking.png b/stock_barcodes/static/src/img/barcode_interface_picking.png new file mode 100644 index 00000000..4ddbc007 Binary files /dev/null and b/stock_barcodes/static/src/img/barcode_interface_picking.png differ diff --git a/stock_barcodes/static/src/img/confirm_all_quantity_items_picking.png b/stock_barcodes/static/src/img/confirm_all_quantity_items_picking.png new file mode 100644 index 00000000..6ecc8884 Binary files /dev/null and b/stock_barcodes/static/src/img/confirm_all_quantity_items_picking.png differ diff --git a/stock_barcodes/static/src/img/confirm_items_picking.png b/stock_barcodes/static/src/img/confirm_items_picking.png new file mode 100644 index 00000000..67fdab6c Binary files /dev/null and b/stock_barcodes/static/src/img/confirm_items_picking.png differ diff --git a/stock_barcodes/static/src/img/create_barcode_action.png b/stock_barcodes/static/src/img/create_barcode_action.png new file mode 100644 index 00000000..d04c6baf Binary files /dev/null and b/stock_barcodes/static/src/img/create_barcode_action.png differ diff --git a/stock_barcodes/static/src/img/form_add_product.png b/stock_barcodes/static/src/img/form_add_product.png new file mode 100644 index 00000000..6b0ce83a Binary files /dev/null and b/stock_barcodes/static/src/img/form_add_product.png differ diff --git a/stock_barcodes/static/src/img/form_add_product_quantity.png b/stock_barcodes/static/src/img/form_add_product_quantity.png new file mode 100644 index 00000000..47d6ce6e Binary files /dev/null and b/stock_barcodes/static/src/img/form_add_product_quantity.png differ diff --git a/stock_barcodes/static/src/img/form_add_product_reset.png b/stock_barcodes/static/src/img/form_add_product_reset.png new file mode 100644 index 00000000..44f458ed Binary files /dev/null and b/stock_barcodes/static/src/img/form_add_product_reset.png differ diff --git a/stock_barcodes/static/src/img/inventory_barcode_action.png b/stock_barcodes/static/src/img/inventory_barcode_action.png new file mode 100644 index 00000000..54f20650 Binary files /dev/null and b/stock_barcodes/static/src/img/inventory_barcode_action.png differ diff --git a/stock_barcodes/static/src/img/list_action_items.png b/stock_barcodes/static/src/img/list_action_items.png new file mode 100644 index 00000000..09bf1305 Binary files /dev/null and b/stock_barcodes/static/src/img/list_action_items.png differ diff --git a/stock_barcodes/static/src/img/list_items.png b/stock_barcodes/static/src/img/list_items.png new file mode 100644 index 00000000..45fd893f Binary files /dev/null and b/stock_barcodes/static/src/img/list_items.png differ diff --git a/stock_barcodes/static/src/img/list_items_picking.png b/stock_barcodes/static/src/img/list_items_picking.png new file mode 100644 index 00000000..4ddbc007 Binary files /dev/null and b/stock_barcodes/static/src/img/list_items_picking.png differ diff --git a/stock_barcodes/static/src/img/list_items_picking_edit.png b/stock_barcodes/static/src/img/list_items_picking_edit.png new file mode 100644 index 00000000..73f07aa3 Binary files /dev/null and b/stock_barcodes/static/src/img/list_items_picking_edit.png differ diff --git a/stock_barcodes/static/src/img/list_items_picking_quantity.png b/stock_barcodes/static/src/img/list_items_picking_quantity.png new file mode 100644 index 00000000..f297f471 Binary files /dev/null and b/stock_barcodes/static/src/img/list_items_picking_quantity.png differ diff --git a/stock_barcodes/static/src/img/list_items_picking_scanned.png b/stock_barcodes/static/src/img/list_items_picking_scanned.png new file mode 100644 index 00000000..32de9814 Binary files /dev/null and b/stock_barcodes/static/src/img/list_items_picking_scanned.png differ diff --git a/stock_barcodes/static/src/img/list_picking.png b/stock_barcodes/static/src/img/list_picking.png new file mode 100644 index 00000000..05fd9240 Binary files /dev/null and b/stock_barcodes/static/src/img/list_picking.png differ diff --git a/stock_barcodes/static/src/img/print_barcodes.png b/stock_barcodes/static/src/img/print_barcodes.png new file mode 100644 index 00000000..17022564 Binary files /dev/null and b/stock_barcodes/static/src/img/print_barcodes.png differ diff --git a/stock_barcodes/static/src/img/scan.png b/stock_barcodes/static/src/img/scan.png new file mode 100644 index 00000000..fe679687 Binary files /dev/null and b/stock_barcodes/static/src/img/scan.png differ diff --git a/stock_barcodes/static/src/scss/barcode.scss b/stock_barcodes/static/src/scss/barcode.scss new file mode 100644 index 00000000..b26a4887 --- /dev/null +++ b/stock_barcodes/static/src/scss/barcode.scss @@ -0,0 +1,135 @@ +@mixin barcode-decoration() { + i.fa-barcode { + font-size: 2em !important; + @include media-breakpoint-down(sm) { + font-size: 3em !important; + } + } +} + +div.o_kanban_renderer { + button[name="action_barcode_scan"] { + @include barcode-decoration; + } +} + +div.o_kanban_stock_barcodes { + padding: 10px !important; + + button.o_stock_mobile_barcode { + @include barcode-decoration; + } + + button.o_stock_mobile_barcode:focus { + box-shadow: none !important; + } +} + +div.alert.barcode-info { + background-color: $o-community-color !important; + + span.fa-barcode { + margin: 0.5rem 1rem 0 1rem !important; + + @include media-breakpoint-down(sm) { + margin: 0 0 0 5px !important; + font-size: 1em !important; + } + } +} + +.inventory_quant_ids_with_form { + height: 710px !important; + @include media-breakpoint-down(sm) { + height: 500px !important; + } +} + +.inventory_quant_ids_without_form { + height: 822px !important; + @include media-breakpoint-down(sm) { + height: 648px !important; + } +} + +div.oe_kanban_picking_done { + background-color: #353840 !important; + border: none !important; + box-shadow: none !important; + height: 230px !important; +} + +div[name="inventory_quant_ids"], +div[name="pending_move_ids"], +div[name="move_line_ids"] { + div.o_kanban_renderer { + padding: 0 !important; + + &:has(div.oe_kanban_picking_done) { + height: 50% !important; + } + + div.o_kanban_record { + box-shadow: rgba(0, 0, 0, 0.35) 0 5px 15px !important; + + i.fa-pencil, + i.fa-trash { + font-size: 3.5em !important; + } + + img, + span.text-end.fw-bold { + margin-right: 5% !important; + } + + div.indent { + text-indent: 5px !important; + } + } + + button.btn-op-rest, + button.btn-op-sum { + background-color: $o-community-color !important; + min-width: 55px !important; + height: 60px !important; + padding: 12px 8px !important; + border-radius: 8px !important; + line-height: 16px !important; + font-size: 16px !important; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + text-transform: none; + } + } +} + +button[name="action_clean_product"], +button[name="action_clean_lot"], +button#btn_create_lot { + width: 5% !important; + padding: 0.9rem !important; + @include media-breakpoint-down(sm) { + width: 95% !important; + margin-top: 0.5em !important; + padding: 0.3rem !important; + i.o_button_icon { + font-size: 1.5em !important; + } + } +} + +div.stock_barcodes_action_kanban { + div.o_kanban_record { + div.oe_kanban_content { + padding: 1.5rem 1.5rem 1.5rem 0.5rem !important; + + div.count-elements { + border: 1px solid; + padding: 1px 4px 1px 4px !important; + border-radius: 40% !important; + background-color: lightgray !important; + } + } + } +} diff --git a/stock_barcodes/static/src/scss/stock.scss b/stock_barcodes/static/src/scss/stock.scss new file mode 100644 index 00000000..5bd70bb1 --- /dev/null +++ b/stock_barcodes/static/src/scss/stock.scss @@ -0,0 +1,285 @@ +@mixin margin-form-edit-sm($margin) { + @include media-breakpoint-down(sm) { + margin: $margin !important; + } +} + +.oe_stock_scan_button { + border: none !important; + background: none !important; + box-shadow: none !important; +} + +.oe_stock_barcodes_bottombar { + bottom: 0; + background-color: $o-view-background-color; + border-width: 1px 0 0 0 solid $border-color; + box-shadow: 0 -3px 10px #c9ccd2; + height: 60px !important; +} + +// Avoid too big small buttons from core +.o_web_client.o_touch_device { + .oe_stock_barcordes_form { + .btn { + &, + .btn-sm { + padding: 0.25rem 0.5rem; + } + } + } +} + +.oe_stock_barcordes_form { + padding: 0 !important; + height: 100%; + // Recover useless space + div[name="_barcode_scanned"] { + min-height: 0 !important; + } + + div[name="package_id"], + div[name="product_id"], + div[name="lot_id"] { + width: 90% !important; + } + + div[name="product_id"], + div[name="package_id"], + div[name="lot_name"] { + @include margin-form-edit-sm(0 0 0 1%); + } + + div[name="location_dest_id"] { + @include margin-form-edit-sm(0 0 1% 1%); + } + + div.widget_numeric_step { + font-size: 1.5rem !important; + } + + input#location_id, + input#location_dest_id, + input#package_id, + input#product_id, + input#lot_id_1, + input#lot_name { + border-radius: 0.5rem !important; + padding: 0.375rem 0.75rem !important; + height: 40px !important; + font-size: 1.5rem !important; + + & + ul.o-autocomplete--dropdown-menu { + li { + font-size: 1.5rem !important; + } + } + } + + div[name="candidate_picking_ids"] { + div.oe_kanban_color_alert { + padding: 0 !important; + margin: 0 !important; + } + + div.o_kanban_ungrouped.o_kanban_renderer { + margin: 0 !important; + padding: 0 !important; + } + + @include media-breakpoint-down(sm) { + div.o_kanban_renderer { + margin: 2% 1% 2% 1% !important; + } + } + } + + div.scan_fields { + width: 100% !important; + margin: 0 !important; + + div.o-autocomplete.dropdown { + + a.o_dropdown_button { + display: none !important; + } + } + + @include media-breakpoint-down(sm) { + padding: 0 2% 0 2% !important; + width: 100% !important; + } + + > div.o_inner_group.grid.col-lg-6 { + div.o_cell { + width: 100% !important; + } + } + + div.mt4.col-lg-6 { + @include media-breakpoint-down(sm) { + margin-bottom: 1.5rem !important; + } + } + + &:has(button[name="action_clean_lot"]) { + div[name="lot_name"] { + width: 88% !important; + @include media-breakpoint-down(sm) { + width: 90% !important; + } + } + button[name="action_clean_lot"] { + margin-left: 5px !important; + } + } + } + + .o_group .scan_fields { + &.o_inner_group { + margin-bottom: 0 !important; + } + + @include media-breakpoint-down(sm) { + padding: 2% 0 2% 0 !important; + } + margin: 0 !important; + } + + .o_form_sheet, + .o_form_sheet_bg { + padding: 0 !important; + margin: 0 !important; + max-width: 100% !important; + border: 0 !important; + } + + // In Odoo 16 the flat input styling lacks proper usability + .o_field_widget { + margin-bottom: 1px !important; + + .o_input { + border-radius: 3px; + border-width: 1px; + background-color: white; + } + + .o_x2m_control_panel { + margin: 0px !important; + } + } + + .o_kanban_record { + flex-basis: 100%; + + .btn-full-width { + margin: -9px; + width: calc(100% + 18px); + height: calc(100% + 18px); + } + + &.o_kanban_ghost { + display: none; + } + } + + .alert { + //position: fixed; + top: 0; + width: 100%; + border-radius: 0; + padding: 0; + min-height: 50px; + z-index: 999; + } + + .oe_stock_barcordes_content { + overflow-y: overlay !important; + + div.g-col-sm-2 { + &:has(div.o_horizontal_separator) { + display: none !important; + } + } + + div.o_inner_group.grid.px-3 { + padding: 0 !important; + } + + div[name="picking_id"] { + > a.o_form_uri { + span { + color: white !important; + } + } + } + + div[name="action_unlock_picking"] { + span { + color: white !important; + } + } + } + + div[name="info"] { + div.alert { + display: flex !important; + @include media-breakpoint-down(sm) { + display: block !important; + text-align: center !important; + } + } + + div.barcode-danger { + background-color: #dc3545 !important; + } + } +} + +.o_kanban_barcode { + .o_kanban_record.oe_kanban_details { + @extend .btn; + @extend .btn-secondary; + padding: 0.6em 0; + margin-bottom: 0.5em; + } +} + +.oe_kanban_action_button:focus { + background-color: lightgray; +} + +// Left icon in small screens +.oe_span_small_icon { + width: 25px; + text-align: center; +} + +// Display 100% all menu elements +.oe_kanban_card_full_width { + width: 100% !important; +} + +// The kanban view adds some pre-styles that we want to be able to tweak +div[name="menu_actions"] { + div[role="article"] { + margin-top: 10px !important; + } +} + +// Dropdown that is desactivated at lg width +@media (min-width: 992px) { + .d-lg-flex-no-dropdown { + position: relative !important; + display: flex !important; + border: none; + box-shadow: none; + bottom: auto !important; + transform: none !important; + } +} + +.dropdown-menu.d-lg-flex-no-dropdown { + .d-flex { + margin-bottom: 5px; + } +} diff --git a/stock_barcodes/static/src/sounds/bell.wav b/stock_barcodes/static/src/sounds/bell.wav new file mode 100644 index 00000000..660779c5 Binary files /dev/null and b/stock_barcodes/static/src/sounds/bell.wav differ diff --git a/stock_barcodes/static/src/sounds/error.wav b/stock_barcodes/static/src/sounds/error.wav new file mode 100644 index 00000000..472f3910 Binary files /dev/null and b/stock_barcodes/static/src/sounds/error.wav differ diff --git a/stock_barcodes/static/src/utils/barcode_handler_field.esm.js b/stock_barcodes/static/src/utils/barcode_handler_field.esm.js new file mode 100644 index 00000000..e351493c --- /dev/null +++ b/stock_barcodes/static/src/utils/barcode_handler_field.esm.js @@ -0,0 +1,36 @@ +/** @odoo-module **/ +import {BarcodeHandlerField} from "@barcodes/barcode_handler_field"; +import {patch} from "@web/core/utils/patch"; +import {useService} from "@web/core/utils/hooks"; +const {useEffect} = owl; + +patch(BarcodeHandlerField.prototype, "stock_barcodes.BarcodeHandlerField", { + /* eslint-disable no-unused-vars */ + setup() { + this._super(...arguments); + const busService = useService("bus_service"); + this.orm = useService("orm"); + const notifyChanges = async ({detail: notifications}) => { + for (const {payload, type} of notifications) { + if (type === "stock_barcodes_refresh_data") { + await this.env.model.root.load(); + this.env.model.notify(); + } + } + }; + useEffect(() => { + busService.addChannel("barcode_reload"); + busService.addEventListener("notification", notifyChanges); + return () => { + busService.deleteChannel("barcode_reload"); + busService.removeEventListener("notification", notifyChanges); + }; + }); + }, + onBarcodeScanned(event) { + this._super(...arguments); + if (this.props.record.resModel.includes("wiz.stock.barcodes.read")) { + $("#dummy_on_barcode_scanned").click(); + } + }, +}); diff --git a/stock_barcodes/static/src/utils/barcodes_models_utils.esm.js b/stock_barcodes/static/src/utils/barcodes_models_utils.esm.js new file mode 100644 index 00000000..54731d65 --- /dev/null +++ b/stock_barcodes/static/src/utils/barcodes_models_utils.esm.js @@ -0,0 +1,26 @@ +/** @odoo-module */ +/* Copyright 2022 Tecnativa - Alexandre D. Díaz + * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ + +// Models allowed to have extra keybinding features +export const barcodeModels = [ + "stock.barcodes.action", + "stock.picking", + "stock.picking.type", + "wiz.candidate.picking", + "wiz.stock.barcodes.new.lot", + "wiz.stock.barcodes.read", + "wiz.stock.barcodes.read.inventory", + "wiz.stock.barcodes.read.picking", + "wiz.stock.barcodes.read.todo", +]; + +/** + * Helper to know if the given model is allowed + * + * @param {String} modelName + * @returns {Boolean} + */ +export function isAllowedBarcodeModel(modelName) { + return barcodeModels.includes(modelName); +} diff --git a/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.esm.js b/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.esm.js new file mode 100644 index 00000000..4cfed06d --- /dev/null +++ b/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.esm.js @@ -0,0 +1,88 @@ +/** @odoo-module **/ +import {_t} from "@web/core/l10n/translation"; +import {browser} from "@web/core/browser/browser"; +import {markup} from "@odoo/owl"; +import {registry} from "@web/core/registry"; +import {useService} from "@web/core/utils/hooks"; + +const {Component, onWillStart, useEffect} = owl; + +export class StockBarcodesMainMenu extends Component { + setup() { + super.setup(); + this.actionService = useService("action"); + this.ormService = useService("orm"); + const busService = useService("bus_service"); + const notification = useService("notification"); + this.modelBarcodeAction = "stock.barcodes.action"; + if (this.hasService("home_menu")) + this.homeMenuService = useService("home_menu"); + onWillStart(async () => { + this.barcodeActions = await this.getBarcodeActions(); + }); + + const handleNotification = ({detail: notifications}) => { + if (notifications && notifications.length > 0) { + notifications.forEach((notif) => { + const {payload, type} = notif; + if (type === "actions_main_menu_barcode") { + if (payload.action_ok && payload.action) { + this.actionService.doAction(payload.action); + } else { + notification.add( + _t("No action found with barcode: " + payload.barcode), + { + type: "danger", + } + ); + } + } + }); + } + }; + useEffect(() => { + busService.addChannel("stock_barcodes_main_menu"); + busService.addEventListener("notification", handleNotification); + return () => { + busService.deleteChannel("stock_barcodes_main_menu"); + busService.removeEventListener("notification", handleNotification); + }; + }); + } + + hasService(service) { + return service in this.env.services; + } + + mainMenuHome() { + // Enterprise + if (this.hasService("home_menu")) { + this.homeMenuService.toggle(true); + } else { + // Community + this.actionService.doAction("mail.action_discuss"); + browser.setTimeout(() => browser.location.reload(), 100); + } + } + + async openAction(action_id) { + const action = await this.ormService.call( + this.modelBarcodeAction, + "open_action", + [action_id] + ); + action.help = markup(_t(action.help)); + this.actionService.doAction(action); + } + + async getBarcodeActions() { + return await this.ormService.call(this.modelBarcodeAction, "search_read", [], { + domain: [["action_window_id", "!=", false]], + fields: ["id", "name", "icon_class"], + }); + } +} + +StockBarcodesMainMenu.template = "stock_barcodes.MainMenu"; + +registry.category("actions").add("stock_barcodes_main_menu", StockBarcodesMainMenu); diff --git a/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.scss b/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.scss new file mode 100644 index 00000000..e11be5b2 --- /dev/null +++ b/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.scss @@ -0,0 +1,74 @@ +@keyframes o_barcode_scanner_intro { + 25% { + top: 75%; + } + 50% { + top: 0; + } + 75% { + top: 100%; + } + 100% { + top: 50%; + } +} + +div.o_action_manager { + &:has(div.stock-barcodes-main-menu) { + overflow-y: scroll !important; + background-color: $o-community-color !important; + @include media-breakpoint-down(sm) { + overflow: scroll !important; + } + } +} + +div.stock-barcodes-main-menu { + background-color: white !important; + margin: 0 10% 5% 10% !important; + border-radius: 5px !important; + min-height: 90% !important; + @include media-breakpoint-down(sm) { + margin: 0 !important; + } + + img { + height: 220px !important; + } + + div.o_stock_barcode_functions { + margin-top: 5rem; + @include media-breakpoint-down(sm) { + margin-top: 3.6rem; + } + } + + div.o_stock_barcode_buttons { + button { + padding: 1.5rem 1.5rem !important; + } + } + + span.o_stock_barcode_laser { + @include o-position-absolute(33%, -15px, auto, -15px); + height: 5px; + background: rgba(red, 0.6); + box-shadow: 0 1px 10px 1px rgba(red, 0.8); + animation: o_barcode_scanner_intro 1s cubic-bezier(0.6, -0.28, 0.735, 0.045) + 0.4s; + width: 26%; + margin-left: 38%; + @include media-breakpoint-down(sm) { + @include o-position-absolute(35%, -15px, auto, -15px); + width: 95%; + margin-left: 6%; + } + } + + div.o_stock_barcode_header_home { + padding-right: 45% !important; + @include media-breakpoint-down(sm) { + padding-right: 27% !important; + } + } +} diff --git a/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.xml b/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.xml new file mode 100644 index 00000000..09e4bbd0 --- /dev/null +++ b/stock_barcodes/static/src/views/actions/stock_barcode_main_menu.xml @@ -0,0 +1,45 @@ + + + +
+
+ + + +

Barcode Scanner

+
+ +
+
+ +
+ +
+
+
+
+
+
diff --git a/stock_barcodes/static/src/views/form/form_controller.esm.js b/stock_barcodes/static/src/views/form/form_controller.esm.js new file mode 100644 index 00000000..1a71bb25 --- /dev/null +++ b/stock_barcodes/static/src/views/form/form_controller.esm.js @@ -0,0 +1,71 @@ +/** @odoo-module */ +/* Copyright 2021 Tecnativa - Alexandre D. Díaz + * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ + +import {onMounted, useEffect} from "@odoo/owl"; +import {FormController} from "@web/views/form/form_controller"; +import {useService} from "@web/core/utils/hooks"; + +export class StockBarcodesFormController extends FormController { + setup() { + super.setup(); + const busService = useService("bus_service"); + const ormService = useService("orm"); + this.enableApplyCount = false; + // Adds support to use control_pannel_hidden from the + // context to disable the control panel + if (this.props.context.control_panel_hidden) { + this.display.controlPanel = false; + } + + const handleNotification = ({detail: notifications}) => { + if (notifications && notifications.length > 0) { + notifications.forEach((notif) => { + const {payload, type} = notif; + if (type === "count_apply_inventory" && payload) { + this.countApplyInventory(payload.count); + } + }); + } + }; + useEffect(() => { + busService.addChannel("stock_barcodes_form_update"); + busService.addEventListener("notification", handleNotification); + const $applyInventory = $("span.count_apply_inventory"); + if ($applyInventory.length > 0) { + if (!this.enableApplyCount) { + this.countApplyInventory(1); + this.enableApplyCount = true; + } + } else { + this.enableApplyCount = false; + } + return () => { + busService.deleteChannel("stock_barcodes_form_update"); + busService.removeEventListener("notification", handleNotification); + }; + }); + + onMounted(async () => { + if (this.props.resModel === "wiz.stock.barcodes.read.inventory") { + const fields = ["count_inventory_quants"]; + const countApply = await ormService.call( + this.props.resModel, + "read", + [this.props.resId], + {fields} + ); + this.countApplyInventory( + countApply.length > 0 ? countApply[0].count_inventory_quants : 0 + ); + } + }); + } + + countApplyInventory(countApply = 0) { + const $countApply = $("span.count_apply_inventory"); + if ($countApply.length) { + $countApply.text(countApply); + } + } +} diff --git a/stock_barcodes/static/src/views/form/form_view.esm.js b/stock_barcodes/static/src/views/form/form_view.esm.js new file mode 100644 index 00000000..a85ed91d --- /dev/null +++ b/stock_barcodes/static/src/views/form/form_view.esm.js @@ -0,0 +1,14 @@ +/** @odoo-module */ +/* Copyright 2021 Tecnativa - Alexandre D. Díaz + * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ + +import {StockBarcodesFormController} from "./form_controller.esm"; +import {formView} from "@web/views/form/form_view"; +import {registry} from "@web/core/registry"; + +export const StockBarcodesFormView = { + ...formView, + Controller: StockBarcodesFormController, +}; + +registry.category("views").add("stock_barcodes_form", StockBarcodesFormView); diff --git a/stock_barcodes/static/src/views/kanban/kanban_record.esm.js b/stock_barcodes/static/src/views/kanban/kanban_record.esm.js new file mode 100644 index 00000000..bf94bdce --- /dev/null +++ b/stock_barcodes/static/src/views/kanban/kanban_record.esm.js @@ -0,0 +1,27 @@ +/** @odoo-module */ +/* Copyright 2022 Tecnativa - Alexandre D. Díaz + * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ + +import {KanbanRecord} from "@web/views/kanban/kanban_record"; +import {patch} from "@web/core/utils/patch"; + +patch(KanbanRecord.prototype, "stock_barcodes.KanbanRecord", { + props: { + ...KanbanRecord.props, + }, + + setup() { + this._super(...arguments); + }, + + async onCustomGlobalClick() { + const record_barcode = $('div[name="inventory_quant_ids"]'); + if (record_barcode.length > 0) { + const record = this.props.record; + $("div.oe_kanban_operations").addClass("d-none"); + $("div.oe_kanban_operations-" + record.data.id).removeClass("d-none"); + return; + } + this._super.apply(this, arguments); + }, +}); diff --git a/stock_barcodes/static/src/views/kanban/kanban_renderer.esm.js b/stock_barcodes/static/src/views/kanban/kanban_renderer.esm.js new file mode 100644 index 00000000..bd3f8468 --- /dev/null +++ b/stock_barcodes/static/src/views/kanban/kanban_renderer.esm.js @@ -0,0 +1,200 @@ +/** @odoo-module */ +/* Copyright 2022 Tecnativa - Alexandre D. Díaz + * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ + +import {onPatched, useEffect, useRef} from "@odoo/owl"; +import {useBus, useService} from "@web/core/utils/hooks"; +import {KanbanRenderer} from "@web/views/kanban/kanban_renderer"; +import {isAllowedBarcodeModel} from "../../utils/barcodes_models_utils.esm"; +import {patch} from "@web/core/utils/patch"; +import {useHotkey} from "@web/core/hotkeys/hotkey_hook"; + +patch(KanbanRenderer.prototype, "stock_barcodes.KanbanRenderer", { + setup() { + const rootRef = useRef("root"); + useHotkey( + "Enter", + ({target}) => { + if (!target.classList.contains("o_kanban_record")) { + return; + } + + // Open first link + let firstLink = null; + if (isAllowedBarcodeModel(this.props.list.resModel)) { + firstLink = target.querySelector( + ".oe_kanban_action_button,.oe_btn_quick_action" + ); + } + if (!firstLink) { + firstLink = target.querySelector( + ".oe_kanban_global_click, a, button" + ); + } + if (firstLink && firstLink instanceof HTMLElement) { + firstLink.click(); + } + return; + }, + {area: () => rootRef.el} + ); + + this._super(...arguments); + this.ormService = useService("orm"); + this.action = useService("action"); + const busService = useService("bus_service"); + this.enableCurrentOperation = 0; + const handleNotification = ({detail: notifications}) => { + if (notifications && notifications.length > 0) { + notifications.forEach((notif) => { + const {payload, type} = notif; + if (type === "enable_operations" && payload) { + this.enableCurrentOperation = payload.id; + } + }); + } + }; + useEffect(() => { + busService.addChannel("stock_barcodes_kanban_update"); + busService.addEventListener("notification", handleNotification); + return () => { + busService.deleteChannel("stock_barcodes_kanban_update"); + busService.removeEventListener("notification", handleNotification); + }; + }); + + onPatched(() => { + $("div.oe_kanban_operations-" + this.enableCurrentOperation).removeClass( + "d-none" + ); + }); + + if (isAllowedBarcodeModel(this.props.list.resModel)) { + if (this.env.searchModel) { + useBus(this.env.searchModel, "focus-view", () => { + const {model} = this.props.list; + if (model.useSampleModel || !model.hasData()) { + return; + } + const cards = Array.from( + rootRef.el.querySelectorAll(".o_kanban_record") + ); + const firstCard = cards.find( + (card) => + card.querySelectorAll("button[name='action_barcode_scan']") + .length > 0 + ); + if (firstCard) { + // Focus first kanban card + firstCard.focus(); + } + }); + } + } + + this.showMessageScanProductPackage = + this.props.list.resModel === "stock.picking"; + }, + + getNextCard(direction, iCard, cards, iGroup, isGrouped) { + let nextCard = null; + switch (direction) { + case "down": + nextCard = iCard < cards[iGroup].length - 1 && cards[iGroup][iCard + 1]; + break; + case "up": + nextCard = iCard > 0 && cards[iGroup][iCard - 1]; + break; + case "right": + if (isGrouped) { + nextCard = iGroup < cards.length - 1 && cards[iGroup + 1][0]; + } else { + nextCard = iCard < cards[0].length - 1 && cards[0][iCard + 1]; + } + break; + case "left": + if (isGrouped) { + nextCard = iGroup > 0 && cards[iGroup - 1][0]; + } else { + nextCard = iCard > 0 && cards[0][iCard - 1]; + } + break; + } + return nextCard; + }, + + // eslint-disable-next-line complexity + // This is copied from the base kanban_renderer. + // We want to only focus card with barcode when isAllowedBarcodeModel returns true + // Since there is no way to hook and change the candidate cards that are selectable + // (cards line 84) we cannot inherit and change the result. And even if we called + // super it would not respect inheritability + /** + * Redefines focusNextCard to select only kanban card with a barcode + * when isAllowBarcodeModel returns true for the current model + * + * @param {Node} area + * @param {String} direction + * + * @returns {String/Boolean} + */ + focusNextCard(area, direction) { + const {isGrouped} = this.props.list; + const closestCard = document.activeElement.closest(".o_kanban_record"); + if (!closestCard) { + return; + } + const groups = isGrouped + ? [...area.querySelectorAll(".o_kanban_group")] + : [area]; + let cards = [...groups] + .map((group) => [...group.querySelectorAll(".o_kanban_record")]) + .filter((group) => group.length); + + if (isAllowedBarcodeModel(this.props.list.resModel)) { + cards = cards.map((group) => { + const result = group.filter((card) => { + return ( + card.querySelectorAll('button[name="action_barcode_scan"]') + .length > 0 + ); + }); + return result; + }); + } + + let iGroup = null; + let iCard = null; + for (iGroup = 0; iGroup < cards.length; iGroup++) { + const i = cards[iGroup].indexOf(closestCard); + if (i !== -1) { + iCard = i; + break; + } + } + if (iCard === undefined) { + iCard = 0; + iGroup = 0; + } + // Find next card to focus + const nextCard = this.getNextCard(direction, iCard, cards, iGroup, isGrouped); + + if (nextCard && nextCard instanceof HTMLElement) { + nextCard.focus(); + return true; + } + }, + + async openBarcodeScanner() { + if (this.showMessageScanProductPackage) { + const action = await this.ormService.call( + "stock.picking", + "action_barcode_scan", + [false, false] + ); + this.action.doAction(action); + } + }, +}); + +KanbanRenderer.template = "stock_barcodes.BarcodeKanbanRenderer"; diff --git a/stock_barcodes/static/src/views/kanban/kanban_view.esm.js b/stock_barcodes/static/src/views/kanban/kanban_view.esm.js new file mode 100644 index 00000000..1e03eab1 --- /dev/null +++ b/stock_barcodes/static/src/views/kanban/kanban_view.esm.js @@ -0,0 +1,8 @@ +/** @odoo-module */ + +import {kanbanView} from "@web/views/kanban/kanban_view"; +import {registry} from "@web/core/registry"; + +registry.category("views").add("stock_barcodes_kanban", { + ...kanbanView, +}); diff --git a/stock_barcodes/static/src/views/kanban/stock_barcodes_kanban.xml b/stock_barcodes/static/src/views/kanban/stock_barcodes_kanban.xml new file mode 100644 index 00000000..e1608140 --- /dev/null +++ b/stock_barcodes/static/src/views/kanban/stock_barcodes_kanban.xml @@ -0,0 +1,28 @@ + + + + + +
+ Scan a transfer, a product or a lot to filter your records + Scan a transfer or a product to filter your records + +
+
+
+ +
diff --git a/stock_barcodes/static/src/views/view_compiler.esm.js b/stock_barcodes/static/src/views/view_compiler.esm.js new file mode 100644 index 00000000..986bd1f6 --- /dev/null +++ b/stock_barcodes/static/src/views/view_compiler.esm.js @@ -0,0 +1,16 @@ +/** @odoo-module */ + +import {ViewCompiler} from "@web/views/view_compiler"; +import {patch} from "@web/core/utils/patch"; + +patch(ViewCompiler.prototype, "Add hotkey props to button tag", { + compileButton(el, params) { + const hotkey = el.getAttribute("data-hotkey"); + el.removeAttribute("data-hotkey"); + const button = this._super(el, params); + if (hotkey) { + button.setAttribute("hotkey", hotkey); + } + return button; + }, +}); diff --git a/stock_barcodes/static/src/views/views.esm.js b/stock_barcodes/static/src/views/views.esm.js new file mode 100644 index 00000000..c126ce3a --- /dev/null +++ b/stock_barcodes/static/src/views/views.esm.js @@ -0,0 +1,225 @@ +/** @odoo-module */ +/* Copyright 2024 Akretion +/* Copyright 2024 Tecnativa + * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ + +import {getVisibleElements, isVisible} from "@web/core/utils/ui"; +import {FormController} from "@web/views/form/form_controller"; +import {KanbanController} from "@web/views/kanban/kanban_controller"; +import {ListController} from "@web/views/list/list_controller"; +import {_t} from "@web/core/l10n/translation"; +import {isAllowedBarcodeModel} from "../utils/barcodes_models_utils.esm"; +import {patch} from "@web/core/utils/patch"; +import {useEffect} from "@odoo/owl"; +import {useService} from "@web/core/utils/hooks"; + +let barcodeOverlaysVisible = false; + +// This is necessary because the hotkey service does not make its API public for +// some reasons +export function barcodeRemoveHotkeyOverlays() { + for (const overlay of document.querySelectorAll(".o_barcode_web_hotkey_overlay")) { + overlay.remove(); + } + barcodeOverlaysVisible = false; +} + +// This is necessary because the hotkey service does not make its API public for +// some reasons +export function barcodeAddHotkeyOverlays(activeElement) { + for (const el of getVisibleElements( + activeElement, + "[data-hotkey]:not(:disabled)" + )) { + const hotkey = el.dataset.hotkey; + const overlay = document.createElement("div"); + overlay.classList.add( + "o_barcode_web_hotkey_overlay", + "position-absolute", + "top-0", + "bottom-0", + "start-0", + "end-0", + "d-flex", + "justify-content-center", + "align-items-center", + "m-0", + "bg-black-50", + "h6" + ); + const overlayKbd = document.createElement("kbd"); + overlayKbd.className = "small"; + overlayKbd.appendChild(document.createTextNode(hotkey.toUpperCase())); + overlay.appendChild(overlayKbd); + + let overlayParent = null; + if (el.tagName.toUpperCase() === "INPUT") { + // Special case for the search input that has an access key + // defined. We cannot set the overlay on the input itself, + // only on its parent. + overlayParent = el.parentElement; + } else { + overlayParent = el; + } + + if (overlayParent.style.position !== "absolute") { + overlayParent.style.position = "relative"; + } + overlayParent.appendChild(overlay); + } + barcodeOverlaysVisible = true; +} + +function setupView() { + const actionService = useService("action"); + const uiService = useService("ui"); + const busService = useService("bus_service"); + const notification = useService("notification"); + + const handleKeys = async (ev) => { + if (ev.keyCode === 113) { + // F2 + const {activeElement} = uiService; + + if (barcodeOverlaysVisible) { + barcodeRemoveHotkeyOverlays(); + } else { + barcodeAddHotkeyOverlays(activeElement); + } + } else if (ev.keyCode === 120) { + // F9 + const button = document.querySelector("button[name='action_clean_values']"); + if (isVisible(button)) { + button.click(); + } + } else if (ev.keyCode === 123 || ev.keyCode === 115) { + // F12 or F4 + await actionService.doAction( + "stock_barcodes.action_stock_barcodes_action_client", + { + name: "Barcode wizard menu", + res_model: "wiz.stock.barcodes.read.picking", + type: "ir.actions.act_window", + } + ); + } + }; + + const handleNotification = ({detail: notifications}) => { + if (notifications && notifications.length > 0) { + notifications.forEach((notif) => { + const {payload, type} = notif; + if ( + (this.model.root.resModel === payload.res_model) & + (this.model.root.resId === payload.res_id) + ) { + if (type === "stock_barcodes_sound") { + if (payload.sound === "ko") { + this.$sound_ko[0].play(); + } else { + this.$sound_ok[0].play(); + } + } else if (type === "stock_barcodes_focus") { + requestIdleCallback(() => { + const input = document.querySelector( + `[name=${payload.field_name}] input` + ); + if (input) { + input.focus(); + } + }); + } else if (type === "stock_barcodes_notify") { + notification.add(notif.payload.message, { + title: notif.payload.title, + type: notif.payload.type, + sticky: notif.payload.sticky, + }); + } + } + + if (type === "stock_barcodes_edit_manual") { + if (payload.manual_entry) { + this.env.bus.trigger("enableFormEditBarcode"); + } else if (!payload.manual_entry) { + this.env.bus.trigger("disableFormEditBarcode"); + } + } else if (type === "actions_barcode") { + if (payload.valid_picking) { + notification.add(_t("The transfer has been validated"), { + type: "success", + }); + } else if (payload.apply_inventory) { + actionService.doAction( + "stock_barcodes.action_stock_barcodes_action_client" + ); + notification.add( + _t("The inventory adjustment has been validated"), + { + type: "success", + } + ); + } + } else if (type === "actions_barcode_notification") { + notification.add(_t(payload.message), { + type: payload.message_type, + sticky: payload.sticky, + }); + } + }); + } + }; + + useEffect(() => { + document.body.addEventListener("keydown", handleKeys); + + this.$sound_ok = $("