From aebf05486b99bf10285f22b8574990fe8ef74174 Mon Sep 17 00:00:00 2001 From: w3houde Date: Tue, 2 Jun 2026 17:42:45 +0200 Subject: [PATCH] Fix #38386 restore origin from db before reception line update handler (#38558) * Fix #38386 restore origin from db before reception line update handler PR #36134 (standalone reception, commit dc4a28cd0be1) changed the $origin / $origin_id init at the top of htdocs/reception/card.php so that an empty origin no longer falls back to 'reception' and the origin_id fallbacks are gated on a non-empty $origin. The earlier block that restored $origin from the loaded $object->origin (still on 22.0 at line 136) was dropped at the same time, leaving the restoration only in the render section that runs much later (around line 1953 on develop). When the line edit form on an existing reception submits, it posts action=updateline and id=N with no origin field, so $origin stays empty when the action handler at line 762 is reached. The standalone branch requires the global RECEPTION_STANDALONE to be set and the origin branch requires $origin and $origin_id > 0, so a regular reception falls through both branches and the line update (quantity, comment, batch, extrafields) is silently dropped. Header data and status changes still work because they use other handlers. Re-introduce the post-fetch restoration right after actions_fetchobject.inc.php so the action handler sees the same origin context the page had when the form was rendered. The fix is minimal: only restore when an id was loaded and the local variable is still empty, so flows that genuinely carry an origin in the POST (the create-from-supplier-order form) are untouched. Reported by @AndiFoFFN on 23.0.3. Same regression on develop. Signed-off-by: Dolicraft * Fix #38386 address standalone-mode regression and refresh view after save Address review feedback from @sonikf on PR #38558: - Gate the post-fetch origin restore on $object->origin_id > 0 so a standalone reception (origin_id = 0) is not affected. With the prior version, Reception::fetch hydrated $object->origin to the literal 'commande' fallback (line 548 'For compatibility'), and the restore block then assigned 'commande' to the local $origin, breaking the standalone branch of the updateline handler. - Prefer $object->origin_type over the deprecated $object->origin alias. - Redirect after a successful updateline so the page leaves edit mode and re-reads the saved values, matching the cancel path and the header-data save handlers. Without it the view stayed on the edit form even after the row was correctly written. Signed-off-by: Dolicraft * Fix #38386 drop redundant isset on origin_id to satisfy phpstan CommonObject::$origin_id is declared @var int non-nullable, so the isset() guard around the int comparison was redundant and phpstan rejects 'Property in isset() is not nullable'. The > 0 test alone is equivalent for the original intent (skip the restore for standalone receptions, whose origin_id is 0). Signed-off-by: Dolicraft --------- Signed-off-by: Dolicraft Co-authored-by: Dolicraft --- htdocs/reception/card.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index 90dd77d6cd5..c471b02fe7e 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -134,6 +134,28 @@ $extrafields->fetch_name_optionals_label($objectorder->table_element_line); // Load object. Make an object->fetch include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once' +// Restore $origin and $origin_id from the loaded object when the request only carried the +// reception id (e.g. the line edit form on an existing reception posts action=updateline +// and id=N but no origin field). Without this, the action handler below sees $origin +// empty and silently skips both its standalone and its origin branches, so updates to +// quantity, comment, batch and extrafields on an existing line are not persisted +// (see issue #38386, regression from PR #36134). +// The restore is gated on $object->origin_id > 0 so standalone receptions, which have +// no upstream origin, are not affected: $origin stays empty and the standalone branch +// of the updateline handler is still selected. +if ($object->origin_id > 0) { + if (empty($origin)) { + if (!empty($object->origin_type)) { + $origin = $object->origin_type; + } elseif (is_string($object->origin) && $object->origin !== '') { + $origin = $object->origin; + } + } + if (empty($origin_id)) { + $origin_id = $object->origin_id; + } +} + // Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context $hookmanager->initHooks(array('receptioncard', 'globalcard')); @@ -904,6 +926,12 @@ if (empty($reshook)) { $ret = $object->fetch($object->id); // Reload to get new records $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } + + // Redirect after the successful save so the page leaves edit mode and the + // updated values are read back from DB, matching the cancel path below + // and the header-data save handlers (see issue #38386). + header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); + exit(); } else { header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To reshow the record we edit exit();