Skip to content

Commit e822aa4

Browse files
committed
[16.0][ADD] repair_preparation
1 parent eb67345 commit e822aa4

20 files changed

Lines changed: 1296 additions & 0 deletions

repair_preparation/README.rst

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
==================
2+
Repair Preparation
3+
==================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:b0bd07927e226fef44773f9c6e5e143ad34e65a9b69ff53deba5485ef9469399
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_preparation
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_preparation
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+
The repair module consumes spare parts at the end of the repair without
32+
considering the quantity reservation. the more natural flow is to have a
33+
**staging step** to bring and reserve parts **before** the repair
34+
begins, improving planning and reducing delays at the workbench.
35+
36+
This addon introduces a **Preparation** flow:
37+
38+
- On **Confirm** (validate) of the repair, a procurement is run
39+
procurement for all eligible **Add** lines
40+
- When a repair line is **created/edited** while the repair is *Under
41+
Repair*:
42+
43+
- If any linked move is **Done** → editing raises a validation error
44+
- Otherwise, linked moves are **canceled** and procurement is
45+
**re-run** for the updated lines
46+
47+
- **Finishing** a repair is blocked if:
48+
49+
- There are consumed lines but **no preparation pickings**, or
50+
- Preparation pickings exist but are **not done**.
51+
52+
**Table of contents**
53+
54+
.. contents::
55+
:local:
56+
57+
Configuration
58+
=============
59+
60+
1) Create a Preparation location
61+
--------------------------------
62+
63+
1. Go to **Inventory / Configuration / Locations**
64+
2. Create an **Internal** location (e.g. **WH/Preparation**)
65+
66+
2) Create a Preparation operation type
67+
--------------------------------------
68+
69+
1. Go to **Inventory / Configuration / Operation Types**
70+
2. Create a picking type named **Repair Preparation**
71+
3. Set:
72+
73+
- **Default Source Location** = *Your Warehouse/Stock*
74+
- **Default Destination Location** = *Your Warehouse/Preparation*
75+
76+
3) Route & Rule (Stock → Preparation)
77+
-------------------------------------
78+
79+
1. Go to **Inventory / Configuration / Routes** and create **Route to
80+
Preparation**
81+
2. Enable **Selectable on warehouse**
82+
3. Add a **Pull Rule**:
83+
84+
- **Action**: *Pull From*
85+
- **Operation Type**: *Preparation* (from step 2)
86+
- **Source Location**: *Your Warehouse/Stock*
87+
- **Destination Location**: *Your Warehouse/Preparation*
88+
- **Warehouse**: your warehouse
89+
90+
4) Warehouse settings (enable & default)
91+
----------------------------------------
92+
93+
1. Go to **Inventory / Configuration / Warehouses**, open your warehouse
94+
2. In **Technical info** tab, under **Repairs — Preparation**:
95+
96+
- Tick **Enable Repair Preparation**
97+
- Set **Default Preparation Operation Type** to the *Repair
98+
Preparation* picking type created earlier
99+
100+
..
101+
102+
You can enable/disable the feature per warehouse. The default picking
103+
type is used for new repairs governed by that warehouse and can still
104+
be overridden per repair.
105+
106+
Bug Tracker
107+
===========
108+
109+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/repair/issues>`_.
110+
In case of trouble, please check there if your issue has already been reported.
111+
If you spotted it first, help us to smash it by providing a detailed and welcomed
112+
`feedback <https://github.com/OCA/repair/issues/new?body=module:%20repair_preparation%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
113+
114+
Do not contact contributors directly about support or help with technical issues.
115+
116+
Credits
117+
=======
118+
119+
Authors
120+
-------
121+
122+
* ACSONE SA/NV
123+
124+
Contributors
125+
------------
126+
127+
- Souheil Bejaoui souheil.bejaoui@acsone.eu
128+
129+
Maintainers
130+
-----------
131+
132+
This module is maintained by the OCA.
133+
134+
.. image:: https://odoo-community.org/logo.png
135+
:alt: Odoo Community Association
136+
:target: https://odoo-community.org
137+
138+
OCA, or the Odoo Community Association, is a nonprofit organization whose
139+
mission is to support the collaborative development of Odoo features and
140+
promote its widespread use.
141+
142+
.. |maintainer-sbejaoui| image:: https://github.com/sbejaoui.png?size=40px
143+
:target: https://github.com/sbejaoui
144+
:alt: sbejaoui
145+
146+
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
147+
148+
|maintainer-sbejaoui|
149+
150+
This module is part of the `OCA/repair <https://github.com/OCA/repair/tree/16.0/repair_preparation>`_ project on GitHub.
151+
152+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

repair_preparation/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models

repair_preparation/__manifest__.py

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+
{
5+
"name": "Repair Preparation",
6+
"summary": """Procure & prepare parts before starting repairs""",
7+
"version": "16.0.1.0.0",
8+
"license": "AGPL-3",
9+
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
10+
"website": "https://github.com/OCA/repair",
11+
"depends": ["repair"],
12+
"maintainers": ["sbejaoui"],
13+
"data": [
14+
"views/stock_warehouse.xml",
15+
"views/repair_order.xml",
16+
],
17+
"demo": [],
18+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from . import repair_order
2+
from . import stock_move
3+
from . import stock_rule
4+
from . import repair_line
5+
from . import stock_warehouse
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copyright 2025 ACSONE SA/NV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from odoo import _, api, fields, models
5+
from odoo.exceptions import ValidationError
6+
7+
8+
class RepairLine(models.Model):
9+
10+
_inherit = "repair.line"
11+
12+
preparation_move_ids = fields.One2many(
13+
comodel_name="stock.move",
14+
inverse_name="repair_line_id",
15+
)
16+
17+
@api.depends("type", "repair_id.location_id")
18+
def _compute_location_id(self):
19+
res = super()._compute_location_id()
20+
for rec in self:
21+
if rec.type == "add" and rec.repair_id.location_id:
22+
rec.location_id = rec.repair_id.location_id
23+
return res
24+
25+
@api.model_create_multi
26+
def create(self, vals_list):
27+
records = super().create(vals_list)
28+
for repair in records.repair_id:
29+
if repair.state != "under_repair":
30+
# we manage procurement auto-run when repair is started
31+
continue
32+
new_lines = records.filtered(lambda line, ro=repair: line.repair_id == ro)
33+
repair._run_preparation_procurements(new_lines)
34+
return records
35+
36+
def write(self, vals):
37+
res = super().write(vals)
38+
fields_affecting = {"type", "product_id", "product_uom_qty", "product_uom"}
39+
if all(_field not in vals for _field in fields_affecting):
40+
return res
41+
for repair in self.repair_id:
42+
43+
updated_lines = self.filtered(lambda line, ro=repair: line.repair_id == ro)
44+
if not updated_lines:
45+
continue
46+
moves = updated_lines.preparation_move_ids
47+
if moves.filtered(lambda m: m.state == "done"):
48+
raise ValidationError(
49+
_(
50+
"You cannot modify product/quantity for preparation lines "
51+
"because some linked moves are already done.\n"
52+
"Repair: %(repair)s\nLines: %(lines)s"
53+
)
54+
% {
55+
"repair": repair.display_name,
56+
"lines": ", ".join(updated_lines.mapped("display_name")),
57+
}
58+
)
59+
if repair.state != "under_repair":
60+
# we manage procurement auto-run when repair is started
61+
continue
62+
moves_to_cancel = moves.filtered(lambda m: m.state != "cancel")
63+
moves_to_cancel._action_cancel()
64+
repair._run_preparation_procurements(updated_lines)
65+
66+
return res

0 commit comments

Comments
 (0)