Skip to content

Commit 3a2107e

Browse files
Merge pull request OCA#5529 from hbrunn/19.0-sale
[19.0][MIG] sale
2 parents fa14241 + c4b11d2 commit 3a2107e

File tree

6 files changed

+295
-1
lines changed

6 files changed

+295
-1
lines changed

docsource/modules180-190.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ Module coverage 18.0 -> 19.0
984984
+---------------------------------------------------+----------------------+-------------------------------------------------+
985985
| |new| rpc | | |
986986
+---------------------------------------------------+----------------------+-------------------------------------------------+
987-
| sale | | |
987+
| sale |Done | |
988988
+---------------------------------------------------+----------------------+-------------------------------------------------+
989989
| |del| sale_async_emails | | |
990990
+---------------------------------------------------+----------------------+-------------------------------------------------+
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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 res_company_downpayment_account_id(env):
7+
"""
8+
Set res_company#downpayment_account_id from categories or default
9+
"""
10+
11+
def get_default(company):
12+
env.cr.execute(
13+
"""
14+
SELECT json_value
15+
FROM ir_default
16+
JOIN ir_model_fields
17+
ON ir_default.field_id=ir_model_fields.id
18+
JOIN ir_model
19+
ON ir_model_fields.model_id=ir_model.id
20+
WHERE
21+
ir_model.model='product.category' AND
22+
ir_model_fields.name='property_account_downpayment_categ_id'
23+
AND """
24+
+ ("company_id IS NULL" if not company else f"company_id={company.id}")
25+
)
26+
result = env.cr.fetchone()
27+
return result and int(result[0]) or None
28+
29+
global_default = get_default(None)
30+
31+
for company in env["res.company"].search([]):
32+
company_default = get_default(company)
33+
34+
env.cr.execute(
35+
f"""
36+
SELECT account_id FROM (
37+
SELECT
38+
property_account_downpayment_categ_id->'{company.id}' account_id,
39+
COUNT(id) cnt
40+
FROM product_category
41+
GROUP BY property_account_downpayment_categ_id->'{company.id}'
42+
) account_counts
43+
ORDER BY cnt DESC
44+
LIMIT 1
45+
"""
46+
)
47+
account_id = env.cr.fetchone()[0]
48+
49+
if not account_id:
50+
account_id = company_default or global_default
51+
52+
if account_id:
53+
company.downpayment_account_id = account_id
54+
55+
56+
def action_orders(env):
57+
"""
58+
This action had its domain deleted
59+
"""
60+
env.ref("sale.action_orders").domain = False
61+
62+
63+
@openupgrade.migrate()
64+
def migrate(env, version):
65+
openupgrade.load_data(env, "sale", "19.0.1.2/noupdate_changes.xml")
66+
openupgrade.delete_record_translations(
67+
env.cr,
68+
"sale",
69+
[
70+
"email_template_edi_sale",
71+
"mail_template_sale_confirmation",
72+
"mail_template_sale_payment_executed",
73+
],
74+
["body_html"],
75+
)
76+
res_company_downpayment_account_id(env)
77+
action_orders(env)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright 2026 Hunki Enterprises BV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from openupgradelib import openupgrade
5+
6+
_added_fields = [
7+
(
8+
"collapse_composition",
9+
"sale.order.line",
10+
"sale_order_line",
11+
"boolean",
12+
None,
13+
"sale",
14+
False,
15+
),
16+
(
17+
"collapse_prices",
18+
"sale.order.line",
19+
"sale_order_line",
20+
"boolean",
21+
None,
22+
"sale",
23+
False,
24+
),
25+
]
26+
27+
28+
_renamed_fields = [
29+
(
30+
"sale.order.line",
31+
"sale_order_line",
32+
"product_uom",
33+
"product_uom_id",
34+
),
35+
(
36+
"sale.order.line",
37+
"sale_order_line",
38+
"tax_id",
39+
"tax_ids",
40+
),
41+
]
42+
43+
_renamed_xmlids = [
44+
("sale_async_emails.async_emails", "sale.async_emails"),
45+
("sale_async_emails.cron", "sale.send_pending_emails_cron"),
46+
]
47+
48+
_deleted_xmlids = [
49+
"sale.sale_order_cancel_rule",
50+
"sale.sale_payment_provider_onboarding_wizard_rule",
51+
"sale.mail_template_sale_cancellation",
52+
"sale.mail_act_sale_upsell",
53+
]
54+
55+
56+
@openupgrade.migrate()
57+
def migrate(env, version):
58+
openupgrade.add_fields(env, _added_fields)
59+
openupgrade.rename_fields(env, _renamed_fields)
60+
openupgrade.rename_xmlids(env.cr, _renamed_xmlids)
61+
openupgrade.delete_records_safely_by_xml_id(env, _deleted_xmlids)
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---Models in module 'sale'---
2+
obsolete model sale.order.cancel [transient]
3+
obsolete model sale.payment.provider.onboarding.wizard [transient]
4+
5+
# NOTHING TO DO
6+
7+
---Fields in module 'sale'---
8+
sale / product.category / property_account_downpayment_categ_id (many2one): DEL relation: account.account
9+
10+
# DONE: used to set res.company#downpayment_account_id
11+
12+
sale / product.packaging / sales (boolean) : DEL
13+
sale / product.template / sale_line_warn (selection) : DEL required, selection_keys: ['block', 'no-message', 'warning']
14+
15+
# NOTHING TO DO
16+
17+
sale / res.company / downpayment_account_id (many2one): NEW relation: account.account
18+
19+
# DONE: set from product.category#property_account_downpayment_categ_id
20+
21+
sale / res.partner / sale_warn (selection) : DEL selection_keys: ['block', 'no-message', 'warning']
22+
23+
# NOTHING TO DO
24+
25+
sale / sale.order / preferred_payment_method_line_id (many2one): NEW relation: account.payment.method.line, hasdefault: compute
26+
27+
# NOTHING TO DO: computed by ORM
28+
29+
sale / sale.order.line / collapse_composition (boolean): NEW hasdefault: default
30+
sale / sale.order.line / collapse_prices (boolean) : NEW hasdefault: default
31+
32+
# DONE: created in pre-migration with default False
33+
34+
sale / sale.order.line / display_type (selection) : selection_keys added: [line_subsection] (most likely nothing to do)
35+
sale / sale.order.line / extra_tax_data (json) : NEW
36+
sale / sale.order.line / product_packaging_id (many2one): DEL relation: product.packaging
37+
sale / sale.order.line / product_packaging_qty (float) : DEL
38+
39+
# NOTHING TO DO
40+
41+
sale / sale.order.line / product_uom (many2one) : DEL relation: uom.uom
42+
sale / sale.order.line / product_uom_id (many2one) : NEW relation: uom.uom, hasdefault: compute
43+
sale / sale.order.line / tax_id (many2many) : DEL relation: account.tax
44+
sale / sale.order.line / tax_ids (many2many) : NEW relation: account.tax, hasdefault: compute
45+
46+
# DONE: renamed in pre-migration
47+
48+
---XML records in module 'sale'---
49+
NEW ir.actions.act_window: sale.action_accrued_revenue_entry_sale_order_line
50+
51+
# NOTHING TO DO
52+
53+
ir.actions.act_window: sale.action_orders (deleted domain)
54+
55+
# DONE: unset in pre-migration
56+
57+
NEW ir.actions.act_window: sale.mail_followers_edit_action_from_sale
58+
59+
# NOTHING TO DO
60+
61+
NEW ir.config_parameter: sale.async_emails [renamed from sale_async_emails module] (noupdate)
62+
DEL ir.config_parameter: sale_async_emails.async_emails [renamed to sale module] (noupdate)
63+
NEW ir.cron: sale.send_pending_emails_cron (noupdate)
64+
DEL ir.cron: sale_async_emails.cron (noupdate)
65+
66+
# DONE: renamed in pre-migration
67+
68+
NEW ir.model.access: sale.access_product_document_sale_manager
69+
DEL ir.model.access: sale.access_product_attribute_sale_manager
70+
DEL ir.model.access: sale.access_product_attribute_value_sale_manager
71+
DEL ir.model.access: sale.access_product_category_sale_manager
72+
DEL ir.model.access: sale.access_product_product_attribute_sale_manager
73+
DEL ir.model.access: sale.access_product_product_sale_manager
74+
DEL ir.model.access: sale.access_product_product_sale_user
75+
DEL ir.model.access: sale.access_product_supplierinfo_sale_manager
76+
DEL ir.model.access: sale.access_product_supplierinfo_user
77+
DEL ir.model.access: sale.access_product_tag_sale_manager
78+
DEL ir.model.access: sale.access_product_template_attribute_exclusion_sale_manager
79+
DEL ir.model.access: sale.access_product_template_attribute_line_sale_manager
80+
DEL ir.model.access: sale.access_product_template_sale_manager
81+
DEL ir.model.access: sale.access_product_template_sale_user
82+
DEL ir.model.access: sale.access_sale_order_cancel
83+
DEL ir.model.access: sale.access_sale_payment_provider_onboarding_wizard
84+
DEL ir.model.access: sale.access_uom_category_sale_manager
85+
DEL ir.model.access: sale.access_uom_uom_sale_manager
86+
DEL ir.model.access: sale.access_update_product_attribute_value_sale_manager
87+
NEW ir.model.constraint: sale.constraint_sale_order_date_order_id_idx
88+
ir.model.constraint: sale.constraint_sale_order_line_accountable_required_fields (changed definition: is now 'CHECK(display_type IS NOT NULL OR is_downpayment OR (product_id IS NOT NULL AND product_uom_id IS NOT NULL))' ('check(display_type is not null or is_downpayment or(product_id is not null and product_uom is not null))'))
89+
ir.model.constraint: sale.constraint_sale_order_line_non_accountable_null_fields (changed definition: is now 'CHECK(display_type IS NULL OR (product_id IS NULL AND price_unit = 0 AND product_uom_qty = 0 AND product_uom_id IS NULL AND customer_lead = 0))' ('check(display_type is null or(product_id is null and price_unit = 0 and product_uom_qty = 0 and product_uom is null and customer_lead = 0))'))
90+
91+
# NOTHING TO DO
92+
93+
DEL ir.rule: sale.sale_order_cancel_rule (noupdate)
94+
DEL ir.rule: sale.sale_payment_provider_onboarding_wizard_rule (noupdate)
95+
96+
# DONE: deleted in pre-migration
97+
98+
DEL ir.ui.menu: sale.menu_product_uom_categ_form_action
99+
DEL ir.ui.menu: sale.next_id_16
100+
NEW ir.ui.view: sale.product_pricelist_item_form
101+
NEW ir.ui.view: sale.res_config_settings_view_form_sale_inherit
102+
NEW ir.ui.view: sale.sale_order_portal_pay_modal
103+
NEW ir.ui.view: sale.sale_order_portal_pay_modal_amount_selector
104+
NEW ir.ui.view: sale.sale_order_portal_sign_modal
105+
DEL ir.ui.view: sale.crm_lead_partner_kanban_view
106+
DEL ir.ui.view: sale.product_packaging_form_view_sale
107+
DEL ir.ui.view: sale.product_packaging_tree_view_sale
108+
DEL ir.ui.view: sale.sale_order_cancel_view_form
109+
DEL ir.ui.view: sale.view_category_property_form
110+
111+
# NOTHING TO DO
112+
113+
DEL mail.activity.type: sale.mail_act_sale_upsell (noupdate)
114+
115+
# DONE: deleted in pre-migration
116+
117+
NEW mail.message.subtype: sale.mt_salesteam_invoice_paid (noupdate)
118+
NEW mail.message.subtype: sale.mt_salesteam_invoice_posted (noupdate)
119+
120+
# NOTHING TO DO
121+
122+
DEL mail.message.subtype: sale.mt_salesteam_invoice_confirmed (noupdate)
123+
DEL mail.message.subtype: sale.mt_salesteam_invoice_created (noupdate)
124+
125+
# NOTHING TO DO: don't delete subtypes because then messages end up without one
126+
127+
NEW mail.template: sale.email_template_proforma (noupdate)
128+
129+
# NOTHING TO DO
130+
131+
DEL mail.template: sale.mail_template_sale_cancellation (noupdate)
132+
133+
# DONE: deleted in pre-migration
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
env = locals().get("env")
2+
3+
# set a default downpayment account for company 1
4+
env["ir.default"].set(
5+
"product.category",
6+
"property_account_downpayment_categ_id",
7+
env.ref("account.1_payable").id,
8+
company_id=env.company.id,
9+
)
10+
11+
env.cr.commit()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from odoo.tests import TransactionCase
2+
3+
from odoo.addons.openupgrade_framework import openupgrade_test
4+
5+
6+
@openupgrade_test
7+
class TestSaleMigration(TransactionCase):
8+
def test_res_company_downpayment_account_id(self):
9+
"""
10+
Test that the migration set res.company#downpayment_account_id
11+
"""
12+
self.assertTrue(self.env.company.downpayment_account_id)

0 commit comments

Comments
 (0)