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 <contact@dolicraft.com>
Co-authored-by: Dolicraft <contact@dolicraft.com>
This commit is contained in:
w3houde 2026-07-19 21:22:57 +07:00 committed by GitHub
parent f495b92d1f
commit cbe0335455
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 8 additions and 2 deletions

View file

@ -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);

View file

@ -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]) {