Skip to content

[FIX] stock_account: skip accounts that don't exist yet in company_data - #5890

Open
quoc-pn wants to merge 1 commit into
OCA:19.0from
komit-consulting:19.0-fix-stock_account-empty-company-data
Open

[FIX] stock_account: skip accounts that don't exist yet in company_data#5890
quoc-pn wants to merge 1 commit into
OCA:19.0from
komit-consulting:19.0-fix-stock_account-empty-company-data

Conversation

@quoc-pn

@quoc-pn quoc-pn commented Aug 6, 2026

Copy link
Copy Markdown
Member

Follow-up to #5885, which fixed the case where a record already exists but the target field is already set. There is still a related bug for records that don't exist yet.

Problem

While testing this migration against a real customer database (from Odoo 16), I hit a crash while migrating a company using the French chart of accounts (fr chart template). The failure happens because the migration tries to attach two optional fields — account_stock_expense_id and account_stock_variation_id — onto a specific account defined by the chart template: the generic "Raw materials and supplies" account (code 310000) and its matching expense account (code 601000, "Inventory item purchases – Raw materials and supplies").

The problem: this customer's company doesn't have those two generic accounts, and never has — going all the way back to their original installation. What they have instead are more specific accounts for the same purpose, split by material category: 311000/312000/317000 (raw materials A/B/C) and 601100/601200/601700 (the matching purchase accounts). This is exactly what Odoo's own French chart template provided by default at the time this company was first set up — it wasn't a customization on their part.

Since then, the official French chart template has evolved: the older per-category accounts (311/312/317, 601.1/601.2/601.7) are no longer part of the standard template, and a single generic pair (310000/601000) was introduced in their place. For a brand-new install today, that generic account gets created as part of the normal chart-of-accounts setup. But for a company migrating from an older version, there is no equivalent account to find because the account structure itself has changed — not because anything is missing or was deleted from their data.

Bug

update_from_coa_generic() in stock_account/19.0.1.1/end-migration.py builds filtered_records[record_id] based on whether the target field appears unset via not ref_or_id(record_id, model_name)[key]. When ref_or_id() can't resolve the xmlid to an existing account.account (the account hasn't been created yet in this company's chart), indexing [key] on the resulting empty recordset is also falsy — so a not-yet-existing account is treated the same as an existing account with the field unset.

AccountChartTemplate._load_data(company_data) then creates a new account.account row from only the partial company_data (just the 2 stock-account fields), missing required fields like name/account_type, causing:

null value in column "name" of relation "account_account" violates not-null constraint

Suggestion

Automatically creating this account during migration would mean introducing a brand-new account into a company's live chart of accounts that they never asked for and never had — purely as a side effect of a version upgrade.

The safer path is to let the migration skip this gap entirely and complete without touching the chart of accounts. Bringing the chart of accounts up to the newer template's structure can then be handled separately.

Fix

Skip record_ids that don't resolve to an existing record instead of partially-creating them. This script is meant to backfill fields on existing accounts, not create new ones.

Test

Reproduced during a 19.0 migration where stock_account's end-migration.py crashed on AccountChartTemplate._load_data() with the above error even after #5885; confirmed the crash disappears with this fix applied.

Assisted-by: Claude Sonnet 5

update_from_coa_generic() included a record_id in filtered_records
whenever the target field appeared unset. But when ref_or_id() can't
resolve the xmlid to an existing account.account record, indexing the
field on the resulting empty recordset is also falsy, so a
not-yet-existing account was treated the same as an existing account
with the field unset.

AccountChartTemplate._load_data() then created a new account.account
row from only the partial company_data (the 2 stock-account fields),
missing required fields like name/account_type, causing:

  null value in column "name" of relation "account_account"
  violates not-null constraint

Skip record_ids that don't resolve to an existing record instead of
partially-creating them.
@quoc-pn
quoc-pn marked this pull request as draft August 6, 2026 03:57
@quoc-pn
quoc-pn marked this pull request as ready for review August 6, 2026 04:15
@quoc-pn

quoc-pn commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

@MiquelRForgeFlow Could you please review this PR? It replaces PR #5887, which was accidentally closed. Thanks!

@OCA-git-bot OCA-git-bot added mod:openupgrade_scripts Module openupgrade_scripts series:19.0 labels Aug 6, 2026

@hbrunn hbrunn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the correct way to deal with this situation. If a record doesn't exist at this point, the COA wasn't migrated correctly. A fallback could be to actually create the record then, but again, getting there points to something going wrong before.

And I keep insisting that your PRs must conform to https://github.com/OCA/.github/blob/master/AI_POLICY.md

@quoc-pn

quoc-pn commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

This is not the correct way to deal with this situation. If a record doesn't exist at this point, the COA wasn't migrated correctly. A fallback could be to actually create the record then, but again, getting there points to something going wrong before.

And I keep insisting that your PRs must conform to https://github.com/OCA/.github/blob/master/AI_POLICY.md

@hbrunn I added details about my current situation to the description. I hope this provides you with more context.

@quoc-pn
quoc-pn requested a review from hbrunn August 6, 2026 09:00
@pedrobaeza

Copy link
Copy Markdown
Member

@quoc-pn you should run account_chart_update before proceeding with the migration. That can be considered a mandatory step.

@quoc-pn

quoc-pn commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

@quoc-pn you should run account_chart_update before proceeding with the migration. That can be considered a mandatory step.

@pedrobaeza Thanks for your suggestion. I'll try using account_chart_update.

@MiquelRForgeFlow MiquelRForgeFlow added this to the 19.0 milestone Aug 6, 2026
@git-pure

git-pure commented Aug 6, 2026

Copy link
Copy Markdown

Please note that I am not a code expert, but I try my best. I keep running into this error, i have spent hours trying to solve this, but my original table account_account ends at 202, there is no row 203. I have no idea where the script is pulling row 203 from. I hope this is the right place to post this.

`2026-08-06 17:12:29,127 12169 INFO newdb odoo.modules.migration: module stock_account: Running upgrade [$19.0.1.1] end-migration
2026-08-06 17:12:29,129 12169 INFO newdb OpenUpgrade: stock_account: end-migration script called with version 18.0.1.1
2026-08-06 17:12:29,909 12169 ERROR newdb odoo.sql_db: bad query: b'INSERT INTO "account_account" ("account_type", "active", "create_date", "create_uid", "non_trade", "reconcile", "write_date", "write_uid") VALUES (NULL, true, '2026-08-06T17:12:27.121767'::timestamp, 1, false, false, '2026-08-06T17:12:27.121767'::timestamp, 1) RETURNING "id"'
ERROR: null value in column "account_type" of relation "account_account" violates not-null constraint
DETAIL: Failing row contains (203, null, 1, 1, null, null, null, null, null, f, f, 2026-08-06 17:12:27.121767, 2026-08-06 17:12:27.121767, null, t, null, null).

2026-08-06 17:12:29,909 12169 ERROR newdb OpenUpgrade: stock_account: error in migration script /opt/openupgrade19/openupgrade_scripts/scripts/stock_account/19.0.1.1/end-migration.py: null value in column "account_type" of relation "account_account" violates not-null constraint
DETAIL: Failing row contains (203, null, 1, 1, null, null, null, null, null, f, f, 2026-08-06 17:12:27.121767, 2026-08-06 17:12:27.121767, null, t, null, null).

2026-08-06 17:12:29,909 12169 ERROR newdb OpenUpgrade: null value in column "account_type" of relation "account_account" violates not-null constraint
DETAIL: Failing row contains (203, null, 1, 1, null, null, null, null, null, f, f, 2026-08-06 17:12:27.121767, 2026-08-06 17:12:27.121767, null, t, null, null).`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:openupgrade_scripts Module openupgrade_scripts series:19.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants