Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
9e9ab7f
add rma_repair
JordiBForgeFlow Sep 19, 2017
fb2ef9e
[9.0][FIX] rma_repair
LoisRForgeFlow Sep 19, 2017
43a9042
[9.0][IMP] rma_repair: change default sequence for repairs.
LoisRForgeFlow Sep 20, 2017
d4572d0
[9.0][FIX] rma_repair: issue with memory autovacuum.
LoisRForgeFlow Oct 24, 2017
d338b84
pylint
LoisRForgeFlow Oct 30, 2017
9827ece
[9.0][REW] rma_repair: adapt
LoisRForgeFlow Oct 20, 2017
4809b7d
fix invoice address
LoisRForgeFlow Oct 20, 2017
76c4bc9
[9.0] add under_warranty field
LoisRForgeFlow Oct 25, 2017
58ec671
set not ported modules to not installable
AaronHForgeFlow Dec 21, 2017
5348031
[IMP] Improved Unit Test Case and Fixed Travis
nikul-serpentcs Nov 10, 2017
dd6fdb7
[11.0][MIG] rma_repair (#55)
AdriaGForgeFlow Nov 26, 2018
e541676
[MIG] rma_repair: Migration to 12.0
grindtildeath Mar 12, 2019
5e41903
[FIX] bring Lot/Serial,Delivery Address and Invoicing Address when cr…
May 24, 2019
33a6f01
[SET] Correct website URL for RMA modules
May 24, 2019
fd21703
[IMP]delivery_policy based on repair quantities
AaronHForgeFlow Jul 11, 2019
5dc3f7f
[FIX] default_gets: avoid using shadowname 'fields'
MiquelRForgeFlow Nov 29, 2019
2d75795
[ENH]qty under repair on rma
AaronHForgeFlow Sep 19, 2019
f5c3a2d
[IMP] : black, isort
AaronHForgeFlow Mar 19, 2020
91e7470
[MIG]rma_repair to v13
AaronHForgeFlow Mar 19, 2020
2b423dc
[UPT]allow to deliver rmas after repair even when not paid
AaronHForgeFlow Apr 6, 2020
3aa9f88
[IMP] black, isort, prettier
AaronHForgeFlow Dec 23, 2020
7d0d8bc
[IMP] rma_repair: black, isort, prettier
MateuGForgeFlow Jan 27, 2021
afe20e5
[MIG] rma_repair: Migration to 14.0
MateuGForgeFlow Jan 27, 2021
ea9a12d
[MIG] rma_repair: Migration to 14.0
MateuGForgeFlow Mar 12, 2021
133dda3
[14.0][FIX] rma_repair:
LoisRForgeFlow Mar 25, 2021
ebdd616
[TEMP] rma_repair: regression upstream.
LoisRForgeFlow Mar 26, 2021
b25904e
[FIX] rma_repair: under_warranty cannot be editable as it is only
LoisRForgeFlow Mar 26, 2021
5f110e1
[IMP] rma_repair: adapt to simplification on rma.line form view.
LoisRForgeFlow Mar 26, 2021
c69c929
Revert "[TEMP] rma_repair: regression upstream."
LoisRForgeFlow Apr 6, 2021
47226b2
[14.0][MIG] rma*: ir.actions.act_window has different access
LoisRForgeFlow Apr 16, 2021
d2fec10
Fix Pre-commit Websites
MateuGForgeFlow Oct 6, 2021
9c735a5
[MIG] rma_repair: Migration to 15.0
JasminSForgeFlow Jan 10, 2022
0357db2
[FIX] rma_repair: re-license to AGPL due to dependency to repair_refu…
AaronHForgeFlow Apr 22, 2022
cb02d7c
[FIX] rma_repair: repair policy not being updated from rma group
LoisRForgeFlow May 13, 2022
28dc2d9
[FIX] rma_repair: fix author in manifest
LoisRForgeFlow Nov 7, 2022
b07c3f4
[IMP] rma_repair: Add the possibility to indicate a default location
JordiBForgeFlow Jun 27, 2022
371790b
[ADD] rma_repair_refurbish: split refurbish dependency from rma_repair
JordiBForgeFlow Aug 4, 2022
38ec491
[IMP] rma_repair: adapt to changes in supplier rma group form view.
LoisRForgeFlow Jan 2, 2023
6cb07cd
[IMP] rma_repair: button cancel
DavidJForgeFlow Feb 15, 2023
2e590c3
[MIG] rma_repair: Migration to 16.0
DavidJForgeFlow Feb 24, 2023
6faed21
[FIX] rma_repair: repair_stock_move conflict
DavidJForgeFlow Mar 9, 2023
8890466
[IMP] rma_repair: create transfer from RMA to Repair location
DavidJForgeFlow Mar 20, 2023
feb8797
[FIX] rma_repair: fix duplicate procurement
JordiBForgeFlow Jul 8, 2023
4ac3377
[FIX] rma_repair: repair_transfer_count compute assigning to wring field
AaronHForgeFlow Oct 30, 2023
758aec7
[ADD] rma_repair_put_away: glue module between rma_repair & rma_put_away
AaronHForgeFlow Aug 1, 2024
d709c96
[IMP] rma_repair: black, isort, prettier
JasminSForgeFlow Jan 7, 2025
e28787d
[MIG] rma_repair: Migration to 17.0
JasminSForgeFlow Jan 8, 2025
780a04b
[FIX] rma_repair: change invisible for column_invisible in tree views…
DavidJForgeFlow Feb 20, 2025
e937ef7
[14.0][IMP] rma_repair: hide buttons if count is 0
MeritxellAForgeFlow Feb 24, 2025
d9cfadf
[IMP] rma_repair: black, isort, prettier
JasminSForgeFlow May 7, 2025
b65c1da
[MIG] rma_repair: Migration to 18.0
JasminSForgeFlow May 7, 2025
0fbf5e4
[18.0][FIX] rma_repair
chafique-delli Jul 24, 2025
6dab4b5
[MIG] rma_repair: Migration to v19
AaronHForgeFlow Nov 18, 2025
d7b06f9
[IMP] rma_repair: manage RMA repair logistics using picking types, li…
AaronHForgeFlow Nov 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions rma_repair/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License AGPL-3

==========
RMA Repair
==========

This module allows you to create repairs from one or more RMA lines.

Installation
============

This module depends on ``repair_refurbish`` which is available at
`OCA/manufacture <https://github.com/OCA/manufacture>`_.

Usage
=====

To create repairs from RMA lines:

#. Go to an approved RMA.
#. Click on *Create Repair Order*.
#. Fill the required information in the lines.
#. Hit *Create Repair Orders*.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues
<https://github.com/Eficent/stock-rma/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed feedback.

Credits
=======

Contributors
------------

* Jordi Ballester Alomar <jordi.ballester@eficent.com>
* Aaron Henriquez <ahenriquez@eficent.com>
* Lois Rilo <lois.rilo@eficent.com>
* Akim Juillerat <akim.juillerat@camptocamp.com>
* Bhavesh Odedra <bodedra@opensourceintegrators.com>

Maintainer
----------

This module is maintained by Eficent
5 changes: 5 additions & 0 deletions rma_repair/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright 2020 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from . import models
from . import wizards
21 changes: 21 additions & 0 deletions rma_repair/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2020 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "RMA Repair",
"version": "19.0.1.0.0",
"license": "AGPL-3",
"category": "RMA",
"summary": "Links RMA with Repairs.",
"author": "ForgeFlow",
"website": "https://github.com/ForgeFlow",
"depends": ["rma_account", "repair"],
"data": [
"security/ir.model.access.csv",
"views/rma_order_view.xml",
"views/rma_operation_view.xml",
"views/repair_view.xml",
"wizards/rma_order_line_make_repair_view.xml",
"views/rma_order_line_view.xml",
],
"installable": True,
}
8 changes: 8 additions & 0 deletions rma_repair/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)

from . import repair
from . import rma_order_line
from . import rma_order
from . import rma_operation
from . import stock_move
from . import stock_rule
15 changes: 15 additions & 0 deletions rma_repair/models/repair.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2020-21 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import fields, models


class RepairOrder(models.Model):
_inherit = "repair.order"

rma_line_id = fields.Many2one(
comodel_name="rma.order.line", string="RMA", ondelete="restrict"
)
under_warranty = fields.Boolean(
related="rma_line_id.under_warranty",
)
32 changes: 32 additions & 0 deletions rma_repair/models/rma_operation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2020 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import fields, models


class RmaOperation(models.Model):
_inherit = "rma.operation"

repair_type = fields.Selection(
[
("no", "Not required"),
("ordered", "Based on Ordered Quantities"),
("received", "Based on Received Quantities"),
],
string="Repair Policy",
default="no",
)
delivery_policy = fields.Selection(
selection_add=[("repair", "Based on Repair Quantities")]
)
repair_route_id = fields.Many2one(
comodel_name="stock.route",
string="Repair Route",
domain=[("rma_selectable", "=", True)],
)
repair_picking_type_id = fields.Many2one(
comodel_name="stock.picking.type",
string="Repair Picking Type",
domain="[('code', '=', 'repair_operation')]",
required=True,
)
48 changes: 48 additions & 0 deletions rma_repair/models/rma_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2020 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import fields, models


class RmaOrder(models.Model):
_inherit = "rma.order"

def _compute_repair_count(self):
for rma in self:
repairs = rma.mapped("rma_line_ids.repair_ids")
rma.repair_count = len(repairs)

def _compute_repair_transfer_count(self):
for order in self:
pickings = (
order.mapped("rma_line_ids.move_ids")
.filtered(lambda m: m.is_rma_repair_transfer)
.mapped("picking_id")
)
order.repair_transfer_count = len(pickings)

repair_count = fields.Integer(
compute="_compute_repair_count", string="# of Repairs"
)

repair_transfer_count = fields.Integer(
compute="_compute_repair_transfer_count", string="# Repair Transfers"
)

def action_view_repair_order(self):
action = self.env.ref("repair.action_repair_order_tree")
result = action.sudo().read()[0]
repair_ids = self.mapped("rma_line_ids.repair_ids").ids
result["domain"] = [("id", "in", repair_ids)]
return result

def action_view_repair_transfers(self):
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_repair_transfer
).mapped("picking_id")
return self._view_shipments(result, pickings)
178 changes: 178 additions & 0 deletions rma_repair/models/rma_order_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Copyright 2020-21 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import api, fields, models


class RmaOrderLine(models.Model):
_inherit = "rma.order.line"

@api.depends("repair_ids", "repair_type", "repair_ids.state", "qty_to_receive")
def _compute_qty_to_repair(self):
for line in self:
if line.repair_type == "no":
line.qty_to_repair = 0.0
elif line.repair_type == "ordered":
qty = line._get_rma_repaired_qty() + line._get_rma_under_repair_qty()
line.qty_to_repair = max(line.product_qty - qty, 0)
elif line.repair_type == "received":
qty = line._get_rma_repaired_qty() + line._get_rma_under_repair_qty()
line.qty_to_repair = max(line.qty_received - qty, 0)
else:
line.qty_to_repair = 0.0

@api.depends("repair_ids", "repair_type", "repair_ids.state", "qty_to_receive")
def _compute_qty_repaired(self):
for line in self:
line.qty_repaired = line._get_rma_repaired_qty()

@api.depends("repair_ids", "repair_type", "repair_ids.state", "qty_to_receive")
def _compute_qty_under_repair(self):
for line in self:
line.qty_under_repair = line._get_rma_under_repair_qty()

@api.depends("repair_ids")
def _compute_repair_count(self):
for line in self:
line.repair_count = len(line.repair_ids)

def _compute_repair_transfer_count(self):
for line in self:
pickings = line.move_ids.filtered(
lambda m: m.is_rma_repair_transfer
).mapped("picking_id")
line.repair_transfer_count = len(pickings)

repair_ids = fields.One2many(
comodel_name="repair.order",
inverse_name="rma_line_id",
string="Repair Orders",
readonly=True,
copy=False,
)
qty_to_repair = fields.Float(
copy=False,
digits="Product Unit of Measure",
readonly=True,
compute="_compute_qty_to_repair",
store=True,
)
qty_under_repair = fields.Float(
copy=False,
digits="Product Unit of Measure",
readonly=True,
compute="_compute_qty_under_repair",
store=True,
)
qty_repaired = fields.Float(
copy=False,
digits="Product Unit of Measure",
readonly=True,
compute="_compute_qty_repaired",
store=True,
help="Quantity repaired or being repaired.",
)
repair_type = fields.Selection(
selection=[
("no", "Not required"),
("ordered", "Based on Ordered Quantities"),
("received", "Based on Received Quantities"),
],
string="Repair Policy",
default="no",
required=True,
)
repair_count = fields.Integer(
compute="_compute_repair_count", string="# of Repairs"
)

repair_transfer_count = fields.Integer(
compute="_compute_repair_transfer_count", string="# of Repair Transfers"
)

delivery_policy = fields.Selection(
selection_add=[("repair", "Based on Repair Quantities")],
ondelete={"repair": lambda recs: recs.write({"delivery_policy": "no"})},
)

def action_view_repair_order(self):
action = self.env.ref("repair.action_repair_order_tree")
result = action.sudo().read()[0]
repair_ids = self.repair_ids.ids
if len(repair_ids) != 1:
result["domain"] = [("id", "in", repair_ids)]
elif len(repair_ids) == 1:
res = self.env.ref("repair.view_repair_order_form", False)
result["views"] = [(res and res.id or False, "form")]
result["res_id"] = repair_ids[0]
return result

def action_rma_cancel(self):
res = super().action_rma_cancel()
for line in self:
line.repair_ids.action_repair_cancel()
return res

def _get_rma_repaired_qty(self):
self.ensure_one()
qty = 0.0
for repair in self.repair_ids.filtered(lambda p: p.state == "done"):
repair_qty = self.uom_id._compute_quantity(
repair.product_qty, repair.product_uom
)
qty += repair_qty
return qty

def _get_rma_under_repair_qty(self):
self.ensure_one()
qty = 0.0
for repair in self.repair_ids.filtered(
lambda p: p.state not in ("cancel", "done")
):
repair_qty = self.uom_id._compute_quantity(
repair.product_qty, repair.product_uom
)
qty += repair_qty
return qty

@api.onchange("operation_id")
def _onchange_operation_id(self):
result = super()._onchange_operation_id()
if self.operation_id:
self.repair_type = self.operation_id.repair_type or "no"
return result

@api.depends(
"move_ids",
"move_ids.state",
"delivery_policy",
"product_qty",
"type",
"qty_delivered",
"qty_received",
"repair_ids",
"repair_type",
"repair_ids.state",
)
def _compute_qty_to_deliver(self):
res = super()._compute_qty_to_deliver()
for rec in self.filtered(lambda line: line.delivery_policy == "repair"):
rec.qty_to_deliver = rec.qty_repaired - rec.qty_delivered
return res

def action_view_repair_transfers(self):
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_repair_transfer
).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
19 changes: 19 additions & 0 deletions rma_repair/models/stock_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2022 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)

from odoo import fields, models


class StockMove(models.Model):
_inherit = "stock.move"

is_rma_repair_transfer = fields.Boolean(
string="Is RMA Repair",
help="This Stock Move has been created from a Repair operation in the RMA.",
)

def _is_in_out_rma_move(self, op, states, location_type):
res = super()._is_in_out_rma_move(op, states, location_type)
if self.is_rma_repair_transfer:
return False
return res
Loading
Loading