odoo-addon-shopfloor 16.0.2.12.0.1__py3-none-any.whl → 18.0.0.1.0.15__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 (105) hide show
  1. odoo/addons/shopfloor/README.rst +79 -52
  2. odoo/addons/shopfloor/__manifest__.py +11 -4
  3. odoo/addons/shopfloor/actions/__init__.py +0 -1
  4. odoo/addons/shopfloor/actions/change_package_lot.py +4 -6
  5. odoo/addons/shopfloor/actions/data.py +7 -6
  6. odoo/addons/shopfloor/actions/inventory.py +1 -1
  7. odoo/addons/shopfloor/actions/message.py +1 -1
  8. odoo/addons/shopfloor/actions/move_line_search.py +1 -1
  9. odoo/addons/shopfloor/actions/search.py +8 -32
  10. odoo/addons/shopfloor/actions/stock.py +7 -6
  11. odoo/addons/shopfloor/i18n/ca.po +0 -5
  12. odoo/addons/shopfloor/i18n/de.po +0 -5
  13. odoo/addons/shopfloor/i18n/es_AR.po +0 -5
  14. odoo/addons/shopfloor/i18n/it.po +2 -8
  15. odoo/addons/shopfloor/i18n/pt_BR.po +0 -5
  16. odoo/addons/shopfloor/i18n/shopfloor.pot +7 -194
  17. odoo/addons/shopfloor/models/stock_location.py +5 -5
  18. odoo/addons/shopfloor/models/stock_move.py +24 -7
  19. odoo/addons/shopfloor/models/stock_move_line.py +29 -82
  20. odoo/addons/shopfloor/models/stock_picking.py +8 -6
  21. odoo/addons/shopfloor/models/stock_quant_package.py +2 -2
  22. odoo/addons/shopfloor/readme/CONTRIBUTORS.md +17 -0
  23. odoo/addons/shopfloor/readme/CREDITS.md +5 -0
  24. odoo/addons/shopfloor/readme/DESCRIPTION.md +37 -0
  25. odoo/addons/shopfloor/readme/{HISTORY.rst → HISTORY.md} +1 -2
  26. odoo/addons/shopfloor/readme/ROADMAP.md +10 -0
  27. odoo/addons/shopfloor/readme/USAGE.md +6 -0
  28. odoo/addons/shopfloor/services/checkout.py +9 -9
  29. odoo/addons/shopfloor/services/cluster_picking.py +2 -2
  30. odoo/addons/shopfloor/services/delivery.py +4 -6
  31. odoo/addons/shopfloor/services/forms/picking_form.py +4 -1
  32. odoo/addons/shopfloor/services/location_content_transfer.py +1 -1
  33. odoo/addons/shopfloor/services/single_pack_transfer.py +1 -1
  34. odoo/addons/shopfloor/services/zone_picking.py +5 -9
  35. odoo/addons/shopfloor/static/description/index.html +41 -18
  36. odoo/addons/shopfloor/tests/__init__.py +74 -73
  37. odoo/addons/shopfloor/tests/common.py +9 -9
  38. odoo/addons/shopfloor/tests/test_actions_change_package_lot.py +104 -71
  39. odoo/addons/shopfloor/tests/test_actions_data.py +17 -21
  40. odoo/addons/shopfloor/tests/test_actions_data_base.py +9 -3
  41. odoo/addons/shopfloor/tests/test_actions_data_detail.py +17 -19
  42. odoo/addons/shopfloor/tests/test_actions_search.py +2 -1
  43. odoo/addons/shopfloor/tests/test_actions_stock.py +0 -1
  44. odoo/addons/shopfloor/tests/test_checkout_auto_post.py +3 -3
  45. odoo/addons/shopfloor/tests/test_checkout_base.py +1 -1
  46. odoo/addons/shopfloor/tests/test_checkout_list_delivery_packaging.py +1 -1
  47. odoo/addons/shopfloor/tests/test_checkout_list_package.py +4 -4
  48. odoo/addons/shopfloor/tests/test_checkout_new_package.py +3 -3
  49. odoo/addons/shopfloor/tests/test_checkout_no_package.py +3 -3
  50. odoo/addons/shopfloor/tests/test_checkout_scan_dest_location.py +1 -1
  51. odoo/addons/shopfloor/tests/test_checkout_scan_package_action.py +11 -11
  52. odoo/addons/shopfloor/tests/test_checkout_select_package_base.py +1 -1
  53. odoo/addons/shopfloor/tests/test_checkout_set_qty.py +17 -17
  54. odoo/addons/shopfloor/tests/test_checkout_summary.py +2 -2
  55. odoo/addons/shopfloor/tests/test_cluster_picking_base.py +1 -1
  56. odoo/addons/shopfloor/tests/test_cluster_picking_batch.py +2 -2
  57. odoo/addons/shopfloor/tests/test_cluster_picking_change_pack_lot.py +1 -1
  58. odoo/addons/shopfloor/tests/test_cluster_picking_is_zero.py +1 -1
  59. odoo/addons/shopfloor/tests/test_cluster_picking_scan_destination.py +17 -19
  60. odoo/addons/shopfloor/tests/test_cluster_picking_scan_line_no_prefill_qty.py +1 -1
  61. odoo/addons/shopfloor/tests/test_cluster_picking_stock_issue.py +5 -5
  62. odoo/addons/shopfloor/tests/test_delivery_base.py +4 -6
  63. odoo/addons/shopfloor/tests/test_delivery_done.py +1 -1
  64. odoo/addons/shopfloor/tests/test_delivery_reset_qty_done_line.py +1 -1
  65. odoo/addons/shopfloor/tests/test_delivery_reset_qty_done_pack.py +1 -1
  66. odoo/addons/shopfloor/tests/test_delivery_scan_deliver.py +6 -6
  67. odoo/addons/shopfloor/tests/test_location_content_transfer_base.py +2 -2
  68. odoo/addons/shopfloor/tests/test_location_content_transfer_mix.py +8 -8
  69. odoo/addons/shopfloor/tests/test_location_content_transfer_set_destination_package_or_line.py +41 -41
  70. odoo/addons/shopfloor/tests/test_location_content_transfer_single.py +3 -3
  71. odoo/addons/shopfloor/tests/test_menu_base.py +4 -4
  72. odoo/addons/shopfloor/tests/test_move_action_assign.py +19 -4
  73. odoo/addons/shopfloor/tests/test_single_pack_transfer.py +3 -3
  74. odoo/addons/shopfloor/tests/test_stock_split.py +77 -17
  75. odoo/addons/shopfloor/tests/test_zone_picking_base.py +5 -5
  76. odoo/addons/shopfloor/tests/test_zone_picking_change_pack_lot.py +2 -2
  77. odoo/addons/shopfloor/tests/test_zone_picking_complete_mix_pack_flux.py +2 -2
  78. odoo/addons/shopfloor/tests/test_zone_picking_require_destination_package.py +3 -3
  79. odoo/addons/shopfloor/tests/test_zone_picking_select_line.py +4 -4
  80. odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination.py +29 -29
  81. odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination_package_not_allowed.py +2 -2
  82. odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination_pick_pack.py +12 -12
  83. odoo/addons/shopfloor/tests/test_zone_picking_start.py +1 -1
  84. odoo/addons/shopfloor/tests/test_zone_picking_unload_all.py +12 -12
  85. odoo/addons/shopfloor/tests/test_zone_picking_unload_buffer_lines.py +4 -4
  86. odoo/addons/shopfloor/tests/test_zone_picking_unload_set_destination.py +10 -10
  87. odoo/addons/shopfloor/tests/test_zone_picking_unload_single.py +3 -3
  88. odoo/addons/shopfloor/views/shopfloor_menu.xml +33 -102
  89. odoo/addons/shopfloor/views/stock_move_line.xml +2 -2
  90. odoo/addons/shopfloor/views/stock_picking_type.xml +1 -1
  91. odoo_addon_shopfloor-18.0.0.1.0.15.dist-info/METADATA +222 -0
  92. {odoo_addon_shopfloor-16.0.2.12.0.1.dist-info → odoo_addon_shopfloor-18.0.0.1.0.15.dist-info}/RECORD +94 -98
  93. {odoo_addon_shopfloor-16.0.2.12.0.1.dist-info → odoo_addon_shopfloor-18.0.0.1.0.15.dist-info}/WHEEL +1 -1
  94. odoo_addon_shopfloor-18.0.0.1.0.15.dist-info/top_level.txt +1 -0
  95. odoo/addons/shopfloor/actions/barcode_parser.py +0 -44
  96. odoo/addons/shopfloor/migrations/16.0.2.0.0/post-migration.py +0 -41
  97. odoo/addons/shopfloor/migrations/16.0.2.4.2/post-init_search_move_line_options.py +0 -33
  98. odoo/addons/shopfloor/migrations/16.0.2.4.2/post-migration.py +0 -29
  99. odoo/addons/shopfloor/readme/CONTRIBUTORS.rst +0 -18
  100. odoo/addons/shopfloor/readme/CREDITS.rst +0 -5
  101. odoo/addons/shopfloor/readme/DESCRIPTION.rst +0 -17
  102. odoo/addons/shopfloor/readme/ROADMAP.rst +0 -4
  103. odoo/addons/shopfloor/readme/USAGE.rst +0 -6
  104. odoo_addon_shopfloor-16.0.2.12.0.1.dist-info/METADATA +0 -193
  105. odoo_addon_shopfloor-16.0.2.12.0.1.dist-info/top_level.txt +0 -1
@@ -253,7 +253,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
253
253
  params={
254
254
  "location_id": 1234567890, # Doesn't exist
255
255
  "move_line_id": move_line.id,
256
- "quantity": move_line.reserved_uom_qty,
256
+ "quantity": move_line.quantity,
257
257
  "barcode": "TEST",
258
258
  },
259
259
  )
@@ -265,7 +265,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
265
265
  params={
266
266
  "location_id": self.content_loc.id,
267
267
  "move_line_id": 1234567890, # Doesn't exist
268
- "quantity": move_line.reserved_uom_qty,
268
+ "quantity": move_line.quantity,
269
269
  "barcode": "TEST",
270
270
  },
271
271
  )
@@ -285,7 +285,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
285
285
  params={
286
286
  "location_id": self.content_loc.id,
287
287
  "move_line_id": move_line.id,
288
- "quantity": move_line.reserved_uom_qty,
288
+ "quantity": move_line.quantity,
289
289
  "barcode": "UNKNOWN_LOCATION",
290
290
  },
291
291
  )
@@ -302,7 +302,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
302
302
  params={
303
303
  "location_id": self.content_loc.id,
304
304
  "move_line_id": move_line.id,
305
- "quantity": move_line.reserved_uom_qty,
305
+ "quantity": move_line.quantity,
306
306
  "barcode": customer_location.barcode,
307
307
  },
308
308
  )
@@ -326,7 +326,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
326
326
  params={
327
327
  "location_id": self.content_loc.id,
328
328
  "move_line_id": move_line.id,
329
- "quantity": move_line.reserved_uom_qty,
329
+ "quantity": move_line.quantity,
330
330
  "barcode": self.shelf2.barcode,
331
331
  },
332
332
  )
@@ -346,7 +346,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
346
346
  params={
347
347
  "location_id": self.content_loc.id,
348
348
  "move_line_id": move_line.id,
349
- "quantity": move_line.reserved_uom_qty,
349
+ "quantity": move_line.quantity,
350
350
  "barcode": barcode,
351
351
  },
352
352
  )
@@ -367,7 +367,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
367
367
  params={
368
368
  "location_id": self.content_loc.id,
369
369
  "move_line_id": move_line.id,
370
- "quantity": move_line.reserved_uom_qty,
370
+ "quantity": move_line.quantity,
371
371
  "barcode": self.dest_location.barcode,
372
372
  },
373
373
  )
@@ -415,7 +415,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
415
415
  params={
416
416
  "location_id": self.content_loc.id,
417
417
  "move_line_id": move_line.id,
418
- "quantity": move_line.reserved_uom_qty,
418
+ "quantity": move_line.quantity,
419
419
  "barcode": self.dest_location.barcode,
420
420
  },
421
421
  )
@@ -449,7 +449,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
449
449
  move_line_c = original_picking.move_line_ids.filtered(
450
450
  lambda m: m.product_id == self.product_c
451
451
  )
452
- self.assertEqual(move_line_c.reserved_uom_qty, 10)
452
+ self.assertEqual(move_line_c.quantity, 10)
453
453
  self.assertEqual(move_line_c.qty_done, 10)
454
454
  self._simulate_selected_move_line(move_line_c)
455
455
  # Scan partial qty (6/10)
@@ -458,14 +458,14 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
458
458
  params={
459
459
  "location_id": self.content_loc.id,
460
460
  "move_line_id": move_line_c.id,
461
- "quantity": move_line_c.reserved_uom_qty - 4, # Scan 6 qty
461
+ "quantity": move_line_c.quantity - 4, # Scan 6 qty
462
462
  "barcode": self.dest_location.barcode,
463
463
  },
464
464
  )
465
465
  done_picking = original_picking.backorder_ids
466
466
  # Check move line data
467
467
  self.assertEqual(move_line_c.move_id.product_uom_qty, 6)
468
- self.assertEqual(move_line_c.reserved_uom_qty, 0)
468
+ self.assertEqual(move_line_c.quantity, 0)
469
469
  self.assertEqual(move_line_c.qty_done, 6)
470
470
  self.assertEqual(move_line_c.state, "done")
471
471
  self.assertEqual(original_picking.backorder_ids, done_picking)
@@ -478,7 +478,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
478
478
  self.assertEqual(move.state, "assigned")
479
479
  self.assertEqual(move.product_id, self.product_c)
480
480
  self.assertEqual(move.product_uom_qty, 4)
481
- self.assertEqual(move.move_line_ids.reserved_uom_qty, 4)
481
+ self.assertEqual(move.move_line_ids.quantity, 4)
482
482
  self.assertEqual(move.move_line_ids.qty_done, 4)
483
483
  # Check the response -> we must first process the backorder
484
484
  self.assert_response_start_single(
@@ -497,14 +497,14 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
497
497
  params={
498
498
  "location_id": self.content_loc.id,
499
499
  "move_line_id": remaining_move_line_c.id,
500
- "quantity": remaining_move_line_c.reserved_uom_qty,
500
+ "quantity": remaining_move_line_c.quantity,
501
501
  "barcode": self.dest_location.barcode,
502
502
  },
503
503
  )
504
504
  done_picking2 = remaining_move_line_c.picking_id
505
505
  # Check move line data
506
506
  self.assertEqual(remaining_move_line_c.move_id.product_uom_qty, 4)
507
- self.assertEqual(remaining_move_line_c.reserved_uom_qty, 0)
507
+ self.assertEqual(remaining_move_line_c.quantity, 0)
508
508
  self.assertEqual(remaining_move_line_c.qty_done, 4)
509
509
  self.assertEqual(remaining_move_line_c.state, "done")
510
510
  self.assertTrue(done_picking2 != original_picking)
@@ -517,8 +517,8 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
517
517
  )
518
518
  moves_product_c_done = all(move.state == "done" for move in moves_product_c)
519
519
  self.assertTrue(moves_product_c_done)
520
- moves_product_c_qty_done = sum([move.quantity_done for move in moves_product_c])
521
- self.assertEqual(moves_product_c_qty_done, 10)
520
+ moves_product_c_picked = sum([move.quantity_picked for move in moves_product_c])
521
+ self.assertEqual(moves_product_c_picked, 10)
522
522
  # The picking is still not done as product_d hasn't been processed
523
523
  self.assertEqual(original_picking.state, "assigned")
524
524
  # Let scan product_d quantity and check picking state
@@ -531,12 +531,12 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
531
531
  params={
532
532
  "location_id": self.content_loc.id,
533
533
  "move_line_id": move_line_d.id,
534
- "quantity": move_line_d.reserved_uom_qty,
534
+ "quantity": move_line_d.quantity,
535
535
  "barcode": self.dest_location.barcode,
536
536
  },
537
537
  )
538
538
  self.assertEqual(move_line_d.move_id.product_uom_qty, 10)
539
- self.assertEqual(move_line_d.reserved_uom_qty, 0)
539
+ self.assertEqual(move_line_d.quantity, 0)
540
540
  self.assertEqual(move_line_d.qty_done, 10)
541
541
  self.assertEqual(move_line_d.state, "done")
542
542
  self.assertEqual(original_picking.state, "done")
@@ -562,14 +562,14 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
562
562
  params={
563
563
  "location_id": self.content_loc.id,
564
564
  "move_line_id": move_line.id,
565
- "quantity": move_line.reserved_uom_qty - 4, # Scan 6 qty
565
+ "quantity": move_line.quantity - 4, # Scan 6 qty
566
566
  "barcode": self.dest_location.barcode,
567
567
  },
568
568
  )
569
569
  done_picking = picking
570
570
  # Check move line data
571
571
  self.assertEqual(move_line.move_id.product_uom_qty, 6)
572
- self.assertEqual(move_line.reserved_uom_qty, 0)
572
+ self.assertEqual(move_line.quantity, 0)
573
573
  self.assertEqual(move_line.qty_done, 6)
574
574
  self.assertEqual(move_line.state, "done")
575
575
  self.assertEqual(done_picking.state, "done")
@@ -605,7 +605,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
605
605
  params={
606
606
  "location_id": self.content_loc.id,
607
607
  "move_line_id": move_line.id,
608
- "quantity": move_line.reserved_uom_qty - 4, # Scan 6 qty
608
+ "quantity": move_line.quantity - 4, # Scan 6 qty
609
609
  "barcode": self.dest_location.barcode,
610
610
  },
611
611
  )
@@ -613,7 +613,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
613
613
  first_done_picking = picking.backorder_ids
614
614
  # Check move line data
615
615
  self.assertEqual(move_line.move_id.product_uom_qty, 6)
616
- self.assertEqual(move_line.reserved_uom_qty, 0)
616
+ self.assertEqual(move_line.quantity, 0)
617
617
  self.assertEqual(move_line.qty_done, 6)
618
618
  self.assertEqual(move_line.state, "done")
619
619
  self.assertEqual(first_done_picking.state, "done")
@@ -632,7 +632,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
632
632
  params={
633
633
  "location_id": self.content_loc.id,
634
634
  "move_line_id": move_line.id,
635
- "quantity": move_line.reserved_uom_qty - 4, # Scan 6 qty
635
+ "quantity": move_line.quantity - 4, # Scan 6 qty
636
636
  "barcode": self.dest_location.barcode,
637
637
  },
638
638
  )
@@ -640,7 +640,7 @@ class LocationContentTransferSetDestinationXCase(LocationContentTransferCommonCa
640
640
  # the initial picking should be done
641
641
  # Check move line data
642
642
  self.assertEqual(move_line.move_id.product_uom_qty, 6)
643
- self.assertEqual(move_line.reserved_uom_qty, 0)
643
+ self.assertEqual(move_line.quantity, 0)
644
644
  self.assertEqual(move_line.qty_done, 6)
645
645
  self.assertEqual(move_line.state, "done")
646
646
  self.assertEqual(picking.state, "done")
@@ -766,7 +766,7 @@ class LocationContentTransferSetDestinationXSpecialCase(
766
766
  self.assertEqual(len(original_picking.move_ids), 2)
767
767
  self.assertEqual(len(self.move_product_b.move_line_ids), 2)
768
768
  move_line = self.move_product_b.move_line_ids.filtered(
769
- lambda ml: ml.reserved_uom_qty == 6
769
+ lambda ml: ml.quantity == 6
770
770
  )
771
771
  self._simulate_selected_move_line(move_line)
772
772
  response = self.service.dispatch(
@@ -774,7 +774,7 @@ class LocationContentTransferSetDestinationXSpecialCase(
774
774
  params={
775
775
  "location_id": self.content_loc.id,
776
776
  "move_line_id": move_line.id,
777
- "quantity": move_line.reserved_uom_qty,
777
+ "quantity": move_line.quantity,
778
778
  "barcode": self.dest_location.barcode,
779
779
  },
780
780
  )
@@ -784,7 +784,7 @@ class LocationContentTransferSetDestinationXSpecialCase(
784
784
  self.assertEqual(done_picking.state, "done")
785
785
  self.assertEqual(original_picking.state, "assigned")
786
786
  self.assertEqual(move_line.move_id.product_uom_qty, 6)
787
- self.assertEqual(move_line.reserved_uom_qty, 0)
787
+ self.assertEqual(move_line.quantity, 0)
788
788
  self.assertEqual(move_line.qty_done, 6)
789
789
  self.assertEqual(move_line.location_dest_id, self.dest_location)
790
790
  self.assertEqual(len(original_picking.move_ids), 2)
@@ -804,7 +804,7 @@ class LocationContentTransferSetDestinationXSpecialCase(
804
804
  )
805
805
  self.assertEqual(remaining_move.state, "assigned")
806
806
  self.assertEqual(remaining_move.product_uom_qty, 4)
807
- self.assertEqual(remaining_move.move_line_ids.reserved_uom_qty, 4)
807
+ self.assertEqual(remaining_move.move_line_ids.quantity, 4)
808
808
  self.assertEqual(remaining_move.move_line_ids.qty_done, 4)
809
809
  # Check the response
810
810
  move_lines = self.service._find_transfer_move_lines(self.content_loc)
@@ -827,7 +827,7 @@ class LocationContentTransferSetDestinationXSpecialCase(
827
827
  params={
828
828
  "location_id": self.content_loc.id,
829
829
  "move_line_id": ml.id,
830
- "quantity": ml.reserved_uom_qty,
830
+ "quantity": ml.quantity,
831
831
  "barcode": self.dest_location.barcode,
832
832
  },
833
833
  )
@@ -903,7 +903,7 @@ class LocationContentTransferSetDestinationChainSpecialCase(
903
903
  lambda m: m.product_id == self.product_c
904
904
  )
905
905
 
906
- self.assertEqual(move_line_c.reserved_uom_qty, 10)
906
+ self.assertEqual(move_line_c.quantity, 10)
907
907
  self.assertEqual(move_line_c.qty_done, 10)
908
908
  # Scan partial qty (6/10)
909
909
  self.service.dispatch(
@@ -911,13 +911,13 @@ class LocationContentTransferSetDestinationChainSpecialCase(
911
911
  params={
912
912
  "location_id": self.content_loc.id,
913
913
  "move_line_id": move_line_c.id,
914
- "quantity": move_line_c.reserved_uom_qty - 4, # Scan 6 qty
914
+ "quantity": move_line_c.quantity - 4, # Scan 6 qty
915
915
  "barcode": self.dest_location.barcode,
916
916
  },
917
917
  )
918
918
  # Check move line data
919
919
  self.assertEqual(move_line_c.move_id.product_uom_qty, 6)
920
- self.assertEqual(move_line_c.reserved_uom_qty, 0)
920
+ self.assertEqual(move_line_c.quantity, 0)
921
921
  self.assertEqual(move_line_c.qty_done, 6)
922
922
  self.assertEqual(move_line_c.state, "done")
923
923
  # the move has been split
@@ -928,7 +928,7 @@ class LocationContentTransferSetDestinationChainSpecialCase(
928
928
  self.assertEqual(move.state, "assigned")
929
929
  move_line = move.move_line_ids
930
930
  self.assertEqual(move_line.move_id.product_uom_qty, 4)
931
- self.assertEqual(move_line.reserved_uom_qty, 4)
931
+ self.assertEqual(move_line.quantity, 4)
932
932
  self.assertEqual(move_line.qty_done, 4)
933
933
 
934
934
  def test_set_destination_package_partial_qty_with_move_orig_ids(self):
@@ -943,8 +943,8 @@ class LocationContentTransferSetDestinationChainSpecialCase(
943
943
  package1 = self.env["stock.quant.package"].create({})
944
944
  package2 = self.env["stock.quant.package"].create({})
945
945
  line1 = picking_a.move_line_ids
946
- line2 = line1.copy({"reserved_uom_qty": 4, "qty_done": 4})
947
- line1.with_context(bypass_reservation_update=True).reserved_uom_qty = 6
946
+ line2 = line1.copy({"quantity": 4, "qty_done": 4})
947
+ line1.with_context(bypass_reservation_update=True).quantity = 6
948
948
  line1.qty_done = 6
949
949
  line1.result_package_id = package1
950
950
  line2.result_package_id = package2
@@ -958,7 +958,7 @@ class LocationContentTransferSetDestinationChainSpecialCase(
958
958
  move_line = picking_b.move_line_ids.filtered(lambda m: m.package_id == package1)
959
959
  move = move_line.move_id
960
960
 
961
- self.assertEqual(move_line.reserved_uom_qty, 6.0)
961
+ self.assertEqual(move_line.quantity, 6.0)
962
962
  self.assertEqual(move_line.qty_done, 6.0)
963
963
  self._simulate_selected_move_line(move_line)
964
964
  # Scan partial qty (6/10)
@@ -973,7 +973,7 @@ class LocationContentTransferSetDestinationChainSpecialCase(
973
973
  )
974
974
  # Check move line data
975
975
  self.assertEqual(move_line.move_id.product_uom_qty, 6)
976
- self.assertEqual(move_line.reserved_uom_qty, 0)
976
+ self.assertEqual(move_line.quantity, 0)
977
977
  self.assertEqual(move_line.qty_done, 6)
978
978
  self.assertEqual(move_line.state, "done")
979
979
  # the move has been split
@@ -983,7 +983,7 @@ class LocationContentTransferSetDestinationChainSpecialCase(
983
983
  self.assertEqual(move.state, "assigned")
984
984
  move_line = move.move_line_ids
985
985
  self.assertEqual(move_line.move_id.product_uom_qty, 4)
986
- self.assertEqual(move_line.reserved_uom_qty, 4)
986
+ self.assertEqual(move_line.quantity, 4)
987
987
  self.assertEqual(move_line.qty_done, 4)
988
988
 
989
989
 
@@ -1034,7 +1034,7 @@ class LocationContentTransferSetDestinationNextOperationSpecialCase(
1034
1034
  params={
1035
1035
  "location_id": self.content_loc.id,
1036
1036
  "move_line_id": move_line.id,
1037
- "quantity": move_line.reserved_uom_qty - 4, # Scan 6 qty
1037
+ "quantity": move_line.quantity - 4, # Scan 6 qty
1038
1038
  "barcode": self.dest_location.barcode,
1039
1039
  },
1040
1040
  )
@@ -1052,7 +1052,7 @@ class LocationContentTransferSetDestinationNextOperationSpecialCase(
1052
1052
  )
1053
1053
  # check that the next operation has the appropriate attributes
1054
1054
  move_line = backorder.move_line_ids
1055
- self.assertEqual(move_line.reserved_uom_qty, 4)
1055
+ self.assertEqual(move_line.quantity, 4)
1056
1056
  self.assertEqual(move_line.qty_done, 4)
1057
1057
  self.assertEqual(move_line.picking_id.user_id, self.env.user)
1058
1058
  # if we process the quantity of the backorder, the next operation should
@@ -1063,7 +1063,7 @@ class LocationContentTransferSetDestinationNextOperationSpecialCase(
1063
1063
  params={
1064
1064
  "location_id": self.content_loc.id,
1065
1065
  "move_line_id": move_line.id,
1066
- "quantity": move_line.reserved_uom_qty, # Scan 6 qty
1066
+ "quantity": move_line.quantity, # Scan 6 qty
1067
1067
  "barcode": self.dest_location.barcode,
1068
1068
  },
1069
1069
  )
@@ -566,7 +566,7 @@ class LocationContentTransferSingleCase(LocationContentTransferCommonCase):
566
566
  params={
567
567
  "location_id": self.content_loc.id,
568
568
  "move_line_id": move_line.id,
569
- "quantity": move_line.reserved_uom_qty,
569
+ "quantity": move_line.quantity,
570
570
  "barcode": self.shelf1.barcode,
571
571
  },
572
572
  )
@@ -817,7 +817,7 @@ class LocationContentTransferSingleSpecialCase(LocationContentTransferCommonCase
817
817
  self.assertEqual(len(self.picking.move_ids), 2)
818
818
  self.assertEqual(len(self.move_product_b.move_line_ids), 2)
819
819
  move_line = self.move_product_b.move_line_ids.filtered(
820
- lambda ml: ml.reserved_uom_qty == 4 # 4/10 to stock out
820
+ lambda ml: ml.quantity == 4 # 4/10 to stock out
821
821
  )
822
822
  self.assertEqual(self.product_b.qty_available, 10)
823
823
  response = self.service.dispatch(
@@ -855,7 +855,7 @@ class LocationContentTransferSingleSpecialCase(LocationContentTransferCommonCase
855
855
  self.env.user = self.shopfloor_manager
856
856
  self.assertTrue(self.env.user != self.picking.create_uid)
857
857
  move_line = self.move_product_b.move_line_ids.filtered(
858
- lambda ml: ml.reserved_uom_qty == 4 # 4/10 to stock out
858
+ lambda ml: ml.quantity == 4 # 4/10 to stock out
859
859
  )
860
860
  move_line.shopfloor_user_id = self.env.user
861
861
  self.service.dispatch(
@@ -149,7 +149,7 @@ class MenuCountersCommonCase(CommonMenuCase):
149
149
  .create(
150
150
  {
151
151
  "name": "Product E",
152
- "type": "product",
152
+ "is_storable": True,
153
153
  "default_code": "E",
154
154
  "barcode": "E",
155
155
  "weight": 3,
@@ -162,7 +162,7 @@ class MenuCountersCommonCase(CommonMenuCase):
162
162
  .create(
163
163
  {
164
164
  "name": "Product F",
165
- "type": "product",
165
+ "is_storable": True,
166
166
  "default_code": "F",
167
167
  "barcode": "F",
168
168
  "weight": 3,
@@ -175,7 +175,7 @@ class MenuCountersCommonCase(CommonMenuCase):
175
175
  .create(
176
176
  {
177
177
  "name": "Product G",
178
- "type": "product",
178
+ "is_storable": True,
179
179
  "default_code": "G",
180
180
  "barcode": "G",
181
181
  "weight": 3,
@@ -188,7 +188,7 @@ class MenuCountersCommonCase(CommonMenuCase):
188
188
  .create(
189
189
  {
190
190
  "name": "Product H",
191
- "type": "product",
191
+ "is_storable": True,
192
192
  "default_code": "H",
193
193
  "barcode": "H",
194
194
  "weight": 3,
@@ -35,7 +35,7 @@ class TestStockMoveActionAssign(CommonCase):
35
35
  An override of ``StockPicking._check_move_lines_map_quant_package()`` ensures
36
36
  that we ignore:
37
37
 
38
- * picked lines (qty_done > 0)
38
+ * picked lines
39
39
  * lines with a different result package already
40
40
  """
41
41
  package = self.env["stock.quant.package"].create({"name": "Src Pack"})
@@ -56,7 +56,7 @@ class TestStockMoveActionAssign(CommonCase):
56
56
  line = move.move_line_ids
57
57
 
58
58
  # we are no longer moving the entire package
59
- line.qty_done = 20
59
+ line._pick_qty(20)
60
60
  line.result_package_id = dest_package1
61
61
 
62
62
  # create remaining quantity
@@ -65,7 +65,12 @@ class TestStockMoveActionAssign(CommonCase):
65
65
  picking.location_id, self.product_a, 30, package=new_package
66
66
  )
67
67
 
68
+ # Starting from Odoo 17.0+, if a move has been picked (even partially)
69
+ # no reservation can be done anymore on it (see '_action_assign()' method).
70
+ # To allow the 2nd reservation we have to unpicked first the 20 units.
71
+ line.picked = False
68
72
  move._action_assign()
73
+ line.picked = True # Re-pick the 20 units
69
74
  new_line = move.move_line_ids - line
70
75
 
71
76
  # At the end of _action_assign(), StockPicking._check_entire_pack() is
@@ -81,7 +86,17 @@ class TestStockMoveActionAssign(CommonCase):
81
86
  self.assertRecordValues(
82
87
  line + new_line,
83
88
  [
84
- {"qty_done": 20, "result_package_id": dest_package1.id},
85
- {"qty_done": 0, "result_package_id": new_package.id},
89
+ {
90
+ "quantity": 20,
91
+ "qty_picked": 20,
92
+ "picked": True,
93
+ "result_package_id": dest_package1.id,
94
+ },
95
+ {
96
+ "quantity": 30,
97
+ "qty_picked": 0,
98
+ "picked": False,
99
+ "result_package_id": new_package.id,
100
+ },
86
101
  ],
87
102
  )
@@ -2,7 +2,7 @@
2
2
  # Copyright 2020 Akretion (http://www.akretion.com)
3
3
  # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
4
4
 
5
- from odoo.tests.common import Form
5
+ from odoo.tests import Form
6
6
 
7
7
  from .test_single_pack_transfer_base import SinglePackTransferCommonBase
8
8
 
@@ -81,7 +81,7 @@ class TestSinglePackTransfer(SinglePackTransferCommonBase):
81
81
  "name": package_level.package_id.name,
82
82
  "weight_uom": package_level.package_id.weight_uom_id.name,
83
83
  "weight": package_level.package_id.pack_weight,
84
- "estimated_weight_kg": package_level.package_id.estimated_pack_weight_kg,
84
+ "estimated_weight_kg": package_level.package_id.shopfloor_weight,
85
85
  "location_src": self.data.location(package_level.location_id),
86
86
  "location_dest": self.data.location(package_level.location_dest_id),
87
87
  "picking": self.data.picking(self.picking),
@@ -194,7 +194,7 @@ class TestSinglePackTransfer(SinglePackTransferCommonBase):
194
194
  "name": package_level.package_id.name,
195
195
  "weight_uom": package_level.package_id.weight_uom_id.name,
196
196
  "weight": package_level.package_id.pack_weight,
197
- "estimated_weight_kg": package_level.package_id.estimated_pack_weight_kg,
197
+ "estimated_weight_kg": package_level.package_id.shopfloor_weight,
198
198
  "location_src": self.data.location(self.shelf1),
199
199
  "location_dest": self.data.location(
200
200
  self.picking_type.default_location_dest_id
@@ -13,7 +13,6 @@ class TestStockSplit(TransactionCase):
13
13
  super().setUpClass()
14
14
  cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
15
15
  cls.warehouse = cls.env.ref("stock.warehouse0")
16
- cls.warehouse.delivery_steps = "pick_pack_ship"
17
16
  cls.customer_location = cls.env.ref("stock.stock_location_customers")
18
17
  cls.pack_location = cls.warehouse.wh_pack_stock_loc_id
19
18
  cls.ship_location = cls.warehouse.wh_output_stock_loc_id
@@ -25,7 +24,7 @@ class TestStockSplit(TransactionCase):
25
24
  .create(
26
25
  {
27
26
  "name": "Product A",
28
- "type": "product",
27
+ "is_storable": True,
29
28
  "default_code": "A",
30
29
  "barcode": "A",
31
30
  "weight": 2,
@@ -49,7 +48,7 @@ class TestStockSplit(TransactionCase):
49
48
  .create(
50
49
  {
51
50
  "name": "Product B",
52
- "type": "product",
51
+ "is_storable": True,
53
52
  "default_code": "B",
54
53
  "barcode": "B",
55
54
  "weight": 2,
@@ -95,7 +94,37 @@ class TestStockSplit(TransactionCase):
95
94
  "warehouse_id": cls.warehouse.id,
96
95
  "picking_type_id": cls.warehouse.out_type_id.id,
97
96
  "procure_method": "make_to_order",
98
- "state": "draft",
97
+ "state": "waiting",
98
+ }
99
+ )
100
+ cls.pack_move_a = cls.env["stock.move"].create(
101
+ {
102
+ "name": cls.product_a.display_name,
103
+ "product_id": cls.product_a.id,
104
+ "product_uom_qty": 15.0,
105
+ "product_uom": cls.product_a.uom_id.id,
106
+ "location_id": cls.pack_location.id,
107
+ "location_dest_id": cls.ship_location.id,
108
+ "warehouse_id": cls.warehouse.id,
109
+ "picking_type_id": cls.warehouse.pack_type_id.id,
110
+ "procure_method": "make_to_order",
111
+ "state": "waiting",
112
+ "move_dest_ids": [(4, cls.ship_move_a.id)],
113
+ }
114
+ )
115
+ cls.pick_move_a = cls.env["stock.move"].create(
116
+ {
117
+ "name": cls.product_a.display_name,
118
+ "product_id": cls.product_a.id,
119
+ "product_uom_qty": 15.0,
120
+ "product_uom": cls.product_a.uom_id.id,
121
+ "location_id": cls.stock_location.id,
122
+ "location_dest_id": cls.pack_location.id,
123
+ "warehouse_id": cls.warehouse.id,
124
+ "picking_type_id": cls.warehouse.pick_type_id.id,
125
+ "procure_method": "make_to_stock",
126
+ "state": "confirmed",
127
+ "move_dest_ids": [(4, cls.pack_move_a.id)],
99
128
  }
100
129
  )
101
130
  cls.ship_move_b = cls.env["stock.move"].create(
@@ -109,15 +138,47 @@ class TestStockSplit(TransactionCase):
109
138
  "warehouse_id": cls.warehouse.id,
110
139
  "picking_type_id": cls.warehouse.out_type_id.id,
111
140
  "procure_method": "make_to_order",
112
- "state": "draft",
141
+ "state": "waiting",
142
+ }
143
+ )
144
+ cls.pack_move_b = cls.env["stock.move"].create(
145
+ {
146
+ "name": cls.product_b.display_name,
147
+ "product_id": cls.product_b.id,
148
+ "product_uom_qty": 4.0,
149
+ "product_uom": cls.product_b.uom_id.id,
150
+ "location_id": cls.pack_location.id,
151
+ "location_dest_id": cls.ship_location.id,
152
+ "warehouse_id": cls.warehouse.id,
153
+ "picking_type_id": cls.warehouse.pack_type_id.id,
154
+ "procure_method": "make_to_order",
155
+ "state": "waiting",
156
+ "move_dest_ids": [(4, cls.ship_move_b.id)],
157
+ }
158
+ )
159
+ cls.pick_move_b = cls.env["stock.move"].create(
160
+ {
161
+ "name": cls.product_b.display_name,
162
+ "product_id": cls.product_b.id,
163
+ "product_uom_qty": 4.0,
164
+ "product_uom": cls.product_b.uom_id.id,
165
+ "location_id": cls.stock_location.id,
166
+ "location_dest_id": cls.pack_location.id,
167
+ "warehouse_id": cls.warehouse.id,
168
+ "picking_type_id": cls.warehouse.pick_type_id.id,
169
+ "procure_method": "make_to_stock",
170
+ "state": "confirmed",
171
+ "move_dest_ids": [(4, cls.pack_move_b.id)],
113
172
  }
114
173
  )
115
- (cls.ship_move_a | cls.ship_move_b)._assign_picking()
116
- (cls.ship_move_a | cls.ship_move_b)._action_confirm(merge=False)
117
- cls.pack_move_a = cls.ship_move_a.move_orig_ids[0]
118
- cls.pick_move_a = cls.pack_move_a.move_orig_ids[0]
119
- cls.pack_move_b = cls.ship_move_b.move_orig_ids[0]
120
- cls.pick_move_b = cls.pack_move_b.move_orig_ids[0]
174
+ (
175
+ cls.ship_move_a
176
+ | cls.ship_move_b
177
+ | cls.pack_move_a
178
+ | cls.pack_move_b
179
+ | cls.pick_move_a
180
+ | cls.pick_move_b
181
+ )._assign_picking()
121
182
  cls.picking = cls.pick_move_a.picking_id
122
183
  cls.packing = cls.pack_move_a.picking_id
123
184
  cls.picking.action_assign()
@@ -146,7 +207,7 @@ class TestStockSplit(TransactionCase):
146
207
  # Pick goods from stock and move some of them to a different destination
147
208
  self.assertEqual(self.pick_move_a.state, "assigned")
148
209
  for i, move_line in enumerate(self.pick_move_a.move_line_ids):
149
- move_line.qty_done = move_line.reserved_uom_qty
210
+ move_line._pick_qty(move_line.quantity)
150
211
  if i % 2:
151
212
  move_line.location_dest_id = dest_location
152
213
  self.pick_move_a.extract_and_action_done()
@@ -159,7 +220,8 @@ class TestStockSplit(TransactionCase):
159
220
  self.assertEqual(len(self.pack_move_a.move_line_ids), 3)
160
221
  self.assertEqual(len(self.packing.package_level_ids), 3)
161
222
  self.assertEqual(len(move_lines_to_process), 1)
162
- new_packing = move_lines_to_process._split_pickings_from_source_location()
223
+ move_lines_to_process._extract_in_split_order()
224
+ new_packing = self.packing.backorder_ids
163
225
  self.assertEqual(len(self.packing.package_level_ids), 2)
164
226
  self.assertEqual(len(new_packing.package_level_ids), 1)
165
227
  self.assertEqual(len(new_packing.move_line_ids), 1)
@@ -176,8 +238,7 @@ class TestStockSplit(TransactionCase):
176
238
  def test_extract_and_action_done_one_assigned_move(self):
177
239
  self.assertFalse(self.picking.backorder_ids)
178
240
  self.assertEqual(self.picking.state, "assigned")
179
- for move_line in self.pick_move_b.move_line_ids:
180
- move_line.qty_done = move_line.reserved_uom_qty
241
+ self.pick_move_b.move_line_ids.picked = True
181
242
  self.pick_move_b.extract_and_action_done()
182
243
  new_picking = self.picking.backorder_ids
183
244
  self.assertTrue(new_picking)
@@ -192,8 +253,7 @@ class TestStockSplit(TransactionCase):
192
253
  def test_extract_and_action_done_multiple_assigned_moves(self):
193
254
  self.assertFalse(self.picking.backorder_ids)
194
255
  self.assertEqual(self.picking.state, "assigned")
195
- for move_line in self.picking.move_line_ids:
196
- move_line.qty_done = move_line.reserved_uom_qty
256
+ self.picking.move_line_ids.picked = True
197
257
  self.picking.move_ids.extract_and_action_done()
198
258
  # No backorder as all moves of the picking have been validated
199
259
  new_picking = self.picking.backorder_ids