odoo-addon-shopfloor 18.0.0.1.2__py3-none-any.whl → 18.0.0.2.0__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 (40) hide show
  1. odoo/addons/shopfloor/README.rst +1 -1
  2. odoo/addons/shopfloor/__manifest__.py +1 -1
  3. odoo/addons/shopfloor/actions/message.py +3 -3
  4. odoo/addons/shopfloor/models/stock_move_line.py +2 -2
  5. odoo/addons/shopfloor/models/stock_picking.py +2 -5
  6. odoo/addons/shopfloor/services/checkout.py +64 -54
  7. odoo/addons/shopfloor/services/cluster_picking.py +3 -2
  8. odoo/addons/shopfloor/services/delivery.py +14 -15
  9. odoo/addons/shopfloor/services/zone_picking.py +3 -2
  10. odoo/addons/shopfloor/static/description/index.html +1 -1
  11. odoo/addons/shopfloor/tests/__init__.py +32 -31
  12. odoo/addons/shopfloor/tests/common.py +3 -1
  13. odoo/addons/shopfloor/tests/test_checkout_auto_post.py +9 -8
  14. odoo/addons/shopfloor/tests/test_checkout_base.py +1 -1
  15. odoo/addons/shopfloor/tests/test_checkout_cancel_line.py +12 -8
  16. odoo/addons/shopfloor/tests/test_checkout_done.py +5 -5
  17. odoo/addons/shopfloor/tests/test_checkout_list_delivery_packaging.py +0 -2
  18. odoo/addons/shopfloor/tests/test_checkout_list_package.py +19 -12
  19. odoo/addons/shopfloor/tests/test_checkout_new_package.py +7 -7
  20. odoo/addons/shopfloor/tests/test_checkout_no_package.py +6 -6
  21. odoo/addons/shopfloor/tests/test_checkout_scan.py +1 -1
  22. odoo/addons/shopfloor/tests/test_checkout_scan_dest_location.py +2 -2
  23. odoo/addons/shopfloor/tests/test_checkout_scan_line.py +3 -1
  24. odoo/addons/shopfloor/tests/test_checkout_scan_package_action.py +14 -14
  25. odoo/addons/shopfloor/tests/test_checkout_scan_package_action_no_prefill_qty.py +9 -9
  26. odoo/addons/shopfloor/tests/test_checkout_select_line.py +1 -1
  27. odoo/addons/shopfloor/tests/test_checkout_select_package_base.py +6 -4
  28. odoo/addons/shopfloor/tests/test_checkout_set_qty.py +12 -11
  29. odoo/addons/shopfloor/tests/test_checkout_summary.py +2 -2
  30. odoo/addons/shopfloor/tests/test_delivery_base.py +3 -3
  31. odoo/addons/shopfloor/tests/test_delivery_done.py +1 -2
  32. odoo/addons/shopfloor/tests/test_delivery_reset_qty_done_line.py +2 -2
  33. odoo/addons/shopfloor/tests/test_delivery_reset_qty_done_pack.py +2 -2
  34. odoo/addons/shopfloor/tests/test_delivery_scan_deliver.py +11 -11
  35. odoo/addons/shopfloor/tests/test_delivery_set_qty_done_line.py +1 -1
  36. odoo/addons/shopfloor/tests/test_delivery_set_qty_done_pack.py +1 -1
  37. {odoo_addon_shopfloor-18.0.0.1.2.dist-info → odoo_addon_shopfloor-18.0.0.2.0.dist-info}/METADATA +2 -2
  38. {odoo_addon_shopfloor-18.0.0.1.2.dist-info → odoo_addon_shopfloor-18.0.0.2.0.dist-info}/RECORD +40 -40
  39. {odoo_addon_shopfloor-18.0.0.1.2.dist-info → odoo_addon_shopfloor-18.0.0.2.0.dist-info}/WHEEL +1 -1
  40. {odoo_addon_shopfloor-18.0.0.1.2.dist-info → odoo_addon_shopfloor-18.0.0.2.0.dist-info}/top_level.txt +0 -0
@@ -11,7 +11,7 @@ Shopfloor
11
11
  !! This file is generated by oca-gen-addon-readme !!
12
12
  !! changes will be overwritten. !!
13
13
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
14
- !! source digest: sha256:01ad1a242b0c8a3b6ab8593cd6dedb31c5b6dd941b58e9af751833dad9cc69f3
14
+ !! source digest: sha256:534d443b8feb0fd2548ede9663e260ceb8dcfb20686a39d06022ee92bcc6d209
15
15
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
16
16
 
17
17
  .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@@ -6,7 +6,7 @@
6
6
  {
7
7
  "name": "Shopfloor",
8
8
  "summary": "manage warehouse operations with barcode scanners",
9
- "version": "18.0.0.1.2",
9
+ "version": "18.0.0.2.0",
10
10
  "development_status": "Beta",
11
11
  "category": "Inventory",
12
12
  "website": "https://github.com/OCA/stock-logistics-shopfloor",
@@ -742,7 +742,7 @@ class MessageAction(Component):
742
742
  "body": _("The picked quantity must be a value above zero."),
743
743
  }
744
744
 
745
- def selected_lines_qty_done_higher_than_allowed(self, line):
745
+ def selected_lines_qty_picked_higher_than_allowed(self, line):
746
746
  """
747
747
  :param line: The selected line
748
748
  """
@@ -753,12 +753,12 @@ class MessageAction(Component):
753
753
  "higher than the maximum allowed. "
754
754
  "(%(product_name)s : %(quantity_done)s > %(quantity_reserved)s)",
755
755
  product_name=line.product_id.name,
756
- quantity_done=str(line.qty_done),
756
+ quantity_done=str(line.qty_picked),
757
757
  quantity_reserved=str(line.quantity),
758
758
  ),
759
759
  }
760
760
 
761
- def line_scanned_qty_done_higher_than_allowed(self):
761
+ def line_scanned_qty_picked_higher_than_allowed(self):
762
762
  return {
763
763
  "message_type": "warning",
764
764
  "body": _(
@@ -117,13 +117,13 @@ class StockMoveLine(models.Model):
117
117
  elif qty_lesser:
118
118
  if not split_partial:
119
119
  return (new_line, "lesser")
120
- new_line = self._split_partial_quantity_to_be_done(
120
+ new_line = self._split_partial_quantity_to_be_picked(
121
121
  qty_done, split_default_vals
122
122
  )
123
123
  return (new_line, "lesser")
124
124
  return (new_line, "full")
125
125
 
126
- def _split_partial_quantity_to_be_done(self, quantity_done, split_default_vals):
126
+ def _split_partial_quantity_to_be_picked(self, quantity_done, split_default_vals):
127
127
  """Create a new move line with the remaining quantity to process."""
128
128
  # split the move line which will be processed later (maybe the user
129
129
  # has to pick some goods from another place because the location
@@ -122,11 +122,8 @@ class StockPicking(models.Model):
122
122
  return new_picking.id
123
123
 
124
124
  def _put_in_pack(self, move_line_ids):
125
- """
126
- Marks the corresponding move lines as 'shopfloor_checkout_done'
127
- when the package is created in the backend.
128
-
129
- """
125
+ # Marks the corresponding move lines as 'shopfloor_checkout_done'
126
+ # when the package is created in the backend.
130
127
  new_package = super()._put_in_pack(move_line_ids)
131
128
  lines = move_line_ids.filtered(lambda p: p.result_package_id == new_package)
132
129
  lines.write({"shopfloor_checkout_done": True})
@@ -426,9 +426,9 @@ class Checkout(Component):
426
426
  continue
427
427
  if self.work.menu.no_prefill_qty and i == 0:
428
428
  # For prefill quantity we only want to increment one line
429
- line.qty_done += prefill_qty
429
+ line.qty_picked += prefill_qty
430
430
  elif not self.work.menu.no_prefill_qty:
431
- line.qty_done = line.quantity
431
+ line.picked = True
432
432
  line.shopfloor_user_id = self.env.user
433
433
 
434
434
  picking = lines.mapped("picking_id")
@@ -440,7 +440,7 @@ class Checkout(Component):
440
440
 
441
441
  def _deselect_lines(self, lines):
442
442
  lines.filtered(lambda x: not x.shopfloor_checkout_done).write(
443
- {"qty_done": 0, "shopfloor_user_id": False}
443
+ {"qty_picked": 0, "shopfloor_user_id": False}
444
444
  )
445
445
 
446
446
  def scan_line(self, picking_id, barcode, confirm_pack_all=False, confirm_lot=None):
@@ -454,7 +454,7 @@ class Checkout(Component):
454
454
  several packs contain it, the endpoint will ask to scan a pack; if the
455
455
  product is tracked by lot, to scan a lot.
456
456
 
457
- Once move lines are found, their ``qty_done`` is set to their reserved
457
+ Once move lines are found, their ``qty_picked`` is set to their reserved
458
458
  quantity.
459
459
 
460
460
  Transitions:
@@ -828,28 +828,28 @@ class Checkout(Component):
828
828
  if not move_lines:
829
829
  message = self.msg_store.record_not_found()
830
830
  for move_line in move_lines:
831
- qty_done = quantity_func(move_line)
832
- if qty_done < 0:
831
+ qty_picked = quantity_func(move_line)
832
+ if qty_picked < 0:
833
833
  message = {
834
834
  "body": _("Negative quantity not allowed."),
835
835
  "message_type": "error",
836
836
  }
837
837
  else:
838
838
  new_line = self.env["stock.move.line"]
839
- if qty_done > 0:
839
+ if qty_picked > 0:
840
840
  new_line, qty_check = move_line._split_qty_to_be_done(
841
- qty_done,
841
+ qty_picked,
842
842
  split_partial=False,
843
843
  result_package_id=False,
844
844
  )
845
- move_line.qty_done = qty_done
845
+ move_line.qty_picked = qty_picked
846
846
  if new_line:
847
847
  selected_line_ids.append(new_line.id)
848
- if qty_done > move_line.quantity:
848
+ if qty_picked > move_line.quantity:
849
849
  return self._response_for_select_package(
850
850
  picking,
851
851
  self.env["stock.move.line"].browse(selected_line_ids).exists(),
852
- message=self.msg_store.line_scanned_qty_done_higher_than_allowed(),
852
+ message=self.msg_store.line_scanned_qty_picked_higher_than_allowed(),
853
853
  )
854
854
  return self._response_for_select_package(
855
855
  picking,
@@ -858,7 +858,7 @@ class Checkout(Component):
858
858
  )
859
859
 
860
860
  def reset_line_qty(self, picking_id, selected_line_ids, move_line_id):
861
- """Reset qty_done of a move line to zero
861
+ """Reset picked quantity of a move line to zero
862
862
 
863
863
  Used to deselect a line in the "select_package" screen.
864
864
  The selected_line_ids parameter is used to keep the selection of lines
@@ -873,7 +873,7 @@ class Checkout(Component):
873
873
  )
874
874
 
875
875
  def set_line_qty(self, picking_id, selected_line_ids, move_line_id):
876
- """Set qty_done of a move line to its reserved quantity
876
+ """Set picked quantity of a move line to its reserved quantity
877
877
 
878
878
  Used to select a line in the "select_package" screen.
879
879
  The selected_line_ids parameter is used to keep the selection of lines
@@ -888,7 +888,7 @@ class Checkout(Component):
888
888
  )
889
889
 
890
890
  def set_custom_qty(self, picking_id, selected_line_ids, move_line_id, qty_done):
891
- """Change qty_done of a move line with a custom value
891
+ """Change picked quantity of a move line with a custom value
892
892
 
893
893
  The selected_line_ids parameter is used to keep the selection of lines
894
894
  stateless.
@@ -901,14 +901,14 @@ class Checkout(Component):
901
901
  picking_id, selected_line_ids, [move_line_id], lambda __: qty_done
902
902
  )
903
903
 
904
- def _switch_line_qty_done(self, picking, selected_lines, switch_lines):
905
- """Switch qty_done on lines and return to the 'select_package' state
904
+ def _switch_line_qty_picked(self, picking, selected_lines, switch_lines):
905
+ """Switch picked qty on lines and return to the 'select_package' state
906
906
 
907
- If at least one of the lines to switch has a qty_done, set them all
908
- to zero. If all the lines to switch have a zero qty_done, switch them
907
+ If at least one of the lines to switch has a picked qty, set them all
908
+ to zero. If all the lines to switch have a zero picked qty, switch them
909
909
  to their quantity to deliver.
910
910
  """
911
- if any(line.qty_done for line in switch_lines):
911
+ if any(line.qty_picked for line in switch_lines):
912
912
  return self._change_line_qty(
913
913
  picking.id, selected_lines.ids, switch_lines.ids, lambda __: 0
914
914
  )
@@ -923,7 +923,7 @@ class Checkout(Component):
923
923
  def _increment_custom_qty(
924
924
  self, picking, selected_lines, increment_lines, qty_increment
925
925
  ):
926
- """Increment the qty_done of a move line with a custom value
926
+ """Increment the picked quantity of a move line with a custom value
927
927
 
928
928
  The selected_line parameter is used to keep the selection of lines
929
929
  stateless.
@@ -936,22 +936,31 @@ class Checkout(Component):
936
936
  picking.id,
937
937
  selected_lines.ids,
938
938
  increment_lines.ids,
939
- lambda line: line.qty_done + qty_increment,
939
+ lambda line: line.qty_picked + qty_increment,
940
940
  )
941
941
 
942
942
  @staticmethod
943
943
  def _filter_lines_unpacked(move_line):
944
944
  return (
945
- move_line.qty_done == 0 or move_line.shopfloor_user_id
945
+ not move_line.picked or move_line.shopfloor_user_id
946
946
  ) and not move_line.shopfloor_checkout_done
947
947
 
948
948
  @staticmethod
949
949
  def _filter_lines_to_pack(move_line):
950
- return move_line.qty_done > 0 and not move_line.shopfloor_checkout_done
950
+ return move_line.picked and not move_line.shopfloor_checkout_done
951
951
 
952
952
  @staticmethod
953
953
  def _filter_lines_checkout_done(move_line):
954
- return move_line.qty_done > 0 and move_line.shopfloor_checkout_done
954
+ # Starting from Odoo 18+, a move line part of a package level is not
955
+ # flagged as picked anymore (it'll be automatically at validation however).
956
+ # See '<stock.picking>._put_in_pack()' changes from
957
+ # https://github.com/odoo/odoo/commit/7dda6bb92715e
958
+ #
959
+ # Based on this new Odoo std behavior, we now consider a move line within
960
+ # a package level as picked (checkout is done).
961
+ return (
962
+ move_line.picked or move_line.package_level_id.is_done
963
+ ) and move_line.shopfloor_checkout_done
955
964
 
956
965
  def _is_package_allowed(self, picking, package):
957
966
  """Check if a package is allowed as a destination/delivery package.
@@ -966,7 +975,7 @@ class Checkout(Component):
966
975
  return package in existing_packages
967
976
 
968
977
  def _put_lines_in_package(self, picking, selected_lines, package):
969
- """Put the current selected lines with a qty_done in a package
978
+ """Put the current selected lines with a picked quantity in a package
970
979
 
971
980
  Note: only packages which are already a delivery package for another
972
981
  line of the stock picking can be selected. Packages which are the
@@ -983,8 +992,8 @@ class Checkout(Component):
983
992
 
984
993
  def _put_lines_in_allowed_package(self, picking, lines_to_pack, package):
985
994
  for line in lines_to_pack:
986
- if line.qty_done < line.quantity:
987
- line._split_partial_quantity_to_be_done(line.qty_done, {})
995
+ if line.qty_picked < line.quantity:
996
+ line._split_partial_quantity_to_be_picked(line.qty_picked, {})
988
997
  lines_to_pack.write(
989
998
  {"result_package_id": package.id, "shopfloor_checkout_done": True}
990
999
  )
@@ -1032,8 +1041,8 @@ class Checkout(Component):
1032
1041
  of a selected line, the package is set to be the destination package of
1033
1042
  all the lines to pack.
1034
1043
 
1035
- When a product is scanned, it selects (set qty_done = reserved qty) or
1036
- deselects (set qty_done = 0) the move lines for this product. Only
1044
+ When a product is scanned, it selects (set qty_picked = reserved qty) or
1045
+ deselects (set qty_picked = 0) the move lines for this product. Only
1037
1046
  products not tracked by lot can use this.
1038
1047
 
1039
1048
  When a lot is scanned, it does the same as for the products but based
@@ -1043,7 +1052,7 @@ class Checkout(Component):
1043
1052
  package is created and set as destination of the lines to pack.
1044
1053
 
1045
1054
  Lines to pack are move lines in the list of ``selected_line_ids``
1046
- where ``qty_done`` > 0 and have not been packed yet
1055
+ where ``picked`` is set and have not been packed yet
1047
1056
  (``shopfloor_checkout_done is False``).
1048
1057
 
1049
1058
  Transitions:
@@ -1104,7 +1113,7 @@ class Checkout(Component):
1104
1113
  If none are found, return the first line for that product.
1105
1114
  """
1106
1115
  return next(
1107
- (line for line in product_lines if line.qty_done < line.quantity),
1116
+ (line for line in product_lines if line.qty_picked < line.quantity),
1108
1117
  fields.first(product_lines),
1109
1118
  )
1110
1119
 
@@ -1126,7 +1135,7 @@ class Checkout(Component):
1126
1135
  self._find_line_to_increment(product_lines),
1127
1136
  quantity_increment,
1128
1137
  )
1129
- return self._switch_line_qty_done(picking, selected_lines, product_lines)
1138
+ return self._switch_line_qty_picked(picking, selected_lines, product_lines)
1130
1139
 
1131
1140
  def _scan_package_action_from_packaging(
1132
1141
  self, picking, selected_lines, packaging, **kw
@@ -1141,7 +1150,7 @@ class Checkout(Component):
1141
1150
  return self._increment_custom_qty(
1142
1151
  picking, selected_lines, self._find_line_to_increment(lot_lines), 1
1143
1152
  )
1144
- return self._switch_line_qty_done(picking, selected_lines, lot_lines)
1153
+ return self._switch_line_qty_picked(picking, selected_lines, lot_lines)
1145
1154
 
1146
1155
  def _scan_package_action_from_serial(self, picking, selection_lines, lot, **kw):
1147
1156
  # Search serial number is actually the same as searching for lot (as of v14...)
@@ -1221,7 +1230,7 @@ class Checkout(Component):
1221
1230
  selected_lines,
1222
1231
  message=self.msg_store.no_delivery_packaging_available(),
1223
1232
  )
1224
- response = self._check_allowed_qty_done(picking, selected_lines)
1233
+ response = self._check_allowed_qty_picked(picking, selected_lines)
1225
1234
  if response:
1226
1235
  return response
1227
1236
  return self._response_for_select_delivery_packaging(picking, delivery_packaging)
@@ -1233,8 +1242,8 @@ class Checkout(Component):
1233
1242
  the selected lines.
1234
1243
 
1235
1244
  Selected lines are move lines in the list of ``move_line_ids`` where
1236
- ``qty_done`` > 0 and have no destination package
1237
- (shopfloor_checkout_done is False).
1245
+ ``picked`` is set and have no destination package
1246
+ (``shopfloor_checkout_done`` is not set).
1238
1247
 
1239
1248
  Transitions:
1240
1249
  * select_line: goes back to selection of lines to work on next lines
@@ -1253,8 +1262,8 @@ class Checkout(Component):
1253
1262
  """Process all selected lines without any package.
1254
1263
 
1255
1264
  Selected lines are move lines in the list of ``move_line_ids`` where
1256
- ``qty_done`` > 0 and have no destination package
1257
- (shopfloor_checkout_done is False).
1265
+ ``picked`` is set and have no destination package
1266
+ (``shopfloor_checkout_done`` is False).
1258
1267
 
1259
1268
  Transitions:
1260
1269
  * select_line: goes back to selection of lines to work on next lines
@@ -1266,13 +1275,11 @@ class Checkout(Component):
1266
1275
  if message:
1267
1276
  return self._response_for_select_document(message=message)
1268
1277
  selected_lines = self.env["stock.move.line"].browse(selected_line_ids).exists()
1269
- selected_lines_with_qty_done = selected_lines.filtered(
1270
- lambda line: line.qty_done > 0
1271
- )
1272
- selected_lines_with_qty_done.write(
1278
+ picked_selected_lines = selected_lines.filtered(lambda line: line.picked)
1279
+ picked_selected_lines.write(
1273
1280
  {"shopfloor_checkout_done": True, "result_package_id": False}
1274
1281
  )
1275
- response = self._check_allowed_qty_done(picking, selected_lines)
1282
+ response = self._check_allowed_qty_picked(picking, selected_lines)
1276
1283
  if response:
1277
1284
  return response
1278
1285
  return self._response_for_select_line(
@@ -1298,21 +1305,21 @@ class Checkout(Component):
1298
1305
  if message:
1299
1306
  return self._response_for_select_document(message=message)
1300
1307
  lines = self.env["stock.move.line"].browse(selected_line_ids).exists()
1301
- response = self._check_allowed_qty_done(picking, lines)
1308
+ response = self._check_allowed_qty_picked(picking, lines)
1302
1309
  if response:
1303
1310
  return response
1304
1311
  return self._response_for_select_dest_package(picking, lines)
1305
1312
 
1306
- def _check_allowed_qty_done(self, picking, lines):
1313
+ def _check_allowed_qty_picked(self, picking, lines):
1307
1314
  for line in lines:
1308
- # Do not allow to proceed if the qty_done of
1315
+ # Do not allow to proceed if the qty_picked of
1309
1316
  # any of the selected lines
1310
1317
  # is higher than the quantity to do.
1311
- if line.qty_done > line.quantity:
1318
+ if line.qty_picked > line.quantity:
1312
1319
  return self._response_for_select_package(
1313
1320
  picking,
1314
1321
  lines,
1315
- message=self.msg_store.selected_lines_qty_done_higher_than_allowed(
1322
+ message=self.msg_store.selected_lines_qty_picked_higher_than_allowed(
1316
1323
  line
1317
1324
  ),
1318
1325
  )
@@ -1329,7 +1336,7 @@ class Checkout(Component):
1329
1336
  def scan_dest_package(self, picking_id, selected_line_ids, barcode):
1330
1337
  """Scan destination package for lines
1331
1338
 
1332
- Set the destination package on the selected lines with a `qty_done` if
1339
+ Set the destination package on the `picked` selected lines if
1333
1340
  the package is valid. It is valid when one of:
1334
1341
 
1335
1342
  * it is already the destination package of another line of the stock.picking
@@ -1459,7 +1466,7 @@ class Checkout(Component):
1459
1466
 
1460
1467
  All the move lines with the package as ``result_package_id`` have their
1461
1468
  ``result_package_id`` reset to the source package (default odoo behavior)
1462
- and their ``qty_done`` set to 0.
1469
+ and their ``qty_picked`` set to 0.
1463
1470
 
1464
1471
  It flags ``shopfloor_checkout_done`` to False
1465
1472
  so they have to be processed again.
@@ -1488,14 +1495,17 @@ class Checkout(Component):
1488
1495
  for move_line in move_lines:
1489
1496
  move_line.write(
1490
1497
  {
1491
- "qty_done": 0,
1498
+ "qty_picked": 0,
1499
+ "picked": False,
1492
1500
  "result_package_id": move_line.package_id,
1493
1501
  "shopfloor_checkout_done": False,
1494
1502
  }
1495
1503
  )
1496
1504
  msg = _("Package cancelled")
1497
1505
  if line:
1498
- line.write({"qty_done": 0, "shopfloor_checkout_done": False})
1506
+ line.write(
1507
+ {"qty_picked": 0, "picked": False, "shopfloor_checkout_done": False}
1508
+ )
1499
1509
  msg = _("Line cancelled")
1500
1510
  return self._response_for_select_line(
1501
1511
  picking, message={"message_type": "success", "body": msg}
@@ -1504,7 +1514,7 @@ class Checkout(Component):
1504
1514
  def done(self, picking_id, confirmation=False):
1505
1515
  """Set the moves as done
1506
1516
 
1507
- If some lines have not the full ``qty_done`` or no destination package set,
1517
+ If some lines are not fully ``picked`` or no destination package set,
1508
1518
  a confirmation is asked to the user.
1509
1519
 
1510
1520
  Transitions:
@@ -1519,7 +1529,7 @@ class Checkout(Component):
1519
1529
  return self._response_for_select_document(message=message)
1520
1530
  lines = picking.move_line_ids
1521
1531
  if not confirmation:
1522
- if not all(line.qty_done == line.quantity for line in lines):
1532
+ if not all(line.qty_picked == line.quantity for line in lines):
1523
1533
  return self._response_for_summary(
1524
1534
  picking,
1525
1535
  need_confirm=True,
@@ -4,8 +4,9 @@
4
4
  # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
5
5
  from odoo import _, fields
6
6
  from odoo.osv import expression
7
+ from odoo.tools import str2bool
7
8
 
8
- from odoo.addons.base_rest.components.service import to_bool, to_int
9
+ from odoo.addons.base_rest.components.service import to_int
9
10
  from odoo.addons.component.core import Component
10
11
 
11
12
  from ..utils import to_float
@@ -1385,7 +1386,7 @@ class ShopfloorClusterPickingValidator(Component):
1385
1386
  return {
1386
1387
  "picking_batch_id": {"coerce": to_int, "required": True, "type": "integer"},
1387
1388
  "move_line_id": {"coerce": to_int, "required": True, "type": "integer"},
1388
- "zero": {"coerce": to_bool, "required": True, "type": "boolean"},
1389
+ "zero": {"coerce": str2bool, "required": True, "type": "boolean"},
1389
1390
  }
1390
1391
 
1391
1392
  def skip_line(self):
@@ -2,9 +2,10 @@
2
2
  # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3
3
  from odoo import _, fields
4
4
  from odoo.osv import expression
5
+ from odoo.tools import str2bool
5
6
  from odoo.tools.float_utils import float_is_zero
6
7
 
7
- from odoo.addons.base_rest.components.service import to_bool, to_int
8
+ from odoo.addons.base_rest.components.service import to_int
8
9
  from odoo.addons.component.core import Component
9
10
 
10
11
 
@@ -211,25 +212,23 @@ class Delivery(Component):
211
212
  if product_qty: # defined with lot/product/packaging scan
212
213
  # With a product_qty we process only one move line,
213
214
  # so one move to deal with regarding the qty
214
- qty_done = lines.move_id.product_id.uom_id._compute_quantity(
215
+ qty_picked = lines.move_id.product_id.uom_id._compute_quantity(
215
216
  product_qty, lines.move_id.product_uom
216
217
  )
217
- lines.qty_done += qty_done
218
+ for line in lines:
219
+ line.qty_picked += qty_picked
218
220
  return self._action_picking_done(
219
221
  lines.picking_id, force=allow_prepackaged_product
220
222
  )
221
223
  for line in lines:
222
224
  # note: the package level is automatically set to "is_done" when
223
- # the qty_done is full
224
- line.qty_done = line.quantity
225
+ # the line is fully picked
226
+ line.picked = True
225
227
  picking = fields.first(lines.mapped("picking_id"))
226
228
  return self._action_picking_done(picking, force=allow_prepackaged_product)
227
229
 
228
230
  def _reset_lines(self, lines):
229
- for line in lines:
230
- # note: the package level "is_done" field is automatically unset
231
- # when the qty_done is not full
232
- line.qty_done = 0
231
+ lines.picked = False
233
232
 
234
233
  def _deliver_package(self, picking, package, location):
235
234
  lines = package.move_line_ids.filtered(
@@ -256,7 +255,7 @@ class Delivery(Component):
256
255
  message = self._check_picking_type(lines.mapped("picking_id"))
257
256
  if message:
258
257
  return self._response_for_deliver(location=location, message=message)
259
- # TODO add a message if any of the lines already had a qty_done > 0
258
+ # TODO add a message if any of the lines are already picked
260
259
  new_picking = fields.first(lines.mapped("picking_id"))
261
260
  if self._set_lines_done(lines):
262
261
  return self._response_for_deliver(
@@ -269,7 +268,7 @@ class Delivery(Component):
269
268
  # in the picking type, and then use IN (ids)
270
269
  domain = []
271
270
  if no_qty_done:
272
- domain.append(("qty_done", "=", 0))
271
+ domain.append(("picked", "=", False))
273
272
  return domain
274
273
 
275
274
  def _lines_from_lot_domain(
@@ -419,8 +418,8 @@ class Delivery(Component):
419
418
  location=location,
420
419
  message=self.msg_store.product_not_unitary_in_package_scan_package(),
421
420
  )
422
- # We focus only on lines on which we can increase the 'qty_done'
423
- lines = lines.filtered(lambda x: (x.qty_done + product_qty) <= x.quantity)
421
+ # We focus only on lines on which we can increase the 'qty_picked'
422
+ lines = lines.filtered(lambda x: (x.qty_picked + product_qty) <= x.quantity)
424
423
  # Filter lines to keep only ones from one delivery operation
425
424
  # (we do not want to process lines of another delivery operation)
426
425
  lines = lines._filter_on_picking(picking)
@@ -716,7 +715,7 @@ class Delivery(Component):
716
715
  "Product Unit of Measure"
717
716
  )
718
717
  no_quantities_done = all(
719
- float_is_zero(move_line.qty_done, precision_digits=precision_digits)
718
+ float_is_zero(move_line.qty_picked, precision_digits=precision_digits)
720
719
  for move_line in picking.move_line_ids.filtered(
721
720
  lambda m: m.state not in ("done", "cancel")
722
721
  )
@@ -799,7 +798,7 @@ class ShopfloorDeliveryValidator(Component):
799
798
  def done(self):
800
799
  return {
801
800
  "picking_id": {"coerce": to_int, "required": True, "type": "integer"},
802
- "confirm": {"coerce": to_bool, "required": False, "type": "boolean"},
801
+ "confirm": {"coerce": str2bool, "required": False, "type": "boolean"},
803
802
  }
804
803
 
805
804
 
@@ -6,9 +6,10 @@ import functools
6
6
  from collections import defaultdict
7
7
 
8
8
  from odoo.fields import first
9
+ from odoo.tools import str2bool
9
10
  from odoo.tools.float_utils import float_compare, float_is_zero
10
11
 
11
- from odoo.addons.base_rest.components.service import to_bool, to_int
12
+ from odoo.addons.base_rest.components.service import to_int
12
13
  from odoo.addons.component.core import Component
13
14
 
14
15
  from ..exceptions import ConcurentWorkOnTransfer
@@ -1802,7 +1803,7 @@ class ShopfloorZonePickingValidator(Component):
1802
1803
  def is_zero(self):
1803
1804
  return {
1804
1805
  "move_line_id": {"coerce": to_int, "required": True, "type": "integer"},
1805
- "zero": {"coerce": to_bool, "required": True, "type": "boolean"},
1806
+ "zero": {"coerce": str2bool, "required": True, "type": "boolean"},
1806
1807
  }
1807
1808
 
1808
1809
  def stock_issue(self):
@@ -372,7 +372,7 @@ ul.auto-toc {
372
372
  !! This file is generated by oca-gen-addon-readme !!
373
373
  !! changes will be overwritten. !!
374
374
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
375
- !! source digest: sha256:01ad1a242b0c8a3b6ab8593cd6dedb31c5b6dd941b58e9af751833dad9cc69f3
375
+ !! source digest: sha256:534d443b8feb0fd2548ede9663e260ceb8dcfb20686a39d06022ee92bcc6d209
376
376
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
377
377
  <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/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/stock-logistics-shopfloor/tree/18.0/shopfloor"><img alt="OCA/stock-logistics-shopfloor" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--shopfloor-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/stock-logistics-shopfloor-18-0/stock-logistics-shopfloor-18-0-shopfloor"><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-shopfloor&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
378
378
  <p>Shopfloor is a barcode scanner application for internal warehouse
@@ -23,37 +23,38 @@ from . import test_actions_stock
23
23
  # from . import test_cluster_picking_stock_issue
24
24
  # from . import test_cluster_picking_change_pack_lot
25
25
  # from . import test_cluster_picking_unload
26
- # from . import test_checkout_base
27
- # from . import test_checkout_scan
28
- # from . import test_checkout_select
29
- # from . import test_checkout_scan_line
30
- # from . import test_checkout_scan_line_no_prefill_qty
31
- # from . import test_checkout_scan_line_base
32
- # from . import test_checkout_scan_dest_location
33
- # from . import test_checkout_select_line
34
- # from . import test_checkout_select_package_base
35
- # from . import test_checkout_set_qty
36
- # from . import test_checkout_scan_package_action
37
- # from . import test_checkout_scan_package_action_no_prefill_qty
38
- # from . import test_checkout_new_package
39
- # from . import test_checkout_no_package
40
- # from . import test_checkout_auto_post
41
- # from . import test_checkout_list_delivery_packaging
42
- # from . import test_checkout_list_package
43
- # from . import test_checkout_summary
44
- # from . import test_checkout_change_packaging
45
- # from . import test_checkout_cancel_line
46
- # from . import test_checkout_done
47
- # from . import test_delivery_base
48
- # from . import test_delivery_done
49
- # from . import test_delivery_scan_deliver
50
- # from . import test_delivery_reset_qty_done_line
51
- # from . import test_delivery_reset_qty_done_pack
52
- # from . import test_delivery_set_qty_done_pack
53
- # from . import test_delivery_set_qty_done_line
54
- # from . import test_delivery_sublocation
55
- # from . import test_delivery_list_stock_picking
56
- # from . import test_delivery_select
26
+ from . import test_checkout_base
27
+ from . import test_checkout_scan
28
+ from . import test_checkout_select
29
+ from . import test_checkout_scan_line
30
+ from . import test_checkout_scan_line_no_prefill_qty
31
+ from . import test_checkout_scan_line_base
32
+ from . import test_checkout_scan_dest_location
33
+ from . import test_checkout_select_line
34
+ from . import test_checkout_select_package_base
35
+ from . import test_checkout_set_qty
36
+ from . import test_checkout_scan_package_action
37
+ from . import test_checkout_scan_package_action_no_prefill_qty
38
+ from . import test_checkout_new_package
39
+ from . import test_checkout_no_package
40
+ from . import test_checkout_auto_post
41
+ from . import test_checkout_list_delivery_packaging
42
+ from . import test_checkout_list_package
43
+ from . import test_checkout_summary
44
+ from . import test_checkout_change_packaging
45
+ from . import test_checkout_cancel_line
46
+ from . import test_checkout_done
47
+ from . import test_delivery_base
48
+ from . import test_delivery_done
49
+ from . import test_delivery_scan_deliver
50
+ from . import test_delivery_reset_qty_done_line
51
+ from . import test_delivery_reset_qty_done_pack
52
+ from . import test_delivery_set_qty_done_pack
53
+ from . import test_delivery_set_qty_done_line
54
+ from . import test_delivery_sublocation
55
+ from . import test_delivery_list_stock_picking
56
+ from . import test_delivery_select
57
+
57
58
  # from . import test_location_content_transfer_base
58
59
  # from . import test_location_content_transfer_start
59
60
  # from . import test_location_content_transfer_get_work
@@ -182,8 +182,10 @@ class CommonCase(BaseCommonCase):
182
182
  )
183
183
  # this method adds the quantity to the current quantity, so remove it
184
184
  quantity -= sum(quants.mapped("quantity"))
185
+ if not quantity:
186
+ return
185
187
  cls.env["stock.quant"]._update_available_quantity(
186
- product, location, quantity, package_id=package, lot_id=lot
188
+ product, location, quantity=quantity, package_id=package, lot_id=lot
187
189
  )
188
190
 
189
191
  @classmethod