mirror of
https://github.com/ForgeFlow/stock-rma.git
synced 2025-01-21 12:57:49 +02:00
Merge pull request #535 from ForgeFlow/16.0-rma_repair_putaway
[16.0][ADD] rma_repair_put_away: glue module between rma_repair & rma_put_away
This commit is contained in:
@@ -16,7 +16,7 @@ class RmaOrder(models.Model):
|
|||||||
for order in self:
|
for order in self:
|
||||||
pickings = (
|
pickings = (
|
||||||
order.mapped("rma_line_ids.move_ids")
|
order.mapped("rma_line_ids.move_ids")
|
||||||
.filtered(lambda m: m.is_rma_put_away)
|
.filtered(lambda m: m.is_rma_repair_transfer)
|
||||||
.mapped("picking_id")
|
.mapped("picking_id")
|
||||||
)
|
)
|
||||||
order.repair_transfer_count = len(pickings)
|
order.repair_transfer_count = len(pickings)
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ class RmaLineMakeRepair(models.TransientModel):
|
|||||||
res["item_ids"] = items
|
res["item_ids"] = items
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def create_repair_procurement_condition_applies(self, rma_line, repair):
|
||||||
|
return rma_line.location_id != repair.location_id
|
||||||
|
|
||||||
def make_repair_order(self):
|
def make_repair_order(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
res = []
|
res = []
|
||||||
@@ -58,10 +61,11 @@ class RmaLineMakeRepair(models.TransientModel):
|
|||||||
data = item._prepare_repair_order(rma_line)
|
data = item._prepare_repair_order(rma_line)
|
||||||
repair = repair_obj.create(data)
|
repair = repair_obj.create(data)
|
||||||
res.append(repair.id)
|
res.append(repair.id)
|
||||||
if rma_line.location_id != repair.location_id:
|
if self.create_repair_procurement_condition_applies(rma_line, repair):
|
||||||
item._run_procurement(
|
item._run_procurement(
|
||||||
rma_line.operation_id.repair_route_id, repair.location_id
|
rma_line.operation_id.repair_route_id, repair.location_id
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"domain": [("id", "in", res)],
|
"domain": [("id", "in", res)],
|
||||||
"name": _("Repairs"),
|
"name": _("Repairs"),
|
||||||
|
|||||||
31
rma_repair_put_away/README.rst
Normal file
31
rma_repair_put_away/README.rst
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||||
|
:alt: License LGPL-3
|
||||||
|
|
||||||
|
===================
|
||||||
|
RMA Repair Put Away
|
||||||
|
===================
|
||||||
|
|
||||||
|
Glue module between rma_repair & rma_put_away
|
||||||
|
|
||||||
|
When not using rma_put_away you can define push rules anyway to move the products
|
||||||
|
to the repair location, and those transfers count as rma repair transfers
|
||||||
|
|
||||||
|
If you install and use rma_put_away then the rma repair transfers are the ones
|
||||||
|
from the putaway moves
|
||||||
|
|
||||||
|
|
||||||
|
Credits
|
||||||
|
=======
|
||||||
|
|
||||||
|
Contributors
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Jordi Ballester Alomar <jordi.ballester@ForgeFlow.com>
|
||||||
|
* David Jimenez <david.jimenez@ForgeFlow.com>
|
||||||
|
* Aaron Henriquez <aaron.henriquez@ForgeFlow.com>
|
||||||
|
|
||||||
|
|
||||||
|
Maintainer
|
||||||
|
----------
|
||||||
|
|
||||||
|
This module is maintained by ForgeFlow
|
||||||
2
rma_repair_put_away/__init__.py
Normal file
2
rma_repair_put_away/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from . import models
|
||||||
|
from . import wizards
|
||||||
14
rma_repair_put_away/__manifest__.py
Normal file
14
rma_repair_put_away/__manifest__.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Copyright 2024 ForgeFlow S.L.
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
|
{
|
||||||
|
"name": "RMA Repair Put Away",
|
||||||
|
"version": "16.0.1.0.0",
|
||||||
|
"license": "AGPL-3",
|
||||||
|
"category": "RMA",
|
||||||
|
"summary": "RMA repairs with Put away",
|
||||||
|
"author": "ForgeFlow",
|
||||||
|
"website": "https://github.com/ForgeFlow/stock-rma",
|
||||||
|
"depends": ["rma_repair", "rma_put_away"],
|
||||||
|
"installable": True,
|
||||||
|
"auto_install": True,
|
||||||
|
}
|
||||||
2
rma_repair_put_away/models/__init__.py
Normal file
2
rma_repair_put_away/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from . import rma_order
|
||||||
|
from . import rma_order_line
|
||||||
31
rma_repair_put_away/models/rma_order.py
Normal file
31
rma_repair_put_away/models/rma_order.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Copyright 2024 ForgeFlow S.L.
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
from odoo import models
|
||||||
|
|
||||||
|
|
||||||
|
class RmaOrder(models.Model):
|
||||||
|
_inherit = "rma.order"
|
||||||
|
|
||||||
|
def _compute_repair_transfer_count(self):
|
||||||
|
res = super()._compute_repair_transfer_count()
|
||||||
|
for order in self:
|
||||||
|
pickings = (
|
||||||
|
order.mapped("rma_line_ids.move_ids")
|
||||||
|
.filtered(lambda m: m.is_rma_put_away)
|
||||||
|
.mapped("picking_id")
|
||||||
|
)
|
||||||
|
order.repair_transfer_count = len(pickings)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def action_view_repair_transfers(self):
|
||||||
|
super()._compute_repair_transfer_count()
|
||||||
|
self.ensure_one()
|
||||||
|
action = self.env.ref("stock.action_picking_tree_all")
|
||||||
|
result = action.sudo().read()[0]
|
||||||
|
pickings = self.env["stock.picking"]
|
||||||
|
for line in self.rma_line_ids:
|
||||||
|
pickings |= line.move_ids.filtered(lambda m: m.is_rma_put_away).mapped(
|
||||||
|
"picking_id"
|
||||||
|
)
|
||||||
|
return self._view_shipments(result, pickings)
|
||||||
33
rma_repair_put_away/models/rma_order_line.py
Normal file
33
rma_repair_put_away/models/rma_order_line.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Copyright 2024 ForgeFlow S.L.
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
from odoo import models
|
||||||
|
|
||||||
|
|
||||||
|
class RmaOrderLine(models.Model):
|
||||||
|
_inherit = "rma.order.line"
|
||||||
|
|
||||||
|
def _compute_repair_transfer_count(self):
|
||||||
|
for line in self:
|
||||||
|
pickings = line.move_ids.filtered(lambda m: m.is_rma_put_away).mapped(
|
||||||
|
"picking_id"
|
||||||
|
)
|
||||||
|
line.repair_transfer_count = len(pickings)
|
||||||
|
|
||||||
|
def action_view_repair_transfers(self):
|
||||||
|
super().action_view_repair_transfers()
|
||||||
|
action = self.env.ref("stock.action_picking_tree_all")
|
||||||
|
result = action.sudo().read()[0]
|
||||||
|
pickings = self.env["stock.picking"]
|
||||||
|
for line in self:
|
||||||
|
pickings |= line.move_ids.filtered(lambda m: m.is_rma_put_away).mapped(
|
||||||
|
"picking_id"
|
||||||
|
)
|
||||||
|
# choose the view_mode accordingly
|
||||||
|
if len(pickings) != 1:
|
||||||
|
result["domain"] = "[('id', 'in', " + str(pickings.ids) + ")]"
|
||||||
|
elif len(pickings) == 1:
|
||||||
|
res = self.env.ref("stock.view_picking_form", False)
|
||||||
|
result["views"] = [(res and res.id or False, "form")]
|
||||||
|
result["res_id"] = pickings.ids[0]
|
||||||
|
return result
|
||||||
1
rma_repair_put_away/tests/__init__.py
Normal file
1
rma_repair_put_away/tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import test_rma_repair_put_away
|
||||||
144
rma_repair_put_away/tests/test_rma_repair_put_away.py
Normal file
144
rma_repair_put_away/tests/test_rma_repair_put_away.py
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
# Copyright 2024 ForgeFlow S.L.
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
from odoo.tests import common
|
||||||
|
|
||||||
|
|
||||||
|
class TestRmaRepairPutAway(common.SingleTransactionCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super(TestRmaRepairPutAway, cls).setUpClass()
|
||||||
|
|
||||||
|
cls.rma_obj = cls.env["rma.order"]
|
||||||
|
cls.rma_make_picking = cls.env["rma_make_picking.wizard"]
|
||||||
|
cls.rma_line_obj = cls.env["rma.order.line"]
|
||||||
|
cls.rma_op_obj = cls.env["rma.operation"]
|
||||||
|
cls.rma_make_put_away_wiz = cls.env["rma_make_put_away.wizard"]
|
||||||
|
cls.product_obj = cls.env["product.product"]
|
||||||
|
cls.partner_obj = cls.env["res.partner"]
|
||||||
|
|
||||||
|
cls.rma_route_cust = cls.env.ref("rma.route_rma_customer")
|
||||||
|
cls.cust_loc = cls.env.ref("stock.stock_location_customers")
|
||||||
|
|
||||||
|
# Create customer
|
||||||
|
cls.customer1 = cls.partner_obj.create({"name": "Customer 1"})
|
||||||
|
|
||||||
|
# Create products
|
||||||
|
cls.product_1 = cls.product_obj.create(
|
||||||
|
{"name": "Test Product 1", "type": "product", "list_price": 100.0}
|
||||||
|
)
|
||||||
|
cls.product_2 = cls.product_obj.create(
|
||||||
|
{
|
||||||
|
"name": "Test Product 2",
|
||||||
|
"type": "product",
|
||||||
|
"list_price": 150.0,
|
||||||
|
"tracking": "lot",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
cls.lot = cls.env["stock.lot"].create(
|
||||||
|
{
|
||||||
|
"name": "Lot for tests",
|
||||||
|
"product_id": cls.product_2.id,
|
||||||
|
"company_id": cls.env.ref("base.main_company").id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
cls.wh = cls.env.ref("stock.warehouse0")
|
||||||
|
cls.stock_rma_location = cls.wh.lot_rma_id
|
||||||
|
|
||||||
|
cls.put_away_loc = cls.env["stock.location"].create(
|
||||||
|
{
|
||||||
|
"name": "WH Repair Location",
|
||||||
|
"location_id": cls.wh.view_location_id.id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
# define the push rule for the putaway
|
||||||
|
cls.repair_route = cls.env["stock.route"].create(
|
||||||
|
{
|
||||||
|
"name": "Transfer RMA to Repair",
|
||||||
|
"rma_selectable": True,
|
||||||
|
"sequence": 10,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
cls.env["stock.rule"].create(
|
||||||
|
{
|
||||||
|
"name": "Transfer",
|
||||||
|
"route_id": cls.repair_route.id,
|
||||||
|
"location_src_id": cls.stock_rma_location.id,
|
||||||
|
"location_dest_id": cls.put_away_loc.id,
|
||||||
|
"action": "pull",
|
||||||
|
"picking_type_id": cls.wh.int_type_id.id,
|
||||||
|
"warehouse_id": cls.wh.id,
|
||||||
|
"procure_method": "make_to_stock",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
cls.rma_group = cls.rma_obj.create({"partner_id": cls.customer1.id})
|
||||||
|
|
||||||
|
cls.operation_1 = cls.rma_op_obj.create(
|
||||||
|
{
|
||||||
|
"code": "TEST",
|
||||||
|
"name": "Repair afer receive",
|
||||||
|
"type": "customer",
|
||||||
|
"receipt_policy": "ordered",
|
||||||
|
"repair_type": "received",
|
||||||
|
"put_away_policy": "received",
|
||||||
|
"in_route_id": cls.rma_route_cust.id,
|
||||||
|
"out_route_id": cls.rma_route_cust.id,
|
||||||
|
"repair_location_id": cls.stock_rma_location.id,
|
||||||
|
"repair_route_id": cls.repair_route.id,
|
||||||
|
"put_away_route_id": cls.repair_route.id,
|
||||||
|
"put_away_location_id": cls.put_away_loc.id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_01_rma_repair_put_away(self):
|
||||||
|
"""Check the putaway repair transfers are seen and counted
|
||||||
|
in the RMA"""
|
||||||
|
rma = self.rma_line_obj.create(
|
||||||
|
{
|
||||||
|
"partner_id": self.customer1.id,
|
||||||
|
"product_id": self.product_1.id,
|
||||||
|
"operation_id": self.operation_1.id,
|
||||||
|
"uom_id": self.product_1.uom_id.id,
|
||||||
|
"in_route_id": self.operation_1.in_route_id.id,
|
||||||
|
"out_route_id": self.operation_1.out_route_id.id,
|
||||||
|
"in_warehouse_id": self.operation_1.in_warehouse_id.id,
|
||||||
|
"out_warehouse_id": self.operation_1.out_warehouse_id.id,
|
||||||
|
"location_id": self.stock_rma_location.id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
rma._onchange_operation_id()
|
||||||
|
rma.action_rma_to_approve()
|
||||||
|
wizard = self.rma_make_picking.with_context(
|
||||||
|
**{
|
||||||
|
"active_ids": rma.id,
|
||||||
|
"active_model": "rma.order.line",
|
||||||
|
"picking_type": "incoming",
|
||||||
|
"active_id": 1,
|
||||||
|
}
|
||||||
|
).create({})
|
||||||
|
wizard._create_picking()
|
||||||
|
wizard = self.rma_make_put_away_wiz.with_context(
|
||||||
|
**{
|
||||||
|
"active_ids": rma.id,
|
||||||
|
"active_model": "rma.order.line",
|
||||||
|
"item_ids": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
"line_id": rma.id,
|
||||||
|
"product_id": rma.product_id.id,
|
||||||
|
"product_qty": rma.product_qty,
|
||||||
|
"location_id": self.put_away_loc.id,
|
||||||
|
"qty_to_put_away": rma.qty_to_put_away,
|
||||||
|
"uom_id": rma.uom_id.id,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
).create({})
|
||||||
|
action = wizard.action_create_put_away()
|
||||||
|
picking_id = action["res_id"]
|
||||||
|
action_view_repair = rma.action_view_repair_transfers()
|
||||||
|
self.assertEqual(action_view_repair["res_id"], picking_id)
|
||||||
|
self.assertEqual(rma.repair_transfer_count, 1)
|
||||||
1
rma_repair_put_away/wizards/__init__.py
Normal file
1
rma_repair_put_away/wizards/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import rma_order_line_make_repair
|
||||||
14
rma_repair_put_away/wizards/rma_order_line_make_repair.py
Normal file
14
rma_repair_put_away/wizards/rma_order_line_make_repair.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Copyright 2024 ForgeFlow S.L.
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
from odoo import models
|
||||||
|
|
||||||
|
|
||||||
|
class RmaLineMakeRepair(models.TransientModel):
|
||||||
|
_inherit = "rma.order.line.make.repair"
|
||||||
|
|
||||||
|
def create_repair_procurement_condition_applies(self, rma_line, repair):
|
||||||
|
res = super().create_repair_procurement_condition_applies(rma_line, repair)
|
||||||
|
if rma_line.operation_id.put_away_location_id:
|
||||||
|
return rma_line.operation_id.put_away_location_id != repair.location_id
|
||||||
|
return res
|
||||||
1
setup/rma_repair_put_away/odoo/addons/rma_repair_put_away
Symbolic link
1
setup/rma_repair_put_away/odoo/addons/rma_repair_put_away
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../../../rma_repair_put_away
|
||||||
6
setup/rma_repair_put_away/setup.py
Normal file
6
setup/rma_repair_put_away/setup.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import setuptools
|
||||||
|
|
||||||
|
setuptools.setup(
|
||||||
|
setup_requires=['setuptools-odoo'],
|
||||||
|
odoo_addon=True,
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user