Skip to content

Commit 9d927cc

Browse files
committed
[MIG] stock_account
1 parent 2373784 commit 9d927cc

5 files changed

Lines changed: 530 additions & 1 deletion

File tree

docsource/modules180-190.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,7 @@ Module coverage 18.0 -> 19.0
10861086
+---------------------------------------------------+----------------------+-------------------------------------------------+
10871087
| stock |Done | |
10881088
+---------------------------------------------------+----------------------+-------------------------------------------------+
1089-
| stock_account | | |
1089+
| stock_account |Done | |
10901090
+---------------------------------------------------+----------------------+-------------------------------------------------+
10911091
| stock_delivery | | |
10921092
+---------------------------------------------------+----------------------+-------------------------------------------------+
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
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+
from odoo import fields
7+
8+
9+
def update_from_coa_generic(env, spec):
10+
"""
11+
Update some models from the COA according to spec:
12+
{model_name1: [fieldname1, fieldname2, ...], model_name2: [...], ...}
13+
14+
TODO: Move this to openupgradelib if needed for more migrations than
15+
account, stock_account
16+
"""
17+
18+
for company in env["res.company"].search([]):
19+
AccountChartTemplate = env["account.chart.template"].with_context(
20+
default_company_id=company.id,
21+
allowed_company_ids=company.ids,
22+
tracking_disable=True,
23+
delay_account_group_sync=True,
24+
lang="en_US",
25+
chart_template_load=True,
26+
)
27+
28+
if company.chart_template not in AccountChartTemplate._template_register:
29+
openupgrade.logger.error(
30+
"chart template %s unknown (not yet migrated?)",
31+
company.chart_template,
32+
)
33+
continue
34+
35+
def ref_or_id(ref_or_id, model_name, AccountChartTemplate=AccountChartTemplate):
36+
if isinstance(ref_or_id, int):
37+
return env[model_name].browse(ref_or_id)
38+
return AccountChartTemplate.ref(ref_or_id, False) or env[model_name].browse(
39+
[]
40+
)
41+
42+
template_data = AccountChartTemplate._get_chart_template_data(
43+
company.chart_template
44+
)
45+
46+
company_data = {}
47+
for model_name, field_names in spec.items():
48+
company_data[model_name] = {
49+
record_id: {
50+
key: value
51+
for key, value in record_data.items()
52+
if key in field_names and not ref_or_id(record_id, model_name)[key]
53+
}
54+
for record_id, record_data in template_data[model_name].items()
55+
if any(record_data.get(key) for key in field_names)
56+
}
57+
AccountChartTemplate._load_data(company_data)
58+
59+
60+
def update_from_coa(env):
61+
"""
62+
Set fields account.account#{account_stock_expense_id,account_stock_variation_id}
63+
and res.company#{account_stock_journal_id,account_stock_valuation_id}
64+
from localization if not set elsewhere and the localization sets it
65+
"""
66+
update_from_coa_generic(
67+
env,
68+
{
69+
"res.company": ["account_stock_journal_id", "account_stock_valuation_id"],
70+
"account.account": [
71+
"account_stock_expense_id",
72+
"account_stock_variation_id",
73+
],
74+
},
75+
)
76+
77+
78+
def stock_lot_avg_cost(env):
79+
"""
80+
Run compute method on stock.lot#avg_cost
81+
"""
82+
lots = (
83+
env["stock.lot"]
84+
.search(
85+
[
86+
("lot_valuated", "=", True),
87+
]
88+
)
89+
.with_context(to_date=fields.Datetime.now())
90+
)
91+
for records in openupgrade.chunked(lots):
92+
records._compute_avg_cost()
93+
94+
95+
def stock_move_is_fields(env):
96+
"""
97+
Run compute methods for stock.move#is_*
98+
"""
99+
moves = env["stock.move"].search(
100+
[
101+
("state", "=", "done"),
102+
]
103+
)
104+
for records in openupgrade.chunked(moves):
105+
records._compute_is_in()
106+
records._compute_is_out()
107+
records._compute_is_dropship()
108+
109+
110+
@openupgrade.migrate()
111+
def migrate(env, version):
112+
update_from_coa(env)
113+
stock_lot_avg_cost(env)
114+
stock_move_is_fields(env)
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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+
7+
def product_value_product_id(env):
8+
"""
9+
Fill product.value#product_id from move_id.product_id
10+
"""
11+
env.cr.execute(
12+
"""
13+
UPDATE product_value
14+
SET product_id=stock_move.product_id
15+
FROM stock_move
16+
WHERE product_value.move_id=stock_move.id
17+
AND product_value.product_id IS NULL
18+
"""
19+
)
20+
21+
22+
def stock_move_account_move_id(env):
23+
"""
24+
Fill stock.move#account_move_id from account.move#stock_move_id
25+
"""
26+
env.cr.execute(
27+
"""
28+
UPDATE stock_move
29+
SET account_move_id=account_move.id
30+
FROM account_move
31+
WHERE
32+
account_move.stock_move_id=stock_move.id
33+
AND stock_move.account_move_id IS NULL
34+
"""
35+
)
36+
37+
38+
def product_category_property_valuation(env):
39+
"""
40+
Change value 'manual_periodic' to 'periodic'
41+
"""
42+
env["ir.default"].search(
43+
[
44+
("field_id.name", "=", "property_valuation"),
45+
("field_id.model_id.model", "=", "product.category"),
46+
("json_value", "=", '"manual_periodic"'),
47+
]
48+
).write({"json_value": '"periodic"'})
49+
50+
for company in env["res.company"].search([]):
51+
env.cr.execute(
52+
f"""
53+
UPDATE product_category
54+
SET
55+
property_valuation = property_valuation || '{{"{company.id}": "periodic"}}'
56+
WHERE
57+
property_valuation->>'{company.id}' = 'manual_periodic'
58+
"""
59+
)
60+
61+
62+
def stock_location_valuation_account_id(env):
63+
"""
64+
Set stock.location#valuation_account_id from valuation_in_account_id and
65+
valuation_out_account_id if they are the same
66+
"""
67+
env.cr.execute(
68+
"""
69+
UPDATE stock_location
70+
SET valuation_account_id=valuation_in_account_id
71+
WHERE
72+
valuation_in_account_id=valuation_out_account_id
73+
"""
74+
)
75+
76+
77+
def stock_move_value(env):
78+
"""
79+
Set stock.move#value to sum of product.value#value for this move
80+
"""
81+
env.cr.execute(
82+
"""
83+
UPDATE stock_move
84+
SET value=aggregated_values.value
85+
FROM (
86+
SELECT
87+
move_id, sum(value) value
88+
FROM
89+
product_value
90+
GROUP BY move_id
91+
) aggregated_values
92+
WHERE aggregated_values.move_id=stock_move.id
93+
"""
94+
)
95+
96+
97+
@openupgrade.migrate()
98+
def migrate(env, version):
99+
product_value_product_id(env)
100+
stock_move_account_move_id(env)
101+
product_category_property_valuation(env)
102+
stock_location_valuation_account_id(env)
103+
stock_move_value(env)
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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+
_renamed_models = [
7+
("stock.valuation.layer", "product.value"),
8+
]
9+
10+
_renamed_tables = [
11+
("stock_valuation_layer", "product_value"),
12+
]
13+
14+
_renamed_fields = [
15+
("product.value", "product_value", "", ""),
16+
]
17+
18+
_copied_columns = {
19+
"product_value": [
20+
("create_date", "date", None),
21+
("create_uid", "user_id", None),
22+
("stock_move_id", "move_id", None),
23+
],
24+
}
25+
26+
_deleted_xmlids = [
27+
"stock_account.stock_valuation_layer_company_rule",
28+
"stock_account.group_stock_accounting_automatic",
29+
]
30+
31+
32+
def stock_lot_avg_cost(env):
33+
"""
34+
Precreate stock.lot#avg_cost to avoid compute method
35+
"""
36+
openupgrade.add_fields(
37+
env,
38+
[
39+
("avg_cost", "stock.lot", "stock_lot", "float", None, "stock_account", 0),
40+
],
41+
)
42+
43+
44+
def stock_move_is_fields(env):
45+
"""
46+
Precreate stock.move#is_* to avoid compute method
47+
"""
48+
openupgrade.add_fields(
49+
env,
50+
[
51+
(
52+
"is_in",
53+
"stock.move",
54+
"stock_move",
55+
"boolean",
56+
None,
57+
"stock_account",
58+
False,
59+
),
60+
(
61+
"is_out",
62+
"stock.move",
63+
"stock_move",
64+
"boolean",
65+
None,
66+
"stock_account",
67+
False,
68+
),
69+
(
70+
"is_dropship",
71+
"stock.move",
72+
"stock_move",
73+
"boolean",
74+
None,
75+
"stock_account",
76+
False,
77+
),
78+
],
79+
)
80+
81+
82+
@openupgrade.migrate()
83+
def migrate(env, version):
84+
openupgrade.rename_models(env.cr, _renamed_models)
85+
openupgrade.rename_tables(env.cr, _renamed_tables)
86+
openupgrade.rename_fields(env, _renamed_fields)
87+
openupgrade.copy_columns(env.cr, _copied_columns)
88+
openupgrade.delete_records_safely_by_xml_id(env, _deleted_xmlids)
89+
stock_lot_avg_cost(env)
90+
stock_move_is_fields(env)

0 commit comments

Comments
 (0)