From aa946ca9106cd6b4ded0f09abe74b13b43f33f14 Mon Sep 17 00:00:00 2001 From: FactorLibre Date: Mon, 16 Dec 2024 15:27:41 +0100 Subject: [PATCH] [UPD] stock_logistics_workflow --- .../models/stock_picking.py | 19 +++- .../tests/test_mass_action.py | 101 ++++++++++++++++++ 2 files changed, 117 insertions(+), 3 deletions(-) diff --git a/stock_picking_mass_action/models/stock_picking.py b/stock_picking_mass_action/models/stock_picking.py index b5ba22626bc1..24467c67e461 100644 --- a/stock_picking_mass_action/models/stock_picking.py +++ b/stock_picking_mass_action/models/stock_picking.py @@ -2,15 +2,19 @@ # Copyright 2018 Tecnativa - Vicent Cubells # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import _, api + +from odoo import _, api, fields 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): + def check_assign_all(self, domain=None, batch_size=False): + if not batch_size: + batch_size = 1000 """Try to assign confirmed pickings""" search_domain = [("state", "=", "confirmed")] if domain: @@ -18,7 +22,16 @@ def check_assign_all(self, domain=None): else: search_domain += [("picking_type_code", "=", "outgoing")] records = self.search(search_domain, order="scheduled_date") - records.action_assign() + + 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() + def action_immediate_transfer_wizard(self): view = self.env.ref("stock.view_immediate_transfer") diff --git a/stock_picking_mass_action/tests/test_mass_action.py b/stock_picking_mass_action/tests/test_mass_action.py index 32329dde143e..c1da0588f28b 100644 --- a/stock_picking_mass_action/tests/test_mass_action.py +++ b/stock_picking_mass_action/tests/test_mass_action.py @@ -2,6 +2,8 @@ # 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 class TestMassAction(common.TransactionCase): @@ -50,6 +52,8 @@ def setUpClass(cls): } ) + + def test_mass_action(self): self.assertEqual(self.picking.state, "draft") wiz = self.env["stock.picking.mass.action"] @@ -114,3 +118,100 @@ 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." + )