Commit graph

151999 commits

Author SHA1 Message Date
Laurent Destailleur
4a409d7519 Fix balance of td with subtotal 2026-06-08 18:53:10 +02:00
Laurent Destailleur
b9961d2cdb Merge branch '23.0' of github.com:Dolibarr/dolibarr into 23.0 2026-06-08 18:25:37 +02:00
Laurent Destailleur
7208ac5e6c Fix setup color of subtotal lines 2026-06-08 18:18:43 +02:00
Nicolas Domenech
1127bde7d5
FIX Reception card shows order line description like shipment card (#38608)
The product line view of the validated reception card used the product
master description (product->description) for the tooltip and the inline
description block, while the shipment card (expedition/card.php) and the
generic line template (core/tpl/objectline_view.tpl.php) use the document
line description (line->description).

Reception lines do carry their own description (copied from
commande_fournisseurdet.description in Reception::fetch_lines()), so the
card displayed the wrong text, or nothing at all when the line description
differed from the master one. Align reception/card.php on
expedition/card.php: use line->description, and compare the inline block
against the displayed label, like the generic template does. No default
behavior change (display still gated by PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 23:34:11 +02:00
Alexandre SPANGARO
8f140fd1e7
Merge pull request #38493 from Hystepik/fix-#38461-SQL-Injection
Fix #38461 Sql Injection in PaymentVAT
2026-06-03 06:29:19 +02:00
Alexandre SPANGARO
fc4945a652
Merge branch '23.0' into fix-#38461-SQL-Injection 2026-06-03 06:22:46 +02:00
w3houde
aebf05486b
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>
2026-06-02 17:42:45 +02:00
Frédéric FRANCE
95a16f7a01
fix ticket list (#38573) 2026-06-02 15:53:51 +02:00
ATM-NicolasV
8c9d668e42
FIX Reception: require receptionlinebatch.class.php to avoid Fatal when Reception is loaded indirectly (#38481)
Reception::fetch_lines_free(), addline(), update_line() and create() all
instantiate ReceptionLineBatch, but reception.class.php never includes its
receptionlinebatch.class.php file. It works in normal navigation only because
the entry pages (reception/card.php, ...) happen to require both classes
side-by-side.

Any code path that loads Reception through a generic helper - typically
fetchObjectByElement() from core/lib/functions.lib.php, called by hooks,
external modules, or some API/CLI tooling - triggers:

    PHP Fatal error: Uncaught Error: Class "ReceptionLineBatch" not found
    in htdocs/reception/class/reception.class.php on line 1230

Reproduced on production: index.php -> llxHeader -> main_area ->
HookManager::executeHooks -> ActionsUserNavHistory::printMainArea ->
UserNavHistory::fetchAll -> fetchObjectByElement() -> Reception::fetch() ->
Reception::fetch_lines_free() -> new ReceptionLineBatch() (fatal).

Adding the missing require_once at the top of reception.class.php makes the
class always available wherever Reception is loaded, consistent with how
other Dolibarr core classes pre-load their line/child classes.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-02 09:42:11 +02:00
Pierre Ardoin
46763ac309
Update card.php (#38551) 2026-06-01 23:09:56 +02:00
atm-corentin
c66e7af312
FIX : Task::getTasksArray() phantom column efpt.search_task_options_* (#38564)
When perweek.php / perday.php submit a filter form containing at least one
projet_task extrafield search input, the SQL produced by getTasksArray()
contains a phantom WHERE clause like:

    AND (efpt.search_task_options_<field> LIKE '%-1%')

which triggers a DB_ERROR_NOSUCHFIELD.

Cause:
- perweek.php / perday.php build their search arrays via
  $extrafields->getOptionalsFromPost('projet_task', '', 'search_task_')
  which produces keys of the form 'search_task_options_<field>'.
- They also include /core/tpl/extrafields_list_search_sql.tpl.php with
  $search_options_pattern = 'search_task_options_' (see e.g. perweek.php
  lines 436 / 469 / 652), so the template's preg_replace correctly
  strips the prefix and the resulting SQL column name is right.
- However, Task::getTasksArray() includes the same template at the end of
  the SQL build but never sets $search_options_pattern. The template
  then falls back to its default value 'search_options_'
  (extrafields_list_search_sql.tpl.php line 48), which does not match
  the actual key prefix. The preg_replace becomes a no-op and the SQL
  is generated against the literal POST name instead of the column name.

Fix:
Add $search_options_pattern = 'search_task_options_' right before the
include, aligned with what perweek.php / perday.php already do.

Reproduction:
1. Enable a third-party module that adds an extrafield to the projet_task
   element type (e.g. ATM doc2project adds fk_product).
2. Open /projet/activity/perweek.php and submit the form (any filter or
   checkbox, including the project's own 'mode=mine' submit).
3. -> SQL error with phantom column efpt.search_task_options_<field>.

Verified affected versions: 20.0, 21.0, 22.0, 23.0, develop.
2026-06-01 23:07:20 +02:00
w3houde
01472ecdff
Fix #38563 skip task-driven project load when allprojects view fetch returns no row (#38565)
* Fix #38563 skip task-driven project load when allprojects view fetch returns no row

The updateline handler at htdocs/projet/tasks/time.php line 302 populates
$object via Task::fetch($id_temp) where $id_temp is the edited line's
task id. After the save, the page falls through to the render block at
line 937. In the all-projects view ($id=0, $ref=''), the outer if is
entered only because $allprojectforuser is set, then the elseif tests
$object->fetch($id, $ref) >= 0. Task::fetch returns 0 for no row but
leaves prior properties untouched, so $object->fk_project carries the
edited task's project. $projectstatic loads that project, $arrayofmassactions
gets filled, and the per-row toselect[] checkbox renders on every row
of the all-projects list, including rows for other projects.

Tighten the guard to > 0 so the body only runs when fetch actually
returned a row. The all-projects list then keeps the same render state
it had before the line edit: no projectstatic load, no massactions.

Reported by @priojk. Same code path on 23.0 and develop; 22.0 has a
different structure for this block and is not affected.

Signed-off-by: Dolicraft <contact@dolicraft.com>

* Update time.php

---------

Signed-off-by: Dolicraft <contact@dolicraft.com>
Co-authored-by: Dolicraft <contact@dolicraft.com>
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-06-01 23:00:48 +02:00
Laurent Destailleur
33608619ff Replace default terre with mars 2026-05-31 15:44:31 +02:00
Laurent Destailleur
525997adeb FIX missing escaping param securekey in url. 2026-05-31 15:44:24 +02:00
w3houde
c4375354fc
Fix #37836 Preserve task id when submitting the timespent filter (#38511)
The timespent list inside a task page was scoped by the id query
parameter (/projet/tasks/time.php?id=X). The filter form right above
the list emits hidden inputs for projectid, withproject, tab and
page_y but no input for id, so submitting the search rewrites the URL
to /projet/tasks/time.php without id and the page falls back to the
global view, displaying entries from every task.

Add a hidden id input next to the others. The form already emits
projectid and withproject, so no other parameter is affected.

The same form on 21.0 and 22.0 still contained the id input; the
regression appeared on 23.0 (the input was dropped together with
unrelated layout changes in the v23 timespent refactor). PR targets
23.0 since 22.0 is unaffected.

Reported by @chris-siebert with a precise before/after URL trace and
a working hidden-input patch.

Signed-off-by: Dolicraft <contact@dolicraft.com>
Co-authored-by: Dolicraft <contact@dolicraft.com>
2026-05-30 23:18:41 +02:00
w3houde
c7ff62a0ea
Fix #38103 Surface SSRF block reason in webhook failure message (#38517)
Webhooks targeting a host on a private/reserved range, on the local
network or on a known cloud metadata server have been blocked since
the GHSA-hh5p-m24x-fwx2 SSRF hardening landed in 23.0.2 (commit
b565d497f9). getURLContent() returns http_code 400 with a textual
explanation in $response['content'], but the webhook trigger only
logged "httpcode=400 curl_error_no=" without that content, so the
operator could not tell their webhook had been blocked on purpose
versus a generic network failure and could not discover the
$dolibarr_allow_localurl_for_webhooks flag that re-enables the
local-host case.

Append $response['content'] to the error message when the failure
matches the SSRF-block signature (curl_error_no empty, http_code
exactly 400, content non-empty). The textual hint emitted by
isIPAllowed() is then visible both in syslog and in the
WebhookHistory record.

The security fix itself is not changed.

Reported by @whoisbarry.

Signed-off-by: Dolicraft <contact@dolicraft.com>
Co-authored-by: Dolicraft <contact@dolicraft.com>
2026-05-30 23:14:50 +02:00
Hystepik
ed6b759611 Fix #38461 Sql Injection in PaymentVAT 2026-05-29 15:50:03 +02:00
Laurent Destailleur
099f88a208 Better sanitization of GETPOST('sortfield') with aZ09comma 2026-05-29 12:07:41 +02:00
Alexandre SPANGARO
a0305a89cf
Merge pull request #38464 from aspangaro/23_fixmemberlistsort
FIX #38427 Donation - List - Sort order don't work if company is linked to third party
2026-05-28 15:45:38 +02:00
Alexandre SPANGARO
8a96ea337f FIX Donation - List - Sort order don't work if company is linked to third party 2026-05-27 14:15:09 +02:00
Regis Houssin
aa4d9cc8a6
FIX missing PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES checking (#38442) 2026-05-26 16:00:28 +02:00
HUPI
5675986268
Fix #38407: API addtimespent crashes with "Illegal offset type" on PHP 8+ (#38408)
* Fix: API addtimespent crashes with "Illegal offset type" on PHP 8+

Fixes #38407

The @param annotations for $date (datetime|string) and $progress (int|null)
in Tasks::addTimeSpent() use union types, which Restler's Validator parses
into a PHP array. Then Validator::validate() at line 427 evaluates
isset(static::$preFilters[$info->type]) using that array as an array key,
which throws "Illegal offset type in isset or empty" on PHP 8+. Every call
to POST /tasks/{id}/addtimespent therefore returns HTTP 500 before the
endpoint code runs.

Use single-type annotations matching the convention already used by
Tasks::putTimeSpent in the same file: @param datetime + @phan-param string
for the date, and plain @param int for progress (its -1 default already
encodes "leave unchanged", so int|null is not needed).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Vincent Moreno <vincent.moreno@hupi.fr>

* Update parameter type for date in API documentation

* Update api_tasks.class.php

---------

Signed-off-by: Vincent Moreno <vincent.moreno@hupi.fr>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-26 06:52:14 +02:00
William Mead
0d8dc4529b
FIX intervention API line updating (#38414)
* Fixed intervention api line updating

* Fixed type
2026-05-25 02:44:25 +02:00
Laurent Destailleur
f32a4884e8 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into 23.0 2026-05-25 01:07:38 +02:00
Laurent Destailleur
bd97fbd653 Fix debian package 2026-05-25 01:01:08 +02:00
Laurent Destailleur
e67c919850 Prepare 22.0.5 2026-05-24 21:30:14 +02:00
Laurent Destailleur
0e87c73107 Fix type 2026-05-23 01:46:54 +02:00
Laurent Destailleur
32a6a95c34 Merge branch '23.0' of git@github.com:Dolibarr/dolibarr.git into 23.0 2026-05-23 01:33:56 +02:00
Laurent Destailleur
a2eadd7ed0 FIX out of dynamically recalculated unit price inc tax was missing
relative discount.
2026-05-23 01:33:38 +02:00
daraelmin
4aff1a7741
FIX: GDPR cron job false positive errors and birth date format (#38218)
- Fixed false positive error logging in `_recordActionResult`: an `update()` returning 0 (no rows affected) is no longer treated as an error (changed `<= 0` to `< 0`).
- Fixed `birth` date data type for Adherent anonymization: replaced the static string '1900-01-01' with a UNIX timestamp using `dol_mktime()` to comply with Dolibarr Core standards and prevent silent DAL failures.
2026-05-22 21:46:09 +02:00
Sacha Pignot
e2c52e8d02
FIX #37867 Rename MAIN_MODULE_OPENIDCONNECT to MAIN_AUTHENTICATION_OIDC_ON in migration (#38326)
OIDC was converted from a module to a config-level feature in v23 (#36051),
renaming the enable constant. No migration was added to update existing
llx_const rows, causing OIDC to appear disabled after a v22 -> v23 upgrade.
2026-05-22 13:52:14 +02:00
Pierre Grasswill
139ecd4a7c
FIX: Allow editing quantity to produce on MO while in draft status (#38176)
Add an inline edit pencil next to 'QtyToProduce' on the MO card and the
MO production view when the order is still in DRAFT status. On save:

1. The MO qty is updated through Mo::update(), which internally calls
   Mo::updateProduction() to scale 'toconsume'/'toproduce' lines
   proportionally (newQty/oldQty), respecting qty_frozen flags.

2. The 'toproduce' line for the MO's main product is then explicitly
   realigned to match the MO qty exactly. This guards against legacy
   inconsistent states and floating-point drift from successive ratio
   scaling, while leaving BOM sub-product ratios and frozen lines
   untouched.

The handler is placed BEFORE the include of
actions_addupdatedelete.inc.php, because that file has a generic
'set<key>' matcher that would otherwise intercept 'setqty', call
$object->fetch() + update() without setting $object->oldQty, and
silently skip the line scaling.

The edit is gated both client-side (pencil only shown when DRAFT) and
server-side (setqty handler checks STATUS_DRAFT) to prevent any
modification once the MO has been validated.

Note: the field type 'real' is temporarily overridden to 'numeric' only
while the edit pencil is active (action=editqty), because
Form::editfieldval() in html.form.class.php does not handle 'real' and
would render the Save/Cancel buttons with no <input> field in between.
Read-mode rendering (via price()) is preserved.
2026-05-22 13:31:23 +02:00
Frédéric FRANCE
0d068d3cb6
fix test (#38392)
* fix test

* Update config.inc.php

* Update config.inc.php

* Update config.inc.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-22 13:15:31 +02:00
John BOTELLA
4f2b717513
Fix php 8 warning (#38343)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-22 11:38:56 +02:00
Laurent Destailleur
228da2b7b7 ci 2026-05-22 11:35:09 +02:00
Laurent Destailleur
b1e13647b2 Fix css 2026-05-22 11:30:30 +02:00
Laurent Destailleur
8f04bb91e3 css 2026-05-22 11:27:13 +02:00
John BOTELLA
928b206514
Fix hard reading on bad screen (#38344) 2026-05-22 11:24:48 +02:00
Laurent Destailleur
395e3d7861 Merge branch '23.0' of git@github.com:Dolibarr/dolibarr.git into 23.0 2026-05-22 11:11:38 +02:00
Laurent Destailleur
2d050a58a6 ci 2026-05-22 11:11:22 +02:00
Laurent Destailleur
1ca89526f0 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2026-05-22 08:29:58 +02:00
Francis Appels
e5d7bc0334
FIX: Kit Substock return on shipment cancel/delete (#38373) 2026-05-21 22:15:46 +02:00
John BOTELLA
92e7a03dc4
Fix : product weight default selection (#38374) 2026-05-21 22:12:17 +02:00
Iván Guevara
1213bccb24
Fix: avoid undefined method stdClass::isEmpty() on PHP 8.1 (#38258)
* Fix: avoid undefined method stdClass::isEmpty() on PHP 8.1

This fixes a fatal error when updating product prices on PHP 8.1 due to stdClass object handling.

* Update ProductCombination.class.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-21 22:10:32 +02:00
Laurent Destailleur
7d5777e41f FIX #36777 2026-05-21 22:00:20 +02:00
Christian Humpel
37c0b3eeb6
Fix selectobject.php unknown-Array Key (#23392 AJAX endless turning) (#38323)
* Fix selectobject.php unknown-Array Key

* remove Debug line

* remove Withespace
2026-05-21 21:57:30 +02:00
sonikf
9118a310d1
fix translation for non latin languages (#38334)
* fix translation

* fix translation

* fix phan

* fix phan
2026-05-21 21:55:44 +02:00
Alexandre SPANGARO
92b10c71eb
ChangeLog (#38315) 2026-05-21 21:52:11 +02:00
Laurent Destailleur
7c144b22ff FIX out of dynamically recalculated unit price inc tax was missing
relative discount.
2026-05-21 21:22:58 +02:00
Laurent Destailleur
5efc5e85a9 Fix tags 2026-05-20 17:29:46 +02:00