[FIX] product_sale_price_from_pricelist: Protect Float computed fields

This commit is contained in:
snt 2026-02-14 18:20:20 +01:00
parent b5410d24bc
commit 713acd065e
3 changed files with 27 additions and 12 deletions

View file

@ -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.6.0] - 2026-02-14
### Fixed
- **Protected Float computed fields to always return valid numbers**
- Error: `TypeError: value.toFixed is not a function` in product list view
- Added explicit float() conversion in all Float computed methods
- Ensures computed fields never return False, None, or dict values
- This prevents JavaScript formatting errors in tree views with monetary columns
## [18.0.2.5.0] - 2026-02-14
### Fixed

View file

@ -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.5.0",
"version": "18.0.2.6.0",
"category": "product",
"summary": "Set sale price from pricelist based on last purchase price",
"author": "Odoo Community Association (OCA), Criptomart",

View file

@ -91,11 +91,12 @@ class ProductTemplate(models.Model):
@api.depends("product_variant_ids.list_price_theoritical")
def _compute_list_price_theoritical(self):
for template in self:
template.list_price_theoritical = (
template.product_variant_ids[:1].list_price_theoritical
if template.product_variant_ids
else 0.0
)
if template.product_variant_ids:
value = template.product_variant_ids[:1].list_price_theoritical
# Ensure we always return a valid float (never False/None/dict)
template.list_price_theoritical = float(value or 0.0)
else:
template.list_price_theoritical = 0.0
def _inverse_list_price_theoritical(self):
for template in self:
@ -110,11 +111,12 @@ class ProductTemplate(models.Model):
@api.depends("product_variant_ids.last_purchase_price_received")
def _compute_last_purchase_price_received(self):
for template in self:
template.last_purchase_price_received = (
template.product_variant_ids[:1].last_purchase_price_received
if template.product_variant_ids
else 0.0
)
if template.product_variant_ids:
value = template.product_variant_ids[:1].last_purchase_price_received
# Ensure we always return a valid float (never False/None/dict)
template.last_purchase_price_received = float(value or 0.0)
else:
template.last_purchase_price_received = 0.0
def _inverse_last_purchase_price_received(self):
for template in self:
@ -155,7 +157,10 @@ class ProductTemplate(models.Model):
def _compute_last_purchase_price(self):
"""Alias for backward compatibility with pricelist computations."""
for template in self:
template.last_purchase_price = template.last_purchase_price_received
# Ensure we always return a valid float (never False/None/dict)
template.last_purchase_price = float(
template.last_purchase_price_received or 0.0
)
def _search_last_purchase_price(self, operator, value):
return [("last_purchase_price_received", operator, value)]