Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

This commit is contained in:
Laurent Destailleur 2026-06-10 20:01:00 +02:00
commit fc380fc584
43 changed files with 590 additions and 318 deletions

View file

@ -48,7 +48,6 @@ jobs:
console.log('Detected language:', isEnglish ? 'english' : 'not english')
#if (hasYoutubeMusic || !isEnglish) {
if (hasYoutubeMusic) {
console.log('Deleting comment...')

View file

@ -8766,18 +8766,6 @@ parameters:
count: 1
path: ../../../htdocs/takepos/split.php
-
message: '#^If condition is always true\.$#'
identifier: if.alwaysTrue
count: 1
path: ../../../htdocs/theme/eldy/manifest.json.php
-
message: '#^If condition is always true\.$#'
identifier: if.alwaysTrue
count: 1
path: ../../../htdocs/theme/md/manifest.json.php
-
message: '#^Negated boolean expression is always true\.$#'
identifier: booleanNot.alwaysTrue

View file

@ -1165,6 +1165,7 @@ if ($action == 'edit') {
print load_fiche_titre($langs->trans("DoTestServerAvailability"));
include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
$mail = new CMailFile('test', '', '', '', array(), array(), array(), '', '', 0, 0, '', '', '', $trackid, $sendcontext);
$errormsg = '';

View file

@ -35,6 +35,13 @@ if (!defined('CSRFCHECK_WITH_TOKEN') && (empty($_GET['action']) || $_GET['action
define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
}
// The modules list is a setup hub: force the menu context to "home" when the
// caller did not provide one, so the previously visited module's menu does not
// stick when the user comes back to this page (issue 38058).
if (!isset($_GET['mainmenu']) && !isset($_POST['mainmenu'])) {
$_GET['mainmenu'] = 'home';
}
// Load Dolibarr environment
require '../main.inc.php';
/**

View file

@ -396,11 +396,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// Confirmation to delete
if ($action == 'delete') {
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteBillOfMaterials'), $langs->trans('ConfirmDeleteBillOfMaterials'), 'confirm_delete', '', 0, 1);
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('DeleteBillOfMaterials'), $langs->trans('ConfirmDeleteBillOfMaterials'), 'confirm_delete', '', 0, 1);
}
// Confirmation to delete line
if ($action == 'deleteline') {
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'lineid' => $lineid]), $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
}
// Confirmation of validation
@ -438,7 +438,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
);
}
if (!$error) {
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $text, 'confirm_validate', $formquestion, 0, 1, 220);
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('Validate'), $text, 'confirm_validate', $formquestion, 0, 1, 220);
} else {
setEventMessage($langs->trans('Error'), 'errors');
$action = '';
@ -465,7 +465,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
);
}
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Close'), $text, 'confirm_close', $formquestion, 0, 1, 220);
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('Close'), $text, 'confirm_close', $formquestion, 0, 1, 220);
}
// Confirmation of reopen
@ -489,22 +489,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
);
}
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ReOpen'), $text, 'confirm_reopen', $formquestion, 0, 1, 220);
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('ReOpen'), $text, 'confirm_reopen', $formquestion, 0, 1, 220);
}
// Clone confirmation
if ($action == 'clone') {
// Create an array for form
$formquestion = array();
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneBillOfMaterials', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('ToClone'), $langs->trans('ConfirmCloneBillOfMaterials', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
}
// Confirmation of action xxxx
// Confirmation of action setdraft
if ($action == 'setdraft') {
$text = $langs->trans('ConfirmSetToDraft', $object->ref);
$formquestion = array();
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('SetToDraft'), $text, 'confirm_setdraft', $formquestion, 0, 1, 220);
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('SetToDraft'), $text, 'confirm_setdraft', $formquestion, 0, 1, 220);
}
// Call Hook formConfirm
@ -741,14 +741,14 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// Back to draft
if ($object->status == $object::STATUS_VALIDATED) {
if ($permissiontoadd) {
print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=setdraft&token='.newToken().'">'.$langs->trans("SetToDraft").'</a>'."\n";
print '<a class="butAction" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'setdraft'], true).'">'.$langs->trans("SetToDraft").'</a>'."\n";
}
}
// Modify
if ($object->status == $object::STATUS_DRAFT) {
if ($permissiontoadd) {
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken().'">'.$langs->trans("Modify").'</a>'."\n";
print '<a class="butAction" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'edit'], true).'">'.$langs->trans("Modify").'</a>'."\n";
} else {
print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans('Modify').'</a>'."\n";
}
@ -758,7 +758,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
if ($object->status == $object::STATUS_DRAFT) {
if ($permissiontoadd) {
if (is_array($object->lines) && count($object->lines) > 0) {
print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=validate&amp;token='.newToken().'">'.$langs->trans("Validate").'</a>'."\n";
print '<a class="butAction" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'validate'], true).'">'.$langs->trans("Validate").'</a>'."\n";
} else {
$langs->load("errors");
print '<a class="butActionRefused classfortooltip" href="" title="'.$langs->trans("ErrorAddAtLeastOneLineFirst").'">'.$langs->trans("Validate").'</a>'."\n";
@ -768,38 +768,38 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// Re-open
if ($permissiontoadd && $object->status == $object::STATUS_CANCELED) {
print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("ReOpen").'</a>'."\n";
print '<a class="butAction" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'reopen'], true).'">'.$langs->trans("ReOpen").'</a>'."\n";
}
// Create MO
if (isModEnabled('mrp')) {
if ($object->status == $object::STATUS_VALIDATED && $user->hasRight('mrp', 'write')) {
print '<a class="butAction" href="'.DOL_URL_ROOT.'/mrp/mo_card.php?action=create&fk_bom='.$object->id.'&token='.newToken().'&backtopageforcancel='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id).'">'.$langs->trans("CreateMO").'</a>'."\n";
print '<a class="butAction" href="'.dolBuildUrl(DOL_URL_ROOT.'/mrp/mo_card.php', ['action' => 'create', 'fk_bom' => $object->id], true).'&backtopageforcancel='.urlencode(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id])).'">'.$langs->trans("CreateMO").'</a>'."\n";
}
}
// Clone
if ($permissiontoadd) {
print dolGetButtonAction($langs->trans("ToClone"), '', 'clone', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=clone&object=bom', 'clone', $permissiontoadd);
print dolGetButtonAction($langs->trans("ToClone"), '', 'clone', dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'clone', 'object' => 'bom'], true), 'clone', $permissiontoadd);
}
// Close / Cancel
if ($permissiontoadd && $object->status == $object::STATUS_VALIDATED) {
print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=close&token='.newToken().'">'.$langs->trans("Disable").'</a>'."\n";
print '<a class="butActionDelete" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'close'], true).'">'.$langs->trans("Disable").'</a>'."\n";
}
/*
if ($user->hasRight('bom', 'write')) {
if ($object->status == 1) {
print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=disable&token='.newToken().'">'.$langs->trans("Disable").'</a>'."\n";
print '<a class="butActionDelete" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'disenable'], true).'">'.$langs->trans("Disable").'</a>'."\n";
} else {
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=enable&token='.newToken().'">'.$langs->trans("Enable").'</a>'."\n";
print '<a class="butAction" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'enable'], true).'">'.$langs->trans("Enable").'</a>'."\n";
}
}
*/
// Delete
print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', $permissiontodelete);
print dolGetButtonAction($langs->trans("Delete"), '', 'delete', dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'delete'], true), 'delete', $permissiontodelete);
}
print '</div>'."\n";
}

View file

@ -2,7 +2,7 @@
/* Copyright (C) 2019 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2023 Benjamin Falière <benjamin.faliere@altairis.fr>
* Copyright (C) 2023 Charlene Benke <charlene@patas-monkey.com>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
@ -1159,7 +1159,9 @@ class BOM extends CommonObject
$label = implode($this->getTooltipContentArray($params));
}
$url = DOL_URL_ROOT.'/bom/bom_card.php?id='.$this->id;
$baseurl = DOL_URL_ROOT.'/bom/bom_card.php';
$query = ['id' => $this->id];
if ($option != 'nolink') {
// Add param to save lastsearch_values or not
@ -1168,9 +1170,10 @@ class BOM extends CommonObject
$add_save_lastsearch_values = 1;
}
if ($add_save_lastsearch_values) {
$url .= '&save_lastsearch_values=1';
$query = array_merge($query, ['save_lastsearch_values' => 1]);
}
}
$url = dolBuildUrl($baseurl, $query);
$linkclose = '';
if (empty($notooltip)) {

View file

@ -352,7 +352,18 @@ class FormSetup
}
$this->setupNotEmpty++;
$out .= '<tr class="'.$trClass.'">';
$tableLineAttr = [
'id' => 'setup-line-item_'. preg_replace('/[^a-zA-Z_]/', '', $item->confKey),
'class' => $trClass
];
if ($item->getType() !== 'title') {
$tableLineAttr['data-conf-key'] = $item->confKey;
}
$tableLineAttrCompiled = commonHtmlAttributeBuilder($tableLineAttr);
$out .= '<tr '. implode(' ', $tableLineAttrCompiled).' >';
$out .= '<td class="col-setup-title'.(!empty($item->fieldParams['isMandatory']) ? ' fieldrequired' : '').'">';
$out .= '<span id="helplink'.$item->confKey.'" class="spanforparamtooltip">';
@ -658,9 +669,15 @@ class FormSetupItem
/** @var bool|string set this var to override field input */
public $fieldInputOverride = false;
/** @var callable this will be call before fieldInputOverride */
public $fieldInputCallBack;
/** @var bool|string set this var to override field output */
public $fieldOutputOverride = false;
/** @var callable this will be call before fieldOutputCallBack */
public $fieldOutputCallBack;
/** @var int */
public $rank = 0;
@ -771,8 +788,7 @@ class FormSetupItem
return $reshook;
}
if (!empty($this->saveCallBack) && is_callable($this->saveCallBack)) {
if ($this->saveCallBack !== null && is_callable($this->saveCallBack)) {
return call_user_func($this->saveCallBack, $this);
}
@ -818,7 +834,7 @@ class FormSetupItem
*/
public function setValueFromPost()
{
if (!empty($this->setValueFromPostCallBack) && is_callable($this->setValueFromPostCallBack)) {
if ($this->setValueFromPostCallBack !== null && is_callable($this->setValueFromPostCallBack)) {
return call_user_func($this->setValueFromPostCallBack);
}
@ -898,6 +914,14 @@ class FormSetupItem
{
global $conf;
if ($this->fieldInputCallBack !== null && is_callable($this->fieldInputCallBack)) {
// can be used to populate fieldInputOverride, fieldOverride or change stuff
$resCallback = call_user_func($this->fieldInputCallBack, $this);
if (!empty($resCallback)) {
return $resCallback;
}
}
if (!empty($this->fieldOverride)) {
return $this->fieldOverride;
}
@ -1310,6 +1334,14 @@ class FormSetupItem
{
global $conf, $user, $langs;
if ($this->fieldOutputCallBack !== null && is_callable($this->fieldOutputCallBack)) {
// can be used to populate fieldOutputOverride, fieldOverride or change stuff
$resCallback = call_user_func($this->fieldOutputCallBack, $this);
if (!empty($resCallback)) {
return $resCallback;
}
}
if (!empty($this->fieldOverride)) {
return $this->fieldOverride;
}

View file

@ -2,7 +2,7 @@
/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2021 Florian Henry <florian.henry@scopen.fr>
* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
@ -28,6 +28,16 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var ExtraFields $extrafields
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*
* @var string $dolibarr_main_url_root
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
@ -37,16 +47,6 @@ require_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorbooth.class
require_once DOL_DOCUMENT_ROOT.'/eventorganization/lib/eventorganization_conferenceorbooth.lib.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*
* @var string $dolibarr_main_url_root
*/
// Load translation files required by the page
$langs->loadLangs(array('eventorganization', 'projects'));
@ -66,7 +66,6 @@ $withproject = GETPOSTINT('withproject');
// Initialize a technical objects
$object = new ConferenceOrBooth($db);
$extrafields = new ExtraFields($db);
$projectstatic = new Project($db);
$diroutputmassaction = $conf->eventorganization->dir_output.'/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array($contextpage, 'globalcard')); // Note that conf->hooks_modules contains array

View file

@ -11,7 +11,7 @@
* Copyright (C) 2015 Claudio Aschieri <c.aschieri@19.coop>
* Copyright (C) 2016-2018 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2016 Yasser Carreón <yacasia@gmail.com>
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2020 Lenin Rivas <lenin@leninrivas.com>
* Copyright (C) 2022 Josep Lluís Amador <joseplluis@lliuretic.cat>
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
@ -43,12 +43,12 @@ require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var ExtraFields $extrafields
* @var HookManager $hookmanager
* @var Societe $mysoc
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
@ -56,7 +56,6 @@ require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/sendings.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/modules/expedition/modules_expedition.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
require_once DOL_DOCUMENT_ROOT . '/product/stock/class/productlot.class.php';
require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php';
@ -116,7 +115,6 @@ $hideref = (GETPOSTINT('hideref') ? GETPOSTINT('hideref') : (getDolGlobalString(
$object = new Expedition($db);
$objectorder = new Commande($db);
$extrafields = new ExtraFields($db);
// fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);

View file

@ -3,7 +3,7 @@
* Copyright (C) 2005-2011 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2023 Christian Foellmann <christian@foellmann.de>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2025-2026 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
@ -28,6 +28,13 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php';
@ -38,13 +45,6 @@ if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
}
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array('orders', 'sendings', 'companies'));

View file

@ -5,7 +5,7 @@
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2025-2026 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
@ -30,6 +30,13 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/lib/order.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
@ -40,14 +47,6 @@ if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
}
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array('companies', 'other'));

View file

@ -4,7 +4,7 @@
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2020 Tobias Sekan <tobias.sekan@startmail.com>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -28,9 +28,6 @@
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
@ -38,6 +35,8 @@ require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
// Load translation files required by the page
$langs->loadLangs(array('orders', 'sendings'));

View file

@ -10,7 +10,7 @@
* Copyright (C) 2024 Benjamin Falière <benjamin.faliere@altairis.fr>
* Copyright (C) 2024 Vincent Maury <vmaury@timgroup.fr>
* Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -34,6 +34,14 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var ExtraFields $extrafields
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
@ -43,14 +51,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array("sendings", 'companies', 'bills', 'products', 'orders'));
@ -116,7 +116,6 @@ $object = new Expedition($db);
// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
$hookmanager->initHooks(array('shipmentlist'));
$extrafields = new ExtraFields($db);
// Fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);

View file

@ -3,7 +3,7 @@
* Copyright (C) 2004-2008 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2025-2026 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
@ -28,13 +28,6 @@
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php';
if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
}
/**
* @var Conf $conf
* @var DoliDB $db
@ -42,6 +35,12 @@ if (isModEnabled('project')) {
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php';
if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
}
// Load translation files required by the page
$langs->loadLangs(array('sendings', 'companies', 'bills', 'orders', 'stocks', 'other', 'propal'));

View file

@ -3,7 +3,7 @@
* Copyright (C) 2005-2012 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2012-2015 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2018-2022 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
*
@ -29,6 +29,15 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var ExtraFields $extrafields
* @var HookManager $hookmanager
* @var Societe $mysoc
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
@ -49,15 +58,6 @@ if (isModEnabled("product") || isModEnabled("service")) {
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
}
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Societe $mysoc
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array('orders', 'sendings', 'companies', 'bills', 'propal', 'stocks', 'productbatch', 'incoterm', 'other'));
@ -77,7 +77,6 @@ $result = restrictedArea($user, 'commande', $order_id);
$object = new Commande($db);
$shipment = new Expedition($db);
$extrafields = new ExtraFields($db);
$product = null;
// fetch optionals attributes and labels

View file

@ -2,6 +2,10 @@ ModuleQuickMemoName = Quick Memo
ModuleQuickMemoDesc = Allows adding quick notes on documents
QuickMemoSetup = QuickMemo Setup
QUICKMEMO_COLORS_PRESET = Define your custom memo colors here
QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE = Disable automatic text resizing based on note content density
QUICKMEMO_AUTO_RESIZE_FONT_SIZE_SECTION = Automatic text resizing settings
QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE = Minimum text size
QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE = Maximum text size
QuickMemoSetupPage = QuickMemo Configuration Page
QuickMemoAbout = About QuickMemo
QuickMemoAboutPage = QuickMemo Home Page

View file

@ -93,3 +93,7 @@ DialogAskConfirm = Confirmation
QuickMemoDeleteModel = Supprimer le modèle
ShowMemo = Consulter le mémo
QUICKMEMO_COLORS_PRESET=Définissez ici vos couleurs de mémo personnalisées
QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE = Désactiver l’ajustement automatique de la taille du texte selon la densité du contenu de la note
QUICKMEMO_AUTO_RESIZE_FONT_SIZE_SECTION = Options de redimensionnement automatique du texte
QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE = Taille minimale du texte
QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE = Taille maximale du texte

View file

@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2015 Florian HENRY <florian.henry@open-concept.pro>
* Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -35,7 +35,6 @@ if (!defined('NOREQUIREAJAX')) {
// Load Dolibarr environment
require '../main.inc.php';
require DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
/**
* @var Conf $conf
* @var DoliDB $db
@ -43,6 +42,7 @@ require DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
* @var Translate $langs
* @var User $user
*/
require DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
$mens = (float) price2num(GETPOST('mens'));
$capital = (float) price2num(GETPOST('capital'));

View file

@ -1,6 +1,6 @@
<?php
/* Copyright (C) 2014-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2015-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2015-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
@ -27,6 +27,13 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
@ -43,15 +50,6 @@ if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
}
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array("banks", "bills", "compta", "loan"));

View file

@ -2,7 +2,7 @@
/* Copyright (C) 2014-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,6 +26,13 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
@ -36,14 +43,6 @@ if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
}
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array("other", "companies", "compta", "bills", "loan"));

View file

@ -2,7 +2,7 @@
/* Copyright (C) 2014-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,13 +26,6 @@
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
}
/**
* @var Conf $conf
* @var DoliDB $db
@ -40,6 +33,12 @@ if (isModEnabled('project')) {
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
}
// Load translation files required by the page
$langs->loadLangs(array("compta", "bills", "loan"));

View file

@ -1,6 +1,6 @@
<?php
/* Copyright (C) 2014-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2015-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2015-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2015 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
*
@ -26,8 +26,6 @@
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
@ -35,6 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
// Load translation files required by the page
$langs->loadLangs(array("banks", "bills", "compta", "loan"));

View file

@ -3,7 +3,7 @@
* Copyright (C) 2004-2007 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2015-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2015-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2016-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
@ -30,11 +30,6 @@
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
@ -42,6 +37,10 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
$action = GETPOST('action', 'aZ09');

View file

@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2014-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -25,12 +25,6 @@
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php';
if (isModEnabled("bank")) {
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
}
/**
* @var Conf $conf
* @var DoliDB $db
@ -38,6 +32,11 @@ if (isModEnabled("bank")) {
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php';
if (isModEnabled("bank")) {
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
}
// Load translation files required by the page
$langs->loadLangs(array("bills", "banks", "companies", "loan"));
@ -102,6 +101,7 @@ $help_url = "EN:Module_Loan|FR:Module_Emprunt";
llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'bodyforlist mod-loan page-payment-card');
$h = 0;
$head = [];
$head = array();
$head[$h][0] = DOL_URL_ROOT.'/loan/payment/card.php?id='.$id;

View file

@ -1,6 +1,6 @@
<?php
/* Copyright (C) 2014-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2015-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2015-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr>
* Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
*
@ -26,12 +26,6 @@
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php';
require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
/**
* @var Conf $conf
* @var DoliDB $db
@ -39,11 +33,16 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php';
require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
$langs->loadLangs(array("bills", "loan"));
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$confirm = GETPOST('confirm', 'alpha');
$cancel = GETPOST('cancel', 'alpha');
$chid = GETPOSTINT('id');

View file

@ -3,7 +3,7 @@
* Copyright (C) 2018-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr>
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -27,6 +27,13 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
@ -37,14 +44,6 @@ if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
}
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
$loanid = GETPOSTINT('loanid');
$action = GETPOST('action', 'aZ09');

View file

@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2020 Lenin Rivas <lenin@leninrivas.com>
* Copyright (C) 2023-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2023-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2025 Noé Cendrier <noe.cendrier@altairis.fr>
*
@ -1543,11 +1543,13 @@ class Mo extends CommonObject
$label = implode($this->getTooltipContentArray($params));
}
$url = DOL_URL_ROOT.'/mrp/mo_card.php?id='.$this->id;
$baseurl = DOL_URL_ROOT.'/mrp/mo_card.php';
if ($option == 'production') {
$url = DOL_URL_ROOT.'/mrp/mo_production.php?id='.$this->id;
$baseurl = DOL_URL_ROOT.'/mrp/mo_production.php';
}
$query = ['id' => $this->id];
if ($option != 'nolink') {
// Add param to save lastsearch_values or not
$add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
@ -1555,9 +1557,10 @@ class Mo extends CommonObject
$add_save_lastsearch_values = 1;
}
if ($add_save_lastsearch_values) {
$url .= '&save_lastsearch_values=1';
$query = array_merge($query, ['save_lastsearch_values' => 1]);
}
}
$url = dolBuildUrl($baseurl, $query);
$linkclose = '';
if (empty($notooltip)) {

View file

@ -1,6 +1,6 @@
<?php
/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
*
@ -26,6 +26,14 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var ExtraFields $extrafields
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
@ -35,15 +43,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php';
require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp_mo.lib.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array("mrp", "other"));
@ -91,7 +90,6 @@ if (!$sortorder) {
// Initialize a technical objects
$object = new Mo($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array('moagenda', 'globalcard')); // Note that conf->hooks_modules contains array

View file

@ -2,7 +2,7 @@
/* Copyright (C) 2017-2020 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -27,7 +27,15 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var ExtraFields $extrafields
* @var HookManager $hookmanager
* @var Societe $mysoc
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
@ -42,16 +50,6 @@ if (isModEnabled('workstation')) {
require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php';
}
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Societe $mysoc
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array('mrp', 'other'));
@ -73,7 +71,6 @@ $socid = GETPOSTINT("socid");
$object = new Mo($db);
$objectbom = new BOM($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array('mocard', 'globalcard')); // Note that conf->hooks_modules contains array

View file

@ -1,6 +1,6 @@
<?php
/* Copyright (C) 2007-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
*
@ -26,7 +26,14 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var ExtraFields $extrafields
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
@ -36,14 +43,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php';
require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp_mo.lib.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array("mrp", "companies", "other", "mails"));
@ -74,7 +73,6 @@ if (!$sortfield) {
// Initialize a technical objects
$object = new Mo($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array('modocument', 'globalcard')); // Note that conf->hooks_modules contains array

View file

@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2007-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
@ -26,7 +26,14 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var ExtraFields $extrafields
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
@ -39,14 +46,6 @@ if (isModEnabled('category')) {
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
}
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array("mrp", "other"));
@ -59,7 +58,7 @@ $cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
$toselect = GETPOST('toselect', 'array:int'); // Array of ids of elements selected into a list
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
$mode = GETPOST('mode', 'alpha');
$groupby = GETPOST('groupby', 'aZ09'); // Example: $groupby = 'p.fk_opp_status' or $groupby = 'p.fk_statut'
@ -92,7 +91,6 @@ $pagenext = $page + 1;
// Initialize a technical objects
$object = new Mo($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array($contextpage)); // Note that conf->hooks_modules contains array of activated contexes

View file

@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2019 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2022 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
*
@ -27,6 +27,14 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var ExtraFields $extrafields
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
@ -39,14 +47,6 @@ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php';
require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp_mo.lib.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array("mrp", "stocks", "other"));
@ -95,7 +95,6 @@ if (!$sortorder) {
// Initialize a technical objects
$object = new Mo($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array('mocard', 'globalcard', 'mocardmovelist' )); // Note that conf->hooks_modules contains array

View file

@ -1,6 +1,6 @@
<?php
/* Copyright (C) 2007-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
*
@ -26,20 +26,20 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var ExtraFields $extrafields
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php';
require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp_mo.lib.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array("mrp", "companies"));
@ -52,7 +52,6 @@ $backtopage = GETPOST('backtopage', 'alpha');
// Initialize a technical objects
$object = new Mo($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array('monote', 'globalcard')); // Note that conf->hooks_modules contains array

View file

@ -2,7 +2,7 @@
/* Copyright (C) 2019-2020 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2023 Christian Humpel <christian.humpel@gmail.com>
* Copyright (C) 2023 Vincent de Grandpré <vincent@de-grandpre.quebec>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2025 Noé Cendrier <noe.cendrier@altairis.fr>
@ -29,6 +29,14 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var ExtraFields $extrafields
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
@ -43,15 +51,6 @@ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array("mrp", "stocks", "other", "product", "productbatch"));
@ -71,7 +70,6 @@ $collapse = GETPOST('collapse', 'aZ09comma');
// Initialize a technical objects
$object = new Mo($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id;
$objectline = new MoLine($db);

View file

@ -1416,6 +1416,7 @@ print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwit
// Fields title search
// --------------------------------------------------------------------
print '<thead>';
print '<tr class="liste_titre_filter">';
// Action column left
if ($conf->main_checkbox_left_column) {
@ -1822,7 +1823,7 @@ if (!$conf->main_checkbox_left_column) {
print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
$totalarray['nbfield']++;
}
print '</tr>'."\n";
print '</tr></thead>'."\n";
$i = 0;

View file

@ -107,31 +107,56 @@ document.addEventListener('Dolibarr:Init', function(e) {
/**
* Clear all cached translations in IndexedDB and in-memory
*/
async function clearCache(clearMemory = false) {
if(clearMemory) {
translations = {};
domainsLoaded = {};
}
async function clearCache(clearMemory = false, rebuildDatabase = false) {
try {
const db = await openDB(true);
const tx = db.transaction('langs', 'readwrite');
const store = tx.objectStore('langs');
await store.clear();
await new Promise((resolve, reject) => {
const tx = db.transaction('langs', 'readwrite');
const store = tx.objectStore('langs');
store.clear();
tx.oncomplete = resolve;
tx.onerror = () => reject(tx.error);
tx.onabort = () => reject(tx.error);
});
db.close();
// Delete database
const dbName = await getSafeDbName();
const deleteRequest = indexedDB.deleteDatabase(dbName);
deleteRequest.onsuccess = () => Dolibarr.log('Dolibarr.tools.langs: database deleted');
deleteRequest.onerror = () => console.error('Dolibarr.tools.langs:Failed to delete DB', deleteRequest.error);
deleteRequest.onblocked = () => console.warn('Dolibarr.tools.langs: DB deletion blocked, maybe open connections exist');
if(rebuildDatabase) {
const dbName = await getSafeDbName();
await new Promise((resolve, reject) => {
const deleteRequest = indexedDB.deleteDatabase(dbName);
// Try Delete all langs database
deleteAllDolibarrLangsDbs();
deleteRequest.onsuccess = () => {
Dolibarr.log('tools: langs: database deleted');
if (clearMemory) {
translations = {};
domainsLoaded = {};
}
resolve();
};
Dolibarr.log('Dolibarr.tools.langs: cache cleared');
deleteRequest.onerror = () => {
console.error('Dolibarr: tools: langs Failed to delete DB', deleteRequest.error);
reject(deleteRequest.error);
};
deleteRequest.onblocked = () => {
console.warn('Dolibarr: tools: langs DB deletion blocked, maybe open connections exist');
};
});
// Try Delete all langs database
deleteAllDolibarrLangsDbs();
}
Dolibarr.log('tools: langs: cache cleared');
Dolibarr.executeHook('tools:langs:CacheCleared');
} catch (err) {
console.error('Dolibarr.tools.langs: failed to clear cache', err);
console.error('Dolibarr: tools: langs failed to clear cache', err);
}
}
@ -146,9 +171,9 @@ document.addEventListener('Dolibarr:Init', function(e) {
for (const dbInfo of dolibarrDbs) {
const deleteRequest = indexedDB.deleteDatabase(dbInfo.name);
deleteRequest.onsuccess = () => console.log(`Database ${dbInfo.name} deleted`);
deleteRequest.onerror = () => console.error(`Failed to delete database ${dbInfo.name}`, deleteRequest.error);
deleteRequest.onblocked = () => console.warn(`Deletion of database ${dbInfo.name} blocked, maybe open connections exist`);
deleteRequest.onsuccess = () => Dolibarr.log(`Database ${dbInfo.name} deleted`);
deleteRequest.onerror = () => console.error(`Dolibarr: tools: langs Failed to delete database ${dbInfo.name}`, deleteRequest.error);
deleteRequest.onblocked = () => console.warn(`Dolibarr: tools: langs Deletion of database ${dbInfo.name} blocked, maybe open connections exist`);
}
}
@ -164,17 +189,17 @@ document.addEventListener('Dolibarr:Init', function(e) {
const dolibarrVersion = Dolibarr.getContextVar('DOL_VERSION', 0);
if (cache && cache.data && (now - cache.timestamp < CACHE_MSTIME) && cache.dolibarrVersion === dolibarrVersion) {
Dolibarr.log('Langs tool : Load lang from cache');
Dolibarr.log('tools: langs: Load lang from cache');
return cache.data;
}
const langInterfaceUrl = Dolibarr.getContextVar('DOL_LANG_INTERFACE_URL', false);
if(!langInterfaceUrl) {
console.error('Dolibarr langs: missing DOL_LANG_INTERFACE_URL')
console.error('Dolibarr: tools: langs missing DOL_LANG_INTERFACE_URL')
return;
}
Dolibarr.log('Langs tool : Load lang from interface');
Dolibarr.log('tools: langs: Load lang from interface');
const params = new URLSearchParams({ domain, local: locale });
const resp = await fetch(`${langInterfaceUrl}?${params.toString()}`);
const json = await resp.json();
@ -236,7 +261,7 @@ document.addEventListener('Dolibarr:Init', function(e) {
}
}
Dolibarr.log(`Locale changed: ${prev} -> ${locale}`);
Dolibarr.log(`tools:langs: Locale changed: ${prev} -> ${locale}`);
}
@ -296,18 +321,25 @@ document.addEventListener('Dolibarr:Init', function(e) {
* Clear cache automatically under specific conditions
* Support for Hard Reload (Shift or Ctrl) and Debug Mode
*/
document.addEventListener('keydown', (e) => {
if (e.key === 'F5' && (e.ctrlKey || e.shiftKey)) {
sessionStorage.setItem('lang_hard_reload', '1');
Dolibarr.log('Lang tool : Hard reload detected');
}
});
(async () => {
const navEntries = performance?.getEntriesByType?.("navigation");
const isReload = navEntries?.[0]?.type === "reload" || performance.navigation.type === 1;
const isReload = navEntries?.[0]?.type === "reload" || performance.navigation?.type === 1;
if (isReload) {
window.addEventListener('keydown', async (e) => {
// Check if user is holding Shift OR Control OR if Dolibarr Debug is enabled
if (e.shiftKey || e.ctrlKey) {
await clearCache(true);
Dolibarr.log('Langs tool: Cache cleared (Reason: Hard Reload or Debug Mode)');
}
}, { once: true });
if (!isReload) return;
const isHardReload = sessionStorage.getItem('lang_hard_reload') === '1';
sessionStorage.removeItem('lang_hard_reload');
if (isHardReload) {
await clearCache(true);
Dolibarr.log('Lang tool : Lang cache cleared (hard reload detected)');
}
})();

View file

@ -73,28 +73,94 @@ if (!class_exists('FormSetup')) {
$formSetup = new FormSetup($db);
$item = $formSetup->newItem('QUICKMEMO_COLORS_PRESET');
$item->fieldInputOverride = '
<div class="color-manager">
<div class="controls">
<input type="color" id="colorPicker" list="predefinedColors">
<datalist id="predefinedColors">
<option value="#fff8a6">
<option value="#ffd6d6">
<option value="#d6ffd9">
<option value="#d6e6ff">
<option value="#f3d6ff">
<option value="#ffffff">
<option value="#f5f5f5">
</datalist>
<button title="'.$langs->trans('Add').'" class="btn-low-emphasis --btn-icon" type="button" id="addColor"><span class="fa fa-plus"></span></button>
</div>
/**
* Callback used to generate the custom HTML input field.
*
* @param FormSetupItem $item Current form/configuration item.
* @return string Generated HTML content.
*/
$item->fieldInputCallBack = function ($item) {
global $langs;
<div class="palette" id="palette"></div>
$item->fieldInputOverride = '
<div class="color-manager">
<div class="controls">
<input type="color" id="colorPicker" list="predefinedColors">
<datalist id="predefinedColors">
<option value="#fff8a6">
<option value="#ffd6d6">
<option value="#d6ffd9">
<option value="#d6e6ff">
<option value="#f3d6ff">
<option value="#ffffff">
<option value="#f5f5f5">
</datalist>
<button title="'.$langs->trans('Add').'" class="btn-low-emphasis --btn-icon" type="button" id="addColor"><span class="fa fa-plus"></span></button>
</div>
<div class="colors-container" id="colorsContainer"></div>
<div class="palette" id="palette"></div>
<div class="colors-container" id="colorsContainer"></div>
<input type="hidden" name="QUICKMEMO_COLORS_PRESET" id="colorsInput">
</div>';
return $item->fieldInputOverride;
};
$formSetup->newItem('QUICKMEMO_AUTO_RESIZE_FONT_SIZE_SECTION')->setAsTitle();
$formSetup->newItem('QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE')->setAsYesNo();
$item = $formSetup->newItem('QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE');
$item->defaultFieldValue = '1';
/**
* Callback used to generate the custom HTML input field.
*
* @param FormSetupItem $item Current form/configuration item.
* @return string Generated HTML content.
*/
$item->fieldInputCallBack = function ($item) {
$item->fieldInputOverride = '
<input
type="range"
class="quickmemo-fontsize-config"
id="autoResizeFontMin"
name="QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE"
min="0.5" max="3" step="0.05"
value="' . getDolGlobalString('QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE', 1) . '"
/>
<div id="previewMinText" class="example-of-memo-text-size">Lorem ipsum dolor sit amet</div>
';
return $item->fieldInputOverride;
};
$item = $formSetup->newItem('QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE');
$item->defaultFieldValue = '1.4';
/**
* Callback used to generate the custom HTML input field.
*
* @param FormSetupItem $item Current form/configuration item.
* @return string Generated HTML content.
*/
$item->fieldInputCallBack = function ($item) {
$item->fieldInputOverride = '
<input
type="range"
id="autoResizeFontMax"
name="QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE"
class="quickmemo-fontsize-config"
min="0.5" max="3" step="0.05"
value="' . getDolGlobalString('QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE', 1.4) . '"
/>
<div id="previewMaxText" class="example-of-memo-text-size">Lorem ipsum dolor sit amet</div>
';
return $item->fieldInputOverride;
};
<input type="hidden" name="QUICKMEMO_COLORS_PRESET" id="colorsInput">
</div>';
$setupnotempty += count($formSetup->items);
@ -134,6 +200,9 @@ llxHeader('', $langs->trans($title), $help_url, '', 0, 0, '', ['quickmemo/css/se
<script nonce="<?php print getNonce(); ?>">
document.addEventListener('DOMContentLoaded', function () {
/**
* PRELOADED COLORS
*/
const PRELOADED_COLORS = <?php print json_encode(Memo::getColorPreset()); ?>;
const colorPicker = document.getElementById('colorPicker');
@ -253,6 +322,73 @@ document.addEventListener('DOMContentLoaded', function () {
PRELOADED_COLORS.forEach(color => {
addColor(color);
});
/**
* FONT SIZE
*/
const QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE = <?php print json_encode(getDolGlobalInt('QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE')); ?>;
(function() {
const minInput = document.getElementById('autoResizeFontMin');
const maxInput = document.getElementById('autoResizeFontMax');
const previewMinText = document.getElementById('previewMinText');
const previewMaxText = document.getElementById('previewMaxText');
function updatePreview(changed) {
let min = parseFloat(minInput.value);
let max = parseFloat(maxInput.value);
if (changed === 'min' && min > max) {
max = min;
maxInput.value = max.toFixed(1);
}
if (changed === 'max' && max < min) {
min = max;
minInput.value = min.toFixed(1);
}
previewMinText.style.fontSize = min + 'em';
previewMaxText.style.fontSize = max + 'em';
}
minInput.addEventListener('input', () => updatePreview('min'));
maxInput.addEventListener('input', () => updatePreview('max'));
updatePreview();
})();
const toggleDisplayLineSize = function (display = true) {
const ids = [
'setup-line-item_QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE',
'setup-line-item_QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE'
];
ids.forEach(id => {
const el = document.getElementById(id);
if (el) el.style.display = display ? '' : 'none';
});
};
toggleDisplayLineSize(!QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE);
Dolibarr.on('delConstant', (data) => {
if(data.code === 'QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE'){
toggleDisplayLineSize(true);
}
});
Dolibarr.on('setConstant', (data) => {
if(data.code === 'QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE'){
toggleDisplayLineSize(false);
}
});
});
</script>
<?php

View file

@ -1050,10 +1050,6 @@ class Memo extends CommonObject
$return .= ' </div>';
}
$this->date_archived = dol_now();
$this->fk_user_archived = (int) $this->user->id;
$return .= '</div>';
@ -1646,6 +1642,18 @@ class Memo extends CommonObject
return false;
}
$autoResizeFontMin = getDolGlobalFloat('QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE', 1);
$autoResizeFontMax = getDolGlobalFloat('QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE', 1.4);
// Apply safety limits
$autoResizeFontMin = max($autoResizeFontMin, 0.3);
$autoResizeFontMax = min($autoResizeFontMax, 5);
// Ensure min value is always lower than max value
if ($autoResizeFontMin >= $autoResizeFontMax) {
$autoResizeFontMin = max(0.3, $autoResizeFontMax - 0.1);
}
$defaultJsConfVars = [
'interfaceUrl' => dol_buildpath('quickmemo/interface.php', 1),
'archivesUrl' => dol_buildpath('quickmemo/memo_list.php', 1) . '?mode=kanban&search_status='.Memo::STATUS_ARCHIVED . ($jsConfVars['archivesUrlParams'] ?? ''),
@ -1656,7 +1664,10 @@ class Memo extends CommonObject
'colors' => Memo::getColorPreset(),
'userReadRight' => $user->hasRight('quickmemo', 'memo', 'read'),
'userWriteRight' => $user->hasRight('quickmemo', 'memo', 'write'),
'userDeleteRight' => $user->hasRight('quickmemo', 'memo', 'delete')
'userDeleteRight' => $user->hasRight('quickmemo', 'memo', 'delete'),
'autoResizeFontSize' => !getDolGlobalInt('QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE'),
'autoResizeFontMin' => $autoResizeFontMin,
'autoResizeFontMax' => $autoResizeFontMax,
];
$jsConfVars = array_merge($defaultJsConfVars, $jsConfVars);

View file

@ -70,3 +70,10 @@
border-radius: 50%;
cursor: pointer;
}
.quickmemo-fontsize-config {
width: 100%;
}
.example-of-memo-text-size{
font-size: 14px;
}

View file

@ -21,6 +21,8 @@ class QuickMemo {
userDeleteRight: false,
elementId: 0,
autoResizeFontSize: true,
autoResizeFontMin: 1,
autoResizeFontMax: 1.2,
elementType: '',
context: '',
token: '',
@ -67,9 +69,14 @@ class QuickMemo {
*/
async init() {
// Load translation files via Dolibarr tools
await Dolibarr.tools.langs.load('quickmemo');
await Dolibarr.tools.langs.load('main');
await Dolibarr.tools.langs.load('other');
const loadLangs = async function () {
await Dolibarr.tools.langs.load('quickmemo');
await Dolibarr.tools.langs.load('main');
await Dolibarr.tools.langs.load('other');
}
await loadLangs();
Dolibarr.on('tools:langs:CacheCleared', loadLangs);
// Load existing memos from server
this.loadMemos();
@ -336,12 +343,66 @@ class QuickMemo {
actions.className = 'quickmemo-actions';
/* ===== ARCHIVE ===== */
const btnArchiveTitleLangs = {
QuickMemoActionDelete : await Dolibarr.tools.langs.transNoEntities('QuickMemoActionDelete'),
QuickMemoActionDeleteEmpty : await Dolibarr.tools.langs.transNoEntities('QuickMemoActionDeleteEmpty'),
QuickMemoActionArchive : await Dolibarr.tools.langs.transNoEntities('QuickMemoActionArchive'),
}
const btnArchive = document.createElement('button');
btnArchive.className = 'btn-low-emphasis --btn-icon quickmemo-btn-archive';
btnArchive.innerHTML = `<i class="${this.param.archiveFontAIcon}"></i>`;
btnArchive.title = await Dolibarr.tools.langs.transNoEntities('QuickMemoActionArchive');
btnArchive.title = btnArchiveTitleLangs.QuickMemoActionArchive;
this.initTooltips(btnArchive);
/** Updates btn txt based onshift key */
const updateBtnArchiveTitle = async () => {
let isHoverArchive = false;
const updateArchiveTitle = (forceDelete = false) => {
const textarea = note.querySelector('textarea');
const textLength = textarea.value.trim().length;
if (forceDelete) {
btnArchive.title = btnArchiveTitleLangs.QuickMemoActionDelete;
} else if (textLength === 0) {
btnArchive.title = btnArchiveTitleLangs.QuickMemoActionDeleteEmpty;
} else {
btnArchive.title = btnArchiveTitleLangs.QuickMemoActionArchive;
}
// Refresh tooltip if needed
btnArchive._quickmemoTooltipSync?.();
};
btnArchive.addEventListener('mouseenter', async (e) => {
isHoverArchive = true;
updateArchiveTitle(e.shiftKey);
});
btnArchive.addEventListener('mouseleave', () => {
isHoverArchive = false;
});
document.addEventListener('keydown', async (e) => {
if (e.key !== 'Shift' || !isHoverArchive) {
return;
}
updateArchiveTitle(true);
});
document.addEventListener('keyup', async (e) => {
if (e.key !== 'Shift' || !isHoverArchive) {
return;
}
updateArchiveTitle(false);
});
};
updateBtnArchiveTitle();
btnArchive.addEventListener('click', async (e) => {
e.stopPropagation();
this.removeTooltips(btnArchive); // JQUERY tooltip need to be destroy because it active at this moment
@ -349,7 +410,7 @@ class QuickMemo {
try {
// If empty, delete permanently, otherwise archive
const textarea = note.querySelector('textarea');
const actionDelete = textarea.value.length ? 'archive' : 'delete';
const actionDelete = (e.shiftKey || textarea.value.length === 0) ? 'delete' : 'archive';
if (actionDelete === 'delete') {
this.deleteWithAnimation(note);
@ -957,6 +1018,8 @@ class QuickMemo {
const btnArchive = noteEl.querySelector('.quickmemo-btn-archive');
if (btnArchive) {
btnArchive.title = await Dolibarr.tools.langs.transNoEntities(textLength > 0 ? 'QuickMemoActionArchive' : 'QuickMemoActionDeleteEmpty');
// Refresh tooltip if needed
btnArchive._quickmemoTooltipSync?.();
}
// Calculate density
@ -965,8 +1028,8 @@ class QuickMemo {
// Linearly map density to font-size
const densityMin = 0.0002;
const densityMax = 0.005;
const fontMin = 0.8;
const fontMax = 1.2;
const fontMin = this.param.autoResizeFontMin;
const fontMax = this.param.autoResizeFontMax;
// Clamp density between min & max
const clampedDensity = Math.max(densityMin, Math.min(densityMax, density));

View file

@ -1,7 +1,7 @@
<?php
/*
* Copyright (C) 2025
* Copyright (C) 2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2025-2026 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -2,7 +2,7 @@
/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2020 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -95,7 +95,12 @@ class WorkstationResource extends CommonObject
{
global $db;
$obj = new self($db);
return array_map('intval', parent::getAllItemsLinkedByObjectID($fk_workstation, 'fk_resource', 'fk_workstation', $obj->table_element));
$all_items = parent::getAllItemsLinkedByObjectID($fk_workstation, 'fk_resource', 'fk_workstation', $obj->table_element);
if (!is_array($all_items)) {
return [];
}
return array_map('intval', $all_items);
}
/**

View file

@ -2,7 +2,7 @@
/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2020 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -95,7 +95,12 @@ class WorkstationUserGroup extends CommonObject
global $db;
$obj = new self($db);
return array_map('intval', parent::getAllItemsLinkedByObjectID($fk_workstation, 'fk_usergroup', 'fk_workstation', $obj->table_element));
$all_items = parent::getAllItemsLinkedByObjectID($fk_workstation, 'fk_usergroup', 'fk_workstation', $obj->table_element);
if (!is_array($all_items)) {
return [];
}
return array_map('intval', $all_items);
}
/**