Skip to content

Commit 27f6e3f

Browse files
[MIG] maintenance_purchase: Migration to version 18.0
1 parent 20f9956 commit 27f6e3f

File tree

9 files changed

+107
-106
lines changed

9 files changed

+107
-106
lines changed

maintenance_purchase/__manifest__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
"name": "Maintenance Purchase",
66
"summary": """
77
Create Equipments with purchases""",
8-
"version": "16.0.1.0.0",
8+
"version": "18.0.1.0.0",
99
"license": "AGPL-3",
1010
"author": "CreuBlanca,Odoo Community Association (OCA)",
1111
"website": "https://github.com/OCA/maintenance",
1212
"depends": [
13-
"maintenance_account",
14-
"purchase_stock",
13+
"purchase",
1514
],
1615
"data": [
1716
"views/purchase_order.xml",
1817
"views/maintenance_equipment.xml",
18+
"views/product_template_view.xml",
1919
],
2020
"demo": [],
2121
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright 2026 Tecnativa - Christian Ramos
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
from openupgradelib import openupgrade
4+
5+
6+
@openupgrade.migrate()
7+
def migrate(env, version):
8+
# Bring the category data from maintenance_equipment_category to the product
9+
if openupgrade.column_exists(
10+
env.cr, "maintenance_equipment_category", "product_category_id"
11+
):
12+
openupgrade.logged_query(
13+
env.cr,
14+
"""
15+
UPDATE product_template pt
16+
SET equipment_category_id = sub.equipment_category_id
17+
FROM (
18+
SELECT mec.product_category_id AS product_category_id,
19+
mec.id AS equipment_category_id
20+
FROM maintenance_equipment_category mec
21+
WHERE mec.product_category_id IS NOT NULL
22+
) AS sub
23+
WHERE pt.categ_id = sub.product_category_id
24+
AND pt.equipment_category_id IS NULL""",
25+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
from . import maintenance_equipment
22
from . import purchase_order
3+
from . import product_template
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright 2022 Tecnativa - Víctor Martínez
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3+
from odoo import fields, models
4+
5+
6+
class ProductTemplate(models.Model):
7+
_inherit = "product.template"
8+
9+
equipment_category_id = fields.Many2one(
10+
comodel_name="maintenance.equipment.category",
11+
string="Equipment Category",
12+
)
Lines changed: 38 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright 2022 CreuBlanca
22
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
33

4-
from odoo import api, fields, models
4+
from odoo import Command, api, fields, models
55

66

77
class PurchaseOrder(models.Model):
@@ -24,8 +24,9 @@ def action_view_equipments(self):
2424
items = self.env["maintenance.equipment"].search(
2525
[("purchase_id", "=", self.id)]
2626
)
27-
action = self.env.ref("maintenance.hr_equipment_action")
28-
action_dict = action.sudo().read()[0]
27+
action_dict = self.env["ir.actions.act_window"]._for_xml_id(
28+
"maintenance.hr_equipment_action"
29+
)
2930
if len(items) == 1:
3031
res = self.env.ref("maintenance.hr_equipment_view_form", False)
3132
action_dict["views"] = [(res and res.id or False, "form")]
@@ -36,29 +37,25 @@ def action_view_equipments(self):
3637
action_dict = {"type": "ir.actions.act_window_close"}
3738
return action_dict
3839

40+
def _get_lines_to_create_equipments(self):
41+
return self.order_line.filtered(
42+
lambda x: (
43+
x.product_qty > len(x.equipment_ids)
44+
and x.product_id
45+
and x.equipment_category_id
46+
)
47+
)
48+
3949
def button_approve(self, force=False):
4050
result = super().button_approve(force=force)
41-
equipment_model = self.env["maintenance.equipment"]
42-
for order in self.filtered(lambda po: po.state in ("purchase", "done")):
43-
for line in order.order_line.filtered(
44-
lambda x: (
45-
not x.equipment_ids
46-
and x.product_id
47-
and x.product_id.product_tmpl_id.maintenance_ok
48-
)
49-
):
50-
if not line.equipment_category_id:
51-
line._set_equipment_category()
52-
# Create equipments
53-
limit = int(line.product_qty) + 1
54-
vals = line._prepare_equipment_vals()
55-
equipment_ids = []
56-
for _i in range(1, limit):
57-
equipment = equipment_model.create(vals)
58-
equipment_ids.append((4, equipment.id))
59-
line.equipment_ids = equipment_ids
51+
self._create_equipments()
6052
return result
6153

54+
def _create_equipments(self):
55+
for order in self.filtered(lambda po: po.state in ("purchase", "done")):
56+
for line in order._get_lines_to_create_equipments():
57+
line.create_equipments()
58+
6259

6360
class PurchaseOrderLine(models.Model):
6461
_inherit = "purchase.order.line"
@@ -70,8 +67,9 @@ class PurchaseOrderLine(models.Model):
7067
store=True,
7168
readonly=False,
7269
)
73-
equipment_ids = fields.Many2many(
70+
equipment_ids = fields.One2many(
7471
comodel_name="maintenance.equipment",
72+
inverse_name="purchase_line_id",
7573
string="Equipments",
7674
copy=False,
7775
)
@@ -80,13 +78,11 @@ class PurchaseOrderLine(models.Model):
8078
@api.depends("product_id")
8179
def _compute_equipment_category_id(self):
8280
for item in self:
83-
if (
84-
item.product_id.maintenance_ok
85-
and item.product_id.product_tmpl_id.categ_id.equipment_category_ids
86-
):
87-
item.equipment_category_id = fields.first(
88-
item.product_id.product_tmpl_id.categ_id.equipment_category_ids
81+
if item.product_id.product_tmpl_id.equipment_category_id:
82+
item.equipment_category_id = (
83+
item.product_id.product_tmpl_id.equipment_category_id
8984
)
85+
9086
else:
9187
item.equipment_category_id = item.equipment_category_id
9288

@@ -100,37 +96,28 @@ def _compute_equipment_count(self):
10096
for item in self:
10197
item.equipment_count = mapping.get(item.id, 0)
10298

103-
def _prepare_equipment_category_vals(self):
104-
categ = self.product_id.product_tmpl_id.categ_id
105-
return {"name": categ.name, "product_category_id": categ.id}
99+
def _qty_to_create_equipments(self):
100+
return int(self.product_qty - len(self.equipment_ids))
106101

107-
def _set_equipment_category(self):
108-
if not self.equipment_category_id:
109-
category_model = self.env["maintenance.equipment.category"].sudo()
110-
category = fields.first(
111-
self.product_id.product_tmpl_id.categ_id.equipment_category_ids
112-
)
113-
if not category:
114-
category = category_model.create(
115-
self._prepare_equipment_category_vals()
116-
)
117-
self.equipment_category_id = category.id
102+
def create_equipments(self):
103+
self.ensure_one()
104+
equipment_model = self.env["maintenance.equipment"]
105+
equipments = equipment_model.create(
106+
[
107+
self._prepare_equipment_vals()
108+
for _ in range(self._qty_to_create_equipments())
109+
]
110+
)
111+
self.equipment_ids = [Command.link(eq.id) for eq in equipments]
112+
return equipments
118113

119114
def _prepare_equipment_vals(self):
120115
return {
121116
"purchase_line_id": self.id,
122117
"name": self.product_id.name,
123-
"product_id": self.product_id.id,
124118
"category_id": self.equipment_category_id.id,
125119
"assign_date": self.order_id.date_order,
126120
"effective_date": self.order_id.date_planned,
127121
"partner_id": self.order_id.partner_id.id,
128122
"partner_ref": self.order_id.partner_ref,
129123
}
130-
131-
def _prepare_account_move_line(self, move=False):
132-
result = super()._prepare_account_move_line(move=move)
133-
result["equipment_ids"] = [
134-
(4, equipment.id) for equipment in self.equipment_ids
135-
]
136-
return result

maintenance_purchase/tests/test_purchase_order.py

Lines changed: 8 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# Copyright 2024 ACSONE SA/NV
22
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
33

4-
from odoo import Command
5-
from odoo.tests.common import TransactionCase
64

5+
from odoo.addons.base.tests.common import BaseCommon
76

8-
class TestMaintenanceProject(TransactionCase):
7+
8+
class TestMaintenanceProject(BaseCommon):
99
@classmethod
1010
def setUpClass(cls):
1111
super().setUpClass()
@@ -35,22 +35,11 @@ def setUpClass(cls):
3535
cls.product_category01 = cls.ProductCategory.create(
3636
{
3737
"name": "My Product Category 1",
38-
"equipment_category_ids": [
39-
Command.set(
40-
[
41-
cls.maintenance_equipment_category1.id,
42-
cls.maintenance_equipment_category2.id,
43-
]
44-
)
45-
],
4638
}
4739
)
4840
cls.product_category02 = cls.ProductCategory.create(
4941
{
5042
"name": "My Product Category 2",
51-
"equipment_category_ids": [
52-
Command.set([cls.maintenance_equipment_category2.id])
53-
],
5443
}
5544
)
5645
cls.product_order_maintenance = cls.ProductProduct.create(
@@ -64,8 +53,8 @@ def setUpClass(cls):
6453
"purchase_method": "purchase",
6554
"default_code": "PROD_ORDER",
6655
"taxes_id": False,
67-
"maintenance_ok": True,
6856
"categ_id": cls.product_category01.id,
57+
"equipment_category_id": cls.maintenance_equipment_category1.id,
6958
}
7059
)
7160
cls.product_order_no_maintenance = cls.ProductProduct.create(
@@ -89,7 +78,7 @@ def setUpClass(cls):
8978
"partner_id": cls.partner.id,
9079
}
9180
)
92-
PurchaseOrderLine = cls.PurchaseOrderLine.with_context(tracking_disable=True)
81+
PurchaseOrderLine = cls.PurchaseOrderLine
9382
cls.purchase_line_order01 = PurchaseOrderLine.create(
9483
{
9584
"name": cls.product_order_maintenance.name,
@@ -145,45 +134,16 @@ def test_equipment_category_id(self):
145134
self.maintenance_equipment_category1,
146135
)
147136
self.assertFalse(self.purchase_line_order02.equipment_category_id)
148-
self.product_order_no_maintenance.product_tmpl_id.maintenance_ok = True
137+
self.product_order_no_maintenance.product_tmpl_id.equipment_category_id = (
138+
self.maintenance_equipment_category2
139+
)
149140
self.assertFalse(self.purchase_line_order02.equipment_category_id)
150141
self.purchase_line_order02.product_id = self.product_order_maintenance
151142
self.purchase_line_order02.product_id = self.product_order_no_maintenance
152143
self.assertEqual(
153144
self.purchase_line_order02.equipment_category_id,
154145
self.maintenance_equipment_category2,
155146
)
156-
self.purchase_line_order01.equipment_ids.unlink()
157-
self.purchase_line_order01.equipment_category_id = False
158-
self.purchase_order.button_approve()
159-
self.assertEqual(
160-
self.purchase_line_order01.equipment_category_id,
161-
self.maintenance_equipment_category1,
162-
)
163-
self.purchase_line_order01.equipment_ids.unlink()
164-
self.purchase_line_order01.equipment_category_id = False
165-
product_category_withouth_equipement_category = self.ProductCategory.create(
166-
{
167-
"name": "My Product Category 2",
168-
}
169-
)
170-
self.purchase_line_order01.product_id.product_tmpl_id.categ_id = (
171-
product_category_withouth_equipement_category.id
172-
)
173-
self.purchase_order.button_approve()
174-
self.assertTrue(self.purchase_line_order01.equipment_category_id)
175-
self.assertNotEqual(
176-
self.purchase_line_order01.equipment_category_id,
177-
self.maintenance_equipment_category1,
178-
)
179-
180-
def test_account_move_line(self):
181-
self.purchase_order.button_approve()
182-
self.purchase_order.action_create_invoice()
183-
self.assertEqual(
184-
self.purchase_order.order_line.equipment_ids,
185-
self.purchase_order.invoice_ids.line_ids.equipment_ids,
186-
)
187147

188148
def test_action_view_equipments(self):
189149
action = self.purchase_order.action_view_equipments()

maintenance_purchase/views/maintenance_equipment.xml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
<field name="model">maintenance.equipment</field>
88
<field name="inherit_id" ref="maintenance.hr_equipment_view_form" />
99
<field name="arch" type="xml">
10-
<xpath expr="//field[@name='serial_no']" position="after">
11-
<field name="purchase_id" />
10+
<xpath
11+
expr="//page[@name='product_information']//field[@name='serial_no']"
12+
position="after"
13+
>
14+
<field name="purchase_id" groups="purchase.group_purchase_user" />
1215
</xpath>
1316
</field>
1417
</record>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<odoo>
3+
<record id="product_template_form_view" model="ir.ui.view">
4+
<field name="name">product.template.common.form</field>
5+
<field name="model">product.template</field>
6+
<field name="inherit_id" ref="product.product_template_form_view" />
7+
<field name="arch" type="xml">
8+
<xpath expr="//field[@name='categ_id']" position="after">
9+
<field name="equipment_category_id" />
10+
</xpath>
11+
</field>
12+
</record>
13+
</odoo>

maintenance_purchase/views/purchase_order.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
type="object"
1414
class="oe_stat_button"
1515
icon="fa-cubes"
16-
attrs="{'invisible': [('equipment_count', '=', 0)]}"
16+
invisible="not equipment_count"
1717
>
1818
<field
1919
string="Equipment(s)"
@@ -23,7 +23,7 @@
2323
</button>
2424
</xpath>
2525
<xpath
26-
expr="//notebook//field[@name='order_line']/tree/field[@name='product_qty']"
26+
expr="//notebook//field[@name='order_line']/list/field[@name='product_qty']"
2727
position="before"
2828
>
2929
<field name="equipment_category_id" optional="hide" />

0 commit comments

Comments
 (0)