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.
Files changed (59) hide show
  1. odoo/addons/stock_barcodes/README.rst +6 -6
  2. odoo/addons/stock_barcodes/__manifest__.py +8 -7
  3. odoo/addons/stock_barcodes/data/stock_barcodes_option.xml +1 -2
  4. odoo/addons/stock_barcodes/hooks.py +15 -13
  5. odoo/addons/stock_barcodes/i18n/es.po +305 -189
  6. odoo/addons/stock_barcodes/i18n/it.po +282 -180
  7. odoo/addons/stock_barcodes/i18n/stock_barcodes.pot +190 -160
  8. odoo/addons/stock_barcodes/models/__init__.py +1 -1
  9. odoo/addons/stock_barcodes/models/stock_barcodes_action.py +2 -1
  10. odoo/addons/stock_barcodes/models/stock_barcodes_option.py +2 -4
  11. odoo/addons/stock_barcodes/models/stock_move.py +37 -0
  12. odoo/addons/stock_barcodes/models/stock_move_line.py +8 -14
  13. odoo/addons/stock_barcodes/models/stock_picking.py +9 -36
  14. odoo/addons/stock_barcodes/models/stock_picking_type.py +5 -6
  15. odoo/addons/stock_barcodes/models/stock_quant.py +3 -4
  16. odoo/addons/stock_barcodes/security/ir.model.access.csv +0 -2
  17. odoo/addons/stock_barcodes/static/description/index.html +9 -11
  18. odoo/addons/stock_barcodes/static/src/css/stock.scss +41 -5
  19. odoo/addons/stock_barcodes/static/src/utils/barcode_handler_field.esm.js +36 -0
  20. odoo/addons/stock_barcodes/static/src/utils/barcodes_models_utils.esm.js +25 -0
  21. odoo/addons/stock_barcodes/static/src/views/form_view.esm.js +17 -0
  22. odoo/addons/stock_barcodes/static/src/views/kanban_renderer.esm.js +149 -0
  23. odoo/addons/stock_barcodes/static/src/views/view_compiler.esm.js +16 -0
  24. odoo/addons/stock_barcodes/static/src/views/views.esm.js +193 -0
  25. odoo/addons/stock_barcodes/static/src/widgets/boolean_toggle.esm.js +26 -0
  26. odoo/addons/stock_barcodes/static/src/widgets/numeric_step.esm.js +40 -0
  27. odoo/addons/stock_barcodes/static/src/widgets/numeric_step.xml +17 -0
  28. odoo/addons/stock_barcodes/static/src/widgets/view_button.esm.js +8 -0
  29. odoo/addons/stock_barcodes/static/src/widgets/view_button.xml +14 -0
  30. odoo/addons/stock_barcodes/tests/common.py +167 -0
  31. odoo/addons/stock_barcodes/tests/test_stock_barcodes.py +4 -172
  32. odoo/addons/stock_barcodes/tests/test_stock_barcodes_new_lot.py +2 -2
  33. odoo/addons/stock_barcodes/tests/test_stock_barcodes_picking.py +8 -8
  34. odoo/addons/stock_barcodes/views/stock_barcodes_option_view.xml +1 -1
  35. odoo/addons/stock_barcodes/views/stock_picking_views.xml +4 -3
  36. odoo/addons/stock_barcodes/wizard/stock_barcodes_read.py +45 -91
  37. odoo/addons/stock_barcodes/wizard/stock_barcodes_read_inventory.py +1 -4
  38. odoo/addons/stock_barcodes/wizard/stock_barcodes_read_inventory_views.xml +14 -15
  39. odoo/addons/stock_barcodes/wizard/stock_barcodes_read_picking.py +256 -92
  40. odoo/addons/stock_barcodes/wizard/stock_barcodes_read_picking_views.xml +59 -37
  41. odoo/addons/stock_barcodes/wizard/stock_barcodes_read_todo.py +33 -107
  42. odoo/addons/stock_barcodes/wizard/stock_barcodes_read_todo_view.xml +70 -28
  43. odoo/addons/stock_barcodes/wizard/stock_barcodes_read_views.xml +172 -189
  44. odoo/addons/stock_barcodes/wizard/stock_production_lot.py +2 -2
  45. odoo/addons/stock_barcodes/wizard/stock_production_lot_views.xml +6 -8
  46. {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
  47. odoo_addon_stock_barcodes-16.0.1.0.0.19.dist-info/RECORD +66 -0
  48. {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
  49. odoo/addons/stock_barcodes/migrations/15.0.1.0.0/pre-migration.py +0 -14
  50. odoo/addons/stock_barcodes/models/stock_barcodes_read_log.py +0 -51
  51. odoo/addons/stock_barcodes/static/src/css/stock.css +0 -5
  52. odoo/addons/stock_barcodes/static/src/js/barcodes_models_mixin.js +0 -34
  53. odoo/addons/stock_barcodes/static/src/js/basic_controller.js +0 -412
  54. odoo/addons/stock_barcodes/static/src/js/basic_fields.js +0 -59
  55. odoo/addons/stock_barcodes/static/src/js/form_view.js +0 -24
  56. odoo/addons/stock_barcodes/static/src/js/kanban_renderer.js +0 -47
  57. odoo/addons/stock_barcodes/static/src/js/numeric_step.js +0 -43
  58. odoo_addon_stock_barcodes-15.0.3.1.6.dist-info/RECORD +0 -62
  59. {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
@@ -13,7 +13,8 @@
13
13
  attrs="{'invisible': [('candidate_picking_ids', '=', [])]}"
14
14
  nolabel="1"
15
15
  force_save="1"
16
- options='{"always_reload": True}'
16
+ class="o_x2m_control_panel"
17
+ options="{'always_reload': True}"
17
18
  >
18
19
  <kanban>
19
20
  <field name="name" />
@@ -39,14 +40,14 @@
39
40
  type="object"
40
41
  title="lock picking"
41
42
  t-if="record.picking_id.raw_value != record.wiz_picking_id.raw_value"
42
- class="fa fa-thumb-tack fa-2x pull-right"
43
+ class="fa fa-thumb-tack fa-2x float-end"
43
44
  context="{'wiz_barcode_id': parent.id, 'picking_id': picking_id}"
44
45
  />
45
46
  <a
46
47
  name="action_unlock_picking"
47
48
  type="object"
48
49
  title="unlock picking"
49
- class="pull-right"
50
+ class="float-end"
50
51
  t-if="record.picking_id.raw_value == record.wiz_picking_id.raw_value"
51
52
  context="{'wiz_barcode_id': parent.id}"
52
53
  >
@@ -83,7 +84,7 @@
83
84
  t-if="!widget.isHtmlEmpty(record.note.raw_value)"
84
85
  >
85
86
  <div
86
- class="text-danger font-italic font-weight-bold text-center"
87
+ class="fw-bold text-center text-danger fst-italic"
87
88
  >
88
89
  <t
89
90
  t-out="record.note.value"
@@ -96,8 +97,9 @@
96
97
  <button
97
98
  name="action_open_picking"
98
99
  type="object"
99
- class="btn btn-secondary pull-left"
100
+ class="float-start btn btn-secondary border"
100
101
  context="{'wiz_barcode_id': parent.id, 'picking_id': picking_id}"
102
+ data-hotkey="'shift+o'"
101
103
  >Open</button>
102
104
  </div>
103
105
  <div class="col">
@@ -105,10 +107,11 @@
105
107
  <button
106
108
  name="action_validate_picking"
107
109
  type="object"
108
- t-att-class="'btn pull-right' + (record.is_pending.raw_value == false ? ' btn-primary' : ' btn-secondary')"
110
+ t-att-class="'btn float-end' + (record.is_pending.raw_value == false ? ' btn-primary' : ' btn-secondary border')"
109
111
  attrs="{'invisible': [('state', 'not in', ['draft', 'assigned', 'confirmed'])]}"
110
112
  confirm="Are you sure to validate the picking ?"
111
113
  context="{'wiz_barcode_id': parent.id, 'picking_id': picking_id}"
114
+ data-hotkey="'shift+v'"
112
115
  >Validate</button>
113
116
  </div>
114
117
  </div>
@@ -118,7 +121,12 @@
118
121
  </templates>
119
122
  </kanban>
120
123
  </field>
121
- <field name="todo_line_display_ids" mode="kanban" force_save="1" />
124
+ <field
125
+ name="todo_line_display_ids"
126
+ mode="kanban"
127
+ force_save="1"
128
+ attrs="{'invisible': [('todo_line_display_ids', '=', [])]}"
129
+ />
122
130
  </xpath>
123
131
  <field name="location_id" position="before">
124
132
  <field name="picking_type_code" invisible="1" force_save="1" />
@@ -127,6 +135,8 @@
127
135
  <field name="picking_location_id" invisible="1" />
128
136
  <field name="picking_location_dest_id" invisible="1" />
129
137
  <field name="company_id" invisible="1" />
138
+ <field name="todo_line_is_extra_line" invisible="1" />
139
+ <field name="qty_available" invisible="1" />
130
140
  </field>
131
141
  <field name="location_id" position="attributes">
132
142
  <attribute
@@ -139,45 +149,52 @@
139
149
  >{'readonly': [('manual_entry', '=', False)], 'invisible': [('picking_type_code', '=', 'incoming')]}</attribute>
140
150
  </group>
141
151
  <group name="location" position="after">
142
- <group
143
- name="location_dest"
144
- attrs="{'invisible': [('picking_type_code', '=', 'outgoing')]}"
145
- >
146
- <div>
147
- <strong class=" d-none d-sm-block">Dest. Location</strong>
148
- <span
149
- class="fa fa-share text-center d-sm-none oe_span_small_icon"
150
- title="Destination Location"
151
- />
152
- <field
153
- name="location_dest_id"
154
- options="{'no_create': True}"
155
- attrs="{'readonly': [('manual_entry', '=', False)]}"
156
- force_save="1"
157
- style="width:85%"
158
- class="h5"
159
- domain="[('id', 'child_of', picking_location_dest_id), '|', ('company_id', '=', False), ('company_id', '=', company_id), ('usage', '!=', 'view')]"
160
- />
161
- </div>
162
- </group>
152
+ <div attrs="{'invisible': [('picking_type_code', '=', 'outgoing')]}">
153
+ <strong class=" d-none d-sm-block">Dest. Location</strong>
154
+ <span
155
+ class="fa fa-share text-center d-sm-none oe_span_small_icon"
156
+ title="Destination Location"
157
+ />
158
+ <field
159
+ name="location_dest_id"
160
+ options="{'no_create': True, 'no_open': True}"
161
+ attrs="{'readonly': [('manual_entry', '=', False)]}"
162
+ force_save="1"
163
+ nolabel="1"
164
+ style="width:90%"
165
+ class="h5"
166
+ domain="[('id', 'child_of', picking_location_dest_id), '|', ('company_id', '=', False), ('company_id', '=', company_id), ('usage', '!=', 'view')]"
167
+ />
168
+ </div>
169
+ </group>
170
+ <group name="scan_fields" position="attributes">
171
+ <!-- hide group scan_fields for extra todo lines -->
172
+ <attribute
173
+ name="attrs"
174
+ >{'invisible': [('todo_line_is_extra_line', '!=', False)]}</attribute>
163
175
  </group>
164
176
  <group name="scan_fields" position="after">
165
177
  <group
166
178
  string="Pending moves"
167
179
  attrs="{'invisible': [('pending_move_ids', '=', [])]}"
180
+ col="2"
168
181
  >
169
182
  <field
170
183
  name="pending_move_ids"
171
184
  options="{'no_open': True, 'always_reload': True}"
172
185
  nolabel="1"
186
+ colspan="2"
173
187
  force_save="1"
174
188
  mode="tree,kanban"
175
189
  >
176
- <tree>
190
+ <tree decoration-warning="is_extra_line">
177
191
  <field name="state" invisible="1" />
192
+ <field name="is_extra_line" invisible="1" />
178
193
  <field name="product_id" />
179
194
  <field name="product_uom_qty" />
180
195
  <field name="line_ids" invisible="1" />
196
+ <field name="location_id" optional="hide" />
197
+ <field name="location_dest_id" optional="hide" />
181
198
  <field
182
199
  name="lot_id"
183
200
  groups="stock.group_production_lot"
@@ -191,6 +208,7 @@
191
208
  <field name="qty_done" />
192
209
  <button
193
210
  name="fill_from_pending_line"
211
+ title="Fill from pending line"
194
212
  type="object"
195
213
  class="btn"
196
214
  icon="fa-upload"
@@ -215,20 +233,20 @@
215
233
  </div>
216
234
  <div class="col-2">
217
235
  <span
218
- class="pull-right text-right text-muted"
236
+ class="float-end text-end text-muted"
219
237
  >
220
238
  <field name="product_uom_qty" />
221
239
  </span>
222
240
  </div>
223
241
  <div class="col-2">
224
242
  <span
225
- class="pull-right text-right"
226
- t-att-class="qty_done >= product_uom_qty ? 'text-success' : ''"
243
+ class="float-end text-end"
244
+ t-att-class="qty_done &gt;= product_uom_qty ? 'text-success' : ''"
227
245
  >
228
246
  <field name="qty_done" />
229
247
  </span>
230
248
  </div>
231
- <div class="col-2 text-right">
249
+ <div class="text-end col-2">
232
250
  <button
233
251
  name="fill_from_pending_line"
234
252
  type="object"
@@ -251,12 +269,14 @@
251
269
  </group>
252
270
  <group
253
271
  string="Detailed operations"
272
+ col="2"
254
273
  attrs="{'invisible': ['|', ('move_line_ids', '=', []), ('show_detailed_operations', '=', False)]}"
255
274
  >
256
275
  <field
257
276
  name="move_line_ids"
258
277
  options="{'no_open': True, 'always_reload': True}"
259
278
  nolabel="1"
279
+ colspan="2"
260
280
  force_save="1"
261
281
  mode="tree,kanban"
262
282
  >
@@ -297,6 +317,7 @@
297
317
  />
298
318
  <button
299
319
  name="action_barcode_detailed_operation_unlink"
320
+ title="Remove detailed operation"
300
321
  type="object"
301
322
  class="btn"
302
323
  icon="fa-trash"
@@ -320,12 +341,12 @@
320
341
  </div>
321
342
  <div class="col-2">
322
343
  <span
323
- class="pull-right text-right font-weight-bold"
344
+ class="fw-bold text-end float-end"
324
345
  >
325
346
  <field name="qty_done" />
326
347
  </span>
327
348
  </div>
328
- <div class="col-3 text-right">
349
+ <div class="text-end col-3">
329
350
  <button
330
351
  name="action_barcode_detailed_operation_unlink"
331
352
  type="object"
@@ -378,12 +399,13 @@
378
399
  name="action_put_in_pack"
379
400
  help="Put in pack"
380
401
  type="object"
402
+ icon="fa-cubes"
403
+ title="Put in Pack"
381
404
  attrs="{'invisible': ['|', ('picking_state', 'in', ('draft', 'done', 'cancel')), ('display_menu', '=', True)]}"
382
- class="ml-auto oe_kanban_action_button btn btn-secondary btn-sm pl-3 pr-3"
405
+ class="ms-auto oe_kanban_action_button btn btn-secondary btn-sm ps-3 pe-3"
383
406
  groups="stock.group_tracking_lot"
384
407
  data-hotkey="6"
385
408
  >
386
- <i class="fa fa-cubes" title="Put in Pack" />
387
409
  </button>
388
410
  </xpath>
389
411
  </field>
@@ -1,9 +1,8 @@
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
- from collections import OrderedDict
4
3
 
5
4
  from odoo import api, fields, models
6
- from odoo.tools.safe_eval import safe_eval
5
+ from odoo.tools.float_utils import float_compare
7
6
 
8
7
 
9
8
  class WizStockBarcodesReadTodo(models.TransientModel):
@@ -50,7 +49,7 @@ class WizStockBarcodesReadTodo(models.TransientModel):
50
49
  string="Destinatino Name", related="location_dest_id.name"
51
50
  )
52
51
  product_id = fields.Many2one(comodel_name="product.product")
53
- lot_id = fields.Many2one(comodel_name="stock.production.lot")
52
+ lot_id = fields.Many2one(comodel_name="stock.lot")
54
53
  uom_id = fields.Many2one(comodel_name="uom.uom")
55
54
  package_id = fields.Many2one(comodel_name="stock.quant.package")
56
55
  result_package_id = fields.Many2one(comodel_name="stock.quant.package")
@@ -62,111 +61,27 @@ class WizStockBarcodesReadTodo(models.TransientModel):
62
61
  stock_move_ids = fields.Many2many(comodel_name="stock.move")
63
62
  position_index = fields.Integer()
64
63
  picking_code = fields.Char("Type of Operation")
65
-
66
- def _group_key(self, wiz, line):
67
- group_key_for_todo_records = wiz.option_group_id.group_key_for_todo_records
68
- if group_key_for_todo_records:
69
- return safe_eval(group_key_for_todo_records, globals_dict={"object": line})
70
- if wiz.option_group_id.source_pending_moves == "move_line_ids":
71
- return (line.location_id, line.product_id, line.lot_id, line.package_id)
72
- else:
73
- return (line.location_id, line.product_id)
74
-
75
- def _get_all_products_quantities_in_package(self, package):
76
- res = {}
77
- for quant in package._get_contained_quants():
78
- if quant.product_id not in res:
79
- res[quant.product_id] = 0
80
- res[quant.product_id] += quant.quantity
81
- return res
82
-
83
- def _prepare_fill_record_values(self, wiz_barcode, line, position):
84
- vals = {
85
- "product_id": line.product_id.id,
86
- "product_uom_qty": line.product_uom_qty,
87
- "name": "To do action",
88
- "position_index": position,
89
- "picking_code": line.picking_code,
90
- }
91
- if wiz_barcode.option_group_id.source_pending_moves == "move_line_ids":
92
- package_product_dic = self._get_all_products_quantities_in_package(
93
- line.package_id
94
- )
95
- vals.update(
96
- {
97
- "location_id": line.location_id.id,
98
- "location_dest_id": line.location_dest_id.id,
99
- "lot_id": line.lot_id.id,
100
- "package_id": line.package_id.id,
101
- "result_package_id": line.result_package_id.id,
102
- "uom_id": line.product_uom_id.id,
103
- "product_qty_reserved": line.product_qty,
104
- "line_ids": [(6, 0, line.ids)],
105
- "stock_move_ids": [(6, 0, line.move_id.ids)],
106
- "package_product_qty": package_product_dic
107
- and package_product_dic[line.product_id]
108
- or 0.0,
109
- }
110
- )
111
- else:
112
- vals.update(
113
- {
114
- "location_id": (line.move_line_ids[:1] or line).location_id.id,
115
- "location_dest_id": (
116
- line.move_line_ids[:1] or line
117
- ).location_dest_id.id,
118
- "uom_id": line.product_uom.id,
119
- "product_qty_reserved": line.move_line_ids
120
- and sum(line.move_line_ids.mapped("product_qty"))
121
- or line.product_uom_qty,
122
- "line_ids": [(6, 0, line.move_line_ids.ids)],
123
- "stock_move_ids": [(6, 0, line.ids)],
124
- }
125
- )
126
- return vals
127
-
128
- def _update_fill_record_values(self, wiz_barcode, line, vals):
129
- vals["product_uom_qty"] += line.product_uom_qty
130
- if wiz_barcode.option_group_id.source_pending_moves == "move_line_ids":
131
- vals["product_qty_reserved"] += line.product_qty
132
- vals["line_ids"][0][2].append(line.id)
133
- vals["stock_move_ids"][0][2].append(line.move_id.id)
134
- else:
135
- vals["product_qty_reserved"] += (
136
- line.move_line_ids
137
- and sum(line.move_line_ids.mapped("product_qty"))
138
- or line.product_uom_qty
139
- )
140
- vals["line_ids"][0][2].extend(line.move_line_ids.ids)
141
- vals["stock_move_ids"][0][2].extend(line.ids)
142
- return vals
143
-
144
- @api.model
145
- def fill_records(self, wiz_barcode, lines_list):
146
- """
147
- :param lines_list: browse list
148
- :return:
149
- """
150
- wiz_barcode.todo_line_ids = self.browse()
151
- todo_vals = OrderedDict()
152
- position = 0
153
- for lines in lines_list:
154
- for line in lines:
155
- key = self._group_key(wiz_barcode, line)
156
- if key not in todo_vals:
157
- todo_vals[key] = self._prepare_fill_record_values(
158
- wiz_barcode, line, position
159
- )
160
- position += 1
161
- else:
162
- todo_vals[key] = self._update_fill_record_values(
163
- wiz_barcode, line, todo_vals[key]
164
- )
165
- wiz_barcode.todo_line_ids = self.create(list(todo_vals.values()))
64
+ is_extra_line = fields.Boolean()
65
+ # Used in kanban view
66
+ is_stock_move_line_origin = fields.Boolean()
166
67
 
167
68
  def action_todo_next(self):
168
69
  self.state = "done_forced"
169
70
  self.line_ids.barcode_scan_state = "done_forced"
71
+ for sml in self.line_ids:
72
+ if sml.reserved_uom_qty != sml.qty_done and sml.move_id.state != "waiting":
73
+ sml.reserved_uom_qty = sml.qty_done
74
+ if self.is_extra_line or not self.is_stock_move_line_origin:
75
+ barcode_backorder_action = self.env.context.get(
76
+ "barcode_backorder_action", "create_backorder"
77
+ )
78
+ self.stock_move_ids.barcode_backorder_action = barcode_backorder_action
79
+ if barcode_backorder_action == "pending":
80
+ self.stock_move_ids.move_line_ids.unlink()
81
+ self.stock_move_ids._action_assign()
82
+ wiz_barcode = self.wiz_barcode_id
83
+ self.wiz_barcode_id.fill_todo_records()
84
+ self.wiz_barcode_id = wiz_barcode
170
85
  self.wiz_barcode_id.determine_todo_action()
171
86
 
172
87
  def action_reset_lines(self):
@@ -174,6 +89,7 @@ class WizStockBarcodesReadTodo(models.TransientModel):
174
89
  self.line_ids.barcode_scan_state = "pending"
175
90
  self.line_ids.qty_done = 0.0
176
91
  self.wiz_barcode_id.action_clean_values()
92
+ self.wiz_barcode_id.fill_todo_records()
177
93
  self.wiz_barcode_id.determine_todo_action()
178
94
 
179
95
  def action_back_line(self):
@@ -194,18 +110,28 @@ class WizStockBarcodesReadTodo(models.TransientModel):
194
110
  @api.depends(
195
111
  "line_ids",
196
112
  "line_ids.qty_done",
197
- "line_ids.product_uom_qty",
113
+ "line_ids.reserved_uom_qty",
198
114
  "line_ids.barcode_scan_state",
199
115
  "qty_done",
200
116
  "product_uom_qty",
201
117
  )
202
118
  def _compute_state(self):
203
119
  for rec in self:
204
- if rec.qty_done >= rec.product_uom_qty or (
120
+ if float_compare(
121
+ rec.qty_done,
122
+ rec.product_uom_qty,
123
+ precision_rounding=rec.uom_id.rounding,
124
+ ) > -1 or (
205
125
  rec.wiz_barcode_id.option_group_id.source_pending_moves
206
126
  == "move_line_ids"
207
127
  and rec.line_ids
208
- and not any(ln.barcode_scan_state == "pending" for ln in rec.line_ids)
128
+ and (
129
+ sum(rec.stock_move_ids.mapped("quantity_done"))
130
+ >= sum(rec.stock_move_ids.mapped("product_uom_qty"))
131
+ or not any(
132
+ ln.barcode_scan_state == "pending" for ln in rec.line_ids
133
+ )
134
+ )
209
135
  ):
210
136
  rec.state = "done"
211
137
  else:
@@ -20,11 +20,13 @@
20
20
  <field name="qty_done" />
21
21
  <field name="line_ids" invisible="1" />
22
22
  <field name="state" />
23
+ <field name="is_extra_line" />
24
+ <field name="is_stock_move_line_origin" />
23
25
  <templates>
24
26
  <t t-name="kanban-box">
25
27
  <div
26
28
  t-attf-class="oe_kanban_content "
27
- style="background-color: #FFF8DC;"
29
+ t-attf-style="background-color: {{record.is_extra_line.raw_value == true and '#ffd683' or '#f0f9fb'}};"
28
30
  >
29
31
  <div class="row">
30
32
  <div class="col">
@@ -41,7 +43,7 @@
41
43
  <span
42
44
  attrs="{'invisible': [('picking_code', '!=', 'internal')]}"
43
45
  >
44
- <field name="location_name" /> \u21E8 <field
46
+ <field name="location_name" /> <field
45
47
  name="location_dest_name"
46
48
  />
47
49
  </span>
@@ -71,10 +73,13 @@
71
73
  class="fa fa-tags"
72
74
  title="Lot S/N"
73
75
  />
74
- <field name="lot_id" />
76
+ <field
77
+ name="lot_id"
78
+ options="{'no_open': True}"
79
+ />
75
80
  </span>
76
81
  </td>
77
- <td class="text-right">
82
+ <td class="text-end">
78
83
  <span class="fa fa-dropbox" />
79
84
  <span>
80
85
  <field name="package_id" />
@@ -94,72 +99,109 @@
94
99
  <div class="row">
95
100
  <div class="col-12">
96
101
  <span>
97
- <span class="font-weight-bold">
102
+ <span class="fw-bold">
98
103
  <t t-esc="record.qty_done.value" />
99
104
  </span> / <t
100
105
  t-esc="record.product_uom_qty.value"
101
106
  /> <t t-esc="record.uom_id.value.slice(0,3)" />
102
107
  </span>
108
+ <strong
109
+ class="bg-danger"
110
+ t-if="record.is_extra_line.raw_value == true"
111
+ >NOT AVAILABLE</strong>
103
112
  </div>
104
113
  </div>
105
114
  <div name="action" class="row">
106
- <div class="col-3">
115
+ <div class="col-2">
107
116
  <button
108
117
  name="action_back_line"
109
118
  type="object"
110
- class="btn btn-primary pull-left btn-sm"
119
+ icon="fa-step-backward"
120
+ title="Previous"
121
+ class="btn-sm float-start btn btn-primary"
111
122
  context="{'wiz_barcode_id': parent.id}"
112
123
  data-hotkey="1"
113
- >
114
- <i
115
- class="fa fa-step-backward"
116
- title="Previous"
117
- />
118
- </button>
124
+ />
119
125
  </div>
120
- <div class="col-3">
126
+ <div class="col-4 p-0">
121
127
  <button
122
128
  name="action_reset_lines"
123
129
  type="object"
124
- class="btn btn-warning pull-right btn-sm"
130
+ icon="fa-trash"
131
+ title="Clean"
132
+ class="btn-sm btn mx-auto d-block btn-warning"
125
133
  context="{'wiz_barcode_id': parent.id}"
126
134
  data-hotkey="2"
127
- >
128
- <i class="fa fa-trash" title="Clean" />
129
- </button>
135
+ />
130
136
  </div>
131
- <div class="col-3">
137
+ <div class="col-4 p-0">
132
138
  <button
133
139
  name="action_todo_next"
134
140
  type="object"
135
- class="btn btn-warning pull-right btn-sm"
141
+ class="btn-sm mx-auto d-block btn-danger btn"
136
142
  context="{'wiz_barcode_id': parent.id}"
137
143
  data-hotkey="3"
138
- attrs="{'invisible': [('qty_done', '=', 0.0)]} "
144
+ attrs="{'invisible': ['|','|', ('qty_done', '=', 0.0), ('is_extra_line', '=', True), ('is_stock_move_line_origin', '=', False)]} "
139
145
  >
140
146
  Ignore rest
141
147
  </button>
148
+ <!-- Ask for confirmation when we've got done quantities to avoid squashing quantities -->
142
149
  <button
143
150
  name="action_todo_next"
144
151
  type="object"
145
- class="btn btn-danger pull-right btn-sm"
152
+ class="btn-sm mx-auto d-block btn-danger btn"
146
153
  context="{'wiz_barcode_id': parent.id}"
147
154
  data-hotkey="3"
148
- attrs="{'invisible': [('qty_done', '!=', 0.0)]} "
155
+ attrs="{'invisible': ['|', '|', ('qty_done', '!=', 0.0), ('is_extra_line', '=', True), ('is_stock_move_line_origin', '=', False)]} "
149
156
  confirm="You have not set any quantity to this operation and it will be removed from pending moves. Are you sure?"
150
- >
151
- Ignore rest
157
+ >Ignore rest
152
158
  </button>
153
159
  </div>
154
- <div class="col-3">
160
+ <div class="col-2">
155
161
  <button
156
162
  name="action_next_line"
157
163
  type="object"
158
- class="btn btn-primary pull-right btn-sm"
164
+ icon="fa-step-forward"
165
+ title="Next"
166
+ class="btn-sm float-end btn btn-primary"
159
167
  context="{'wiz_barcode_id': parent.id}"
160
168
  data-hotkey="4"
169
+ />
170
+ </div>
171
+ </div>
172
+ <div name="action_extra" class="row mt-2">
173
+ <div class="col-12">
174
+ <button
175
+ name="action_todo_next"
176
+ type="object"
177
+ class="btn btn-warning float-end btn-sm"
178
+ context="{'wiz_barcode_id': parent.id, 'barcode_backorder_action': 'pending'}"
179
+ data-hotkey="3"
180
+ attrs="{'invisible': [('is_extra_line', '=', False), ('is_stock_move_line_origin', '=', True)]} "
181
+ confirm="This move will be set to pending. Are you sure?"
182
+ >
183
+ Restore to pending
184
+ </button>
185
+ <button
186
+ name="action_todo_next"
187
+ type="object"
188
+ class="btn btn-danger float-end btn-sm me-5"
189
+ context="{'wiz_barcode_id': parent.id, 'barcode_backorder_action': 'skip_backorder'}"
190
+ data-hotkey="3"
191
+ attrs="{'invisible': [('is_extra_line', '=', False), ('is_stock_move_line_origin', '=', True)]} "
192
+ confirm="Odoo will not create a backorder for this move. Are you sure?"
193
+ >
194
+ No Backorder
195
+ </button>
196
+ <button
197
+ name="action_todo_next"
198
+ type="object"
199
+ class="btn btn-primary float-end btn-sm me-3"
200
+ context="{'wiz_barcode_id': parent.id, 'barcode_backorder_action': 'create_backorder'}"
201
+ data-hotkey="3"
202
+ attrs="{'invisible': [('is_extra_line', '=', False), ('is_stock_move_line_origin', '=', True)]} "
161
203
  >
162
- <i class="fa fa-step-forward" title="Next" />
204
+ Create Backorder
163
205
  </button>
164
206
  </div>
165
207
  </div>