[FIX] rma: do not force reservation on supplier RMA deliveries

This commit is contained in:
Lois Rilo
2022-03-04 12:01:02 +01:00
committed by Christopher Ormaza
parent ae61efe191
commit 7b7a8b4f2b
5 changed files with 110 additions and 74 deletions

View File

@@ -1,13 +1,12 @@
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
from . import rma_order from . import rma_order
from . import rma_order_line from . import rma_order_line
from . import rma_operation from . import rma_operation
from . import stock from . import stock_move
from . import stock_warehouse from . import stock_warehouse
from . import product from . import product
from . import product_category from . import product_category
from . import procurement from . import procurement_group
from . import stock_rule
from . import res_partner from . import res_partner
from . import res_company from . import res_company
from . import res_config_settings from . import res_config_settings

View File

@@ -0,0 +1,15 @@
# Copyright (C) 2017-22 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
from odoo import fields, models
class ProcurementGroup(models.Model):
_inherit = "procurement.group"
rma_id = fields.Many2one(
comodel_name="rma.order", string="RMA", ondelete="set null"
)
rma_line_id = fields.Many2one(
comodel_name="rma.order.line", string="RMA line", ondelete="set null"
)

View File

@@ -4,25 +4,6 @@
from odoo import api, fields, models from odoo import api, fields, models
class StockPicking(models.Model):
_inherit = "stock.picking"
def action_assign(self):
"""When you try to bring back a product from a customer location,
it may happen that there is no quants available to perform the
picking."""
res = super(StockPicking, self).action_assign()
for picking in self:
for move in picking.move_lines:
if (
move.rma_line_id
and move.state == "confirmed"
and move.location_id.usage == "customer"
):
move.force_assign()
return res
class StockMove(models.Model): class StockMove(models.Model):
_inherit = "stock.move" _inherit = "stock.move"
@@ -66,3 +47,55 @@ class StockMove(models.Model):
if self.env.context.get("force_no_bypass_reservation"): if self.env.context.get("force_no_bypass_reservation"):
return False return False
return res return res
def _get_available_quantity(
self,
location_id,
lot_id=None,
package_id=None,
owner_id=None,
strict=False,
allow_negative=False,
):
if (
not lot_id
and self.rma_line_id.lot_id
and self.location_id.usage == "internal"
):
# In supplier RMA deliveries we can only send the RMA lot/serial.
lot_id = self.rma_line_id.lot_id
return super()._get_available_quantity(
location_id,
lot_id=lot_id,
package_id=package_id,
owner_id=owner_id,
strict=strict,
allow_negative=allow_negative,
)
def _update_reserved_quantity(
self,
need,
available_quantity,
location_id,
lot_id=None,
package_id=None,
owner_id=None,
strict=True,
):
if (
not lot_id
and self.rma_line_id.lot_id
and self.location_id.usage == "internal"
):
# In supplier RMA deliveries we can only send the RMA lot/serial.
lot_id = self.rma_line_id.lot_id
return super()._update_reserved_quantity(
need,
available_quantity,
location_id,
lot_id=lot_id,
package_id=package_id,
owner_id=owner_id,
strict=strict,
)

View File

@@ -1,7 +1,7 @@
# Copyright (C) 2017-20 ForgeFlow S.L. # Copyright (C) 2017-22 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
from odoo import fields, models from odoo import models
class StockRule(models.Model): class StockRule(models.Model):
@@ -18,7 +18,7 @@ class StockRule(models.Model):
company_id, company_id,
values, values,
): ):
res = super(StockRule, self)._get_stock_move_values( res = super()._get_stock_move_values(
product_id, product_id,
product_qty, product_qty,
product_uom, product_uom,
@@ -39,14 +39,3 @@ class StockRule(models.Model):
if dest_loc.usage == "internal": if dest_loc.usage == "internal":
res["price_unit"] = line.price_unit res["price_unit"] = line.price_unit
return res return res
class ProcurementGroup(models.Model):
_inherit = "procurement.group"
rma_id = fields.Many2one(
comodel_name="rma.order", string="RMA", ondelete="set null"
)
rma_line_id = fields.Many2one(
comodel_name="rma.order.line", string="RMA line", ondelete="set null"
)

View File

@@ -191,43 +191,46 @@ class RmaMakePicking(models.TransientModel):
self._create_picking() self._create_picking()
move_line_model = self.env["stock.move.line"] move_line_model = self.env["stock.move.line"]
picking_type = self.env.context.get("picking_type") picking_type = self.env.context.get("picking_type")
pickings = self.env["stock.picking"].browse()
if picking_type == "outgoing": if picking_type == "outgoing":
pickings = self.mapped("item_ids.line_id")._get_out_pickings() pickings = self.mapped("item_ids.line_id")._get_out_pickings()
action = self.item_ids.line_id.action_view_out_shipments() action = self.item_ids.line_id.action_view_out_shipments()
else: else:
pickings = self.mapped("item_ids.line_id")._get_in_pickings() pickings = self.mapped("item_ids.line_id")._get_in_pickings()
action = self.item_ids.line_id.action_view_in_shipments() action = self.item_ids.line_id.action_view_in_shipments()
for move in pickings.move_lines.filtered(
lambda x: x.state not in ("draft", "cancel", "done")
and x.rma_line_id
and x.product_id.tracking in ("lot", "serial")
and x.rma_line_id.lot_id
):
move.move_line_ids.unlink()
if move.product_id.tracking == "serial":
move.write({"lot_ids": [(6, 0, move.rma_line_id.lot_id.ids)]})
move.move_line_ids.write({"product_uom_qty": 1, "qty_done": 0})
elif move.product_id.tracking == "lot":
if picking_type == "incoming":
qty = self.item_ids.filtered(
lambda x: x.line_id.id == move.rma_line_id.id
).qty_to_receive
else:
qty = self.item_ids.filtered(
lambda x: x.line_id.id == move.rma_line_id.id
).qty_to_deliver
move_line_data = move._prepare_move_line_vals()
move_line_data.update(
{
"lot_id": move.rma_line_id.lot_id.id,
"product_uom_id": move.product_id.uom_id.id,
"qty_done": 0,
"product_uom_qty": qty,
}
)
move_line_model.create(move_line_data)
if picking_type == "incoming": if picking_type == "incoming":
# Force the reservation of the RMA specific lot for incoming shipments.
# FIXME: still needs fixing, not reserving appropriate serials.
for move in pickings.move_lines.filtered(
lambda x: x.state not in ("draft", "cancel", "done")
and x.rma_line_id
and x.product_id.tracking in ("lot", "serial")
and x.rma_line_id.lot_id
):
# Force the reservation of the RMA specific lot for incoming shipments.
move.move_line_ids.unlink()
if move.product_id.tracking == "serial":
move.write({"lot_ids": [(6, 0, move.rma_line_id.lot_id.ids)]})
move.move_line_ids.write({"product_uom_qty": 1, "qty_done": 0})
elif move.product_id.tracking == "lot":
if picking_type == "incoming":
qty = self.item_ids.filtered(
lambda x: x.line_id.id == move.rma_line_id.id
).qty_to_receive
else:
qty = self.item_ids.filtered(
lambda x: x.line_id.id == move.rma_line_id.id
).qty_to_deliver
move_line_data = move._prepare_move_line_vals()
move_line_data.update(
{
"lot_id": move.rma_line_id.lot_id.id,
"product_uom_id": move.product_id.uom_id.id,
"qty_done": 0,
"product_uom_qty": qty,
}
)
move_line_model.create(move_line_data)
pickings.with_context(force_no_bypass_reservation=True).action_assign() pickings.with_context(force_no_bypass_reservation=True).action_assign()
return action return action
@@ -241,18 +244,15 @@ class RmaMakePickingItem(models.TransientModel):
wiz_id = fields.Many2one("rma_make_picking.wizard", string="Wizard", required=True) wiz_id = fields.Many2one("rma_make_picking.wizard", string="Wizard", required=True)
line_id = fields.Many2one( line_id = fields.Many2one(
"rma.order.line", string="RMA order Line", readonly=True, ondelete="cascade" "rma.order.line", string="RMA order Line", ondelete="cascade"
) )
rma_id = fields.Many2one( rma_id = fields.Many2one("rma.order", related="line_id.rma_id", string="RMA Group")
"rma.order", related="line_id.rma_id", string="RMA Group", readonly=True product_id = fields.Many2one("product.product", string="Product")
)
product_id = fields.Many2one("product.product", string="Product", readonly=True)
product_qty = fields.Float( product_qty = fields.Float(
related="line_id.product_qty", related="line_id.product_qty",
string="Quantity Ordered", string="Quantity Ordered",
copy=False, copy=False,
digits="Product Unit of Measure", digits="Product Unit of Measure",
readonly=True,
) )
qty_to_receive = fields.Float( qty_to_receive = fields.Float(
string="Quantity to Receive", digits="Product Unit of Measure" string="Quantity to Receive", digits="Product Unit of Measure"
@@ -260,4 +260,4 @@ class RmaMakePickingItem(models.TransientModel):
qty_to_deliver = fields.Float( qty_to_deliver = fields.Float(
string="Quantity To Deliver", digits="Product Unit of Measure" string="Quantity To Deliver", digits="Product Unit of Measure"
) )
uom_id = fields.Many2one("uom.uom", string="Unit of Measure", readonly=True) uom_id = fields.Many2one("uom.uom", string="Unit of Measure")