From 3eae4fa8841df6cd2ce1c124a4f204ff1ba1f008 Mon Sep 17 00:00:00 2001 From: snt Date: Sat, 14 Feb 2026 17:45:53 +0100 Subject: [PATCH] [FIX] product_sale_price_from_pricelist: Clean up old ir_property records Fixed error: TypeError: float() argument must be a string or a real number, not 'dict' when entering decimal values in product form. Added post-migration to delete ir_property records left over from when fields were company_dependent. These leftover records were causing dict values to be passed to Float fields during onchange operations. Migration checks if ir_property table exists to handle fresh installs gracefully. Version bump: 18.0.2.3.0 -> 18.0.2.4.0 --- .../CHANGELOG.md | 10 +++ .../__manifest__.py | 2 +- .../migrations/18.0.2.4.0/post-migration.py | 74 +++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 product_sale_price_from_pricelist/migrations/18.0.2.4.0/post-migration.py diff --git a/product_sale_price_from_pricelist/CHANGELOG.md b/product_sale_price_from_pricelist/CHANGELOG.md index 80b57f6..ef38340 100644 --- a/product_sale_price_from_pricelist/CHANGELOG.md +++ b/product_sale_price_from_pricelist/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [18.0.2.4.0] - 2026-02-14 + +### Fixed + +- **Clean up old ir_property records** + - Error: `TypeError: float() argument must be a string or a real number, not 'dict'` + - Added post-migration to delete ir_property records left over from company_dependent fields + - This prevents dict values from being passed to Float fields during onchange + - Migration runs after module load to ensure ir_property table exists + ## [18.0.2.3.0] - 2026-02-14 ### Fixed diff --git a/product_sale_price_from_pricelist/__manifest__.py b/product_sale_price_from_pricelist/__manifest__.py index 1fe4285..32023e7 100644 --- a/product_sale_price_from_pricelist/__manifest__.py +++ b/product_sale_price_from_pricelist/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { # noqa: B018 "name": "Product Sale Price from Pricelist", - "version": "18.0.2.3.0", + "version": "18.0.2.4.0", "category": "product", "summary": "Set sale price from pricelist based on last purchase price", "author": "Odoo Community Association (OCA), Criptomart", diff --git a/product_sale_price_from_pricelist/migrations/18.0.2.4.0/post-migration.py b/product_sale_price_from_pricelist/migrations/18.0.2.4.0/post-migration.py new file mode 100644 index 0000000..d2386b1 --- /dev/null +++ b/product_sale_price_from_pricelist/migrations/18.0.2.4.0/post-migration.py @@ -0,0 +1,74 @@ +# Copyright (C) 2026 Criptomart +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging + +_logger = logging.getLogger(__name__) + + +def migrate(cr, version): + """Clean up old ir_property records for fields that are no longer company_dependent. + + This migration removes ir_property records that were created when these fields + were company_dependent. These records can cause TypeError: float() argument must + be a string or a real number, not 'dict' when Odoo tries to read the fields. + + Fields cleaned up: + - last_purchase_price_updated + - list_price_theoritical + - last_purchase_price_received + - last_purchase_price_compute_type + """ + _logger.info( + "Cleaning up ir_property records for product_sale_price_from_pricelist fields" + ) + + # Check if ir_property table exists + cr.execute(""" + SELECT EXISTS ( + SELECT FROM information_schema.tables + WHERE table_name = 'ir_property' + ) + """) + table_exists = cr.fetchone()[0] + + if not table_exists: + _logger.info( + "Table ir_property does not exist yet, skipping cleanup (fresh install)" + ) + return + + # Delete all ir_property records for these fields on product.product + cr.execute(""" + DELETE FROM ir_property + WHERE name IN ( + 'last_purchase_price_updated', + 'list_price_theoritical', + 'last_purchase_price_received', + 'last_purchase_price_compute_type' + ) + AND res_id LIKE 'product.product,%%' + """) + deleted_count = cr.rowcount + _logger.info("Deleted %s ir_property records for product.product", deleted_count) + + # Also clean up for product.template if any exist + cr.execute(""" + DELETE FROM ir_property + WHERE name IN ( + 'last_purchase_price_updated', + 'list_price_theoritical', + 'last_purchase_price_received', + 'last_purchase_price_compute_type' + ) + AND res_id LIKE 'product.template,%%' + """) + deleted_template_count = cr.rowcount + _logger.info( + "Deleted %s ir_property records for product.template", deleted_template_count + ) + + _logger.info( + "Migration completed successfully. Total records deleted: %s", + deleted_count + deleted_template_count, + )