Skip to content

Commit e7fbf35

Browse files
[ADD] repair_sale_multi
1 parent 65cdfe0 commit e7fbf35

21 files changed

+988
-0
lines changed

repair_sale_multi/README.rst

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
=================
2+
Repair Sale Multi
3+
=================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:9307b36d8ef4b6fe2e8fe3a6d25c99a58b59d15f293577fef1bcfe0048c5e909
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Alpha
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/18.0/repair_sale_multi
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-18-0/repair-18-0-repair_sale_multi
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=18.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
This module extends the repair workflow introduced in Odoo 17 by
32+
providing tools to ease the transition to quotation-based invoicing. It
33+
allows users to create a single quotation from multiple repair orders.
34+
35+
.. IMPORTANT::
36+
This is an alpha version, the data model and design can change at any time without warning.
37+
Only for development or testing purpose, do not use in production.
38+
`More details on development status <https://odoo-community.org/page/development-status>`_
39+
40+
**Table of contents**
41+
42+
.. contents::
43+
:local:
44+
45+
Usage
46+
=====
47+
48+
From the repair order list view, select multiple repair orders and use
49+
the **"Create Quotation"** action to generate a new quotation.
50+
51+
Bug Tracker
52+
===========
53+
54+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/repair/issues>`_.
55+
In case of trouble, please check there if your issue has already been reported.
56+
If you spotted it first, help us to smash it by providing a detailed and welcomed
57+
`feedback <https://github.com/OCA/repair/issues/new?body=module:%20repair_sale_multi%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
58+
59+
Do not contact contributors directly about support or help with technical issues.
60+
61+
Credits
62+
=======
63+
64+
Authors
65+
-------
66+
67+
* ForgeFlow
68+
69+
Contributors
70+
------------
71+
72+
- `ForgeFlow <https://forgeflow.com>`__:
73+
74+
- Aaron Henriquez <aaron.henriquez@forgeflow.com>
75+
76+
Maintainers
77+
-----------
78+
79+
This module is maintained by the OCA.
80+
81+
.. image:: https://odoo-community.org/logo.png
82+
:alt: Odoo Community Association
83+
:target: https://odoo-community.org
84+
85+
OCA, or the Odoo Community Association, is a nonprofit organization whose
86+
mission is to support the collaborative development of Odoo features and
87+
promote its widespread use.
88+
89+
.. |maintainer-AaronHForgeFlow| image:: https://github.com/AaronHForgeFlow.png?size=40px
90+
:target: https://github.com/AaronHForgeFlow
91+
:alt: AaronHForgeFlow
92+
93+
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
94+
95+
|maintainer-AaronHForgeFlow|
96+
97+
This module is part of the `OCA/repair <https://github.com/OCA/repair/tree/18.0/repair_sale_multi>`_ project on GitHub.
98+
99+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

repair_sale_multi/__init__.py

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

repair_sale_multi/__manifest__.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Copyright 2025 ForgeFlow S.L.
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
3+
4+
{
5+
"name": "Repair Sale Multi",
6+
"version": "18.0.1.0.0",
7+
"author": "ForgeFlow, Odoo Community Association (OCA)",
8+
"website": "https://github.com/OCA/repair",
9+
"summary": "Repair Sale Multi",
10+
"category": "Repair",
11+
"depends": ["repair"],
12+
"data": [
13+
"security/ir.model.access.csv",
14+
"views/repair_order_views.xml",
15+
],
16+
"installable": True,
17+
"development_status": "Alpha",
18+
"license": "AGPL-3",
19+
"maintainers": ["AaronHForgeFlow"],
20+
}

repair_sale_multi/i18n/es_ES.po

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Translation of Odoo Server.
2+
# This file contains the translation of the following modules:
3+
# * repair_sale_multi
4+
#
5+
msgid ""
6+
msgstr ""
7+
"Project-Id-Version: Odoo Server 18.0+e\n"
8+
"Report-Msgid-Bugs-To: \n"
9+
"POT-Creation-Date: 2025-09-09 13:19+0000\n"
10+
"PO-Revision-Date: 2025-09-09 13:19+0000\n"
11+
"Last-Translator: \n"
12+
"Language-Team: \n"
13+
"Language: es_ES\n"
14+
"MIME-Version: 1.0\n"
15+
"Content-Type: text/plain; charset=UTF-8\n"
16+
"Content-Transfer-Encoding: 8bit\n"
17+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
18+
19+
#. module: repair_sale_multi
20+
#. odoo-python
21+
#: code:addons/repair_sale_multi/wizards/repair_create_sale_order_wizard.py:0
22+
msgid "All repair orders must belong to the same customer."
23+
msgstr "Todas las órdenes de reparación deben pertenecer al mismo cliente."
24+
25+
#. module: repair_sale_multi
26+
#. odoo-python
27+
#: code:addons/repair_sale_multi/models/repair_order.py:0
28+
msgid "All selected repair orders must have the same customer defined."
29+
msgstr "Todas las órdenes de reparación seleccionadas deben tener el mismo cliente definido."
30+
31+
#. module: repair_sale_multi
32+
#. odoo-python
33+
#: code:addons/repair_sale_multi/models/repair_order.py:0
34+
msgid "All selected repair orders must have the same picking type."
35+
msgstr "Todas las órdenes de reparación seleccionadas deben tener el mismo tipo de picking."
36+
37+
#. module: repair_sale_multi
38+
#: model:ir.actions.server,name:repair_sale_multi.action_create_sale_order_from_repairs
39+
msgid "Create Quotation"
40+
msgstr "Crear Presupuesto"
41+
42+
#. module: repair_sale_multi
43+
#: model:ir.model,name:repair_sale_multi.model_repair_create_sale_order_wizard
44+
msgid "Create Quotation from Repair Orders"
45+
msgstr "Crear Presupuesto desde Órdenes de Reparación"
46+
47+
#. module: repair_sale_multi
48+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__create_uid
49+
msgid "Created by"
50+
msgstr "Creado por"
51+
52+
#. module: repair_sale_multi
53+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__create_date
54+
msgid "Created on"
55+
msgstr "Creado el"
56+
57+
#. module: repair_sale_multi
58+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__display_name
59+
msgid "Display Name"
60+
msgstr "Nombre a Mostrar"
61+
62+
#. module: repair_sale_multi
63+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__id
64+
msgid "ID"
65+
msgstr "ID"
66+
67+
#. module: repair_sale_multi
68+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__write_uid
69+
msgid "Last Updated by"
70+
msgstr "Última Actualización por"
71+
72+
#. module: repair_sale_multi
73+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__write_date
74+
msgid "Last Updated on"
75+
msgstr "Última Actualización el"
76+
77+
#. module: repair_sale_multi
78+
#: model:ir.model,name:repair_sale_multi.model_repair_order
79+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__repair_order_ids
80+
#: model:ir.model.fields,field_description:repair_sale_multi.field_sale_order_line__repair_order_id
81+
msgid "Repair Order"
82+
msgstr "Orden de Reparación"
83+
84+
#. module: repair_sale_multi
85+
#: model:ir.model,name:repair_sale_multi.model_sale_order_line
86+
msgid "Sales Order Line"
87+
msgstr "Línea de Pedido de Venta"
88+
89+
#. module: repair_sale_multi
90+
#: model:ir.model,name:repair_sale_multi.model_stock_move
91+
msgid "Stock Move"
92+
msgstr "Movimiento de Stock"
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Translation of Odoo Server.
2+
# This file contains the translation of the following modules:
3+
# * repair_sale_multi
4+
#
5+
msgid ""
6+
msgstr ""
7+
"Project-Id-Version: Odoo Server 18.0+e\n"
8+
"Report-Msgid-Bugs-To: \n"
9+
"POT-Creation-Date: 2025-09-09 13:19+0000\n"
10+
"PO-Revision-Date: 2025-09-09 13:19+0000\n"
11+
"Last-Translator: \n"
12+
"Language-Team: \n"
13+
"MIME-Version: 1.0\n"
14+
"Content-Type: text/plain; charset=UTF-8\n"
15+
"Content-Transfer-Encoding: \n"
16+
"Plural-Forms: \n"
17+
18+
#. module: repair_sale_multi
19+
#. odoo-python
20+
#: code:addons/repair_sale_multi/wizards/repair_create_sale_order_wizard.py:0
21+
msgid "All repair orders must belong to the same customer."
22+
msgstr ""
23+
24+
#. module: repair_sale_multi
25+
#. odoo-python
26+
#: code:addons/repair_sale_multi/models/repair_order.py:0
27+
msgid "All selected repair orders must have the same customer defined."
28+
msgstr ""
29+
30+
#. module: repair_sale_multi
31+
#. odoo-python
32+
#: code:addons/repair_sale_multi/models/repair_order.py:0
33+
msgid "All selected repair orders must have the same picking type."
34+
msgstr ""
35+
36+
#. module: repair_sale_multi
37+
#: model:ir.actions.server,name:repair_sale_multi.action_create_sale_order_from_repairs
38+
msgid "Create Quotation"
39+
msgstr ""
40+
41+
#. module: repair_sale_multi
42+
#: model:ir.model,name:repair_sale_multi.model_repair_create_sale_order_wizard
43+
msgid "Create Quotation from Repair Orders"
44+
msgstr ""
45+
46+
#. module: repair_sale_multi
47+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__create_uid
48+
msgid "Created by"
49+
msgstr ""
50+
51+
#. module: repair_sale_multi
52+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__create_date
53+
msgid "Created on"
54+
msgstr ""
55+
56+
#. module: repair_sale_multi
57+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__display_name
58+
msgid "Display Name"
59+
msgstr ""
60+
61+
#. module: repair_sale_multi
62+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__id
63+
msgid "ID"
64+
msgstr ""
65+
66+
#. module: repair_sale_multi
67+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__write_uid
68+
msgid "Last Updated by"
69+
msgstr ""
70+
71+
#. module: repair_sale_multi
72+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__write_date
73+
msgid "Last Updated on"
74+
msgstr ""
75+
76+
#. module: repair_sale_multi
77+
#: model:ir.model,name:repair_sale_multi.model_repair_order
78+
#: model:ir.model.fields,field_description:repair_sale_multi.field_repair_create_sale_order_wizard__repair_order_ids
79+
#: model:ir.model.fields,field_description:repair_sale_multi.field_sale_order_line__repair_order_id
80+
msgid "Repair Order"
81+
msgstr ""
82+
83+
#. module: repair_sale_multi
84+
#: model:ir.model,name:repair_sale_multi.model_sale_order_line
85+
msgid "Sales Order Line"
86+
msgstr ""
87+
88+
#. module: repair_sale_multi
89+
#: model:ir.model,name:repair_sale_multi.model_stock_move
90+
msgid "Stock Move"
91+
msgstr ""
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import repair_order
2+
from . import sale_order_line
3+
from . import stock_move
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Copyright 2025 ForgeFlow S.L.
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
3+
from odoo import models
4+
from odoo.exceptions import UserError
5+
from odoo.fields import Command
6+
7+
8+
class RepairOrder(models.Model):
9+
_inherit = "repair.order"
10+
11+
def _prepare_combined_sale_order_vals(self, partners, picking_types):
12+
return {
13+
"company_id": self.company_id.id,
14+
"partner_id": partners.id,
15+
"warehouse_id": picking_types.warehouse_id.id,
16+
"repair_order_ids": [Command.link(ro.id) for ro in self],
17+
}
18+
19+
def action_create_combined_sale_order(self):
20+
if not self:
21+
return
22+
already_linked = self.filtered("sale_order_id")
23+
if already_linked:
24+
ref_str = "\n".join(ro.name for ro in already_linked)
25+
error_msg = (
26+
"You cannot create a quotation for repair orders already linked to "
27+
f"a sale order:\n{ref_str}"
28+
)
29+
raise UserError(self.env._(error_msg))
30+
picking_types = self.mapped("picking_type_id")
31+
if not picking_types or len(picking_types) != 1:
32+
raise UserError(
33+
self.env._(
34+
"All selected repair orders must have the same picking type."
35+
)
36+
)
37+
38+
partners = self.mapped("partner_id")
39+
if not partners or len(partners) != 1:
40+
raise UserError(
41+
self.env._(
42+
"All selected repair orders must have the same customer defined."
43+
)
44+
)
45+
46+
sale_order_vals = self._prepare_combined_sale_order_vals(
47+
partners, picking_types
48+
)
49+
self.env["sale.order"].create(sale_order_vals)
50+
self.mapped("move_ids")._create_repair_sale_order_line()
51+
return self.action_view_sale_order()
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from odoo import fields, models
2+
3+
4+
class SaleOrderLine(models.Model):
5+
_inherit = "sale.order.line"
6+
7+
# to be able to group lines by repair in sections
8+
repair_order_id = fields.Many2one(
9+
"repair.order",
10+
copy=False,
11+
)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from odoo import models
2+
3+
4+
class StockMove(models.Model):
5+
_inherit = "stock.move"
6+
7+
def _create_repair_sale_order_line(self):
8+
res = super()._create_repair_sale_order_line()
9+
for move in self:
10+
sale_lines = self.env["sale.order.line"].search(
11+
[
12+
("move_ids", "in", move.id),
13+
(
14+
"order_id",
15+
"=",
16+
move.repair_id.sale_order_id.id
17+
if move.repair_id.sale_order_id
18+
else False,
19+
),
20+
]
21+
)
22+
sale_lines.write({"repair_order_id": move.repair_id.id})
23+
return res

0 commit comments

Comments
 (0)