From cbe0335455a6e192faeb46ff96a3011d28dcedc9 Mon Sep 17 00:00:00 2001 From: w3houde Date: Sun, 19 Jul 2026 21:22:57 +0700 Subject: [PATCH] Fix #39143 store computed extrafields with object context (#39172) When MAIN_STORE_COMPUTED_EXTRAFIELDS is enabled, insertExtraFields() and updateExtraField() evaluated the computed formula without setting the global $objectoffield to the current object, so formulas relying on $objectoffield->array_options returned a wrong value (often 0) when stored, unlike fetch_optionals() which already sets it. The list template also always recomputed computed extrafields, but the raw row available in a list has no object context, giving wrong display and wrong totals. When MAIN_STORE_COMPUTED_EXTRAFIELDS is enabled the value stored in database is now used instead. Signed-off-by: Dolicraft Co-authored-by: Dolicraft --- htdocs/core/class/commonobject.class.php | 4 ++++ htdocs/core/tpl/extrafields_list_print_fields.tpl.php | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 641da65657b..ded8ec4fa35 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7011,6 +7011,8 @@ abstract class CommonObject if (!empty($attrfieldcomputed)) { if (getDolGlobalString('MAIN_STORE_COMPUTED_EXTRAFIELDS')) { + global $objectoffield; // We set a global variable to $objectoffield so + $objectoffield = $this; // we can use it inside the computed formula $value = dol_eval((string) $attrfieldcomputed, 1, 0, '2'); dol_syslog($langs->trans("Extrafieldcomputed")." on ".$attributeLabel."(".$value.")", LOG_DEBUG); $new_array_options[$key] = $value; @@ -7499,6 +7501,8 @@ abstract class CommonObject //dol_syslog("attributeType=".$attributeType, LOG_DEBUG); if (!empty($attrfieldcomputed)) { if (getDolGlobalString('MAIN_STORE_COMPUTED_EXTRAFIELDS')) { + global $objectoffield; // We set a global variable to $objectoffield so + $objectoffield = $this; // we can use it inside the computed formula $value = dol_eval((string) $attrfieldcomputed, 1, 0, '2'); dol_syslog($langs->trans("Extrafieldcomputed")." on ".$attributeLabel."(".$value.")", LOG_DEBUG); diff --git a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php index 22517ac67eb..31c681f88b1 100644 --- a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php +++ b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php @@ -76,8 +76,10 @@ if (!empty($extrafieldsobjectkey) && !empty($extrafields->attributes[$extrafield $value = (isset($obj->$tmpkey) ? $obj->$tmpkey : (isset($obj->array_options[$tmpkey]) ? $obj->array_options[$tmpkey] : '')); } - // If field is a computed field, we make computation to get value - if ($extrafields->attributes[$extrafieldsobjectkey]['computed'][$key]) { + // If field is a computed field, we make computation to get value. + // But when MAIN_STORE_COMPUTED_EXTRAFIELDS is enabled, the value stored in database is used instead, + // because the raw row available in a list has no object context (like $objectoffield->array_options) that the formula may rely on. + if ($extrafields->attributes[$extrafieldsobjectkey]['computed'][$key] && !getDolGlobalString('MAIN_STORE_COMPUTED_EXTRAFIELDS')) { $objectoffield = $object; // For compatibility with the computed formula. $objectoffield is exported by dol_eval(). $value = dol_eval((string) $extrafields->attributes[$extrafieldsobjectkey]['computed'][$key], 1, 1, '2'); if (is_numeric(price2num($value)) && $extrafields->attributes[$extrafieldsobjectkey]['totalizable'][$key]) {