Skip to content

Commit

Permalink
[IMP] stock_picking_batch_creation: prioritize picking groups based o…
Browse files Browse the repository at this point in the history
…n weight
  • Loading branch information
sbejaoui committed Dec 5, 2024
1 parent a0c4741 commit 06b9ab4
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
21 changes: 21 additions & 0 deletions stock_picking_batch_creation/tests/test_clustering_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,27 @@ def test_pickings_with_different_partners(self):
batch2 = self.make_picking_batch._create_batch()
self.assertEqual(self.pick1 | self.pick2, batch2.picking_ids)

def test_pickings_with_different_partners_max_capacity_enabled(self):
"""same as previous test but this time use_maximum_capacity_priority_grouping
is enabled"""
partner1 = self.env["res.partner"].create({"name": "partner 1"})
partner2 = self.env["res.partner"].create({"name": "partner 2"})
self._set_quantity_in_stock(self.stock_location, self.p5)
self._create_picking_pick_and_assign(self.picking_type_1.id, products=self.p5)
(self.pick1 | self.pick2).write({"partner_id": partner1.id})
self.pick3.write({"partner_id": partner2.id})
self.make_picking_batch.write(
{
"maximum_number_of_preparation_lines": 10,
"restrict_to_same_partner": True,
"use_maximum_capacity_priority_grouping": True,
}
)
batch = self.make_picking_batch._create_batch()
self.assertEqual(self.pick1 | self.pick2, batch.picking_ids)
batch2 = self.make_picking_batch._create_batch()
self.assertEqual(self.pick3, batch2.picking_ids)

def test_picking_with_maximum_number_of_lines_exceed(self):
# pick 3 has 2 lines
# create a batch picking with maximum number of lines = 1
Expand Down
63 changes: 63 additions & 0 deletions stock_picking_batch_creation/wizards/make_picking_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ class MakePickingBatch(models.TransientModel):
"picking for the sole case where a device is suitable for the picking but the "
"picking has more lines than the maximum number of lines.",
)
use_maximum_capacity_priority_grouping = fields.Boolean(
help="Enable to prioritize stock picking groups based on their total weight and"
"number of picking lines, ensuring the highest priority groups are processed"
"first.",
)

__slots__ = (
"_volume_by_partners",
Expand Down Expand Up @@ -268,6 +273,8 @@ def _get_first_picking(self, no_nbr_lines_limit=False):
for device in self.stock_device_type_ids:
device_domains.append(self._get_picking_domain_for_device(device))
domain = AND([domain, OR(device_domains)])
if self.use_maximum_capacity_priority_grouping:
domain = self._get_domain_for_highest_priority_picking_group(domain)
return self._execute_search_pickings(domain, limit=1)

def _get_additional_picking(self):
Expand Down Expand Up @@ -466,3 +473,59 @@ def _create_batch_values(self):
"batch_nbr_bins": self._device.nbr_bins - self._remaining_nbr_bins,
"batch_nbr_lines": sum(selected_pickings.mapped("nbr_picking_lines")),
}

def _get_group_by_for_highest_priority_picking_group(self):
"""
Retrieves the fields used for grouping stock pickings in order to determine
the highest priority picking group.
"""
res = []
if self.restrict_to_same_priority:
res.append("priority")

Check warning on line 484 in stock_picking_batch_creation/wizards/make_picking_batch.py

View check run for this annotation

Codecov / codecov/patch

stock_picking_batch_creation/wizards/make_picking_batch.py#L484

Added line #L484 was not covered by tests
if self.restrict_to_same_partner:
res.append("partner_id")
return res

@api.model
def _get_comparison_fields_for_highest_priority_picking_group(self):
"""This method can be overwritten to add more comparison fields or change the
comparison order"""
return ["weight", "nbr_picking_lines"]

def _get_domain_for_highest_priority_picking_group(self, domain):
"""
This method retrieves the domain for the group of stock pickings that has the
highest priority, based on the sum of weight, number of picking lines, and the
count of pickings.
It first groups the stock pickings by specified fields, then sorts the groups
in descending order of weight, number of picking lines, and count.
The method returns the domain for the group with the highest priority or
original domain if no groups are found.
Args:
domain (list): The original domain to filter the stock pickings.
Returns:
list: The domain corresponding to the group of stock pickings with the
highest priority, or the original domain.
"""
group_by_fields = self._get_group_by_for_highest_priority_picking_group()
comparison_fields = (
self._get_comparison_fields_for_highest_priority_picking_group()
)
items = self.env["stock.picking"].read_group(
domain,
groupby=group_by_fields,
fields=[f"{f}:sum" for f in comparison_fields],
lazy=False,
)
sorted_items = sorted(
items,
key=lambda x: [x[f] for f in comparison_fields + ["__count"]],
reverse=True,
)
# Return the first item, which has the highest priority
item = sorted_items[0] if sorted_items else None
if item and item.get("__domain"):
return item.get("__domain")
return domain

Check warning on line 531 in stock_picking_batch_creation/wizards/make_picking_batch.py

View check run for this annotation

Codecov / codecov/patch

stock_picking_batch_creation/wizards/make_picking_batch.py#L531

Added line #L531 was not covered by tests
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<field name="user_id" />
<field name="picking_type_ids" widget="many2many_tags" />
<field name="maximum_number_of_preparation_lines" />
<field name="use_maximum_capacity_priority_grouping" />
<field name="no_line_limit_if_no_candidate" />
</group>
<group name="devices">
Expand Down

0 comments on commit 06b9ab4

Please sign in to comment.