Skip to content

Commit

Permalink
[UPD] stock_picking_mass_action
Browse files Browse the repository at this point in the history
Added reservation logic for moves defined in odoo base
and added test for "by_date" resevation method
  • Loading branch information
FLAlvaroGomez committed Jan 9, 2025
1 parent aa946ca commit 5fdc41b
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 119 deletions.
33 changes: 15 additions & 18 deletions stock_picking_mass_action/models/stock_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,32 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).


from odoo import _, api, fields
from odoo import _, api
from odoo.models import Model
from odoo.tools.misc import split_every


class StockPicking(Model):
_inherit = "stock.picking"

@api.model
def check_assign_all(self, domain=None, batch_size=False):
"""Try to assign confirmed pickings"""
if not batch_size:
batch_size = 1000
"""Try to assign confirmed pickings"""
search_domain = [("state", "=", "confirmed")]
domains = self.env["procurement.group"]._get_moves_to_assign_domain(
self.company_id.id
)
if domain:
search_domain += domain
else:
search_domain += [("picking_type_code", "=", "outgoing")]
records = self.search(search_domain, order="scheduled_date")

filtered_records = []
for picking in records:
if all([m.state in ["confirmed", "partially_available"] and m.product_uom_qty != 0 and m.reservation_date != False and m.reservation_date <= fields.Date.today() for m in picking.move_ids]):
filtered_records.append(picking)
for i in range(0, len(filtered_records), batch_size):
batch = filtered_records[i:i + batch_size]
for picking in batch:
picking.sudo().action_assign()

domains.append(domain)
moves_to_assign = self.env["stock.move"].search(
domains,
limit=None,
order="reservation_date, priority desc, date asc, id asc",
)
total_items = len(moves_to_assign)
for i in range(0, total_items, batch_size):
batch = moves_to_assign[i : i + batch_size]
self.env["stock.move"].browse(batch.ids).sudo()._action_assign()

def action_immediate_transfer_wizard(self):
view = self.env.ref("stock.view_immediate_transfer")
Expand Down
135 changes: 34 additions & 101 deletions stock_picking_mass_action/tests/test_mass_action.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Copyright 2018 Tecnativa - Vicent Cubells
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo.tests import common
from odoo import fields
from datetime import timedelta

from odoo import fields
from odoo.tests import common


class TestMassAction(common.TransactionCase):
@classmethod
Expand Down Expand Up @@ -52,8 +53,6 @@ def setUpClass(cls):
}
)



def test_mass_action(self):
self.assertEqual(self.picking.state, "draft")
wiz = self.env["stock.picking.mass.action"]
Expand Down Expand Up @@ -103,6 +102,37 @@ def test_mass_action(self):
self.assertEqual(pick1.state, "assigned")
self.assertEqual(pick2.state, "assigned")

def test_mass_action_by_date(self):
# Set by date method
self.env.ref("stock.picking_type_out").write(
{"reservation_method": "by_date", "reservation_days_before": 4}
)
self.assertEqual(self.picking.state, "draft")
wiz = self.env["stock.picking.mass.action"]
# We test checking assign all with "by date" method
pickings = self.env["stock.picking"]
pickOutDate = self.picking.copy()
# Set scheduled date out of the range of 4 days
pickOutDate.scheduled_date = fields.Date.today() + timedelta(days=15)
pickings |= pickOutDate
pickInDate = self.picking.copy()
pickings |= pickInDate
self.assertEqual(pickOutDate.state, "draft")
self.assertEqual(pickInDate.state, "draft")
wiz_confirm = wiz.create(
{"picking_ids": [(6, 0, [pickOutDate.id, pickInDate.id])]}
)
wiz_confirm.confirm = True
wiz_confirm.mass_action()
self.assertEqual(pickOutDate.state, "confirmed")
self.assertEqual(pickInDate.state, "assigned")
pickings.check_assign_all()
self.assertEqual(pickOutDate.state, "confirmed")
# Change scheduled date in the range of 4 days
pickOutDate.scheduled_date = fields.Date.today() + timedelta(days=1)
pickings.check_assign_all()
self.assertEqual(pickOutDate.state, "assigned")

def test_mass_action_inmediate_transfer(self):
wiz_tranfer = self.env["stock.picking.mass.action"].create(
{"picking_ids": [(4, self.picking.id)], "confirm": True, "transfer": True}
Expand All @@ -118,100 +148,3 @@ def test_mass_action_backorder(self):
self.picking.move_ids[0].quantity_done = 30
res = wiz_tranfer.mass_action()
self.assertEqual(res["res_model"], "stock.backorder.confirmation")

def test_mass_action_reservation_by_date(self):
picking_type_out = self.env.ref("stock.picking_type_out")
picking_type_out.reservation_method = "by_date"
picking_type_out.reservation_days_before = 2

product = self.env["product.product"].create(
{"name": "Product Test Date", "type": "product"}
)
stock_location = self.env.ref("stock.stock_location_stock")
customer_location = self.env.ref("stock.stock_location_customers")

self.env["stock.quant"].create(
{
"product_id": product.id,
"location_id": stock_location.id,
"quantity": 100.0,
}
)

# Creamos dos pickings: uno con fecha válida y otro fuera del rango permitido
picking_valid_date = self.env["stock.picking"].create(
{
"partner_id": self.env["res.partner"].create({"name": "Partner 1"}).id,
"picking_type_id": picking_type_out.id,
"location_id": stock_location.id,
"location_dest_id": customer_location.id,
"scheduled_date": fields.Date.today() + timedelta(days=1),
"move_ids": [
(
0,
0,
{
"name": product.name,
"product_id": product.id,
"product_uom_qty": 50,
"product_uom": product.uom_id.id,
"location_id": stock_location.id,
"location_dest_id": customer_location.id,
},
)
],
}
)

picking_out_of_range = self.env["stock.picking"].create(
{
"partner_id": self.env["res.partner"].create({"name": "Partner 2"}).id,
"picking_type_id": picking_type_out.id,
"location_id": stock_location.id,
"location_dest_id": customer_location.id,
"scheduled_date": fields.Date.today() + timedelta(days=6),
"move_ids": [
(
0,
0,
{
"name": product.name,
"product_id": product.id,
"product_uom_qty": 50,
"product_uom": product.uom_id.id,
"location_id": stock_location.id,
"location_dest_id": customer_location.id,
},
)
],
}
)
self.assertEqual(picking_valid_date.state, "draft")
self.assertEqual(picking_out_of_range.state, "draft")
wiz = self.env["stock.picking.mass.action"]
wiz_confirm = wiz.create({"picking_ids": [(4, picking_valid_date.id), (4, picking_out_of_range.id)]})
wiz_confirm.confirm = True
wiz_confirm.mass_action()
# Confirmamos los pickings
# picking_valid_date.action_confirm()
# picking_out_of_range.action_confirm()
self.assertEqual(picking_valid_date.state, "confirmed")
self.assertEqual(picking_out_of_range.state, "confirmed")
self.env["stock.picking"].check_assign_all()
self.assertEqual(
picking_valid_date.state, "assigned",
"El picking con fecha dentro del rango no fue asignado."
)
self.assertEqual(
picking_out_of_range.state, "confirmed",
"El picking con fecha fuera del rango no debería haberse asignado."
)
self.env["stock.picking"].check_assign_all()
self.assertEqual(
picking_valid_date.state, "assigned",
"El picking con fecha válida no fue asignado."
)
self.assertEqual(
picking_out_of_range.state, "confirmed",
"El picking con fecha futura no debería haberse asignado."
)

0 comments on commit 5fdc41b

Please sign in to comment.