Skip to content

Commit dafcfe0

Browse files
committed
[MIG] sale_management
1 parent a406de4 commit dafcfe0

File tree

5 files changed

+207
-1
lines changed

5 files changed

+207
-1
lines changed

docsource/modules180-190.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ Module coverage 18.0 -> 19.0
10041004
+---------------------------------------------------+----------------------+-------------------------------------------------+
10051005
| sale_loyalty_delivery | |No DB layout changes. |
10061006
+---------------------------------------------------+----------------------+-------------------------------------------------+
1007-
| sale_management | | |
1007+
| sale_management |Done | |
10081008
+---------------------------------------------------+----------------------+-------------------------------------------------+
10091009
| sale_margin | | |
10101010
+---------------------------------------------------+----------------------+-------------------------------------------------+
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Copyright 2026 Hunki Enterprises BV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
from openupgradelib import openupgrade
4+
5+
6+
def sale_order_line_options(env):
7+
"""
8+
Model sale.order.option has been replaced by optional lines on sale orders
9+
"""
10+
SaleOrderLine = env["sale.order.line"]
11+
link_column = openupgrade.get_legacy_name("option_id")
12+
env.cr.execute(
13+
f"ALTER TABLE sale_order_line ADD COLUMN IF NOT EXISTS {link_column} int "
14+
)
15+
env.cr.execute(
16+
"""
17+
SELECT
18+
id, order_id, name, product_id, quantity, price_unit, sequence, uom_id, discount
19+
FROM
20+
sale_order_option
21+
"""
22+
)
23+
for (
24+
option_id,
25+
order_id,
26+
name,
27+
product_id,
28+
quantity,
29+
price_unit,
30+
sequence,
31+
uom_id,
32+
discount,
33+
) in env.cr.fetchall():
34+
line = SaleOrderLine.create(
35+
{
36+
"is_optional": True,
37+
"order_id": order_id,
38+
"name": name,
39+
"product_id": product_id,
40+
"product_uom_qty": quantity,
41+
"price_unit": price_unit,
42+
"sequence": sequence,
43+
"product_uom_id": uom_id,
44+
"discount": discount,
45+
}
46+
)
47+
env.cr.execute(
48+
f"""
49+
UPDATE sale_order_line
50+
SET {link_column}={option_id}
51+
WHERE id={line.id}
52+
"""
53+
)
54+
55+
56+
def sale_order_template_options(env):
57+
"""
58+
Model sale.order.template.option has been replaced by optional lines
59+
"""
60+
SaleOrderTemplateLine = env["sale.order.template.line"]
61+
link_column = openupgrade.get_legacy_name("option_id")
62+
env.cr.execute(
63+
"ALTER TABLE sale_order_template_line "
64+
f"ADD COLUMN IF NOT EXISTS {link_column} int "
65+
)
66+
env.cr.execute(
67+
"""
68+
SELECT
69+
id, sale_order_template_id, name, product_id, quantity, uom_id
70+
FROM
71+
sale_order_template_option
72+
"""
73+
)
74+
for (
75+
option_id,
76+
template_id,
77+
name,
78+
product_id,
79+
quantity,
80+
uom_id,
81+
) in env.cr.fetchall():
82+
line = SaleOrderTemplateLine.create(
83+
{
84+
"is_optional": True,
85+
"sale_order_template_id": template_id,
86+
"name": name,
87+
"product_id": product_id,
88+
"product_uom_qty": quantity,
89+
"product_uom_id": uom_id,
90+
}
91+
)
92+
env.cr.execute(
93+
f"""
94+
UPDATE sale_order_template_line
95+
SET {link_column}={option_id}
96+
WHERE id={line.id}
97+
"""
98+
)
99+
100+
101+
@openupgrade.migrate()
102+
def migrate(env, version):
103+
sale_order_line_options(env)
104+
sale_order_template_options(env)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---Models in module 'sale_management'---
2+
obsolete model sale.order.option
3+
obsolete model sale.order.template.option
4+
5+
# DONE: moved to sale.order.line/sale.order.template.line
6+
7+
---Fields in module 'sale_management'---
8+
sale_management / sale.order / sale_order_option_ids (one2many): DEL relation: sale.order.option
9+
sale_management / sale.order.line / is_optional (boolean) : NEW hasdefault: default
10+
sale_management / sale.order.line / sale_order_option_ids (one2many): DEL relation: sale.order.option
11+
sale_management / sale.order.option / discount (float) : DEL
12+
sale_management / sale.order.option / line_id (many2one) : DEL relation: sale.order.line
13+
sale_management / sale.order.option / name (text) : DEL required
14+
sale_management / sale.order.option / order_id (many2one) : DEL relation: sale.order
15+
sale_management / sale.order.option / price_unit (float) : DEL required
16+
sale_management / sale.order.option / product_id (many2one) : DEL relation: product.product, required
17+
sale_management / sale.order.option / quantity (float) : DEL required
18+
sale_management / sale.order.option / sequence (integer) : DEL
19+
sale_management / sale.order.option / uom_id (many2one) : DEL relation: uom.uom, required
20+
sale_management / sale.order.template / sale_order_template_option_ids (one2many): DEL relation: sale.order.template.option
21+
sale_management / sale.order.template.line / display_type (selection) : selection_keys added: [line_subsection] (most likely nothing to do)
22+
sale_management / sale.order.template.line / is_optional (boolean) : NEW hasdefault: default
23+
sale_management / sale.order.template.option / company_id (many2one) : DEL relation: res.company
24+
sale_management / sale.order.template.option / name (text) : DEL required
25+
sale_management / sale.order.template.option / product_id (many2one) : DEL relation: product.product, required
26+
sale_management / sale.order.template.option / quantity (float) : DEL required
27+
sale_management / sale.order.template.option / sale_order_template_id (many2one): DEL relation: sale.order.template, required
28+
sale_management / sale.order.template.option / uom_id (many2one) : DEL relation: uom.uom, required
29+
30+
# DONE: create optional lines / template lines from former options
31+
32+
---XML records in module 'sale_management'---
33+
DEL ir.model.access: sale_management.access_sale_order_option
34+
DEL ir.model.access: sale_management.access_sale_order_option_invoice
35+
DEL ir.model.access: sale_management.access_sale_order_option_readonly
36+
DEL ir.model.access: sale_management.access_sale_order_template_option
37+
DEL ir.model.access: sale_management.access_sale_order_template_option_manager
38+
NEW ir.ui.view: sale_management.sale_order_portal_optional_product_quantity
39+
DEL ir.ui.view: sale_management.report_saleorder_document_inherit_sale_management
40+
41+
# NOTHING TO DO
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
env = locals().get("env")
2+
3+
# create template with options
4+
template = env["sale.order.template"].create(
5+
{
6+
"name": "Sale order template",
7+
"sale_order_template_line_ids": [],
8+
"sale_order_template_option_ids": [
9+
(
10+
0,
11+
0,
12+
{
13+
"name": "some option",
14+
"product_id": env.ref("product.product_product_1").id,
15+
"uom_id": env.ref("uom.product_uom_unit").id,
16+
"quantity": 42,
17+
},
18+
),
19+
(
20+
0,
21+
0,
22+
{
23+
"name": "another option",
24+
"product_id": env.ref("product.product_product_2").id,
25+
"uom_id": env.ref("uom.product_uom_unit").id,
26+
"quantity": 4242,
27+
},
28+
),
29+
],
30+
}
31+
)
32+
order = env["sale.order"].create(
33+
{
34+
"partner_id": env.user.partner_id.id,
35+
"sale_order_template_id": template.id,
36+
}
37+
)
38+
order._onchange_sale_order_template_id()
39+
40+
env.cr.commit()
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from odoo.tests import TransactionCase
2+
3+
from odoo.addons.openupgrade_framework import openupgrade_test
4+
5+
6+
@openupgrade_test
7+
class TestSaleManagementMigration(TransactionCase):
8+
def test_sale_order_template_migration(self):
9+
template = self.env["sale.order.template"].search(
10+
[("name", "=", "Sale order template")],
11+
)
12+
order = self.env["sale.order"].search(
13+
[("sale_order_template_id", "=", template.id)]
14+
)
15+
self.assertItemsEqual(
16+
order.order_line.mapped("name"), ("some option", "another option")
17+
)
18+
self.assertItemsEqual(order.order_line.mapped("is_optional"), (True, True))
19+
self.assertItemsEqual(
20+
template.sale_order_template_line_ids.mapped("is_optional"), (True, True)
21+
)

0 commit comments

Comments
 (0)