Skip to content

Commit

Permalink
shopfloor_delivery_shipment: Group package by sales
Browse files Browse the repository at this point in the history
When working from a location after a dock and then a location.
There can be a long list of packages without hints about the one
belonging to a delivery already started.

To improve this, the packages are grouped by sales order, keep on top of
the list the sales order started but not yet all loaded.
  • Loading branch information
TDu committed Jan 26, 2024
1 parent c114af4 commit 4b2e398
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 36 deletions.
82 changes: 56 additions & 26 deletions shopfloor_delivery_shipment/services/delivery_shipment.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,17 +563,6 @@ def _data_for_content_to_load_from_pickings(self, shipment_advice):
It returns a dict where keys are source locations and values are
dictionaries listing package_levels and move_lines that remain to load
from transfers partially loaded in a shipment.
E.g:
{
"SRC_LOCATION1": {
"package_levels": [{PKG_LEVEL_DATA}, ...],
"move_lines": [{MOVE_LINE_DATA}, ...],
},
"SRC_LOCATION2": {
...
},
}
"""
domain = self._find_move_lines_domain(shipment_advice)
# Restrict to lines not loaded
Expand All @@ -593,46 +582,87 @@ def _data_for_content_to_load_from_pickings(self, shipment_advice):
pickings_partially_loaded = loaded_lines.picking_id
domain += [("picking_id", "in", pickings_partially_loaded.ids)]
move_lines = self.env["stock.move.line"].search(domain)
return self._prepare_data_for_content(move_lines)
return self._prepare_data_for_content(move_lines, False)

def _data_for_content_to_load_from_picking(
self, shipment_advice, picking=None, location=None
):
"""Return a dictionary where keys are source locations
and values are dictionaries listing package_levels and move_lines
loaded or to load.
"""
# Grab move lines to sort, restricted to the current delivery
if picking:
move_lines = self._find_move_lines_to_process_from_picking(
shipment_advice, picking
)
elif location:
move_lines = self._find_move_lines_from_location(shipment_advice, location)
group_by_sales = bool(location)
return self._prepare_data_for_content(move_lines, group_by_sales)

def _prepare_data_for_content(self, move_lines, group_by_sales):
"""Returns data for package levels and/or move lines.
The data is grouped by source location with a key for package levels and
a key for move lines.
The package levels can be grouped by related sales order and if they are not
they will be all stored into a key whose name is only spaces.
The move lines are not grouped by sales.
E.g:
{
"SRC_LOCATION1": {
"package_levels": [{PKG_LEVEL_DATA}, ...],
"package_levels": {
"sale 01": [{PKG_LEVEL_DATA}, ...],
"sale 02": [{PKG_LEVEL_DATA}, ...],
" ": [{PKG_LEVEL_DATA}, ...],
}
"move_lines": [{MOVE_LINE_DATA}, ...],
},
"SRC_LOCATION2": {
...
},
}
"""
# Grab move lines to sort, restricted to the current delivery
if picking:
move_lines = self._find_move_lines_to_process_from_picking(
shipment_advice, picking
)
elif location:
move_lines = self._find_move_lines_from_location(shipment_advice, location)
return self._prepare_data_for_content(move_lines)

def _prepare_data_for_content(self, move_lines):
empty_group_name = " "
data = collections.OrderedDict()
package_level_ids = []

# Sort and group move lines by source location and prepare the data
for move_line in move_lines.sorted(lambda ml: ml.location_id.name):
sales_started = []
if group_by_sales:
sales_started = move_lines.shipment_advice_id.loaded_picking_ids.sale_id
# Grouping by sales (the packages) sort starting from last position
# 2 the lines NOT in a sales order whose loading has started.
# 1 the lines in a sales being loaded and the line is done.
# 0 the lines in a sales being loaded and not yet done
move_lines = move_lines.sorted(
lambda ml: 2
if ml.move_id.sale_line_id.order_id not in sales_started
else (1 if ml.package_level_id.is_done else 0)
)
else:
move_lines = move_lines.sorted(lambda ml: ml.location_id.name)

for move_line in move_lines:
location_data = data.setdefault(move_line.location_id.name, {})
if move_line.package_level_id:
pl_data = location_data.setdefault("package_levels", [])
pl_data = location_data.setdefault(
"package_levels", collections.OrderedDict()
)
if move_line.package_level_id.id in package_level_ids:
continue
pl_data.append(self.data.package_level(move_line.package_level_id))
if group_by_sales:
group_name = (
move_line.move_id.sale_line_id.order_id.name or empty_group_name
)
else:
group_name = empty_group_name
pl_group_data = pl_data.setdefault(group_name, [])
pl_group_data.append(
self.data.package_level(move_line.package_level_id)
)
package_level_ids.append(move_line.package_level_id.id)
else:
location_data.setdefault("move_lines", []).append(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@ def assert_response_scan_document(
shipment_advice, picking
)
if lines_to_load:
data["content"] = self.service._prepare_data_for_content(lines_to_load)
group_by_sales = bool(location)
data["content"] = self.service._prepare_data_for_content(
lines_to_load, group_by_sales
)
self.assert_response(
response,
next_state="scan_document",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def test_scan_document_shipment_not_planned_lot_not_planned(self):
)
# 'package_levels' key contains the package available from the same delivery
self.assertEqual(
content[location_src]["package_levels"],
content[location_src]["package_levels"][" "],
self.service.data.package_levels(self.picking1.package_level_ids),
)

Expand Down Expand Up @@ -187,7 +187,7 @@ def test_scan_document_lot_already_loaded(self):
)
# 'package_levels' key contains the package available from the same delivery
self.assertEqual(
content[location_src]["package_levels"],
content[location_src]["package_levels"][" "],
self.service.data.package_levels(self.picking1.package_level_ids),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ def test_scan_document_shipment_not_planned_package_not_planned(self):
self.service.data.move_lines(self.picking1.move_line_ids_without_package),
)
# 'package_levels' key contains the package which has been loaded
# grouped in a dict
self.assertEqual(
content[location_src]["package_levels"],
content[location_src]["package_levels"][" "],
self.service.data.package_levels(package_level),
)

Expand Down Expand Up @@ -141,8 +142,9 @@ def test_scan_document_package_already_loaded(self):
self.service.data.move_lines(self.picking1.move_line_ids_without_package),
)
# 'package_levels' key contains the package which has been loaded
# grouped in a dic
self.assertEqual(
content[location_src]["package_levels"],
content[location_src]["package_levels"][" "],
self.service.data.package_levels(package_level),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def test_scan_document_shipment_planned_picking_planned(self):
)
# 'package_levels' key contains the packages
self.assertEqual(
content[location_src]["package_levels"],
content[location_src]["package_levels"][" "],
self.service.data.package_levels(self.picking1.package_level_ids),
)

Expand Down Expand Up @@ -199,7 +199,7 @@ def test_scan_document_shipment_not_planned_picking_partially_planned(self):
self.assertNotIn("move_lines", content[location_src])
# 'package_levels' key contains the not planned packages
self.assertEqual(
content[location_src]["package_levels"],
content[location_src]["package_levels"][" "],
self.service.data.package_levels(self.picking1.package_level_ids),
)

Expand Down Expand Up @@ -261,6 +261,6 @@ def test_scan_document_shipment_not_planned_picking_partially_loaded(self):
self.assertNotIn("move_lines", content[location_src])
# 'package_levels' key contains the already loaded package levels
self.assertEqual(
content[location_src]["package_levels"],
content[location_src]["package_levels"][" "],
self.service.data.package_levels(self.picking1.package_level_ids),
)
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,9 @@ def test_scan_document_shipment_not_planned_product_not_planned(self):
),
)
# 'package_levels' key contains the package available from the same delivery
# grouped in a dict
self.assertEqual(
content[location_src]["package_levels"],
content[location_src]["package_levels"][" "],
self.service.data.package_levels(self.picking1.package_level_ids),
)

Expand Down Expand Up @@ -184,7 +185,7 @@ def test_scan_document_product_already_loaded(self):
)
# 'package_levels' key contains the package available from the same delivery
self.assertEqual(
content[location_src]["package_levels"],
content[location_src]["package_levels"][" "],
self.service.data.package_levels(self.picking1.package_level_ids),
)

Expand Down

0 comments on commit 4b2e398

Please sign in to comment.