When a checkbox in the admin UI is silently overridden by a hidden global, users lose trust in every other setting.
Short answer
In Dolibarr's Holiday module, enabling "Blocked when balance is negative" on a leave type did nothing unless an undocumented global constant, HOLIDAY_DISALLOW_NEGATIVE_BALANCE, was also set. The fix removes that extra condition from the three balance checks, so the per-type setting governs on its own. It was merged as PR #39654 and closed issue #39605.
The problem
Dolibarr is an open-source ERP and CRM written in PHP. Issue #39605, reported on Dolibarr 23.0.1, described a user with one day of paid-leave balance submitting a two-day request. The request was created without an error, then approved without a warning, leaving the balance negative, even though the leave type was set to block negative balances.
Root cause
Holiday::validate(), Holiday::approve() and Holiday::update() each checked the balance like this:
if (($balance - $daysAsked) < 0 && getDolGlobalString('HOLIDAY_DISALLOW_NEGATIVE_BALANCE')) {
As the PR describes it, the per-type block_if_negative check was neutralized by this undocumented global. Blocking required the constant too, so without it the dictionary setting was ignored.
The fix
if (($balance - $daysAsked) < 0) {
$this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
return -1;
}
The PR description addresses compatibility. The block_if_negative column defaults to 0 and no shipped leave type enables it, so default behavior stays the same. That preserves the intent of an earlier commit titled "Keep same behaviour by default" while making the setting effective when an admin turns it on.
By the numbers
- Repository: Dolibarr/dolibarr, 7,826 stars (Nov 3, 2026), PHP, GPL-3.0
- Files changed: 1
- Lines: +3 / -3
- Commits: 1
- Opened: Aug 21, 2026. Merged: Sep 8, 2026. Time to merge: 17 days, 22 hours
- Review: merged by a maintainer without review comments
How the review went
There was no discussion on the pull request. A Dolibarr maintainer merged it into develop, and the issue was closed at the same time.
FAQ
Does this block leave for everyone by default?
No. Blocking only applies to leave types where an admin has enabled "Blocked when balance is negative".
Where can I read more?
See the pull request and the original issue.
The goal
Small fixes like this are easy to skip and costly to leave in place. The diff is three identical lines, and the reasoning about default behavior is in the PR, where a reviewer can check it in a minute.