Skip to content

Commit 0527711

Browse files
committed
[ADD] repair_stock_consumption_step
In the base repair module, consumption moves for spare parts are created and immediately validated when the repair order is marked as done. This prevents user interaction such as choosing lot/serial numbers. This module introduces an optional intermediate step: - When enabled at warehouse level, repair consumption moves are grouped into a stock picking. - The repair order is set to a new **Consumption** state until the picking is validated. - Users can process the picking manually, assign lots/serials, and only then complete the repair.
1 parent eb67345 commit 0527711

21 files changed

Lines changed: 972 additions & 0 deletions
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
=============================
2+
Repair Stock Consumption Step
3+
=============================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:93fc83002290646de5793f5425fca96699172ab4f9487b4196a3e8481bbaead6
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Frepair-lightgray.png?logo=github
20+
:target: https://github.com/OCA/repair/tree/16.0/repair_stock_consumption_step
21+
:alt: OCA/repair
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/repair-16-0/repair-16-0-repair_stock_consumption_step
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/repair&target_branch=16.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
This module introduces an optional intermediate step:
32+
33+
- When enabled at warehouse level, repair consumption moves are grouped
34+
into a stock picking.
35+
- The repair order is set to a new **Consumption** state until the
36+
picking is validated.
37+
- Users can process the picking manually, assign lots/serials, and only
38+
then complete the repair.
39+
40+
**Table of contents**
41+
42+
.. contents::
43+
:local:
44+
45+
Use Cases / Context
46+
===================
47+
48+
In the base repair module, consumption moves for spare parts are created
49+
and immediately validated when the repair order is marked as done. This
50+
prevents user interaction such as choosing lot/serial numbers.
51+
52+
Configuration
53+
=============
54+
55+
1. Go to **Inventory / Configuration / Warehouses**.
56+
57+
2. Open the warehouse you want to use for repairs.
58+
59+
3.
60+
61+
2. In **Technical info** :
62+
63+
- Enable **Repair Consumption Step**.
64+
- Select the **Repair Consumption Picking Type** (an internal
65+
transfer type from the repair location to a production/virtual
66+
location).
67+
68+
Usage
69+
=====
70+
71+
1. Create a repair order with spare part lines.
72+
2. Confirm the repair order.
73+
3. Click **End Repair**:
74+
75+
- If the warehouse setting is disabled:
76+
77+
- Consumption moves are validated immediately, repair goes
78+
directly to **Done**.
79+
80+
- If the setting is enabled:
81+
82+
- The repair order moves to the **Consumption** state.
83+
- A stock picking is created for the spare part moves.
84+
85+
4. Open the **Consumption Picking** from the repair order.
86+
5. Process the picking:
87+
88+
- Assign quantities and lots/serials.
89+
- Validate the picking.
90+
91+
6. Once the picking is validated, the repair order automatically moves
92+
to **Done**.
93+
94+
Bug Tracker
95+
===========
96+
97+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/repair/issues>`_.
98+
In case of trouble, please check there if your issue has already been reported.
99+
If you spotted it first, help us to smash it by providing a detailed and welcomed
100+
`feedback <https://github.com/OCA/repair/issues/new?body=module:%20repair_stock_consumption_step%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
101+
102+
Do not contact contributors directly about support or help with technical issues.
103+
104+
Credits
105+
=======
106+
107+
Authors
108+
-------
109+
110+
* ACSONE SA/NV
111+
112+
Contributors
113+
------------
114+
115+
- Souheil Bejaoui souheil.bejaoui@acsone.eu
116+
117+
Maintainers
118+
-----------
119+
120+
This module is maintained by the OCA.
121+
122+
.. image:: https://odoo-community.org/logo.png
123+
:alt: Odoo Community Association
124+
:target: https://odoo-community.org
125+
126+
OCA, or the Odoo Community Association, is a nonprofit organization whose
127+
mission is to support the collaborative development of Odoo features and
128+
promote its widespread use.
129+
130+
.. |maintainer-sbejaoui| image:: https://github.com/sbejaoui.png?size=40px
131+
:target: https://github.com/sbejaoui
132+
:alt: sbejaoui
133+
134+
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
135+
136+
|maintainer-sbejaoui|
137+
138+
This module is part of the `OCA/repair <https://github.com/OCA/repair/tree/16.0/repair_stock_consumption_step>`_ project on GitHub.
139+
140+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright 2025 ACSONE SA/NV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
{
5+
"name": "Repair Stock Consumption Step",
6+
"summary": """Adds a warehouse-configurable step to process repair consumption
7+
moves in a picking""",
8+
"version": "16.0.1.0.0",
9+
"license": "AGPL-3",
10+
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
11+
"website": "https://github.com/OCA/repair",
12+
"maintainers": ["sbejaoui"],
13+
"depends": ["repair"],
14+
"data": ["views/repair_order.xml", "views/stock_warehouse.xml"],
15+
"demo": [],
16+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from . import stock_warehouse
2+
from . import repair_order
3+
from . import stock_move
4+
from . import stock_picking
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Copyright 2025 ACSONE SA/NV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from odoo import fields, models
5+
6+
7+
class RepairOrder(models.Model):
8+
9+
_inherit = "repair.order"
10+
11+
consumption_picking_id = fields.Many2one(
12+
"stock.picking", string="Consumption Picking", readonly=True, copy=False
13+
)
14+
warehouse_id = fields.Many2one(
15+
"stock.warehouse", related="location_id.warehouse_id"
16+
)
17+
repair_consumption_step = fields.Boolean(
18+
related="warehouse_id.repair_consumption_step"
19+
)
20+
state = fields.Selection(
21+
selection_add=[("consumption", "Waiting Consumption")],
22+
ondelete={"consumption": "set done"},
23+
)
24+
25+
def action_view_consumption_picking(self):
26+
self.ensure_one()
27+
return {
28+
"name": "Repair Consumption Picking",
29+
"type": "ir.actions.act_window",
30+
"res_model": "stock.picking",
31+
"view_mode": "form",
32+
"res_id": self.consumption_picking_id.id,
33+
}
34+
35+
def action_repair_done(self):
36+
need_consumption_step = self.filtered("repair_consumption_step")
37+
res = super(RepairOrder, self - need_consumption_step).action_repair_done()
38+
for rec in need_consumption_step:
39+
rec_res = super(
40+
RepairOrder, rec.with_context(dont_validate_repair_move=True)
41+
).action_repair_done()
42+
res.update(rec_res)
43+
moves = self.env["stock.move"].search([("repair_id", "=", rec.id)])
44+
if not moves:
45+
continue
46+
picking = self.env["stock.picking"].create(
47+
{
48+
"picking_type_id": rec.warehouse_id.repair_consumption_picking_type_id.id,
49+
"origin": rec.name,
50+
"location_id": moves[0].location_id.id,
51+
"location_dest_id": moves[0].location_dest_id.id,
52+
}
53+
)
54+
moves.write({"picking_id": picking.id})
55+
moves._action_confirm()
56+
moves._action_assign()
57+
rec.consumption_picking_id = picking
58+
rec.state = "consumption"
59+
return res
60+
61+
def action_repair_end(self):
62+
super().action_repair_end()
63+
need_consumption_step = self.filtered("consumption_picking_id")
64+
need_consumption_step.state = "consumption"
65+
return True
66+
67+
def _action_consumption_done(self):
68+
for rec in self:
69+
state = "done"
70+
if not rec.invoice_id and rec.invoice_method == "after_repair":
71+
state = "2binvoiced"
72+
rec.state = state
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2025 ACSONE SA/NV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from odoo import models
5+
6+
7+
class StockMove(models.Model):
8+
9+
_inherit = "stock.move"
10+
11+
def _action_done(self, cancel_backorder=False):
12+
repair_moves = self.browse()
13+
if self.env.context.get("dont_validate_repair_move"):
14+
repair_moves = self.filtered("repair_id")
15+
16+
return super(StockMove, self - repair_moves)._action_done(
17+
cancel_backorder=cancel_backorder
18+
)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2025 ACSONE SA/NV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from odoo import models
5+
6+
7+
class StockPicking(models.Model):
8+
9+
_inherit = "stock.picking"
10+
11+
def _action_done(self):
12+
res = super()._action_done()
13+
done_pickings = self.filtered(lambda p: p.state == "done")
14+
repair_orders = self.env["repair.order"].search(
15+
[
16+
("state", "=", "consumption"),
17+
("consumption_picking_id", "in", done_pickings.ids),
18+
]
19+
)
20+
repair_orders._action_consumption_done()
21+
return res
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2025 ACSONE SA/NV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from odoo import fields, models
5+
6+
7+
class StockWarehouse(models.Model):
8+
9+
_inherit = "stock.warehouse"
10+
11+
repair_consumption_step = fields.Boolean(
12+
string="Enable Repair Consumption Step",
13+
help="If enabled, consumption moves from repairs will be grouped "
14+
"in a picking instead of being directly validated.",
15+
)
16+
repair_consumption_picking_type_id = fields.Many2one(
17+
"stock.picking.type",
18+
string="Repair Consumption Picking Type",
19+
domain="[('code','=','internal'), ('warehouse_id','=', id)]",
20+
help="Picking type used for repair consumption moves when the extra step is enabled.",
21+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
1. Go to **Inventory / Configuration / Warehouses**.
2+
2. Open the warehouse you want to use for repairs.
3+
3. 2. In **Technical info** :
4+
- Enable **Repair Consumption Step**.
5+
- Select the **Repair Consumption Picking Type** (an internal transfer type from the repair location to a production/virtual location).
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
In the base repair module, consumption moves for spare parts are
2+
created and immediately validated when the repair order is marked as done.
3+
This prevents user interaction such as choosing lot/serial numbers.

0 commit comments

Comments
 (0)