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 dc4a28cd0b) 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 <contact@dolicraft.com>

* 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 <contact@dolicraft.com>

* 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 <contact@dolicraft.com>

---------

Signed-off-by: Dolicraft <contact@dolicraft.com>
Co-authored-by: Dolicraft <contact@dolicraft.com>
This commit is contained in:
w3houde 2026-06-02 17:42:45 +02:00 committed by GitHub
parent 95a16f7a01
commit aebf05486b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

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