odoo-addon-stock-barcodes 15.0.3.1.6__py3-none-any.whl → 16.0.1.0.0.19__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odoo/addons/stock_barcodes/README.rst +6 -6
- odoo/addons/stock_barcodes/__manifest__.py +8 -7
- odoo/addons/stock_barcodes/data/stock_barcodes_option.xml +1 -2
- odoo/addons/stock_barcodes/hooks.py +15 -13
- odoo/addons/stock_barcodes/i18n/es.po +305 -189
- odoo/addons/stock_barcodes/i18n/it.po +282 -180
- odoo/addons/stock_barcodes/i18n/stock_barcodes.pot +190 -160
- odoo/addons/stock_barcodes/models/__init__.py +1 -1
- odoo/addons/stock_barcodes/models/stock_barcodes_action.py +2 -1
- odoo/addons/stock_barcodes/models/stock_barcodes_option.py +2 -4
- odoo/addons/stock_barcodes/models/stock_move.py +37 -0
- odoo/addons/stock_barcodes/models/stock_move_line.py +8 -14
- odoo/addons/stock_barcodes/models/stock_picking.py +9 -36
- odoo/addons/stock_barcodes/models/stock_picking_type.py +5 -6
- odoo/addons/stock_barcodes/models/stock_quant.py +3 -4
- odoo/addons/stock_barcodes/security/ir.model.access.csv +0 -2
- odoo/addons/stock_barcodes/static/description/index.html +9 -11
- odoo/addons/stock_barcodes/static/src/css/stock.scss +41 -5
- odoo/addons/stock_barcodes/static/src/utils/barcode_handler_field.esm.js +36 -0
- odoo/addons/stock_barcodes/static/src/utils/barcodes_models_utils.esm.js +25 -0
- odoo/addons/stock_barcodes/static/src/views/form_view.esm.js +17 -0
- odoo/addons/stock_barcodes/static/src/views/kanban_renderer.esm.js +149 -0
- odoo/addons/stock_barcodes/static/src/views/view_compiler.esm.js +16 -0
- odoo/addons/stock_barcodes/static/src/views/views.esm.js +193 -0
- odoo/addons/stock_barcodes/static/src/widgets/boolean_toggle.esm.js +26 -0
- odoo/addons/stock_barcodes/static/src/widgets/numeric_step.esm.js +40 -0
- odoo/addons/stock_barcodes/static/src/widgets/numeric_step.xml +17 -0
- odoo/addons/stock_barcodes/static/src/widgets/view_button.esm.js +8 -0
- odoo/addons/stock_barcodes/static/src/widgets/view_button.xml +14 -0
- odoo/addons/stock_barcodes/tests/common.py +167 -0
- odoo/addons/stock_barcodes/tests/test_stock_barcodes.py +4 -172
- odoo/addons/stock_barcodes/tests/test_stock_barcodes_new_lot.py +2 -2
- odoo/addons/stock_barcodes/tests/test_stock_barcodes_picking.py +8 -8
- odoo/addons/stock_barcodes/views/stock_barcodes_option_view.xml +1 -1
- odoo/addons/stock_barcodes/views/stock_picking_views.xml +4 -3
- odoo/addons/stock_barcodes/wizard/stock_barcodes_read.py +45 -91
- odoo/addons/stock_barcodes/wizard/stock_barcodes_read_inventory.py +1 -4
- odoo/addons/stock_barcodes/wizard/stock_barcodes_read_inventory_views.xml +14 -15
- odoo/addons/stock_barcodes/wizard/stock_barcodes_read_picking.py +256 -92
- odoo/addons/stock_barcodes/wizard/stock_barcodes_read_picking_views.xml +59 -37
- odoo/addons/stock_barcodes/wizard/stock_barcodes_read_todo.py +33 -107
- odoo/addons/stock_barcodes/wizard/stock_barcodes_read_todo_view.xml +70 -28
- odoo/addons/stock_barcodes/wizard/stock_barcodes_read_views.xml +172 -189
- odoo/addons/stock_barcodes/wizard/stock_production_lot.py +2 -2
- odoo/addons/stock_barcodes/wizard/stock_production_lot_views.xml +6 -8
- {odoo_addon_stock_barcodes-15.0.3.1.6.dist-info → odoo_addon_stock_barcodes-16.0.1.0.0.19.dist-info}/METADATA +11 -11
- odoo_addon_stock_barcodes-16.0.1.0.0.19.dist-info/RECORD +66 -0
- {odoo_addon_stock_barcodes-15.0.3.1.6.dist-info → odoo_addon_stock_barcodes-16.0.1.0.0.19.dist-info}/WHEEL +1 -1
- odoo/addons/stock_barcodes/migrations/15.0.1.0.0/pre-migration.py +0 -14
- odoo/addons/stock_barcodes/models/stock_barcodes_read_log.py +0 -51
- odoo/addons/stock_barcodes/static/src/css/stock.css +0 -5
- odoo/addons/stock_barcodes/static/src/js/barcodes_models_mixin.js +0 -34
- odoo/addons/stock_barcodes/static/src/js/basic_controller.js +0 -412
- odoo/addons/stock_barcodes/static/src/js/basic_fields.js +0 -59
- odoo/addons/stock_barcodes/static/src/js/form_view.js +0 -24
- odoo/addons/stock_barcodes/static/src/js/kanban_renderer.js +0 -47
- odoo/addons/stock_barcodes/static/src/js/numeric_step.js +0 -43
- odoo_addon_stock_barcodes-15.0.3.1.6.dist-info/RECORD +0 -62
- {odoo_addon_stock_barcodes-15.0.3.1.6.dist-info → odoo_addon_stock_barcodes-16.0.1.0.0.19.dist-info}/top_level.txt +0 -0
@@ -40,10 +40,11 @@ class StockBarcodesAction(models.Model):
|
|
40
40
|
vals = {
|
41
41
|
"option_group_id": option_group.id,
|
42
42
|
"manual_entry": option_group.manual_entry,
|
43
|
+
"display_read_quant": option_group.display_read_quant,
|
43
44
|
}
|
44
45
|
if option_group.get_option_value("location_id", "filled_default"):
|
45
46
|
vals["location_id"] = (
|
46
|
-
self.env["stock.warehouse"].search([])
|
47
|
+
self.env["stock.warehouse"].search([], limit=1).lot_stock_id.id
|
47
48
|
)
|
48
49
|
wiz = self.env["wiz.stock.barcodes.read.inventory"].create(vals)
|
49
50
|
action = self.env["ir.actions.actions"]._for_xml_id(
|
@@ -35,13 +35,10 @@ class StockBarcodesOptionGroup(models.Model):
|
|
35
35
|
string="Show pending moves", help="Shows a list of movements to process"
|
36
36
|
)
|
37
37
|
source_pending_moves = fields.Selection(
|
38
|
-
[("move_line_ids", "Detailed operations"), ("
|
38
|
+
[("move_line_ids", "Detailed operations"), ("move_ids", "Operations")],
|
39
39
|
default="move_line_ids",
|
40
40
|
help="Origin of the data to generate the movements to process",
|
41
41
|
)
|
42
|
-
show_scan_log = fields.Boolean(
|
43
|
-
string="Show scan log", help="Displays a log of the scans processed"
|
44
|
-
)
|
45
42
|
ignore_filled_fields = fields.Boolean(
|
46
43
|
string="Ignore filled fields",
|
47
44
|
)
|
@@ -103,6 +100,7 @@ class StockBarcodesOptionGroup(models.Model):
|
|
103
100
|
("location_dest_id", "Destination Location"),
|
104
101
|
]
|
105
102
|
)
|
103
|
+
display_read_quant = fields.Boolean(string="Read items on inventory mode")
|
106
104
|
|
107
105
|
def get_option_value(self, field_name, attribute):
|
108
106
|
option = self.option_ids.filtered(lambda op: op.field_name == field_name)[:1]
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Copyright 2024 Tecnativa - Sergio Teruel
|
2
|
+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
3
|
+
|
4
|
+
from odoo import fields, models
|
5
|
+
|
6
|
+
|
7
|
+
class StockMove(models.Model):
|
8
|
+
_inherit = "stock.move"
|
9
|
+
|
10
|
+
barcode_backorder_action = fields.Selection(
|
11
|
+
[
|
12
|
+
("pending", "Pending"),
|
13
|
+
("create_backorder", "Create Backorder"),
|
14
|
+
("skip_backorder", "No Backorder"),
|
15
|
+
],
|
16
|
+
string="Backorder action",
|
17
|
+
default="pending",
|
18
|
+
)
|
19
|
+
|
20
|
+
def _action_done(self, cancel_backorder=False):
|
21
|
+
moves_cancel_backorder = self.browse()
|
22
|
+
if not cancel_backorder:
|
23
|
+
moves_cancel_backorder = self.filtered(
|
24
|
+
lambda sm: sm.barcode_backorder_action == "skip_backorder"
|
25
|
+
)
|
26
|
+
super(StockMove, moves_cancel_backorder)._action_done(cancel_backorder=True)
|
27
|
+
moves_backorder = self - moves_cancel_backorder
|
28
|
+
moves_backorder.barcode_backorder_action = "pending"
|
29
|
+
return super(StockMove, moves_backorder)._action_done(
|
30
|
+
cancel_backorder=cancel_backorder
|
31
|
+
)
|
32
|
+
|
33
|
+
def copy_data(self, default=None):
|
34
|
+
vals_list = super().copy_data(default=default)
|
35
|
+
for vals in vals_list:
|
36
|
+
vals.pop("barcode_backorder_action", None)
|
37
|
+
return vals_list
|
@@ -15,10 +15,10 @@ class StockMoveLine(models.Model):
|
|
15
15
|
store=True,
|
16
16
|
)
|
17
17
|
|
18
|
-
@api.depends("qty_done", "
|
18
|
+
@api.depends("qty_done", "reserved_uom_qty")
|
19
19
|
def _compute_barcode_scan_state(self):
|
20
20
|
for line in self:
|
21
|
-
if line.qty_done >= line.
|
21
|
+
if line.qty_done >= line.reserved_uom_qty:
|
22
22
|
line.barcode_scan_state = "done"
|
23
23
|
else:
|
24
24
|
line.barcode_scan_state = "pending"
|
@@ -28,19 +28,13 @@ class StockMoveLine(models.Model):
|
|
28
28
|
|
29
29
|
def action_barcode_detailed_operation_unlink(self):
|
30
30
|
for sml in self:
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
sml.unlink()
|
31
|
+
stock_move = sml.move_id
|
32
|
+
stock_move.barcode_backorder_action = "pending"
|
33
|
+
sml.unlink()
|
35
34
|
# HACK: To force refresh wizard values
|
36
35
|
wiz_barcode = self.env["wiz.stock.barcodes.read.picking"].browse(
|
37
36
|
self.env.context.get("wiz_barcode_id", False)
|
38
37
|
)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
wiz_barcode.fill_todo_records()
|
43
|
-
wiz_barcode.determine_todo_action()
|
44
|
-
else:
|
45
|
-
wiz_barcode.fill_todo_records()
|
46
|
-
wiz_barcode.todo_line_id.line_ids = wiz_barcode.todo_line_id.line_ids
|
38
|
+
stock_move._action_assign()
|
39
|
+
wiz_barcode.fill_todo_records()
|
40
|
+
wiz_barcode.determine_todo_action()
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# Copyright 2019 Sergio Teruel <sergio.teruel@tecnativa.com>
|
2
2
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
3
3
|
from odoo import models
|
4
|
-
from odoo.tools.float_utils import float_compare
|
5
4
|
|
6
5
|
|
7
6
|
class StockPicking(models.Model):
|
@@ -19,7 +18,7 @@ class StockPicking(models.Model):
|
|
19
18
|
}
|
20
19
|
if self.picking_type_id.code == "outgoing":
|
21
20
|
vals["location_dest_id"] = self.location_dest_id.id
|
22
|
-
|
21
|
+
elif self.picking_type_id.code == "incoming":
|
23
22
|
vals["location_id"] = self.location_id.id
|
24
23
|
|
25
24
|
if option_group.get_option_value("location_id", "filled_default"):
|
@@ -33,8 +32,8 @@ class StockPicking(models.Model):
|
|
33
32
|
wiz = self.env["wiz.stock.barcodes.read.picking"].create(
|
34
33
|
self._prepare_barcode_wiz_vals(option_group)
|
35
34
|
)
|
36
|
-
wiz.determine_todo_action()
|
37
35
|
wiz.fill_pending_moves()
|
36
|
+
wiz.determine_todo_action()
|
38
37
|
action = self.env["ir.actions.actions"]._for_xml_id(
|
39
38
|
"stock_barcodes.action_stock_barcodes_read_picking"
|
40
39
|
)
|
@@ -42,41 +41,15 @@ class StockPicking(models.Model):
|
|
42
41
|
return action
|
43
42
|
|
44
43
|
def button_validate(self):
|
45
|
-
|
46
|
-
|
47
|
-
and not
|
48
|
-
)
|
49
|
-
|
50
|
-
|
51
|
-
# Variable initialized as True to optimize break loop
|
52
|
-
skip_backorder = True
|
44
|
+
put_in_pack_picks = self.filtered(
|
45
|
+
lambda p: p.picking_type_id.barcode_option_group_id.auto_put_in_pack
|
46
|
+
and not p.move_line_ids.result_package_id
|
47
|
+
)
|
48
|
+
if put_in_pack_picks:
|
49
|
+
put_in_pack_picks.action_put_in_pack()
|
53
50
|
if self.env.context.get("stock_barcodes_validate_picking", False):
|
54
|
-
# Avoid backorder when all move lines are processed (done or done_forced)
|
55
|
-
prec = self.env["decimal.precision"].precision_get(
|
56
|
-
"Product Unit of Measure"
|
57
|
-
)
|
58
|
-
for move in self.move_lines.filtered(lambda sm: sm.state != "cancel"):
|
59
|
-
if (
|
60
|
-
float_compare(
|
61
|
-
move.quantity_done, move.product_uom_qty, precision_digits=prec
|
62
|
-
)
|
63
|
-
< 0
|
64
|
-
):
|
65
|
-
# In normal conditions backorder will be created
|
66
|
-
create_backorder = True
|
67
|
-
if not move.move_line_ids or any(
|
68
|
-
sml.barcode_scan_state in ["pending"]
|
69
|
-
for sml in move.move_line_ids
|
70
|
-
):
|
71
|
-
# If any move are not processed we can not skip backorder
|
72
|
-
skip_backorder = False
|
73
|
-
break
|
74
|
-
if create_backorder and skip_backorder:
|
75
51
|
res = super(
|
76
|
-
StockPicking,
|
77
|
-
self.with_context(
|
78
|
-
picking_ids_not_to_backorder=self.ids, skip_backorder=True
|
79
|
-
),
|
52
|
+
StockPicking, self.with_context(skip_backorder=True)
|
80
53
|
).button_validate()
|
81
54
|
else:
|
82
55
|
res = super().button_validate()
|
@@ -26,17 +26,15 @@ class StockPickingType(models.Model):
|
|
26
26
|
"picking_mode": "picking",
|
27
27
|
}
|
28
28
|
if self.code == "outgoing":
|
29
|
-
location_dest_id = (
|
29
|
+
vals["location_dest_id"] = (
|
30
30
|
self.default_location_dest_id.id
|
31
31
|
or self.env.ref("stock.stock_location_customers").id
|
32
32
|
)
|
33
|
-
|
34
|
-
|
35
|
-
location_src_id = (
|
33
|
+
elif self.code == "incoming":
|
34
|
+
vals["location_id"] = (
|
36
35
|
self.default_location_src_id.id
|
37
36
|
or self.env.ref("stock.stock_location_suppliers").id
|
38
37
|
)
|
39
|
-
vals["location_id"] = location_src_id
|
40
38
|
if self.barcode_option_group_id.get_option_value(
|
41
39
|
"location_id", "filled_default"
|
42
40
|
):
|
@@ -46,8 +44,8 @@ class StockPickingType(models.Model):
|
|
46
44
|
):
|
47
45
|
vals["location_dest_id"] = self.default_location_dest_id.id
|
48
46
|
wiz = self.env["wiz.stock.barcodes.read.picking"].create(vals)
|
49
|
-
wiz.determine_todo_action()
|
50
47
|
wiz.fill_pending_moves()
|
48
|
+
wiz.determine_todo_action()
|
51
49
|
action = self.env["ir.actions.actions"]._for_xml_id(
|
52
50
|
"stock_barcodes.action_stock_barcodes_read_picking"
|
53
51
|
)
|
@@ -55,6 +53,7 @@ class StockPickingType(models.Model):
|
|
55
53
|
return action
|
56
54
|
|
57
55
|
def action_barcode_new_picking(self):
|
56
|
+
self.ensure_one()
|
58
57
|
picking = (
|
59
58
|
self.env["stock.picking"]
|
60
59
|
.with_context(default_immediate_transfer=True)
|
@@ -16,7 +16,6 @@ class StockQuant(models.Model):
|
|
16
16
|
"product_uom_id",
|
17
17
|
"lot_id",
|
18
18
|
"package_id",
|
19
|
-
"product_qty",
|
20
19
|
]
|
21
20
|
|
22
21
|
def action_barcode_inventory_quant_edit(self):
|
@@ -25,7 +24,7 @@ class StockQuant(models.Model):
|
|
25
24
|
wiz_barcode_id
|
26
25
|
)
|
27
26
|
for quant in self:
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
# Try to assign fields with the same name between quant and the scan wizard
|
28
|
+
for fname in self._get_fields_to_edit():
|
29
|
+
wiz_barcode[fname] = quant[fname]
|
31
30
|
wiz_barcode.product_qty = quant.inventory_quantity
|
@@ -1,6 +1,4 @@
|
|
1
1
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
2
|
-
access_stock_barcodes_read_log,access_stock_barcodes_read_log,model_stock_barcodes_read_log,base.group_user,1,1,1,1
|
3
|
-
access_stock_barcodes_read_log_line,access_stock_barcodes_read_log_line,model_stock_barcodes_read_log_line,base.group_user,1,1,1,1
|
4
2
|
access_wiz_stock_barcodes_read_picking,access_wiz_stock_barcodes_read_picking,model_wiz_stock_barcodes_read_picking,base.group_user,1,1,1,1
|
5
3
|
access_wiz_candidate_picking,access_wiz_candidate_picking,model_wiz_candidate_picking,base.group_user,1,1,1,1
|
6
4
|
access_wiz_stock_barcodes_new_lot,access_wiz_stock_barcodes_new_lot,model_wiz_stock_barcodes_new_lot,base.group_user,1,1,1,1
|
@@ -1,3 +1,4 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
1
2
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
3
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
3
4
|
<head>
|
@@ -8,11 +9,10 @@
|
|
8
9
|
|
9
10
|
/*
|
10
11
|
:Author: David Goodger (goodger@python.org)
|
11
|
-
:Id: $Id: html4css1.css
|
12
|
+
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
|
12
13
|
:Copyright: This stylesheet has been placed in the public domain.
|
13
14
|
|
14
15
|
Default cascading style sheet for the HTML output of Docutils.
|
15
|
-
Despite the name, some widely supported CSS2 features are used.
|
16
16
|
|
17
17
|
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
|
18
18
|
customize this style sheet.
|
@@ -275,7 +275,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code {
|
|
275
275
|
margin-left: 2em ;
|
276
276
|
margin-right: 2em }
|
277
277
|
|
278
|
-
pre.code .ln { color:
|
278
|
+
pre.code .ln { color: grey; } /* line numbers */
|
279
279
|
pre.code, code { background-color: #eeeeee }
|
280
280
|
pre.code .comment, code .comment { color: #5C6576 }
|
281
281
|
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
@@ -301,7 +301,7 @@ span.option {
|
|
301
301
|
span.pre {
|
302
302
|
white-space: pre }
|
303
303
|
|
304
|
-
span.problematic
|
304
|
+
span.problematic {
|
305
305
|
color: red }
|
306
306
|
|
307
307
|
span.section-subtitle {
|
@@ -367,9 +367,9 @@ ul.auto-toc {
|
|
367
367
|
!! This file is generated by oca-gen-addon-readme !!
|
368
368
|
!! changes will be overwritten. !!
|
369
369
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
370
|
-
!! source digest: sha256:
|
370
|
+
!! source digest: sha256:f6453112d1afcb3f171e5f468a06e4927c98ed93493c10c8af4e4aef077de7fd
|
371
371
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
372
|
-
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/stock-logistics-barcode/tree/
|
372
|
+
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/stock-logistics-barcode/tree/16.0/stock_barcodes"><img alt="OCA/stock-logistics-barcode" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--barcode-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/stock-logistics-barcode-16-0/stock-logistics-barcode-16-0-stock_barcodes"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-barcode&target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
373
373
|
<p>This module provides a barcode reader interface for stock module.</p>
|
374
374
|
<p>This module contains a base wizard read barcode that can be extended by
|
375
375
|
other modules.</p>
|
@@ -518,7 +518,7 @@ Add security for users.</li>
|
|
518
518
|
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/stock-logistics-barcode/issues">GitHub Issues</a>.
|
519
519
|
In case of trouble, please check there if your issue has already been reported.
|
520
520
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
521
|
-
<a class="reference external" href="https://github.com/OCA/stock-logistics-barcode/issues/new?body=module:%20stock_barcodes%0Aversion:%
|
521
|
+
<a class="reference external" href="https://github.com/OCA/stock-logistics-barcode/issues/new?body=module:%20stock_barcodes%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
522
522
|
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
523
523
|
</div>
|
524
524
|
<div class="section" id="credits">
|
@@ -557,13 +557,11 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
|
557
557
|
<div class="section" id="maintainers">
|
558
558
|
<h2><a class="toc-backref" href="#toc-entry-16">Maintainers</a></h2>
|
559
559
|
<p>This module is maintained by the OCA.</p>
|
560
|
-
<a class="reference external image-reference" href="https://odoo-community.org">
|
561
|
-
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
|
562
|
-
</a>
|
560
|
+
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
|
563
561
|
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
564
562
|
mission is to support the collaborative development of Odoo features and
|
565
563
|
promote its widespread use.</p>
|
566
|
-
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/stock-logistics-barcode/tree/
|
564
|
+
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/stock-logistics-barcode/tree/16.0/stock_barcodes">OCA/stock-logistics-barcode</a> project on GitHub.</p>
|
567
565
|
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
|
568
566
|
</div>
|
569
567
|
</div>
|
@@ -12,15 +12,29 @@
|
|
12
12
|
border-width: 1px 0 0 0;
|
13
13
|
}
|
14
14
|
|
15
|
+
// Avoid too big small buttons from core
|
16
|
+
.o_web_client.o_touch_device {
|
17
|
+
.oe_stock_barcordes_form {
|
18
|
+
.btn {
|
19
|
+
&,
|
20
|
+
.btn-sm {
|
21
|
+
padding: 0.25rem 0.5rem;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
15
27
|
.oe_stock_barcordes_form {
|
16
28
|
padding: 0 !important;
|
17
29
|
height: 100%;
|
18
|
-
|
19
|
-
|
30
|
+
// Recover useless space
|
31
|
+
div[name="_barcode_scanned"] {
|
32
|
+
min-height: 0 !important;
|
33
|
+
}
|
34
|
+
.o_group .scan_fields {
|
20
35
|
&.o_inner_group {
|
21
36
|
margin-bottom: 0 !important;
|
22
37
|
}
|
23
|
-
|
24
38
|
margin: 0 !important;
|
25
39
|
}
|
26
40
|
|
@@ -32,12 +46,27 @@
|
|
32
46
|
border: 0 !important;
|
33
47
|
}
|
34
48
|
|
49
|
+
// In Odoo 16 the flat input styling lacks proper usability
|
35
50
|
.o_field_widget {
|
36
|
-
margin-bottom:
|
51
|
+
margin-bottom: 1px !important;
|
52
|
+
.o_input {
|
53
|
+
border-radius: 3px;
|
54
|
+
border-width: 1px;
|
55
|
+
background-color: white;
|
56
|
+
}
|
57
|
+
.o_x2m_control_panel {
|
58
|
+
margin: 0px !important;
|
59
|
+
}
|
37
60
|
}
|
38
61
|
|
39
62
|
.o_kanban_record {
|
40
|
-
|
63
|
+
flex-basis: 100%;
|
64
|
+
|
65
|
+
.btn-full-width {
|
66
|
+
margin: -9px;
|
67
|
+
width: calc(100% + 18px);
|
68
|
+
height: calc(100% + 18px);
|
69
|
+
}
|
41
70
|
|
42
71
|
&.o_kanban_ghost {
|
43
72
|
display: none;
|
@@ -82,6 +111,13 @@
|
|
82
111
|
width: 100% !important;
|
83
112
|
}
|
84
113
|
|
114
|
+
// The kanban view adds some pre-styles that we want to be able to tweak
|
115
|
+
div[name="menu_actions"] {
|
116
|
+
div[role="article"] {
|
117
|
+
margin-top: 10px !important;
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
85
121
|
// Dropdown that is desactivated at lg width
|
86
122
|
@media (min-width: 992px) {
|
87
123
|
.d-lg-flex-no-dropdown {
|
@@ -0,0 +1,36 @@
|
|
1
|
+
/** @odoo-module **/
|
2
|
+
import {BarcodeHandlerField} from "@barcodes/barcode_handler_field";
|
3
|
+
import {patch} from "@web/core/utils/patch";
|
4
|
+
import {useService} from "@web/core/utils/hooks";
|
5
|
+
const {useEffect} = owl;
|
6
|
+
|
7
|
+
patch(BarcodeHandlerField.prototype, "stock_barcodes.BarcodeHandlerField", {
|
8
|
+
/* eslint-disable no-unused-vars */
|
9
|
+
setup() {
|
10
|
+
this._super(...arguments);
|
11
|
+
const busService = useService("bus_service");
|
12
|
+
this.orm = useService("orm");
|
13
|
+
const notifyChanges = async ({detail: notifications}) => {
|
14
|
+
for (const {payload, type} of notifications) {
|
15
|
+
if (type === "stock_barcodes_refresh_data") {
|
16
|
+
await this.env.model.root.load();
|
17
|
+
this.env.model.notify();
|
18
|
+
}
|
19
|
+
}
|
20
|
+
};
|
21
|
+
useEffect(() => {
|
22
|
+
busService.addChannel("barcode_reload");
|
23
|
+
busService.addEventListener("notification", notifyChanges);
|
24
|
+
return () => {
|
25
|
+
busService.deleteChannel("barcode_reload");
|
26
|
+
busService.removeEventListener("notification", notifyChanges);
|
27
|
+
};
|
28
|
+
});
|
29
|
+
},
|
30
|
+
onBarcodeScanned(event) {
|
31
|
+
this._super(...arguments);
|
32
|
+
if (this.props.record.resModel.includes("wiz.stock.barcodes.read")) {
|
33
|
+
$("#dummy_on_barcode_scanned").click();
|
34
|
+
}
|
35
|
+
},
|
36
|
+
});
|
@@ -0,0 +1,25 @@
|
|
1
|
+
/** @odoo-module */
|
2
|
+
/* Copyright 2022 Tecnativa - Alexandre D. Díaz
|
3
|
+
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
4
|
+
|
5
|
+
// Models allowed to have extra keybinding features
|
6
|
+
export const barcodeModels = [
|
7
|
+
"stock.barcodes.action",
|
8
|
+
"stock.picking",
|
9
|
+
"stock.picking.type",
|
10
|
+
"wiz.candidate.picking",
|
11
|
+
"wiz.stock.barcodes.new.lot",
|
12
|
+
"wiz.stock.barcodes.read",
|
13
|
+
"wiz.stock.barcodes.read.inventory",
|
14
|
+
"wiz.stock.barcodes.read.picking",
|
15
|
+
"wiz.stock.barcodes.read.todo",
|
16
|
+
];
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Helper to know if the given model is allowed
|
20
|
+
*
|
21
|
+
* @returns {Boolean}
|
22
|
+
*/
|
23
|
+
export function isAllowedBarcodeModel(modelName) {
|
24
|
+
return barcodeModels.includes(modelName);
|
25
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
/** @odoo-module */
|
2
|
+
/* Copyright 2021 Tecnativa - Alexandre D. Díaz
|
3
|
+
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
4
|
+
|
5
|
+
import {FormController} from "@web/views/form/form_controller";
|
6
|
+
import {patch} from "@web/core/utils/patch";
|
7
|
+
|
8
|
+
patch(FormController.prototype, "Allow display.controlPanel overriding", {
|
9
|
+
setup() {
|
10
|
+
this._super(...arguments);
|
11
|
+
// Adds support to use control_pannel_hidden from the
|
12
|
+
// context to disable the control panel
|
13
|
+
if (this.props.context.control_panel_hidden) {
|
14
|
+
this.display.controlPanel = false;
|
15
|
+
}
|
16
|
+
},
|
17
|
+
});
|
@@ -0,0 +1,149 @@
|
|
1
|
+
/** @odoo-module */
|
2
|
+
/* Copyright 2022 Tecnativa - Alexandre D. Díaz
|
3
|
+
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
4
|
+
|
5
|
+
import {KanbanRenderer} from "@web/views/kanban/kanban_renderer";
|
6
|
+
import {isAllowedBarcodeModel} from "../utils/barcodes_models_utils.esm";
|
7
|
+
import {patch} from "@web/core/utils/patch";
|
8
|
+
import {useBus} from "@web/core/utils/hooks";
|
9
|
+
import {useHotkey} from "@web/core/hotkeys/hotkey_hook";
|
10
|
+
import {useRef} from "@odoo/owl";
|
11
|
+
|
12
|
+
patch(KanbanRenderer.prototype, "add hotkey", {
|
13
|
+
setup() {
|
14
|
+
const rootRef = useRef("root");
|
15
|
+
useHotkey(
|
16
|
+
"Enter",
|
17
|
+
({target}) => {
|
18
|
+
if (!target.classList.contains("o_kanban_record")) {
|
19
|
+
return;
|
20
|
+
}
|
21
|
+
|
22
|
+
// Open first link
|
23
|
+
let firstLink = null;
|
24
|
+
if (isAllowedBarcodeModel(this.props.list.resModel)) {
|
25
|
+
firstLink = target.querySelector(
|
26
|
+
".oe_kanban_action_button,.oe_btn_quick_action"
|
27
|
+
);
|
28
|
+
}
|
29
|
+
if (!firstLink) {
|
30
|
+
firstLink = target.querySelector(
|
31
|
+
".oe_kanban_global_click, a, button"
|
32
|
+
);
|
33
|
+
}
|
34
|
+
if (firstLink && firstLink instanceof HTMLElement) {
|
35
|
+
firstLink.click();
|
36
|
+
}
|
37
|
+
return;
|
38
|
+
},
|
39
|
+
{area: () => rootRef.el}
|
40
|
+
);
|
41
|
+
|
42
|
+
this._super(...arguments);
|
43
|
+
|
44
|
+
if (isAllowedBarcodeModel(this.props.list.resModel)) {
|
45
|
+
if (this.env.searchModel) {
|
46
|
+
useBus(this.env.searchModel, "focus-view", () => {
|
47
|
+
const {model} = this.props.list;
|
48
|
+
if (model.useSampleModel || !model.hasData()) {
|
49
|
+
return;
|
50
|
+
}
|
51
|
+
const cards = Array.from(
|
52
|
+
rootRef.el.querySelectorAll(".o_kanban_record")
|
53
|
+
);
|
54
|
+
const firstCard = cards.find(
|
55
|
+
(card) =>
|
56
|
+
card.querySelectorAll("button[name='action_barcode_scan']")
|
57
|
+
.length > 0
|
58
|
+
);
|
59
|
+
if (firstCard) {
|
60
|
+
// Focus first kanban card
|
61
|
+
firstCard.focus();
|
62
|
+
}
|
63
|
+
});
|
64
|
+
}
|
65
|
+
}
|
66
|
+
},
|
67
|
+
|
68
|
+
// eslint-disable-next-line complexity
|
69
|
+
// This is copied from the base kanban_renderer.
|
70
|
+
// We want to only focus card with barcode when isAllowedBarcodeModel returns true
|
71
|
+
// Since there is no way to hook and change the candidate cards that are selectable
|
72
|
+
// (cards line 84) we cannot inherit and change the result. And even if we called
|
73
|
+
// super it would not respect inheritability
|
74
|
+
/**
|
75
|
+
* Redefines focusNextCard to select only kanban card with a barcode
|
76
|
+
* when isAllowBarcodeModel returns true for the current model
|
77
|
+
*
|
78
|
+
* @param {Node} area
|
79
|
+
* @param {String} direction
|
80
|
+
*/
|
81
|
+
focusNextCard(area, direction) {
|
82
|
+
const {isGrouped} = this.props.list;
|
83
|
+
const closestCard = document.activeElement.closest(".o_kanban_record");
|
84
|
+
if (!closestCard) {
|
85
|
+
return;
|
86
|
+
}
|
87
|
+
const groups = isGrouped
|
88
|
+
? [...area.querySelectorAll(".o_kanban_group")]
|
89
|
+
: [area];
|
90
|
+
let cards = [...groups]
|
91
|
+
.map((group) => [...group.querySelectorAll(".o_kanban_record")])
|
92
|
+
.filter((group) => group.length);
|
93
|
+
|
94
|
+
if (isAllowedBarcodeModel(this.props.list.resModel)) {
|
95
|
+
cards = cards.map((group) => {
|
96
|
+
const result = group.filter((card) => {
|
97
|
+
return (
|
98
|
+
card.querySelectorAll('button[name="action_barcode_scan"]')
|
99
|
+
.length > 0
|
100
|
+
);
|
101
|
+
});
|
102
|
+
return result;
|
103
|
+
});
|
104
|
+
}
|
105
|
+
|
106
|
+
let iGroup = null;
|
107
|
+
let iCard = null;
|
108
|
+
for (iGroup = 0; iGroup < cards.length; iGroup++) {
|
109
|
+
const i = cards[iGroup].indexOf(closestCard);
|
110
|
+
if (i !== -1) {
|
111
|
+
iCard = i;
|
112
|
+
break;
|
113
|
+
}
|
114
|
+
}
|
115
|
+
if (iCard === undefined) {
|
116
|
+
iCard = 0;
|
117
|
+
iGroup = 0;
|
118
|
+
}
|
119
|
+
// Find next card to focus
|
120
|
+
let nextCard = null;
|
121
|
+
switch (direction) {
|
122
|
+
case "down":
|
123
|
+
nextCard = iCard < cards[iGroup].length - 1 && cards[iGroup][iCard + 1];
|
124
|
+
break;
|
125
|
+
case "up":
|
126
|
+
nextCard = iCard > 0 && cards[iGroup][iCard - 1];
|
127
|
+
break;
|
128
|
+
case "right":
|
129
|
+
if (isGrouped) {
|
130
|
+
nextCard = iGroup < cards.length - 1 && cards[iGroup + 1][0];
|
131
|
+
} else {
|
132
|
+
nextCard = iCard < cards[0].length - 1 && cards[0][iCard + 1];
|
133
|
+
}
|
134
|
+
break;
|
135
|
+
case "left":
|
136
|
+
if (isGrouped) {
|
137
|
+
nextCard = iGroup > 0 && cards[iGroup - 1][0];
|
138
|
+
} else {
|
139
|
+
nextCard = iCard > 0 && cards[0][iCard - 1];
|
140
|
+
}
|
141
|
+
break;
|
142
|
+
}
|
143
|
+
|
144
|
+
if (nextCard && nextCard instanceof HTMLElement) {
|
145
|
+
nextCard.focus();
|
146
|
+
return true;
|
147
|
+
}
|
148
|
+
},
|
149
|
+
});
|