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

This commit is contained in:
Laurent Destailleur
2025-11-07 19:26:08 +01:00
13 changed files with 90 additions and 150 deletions

View File

@@ -8946,12 +8946,6 @@ parameters:
count: 2
path: ../../../htdocs/eventorganization/conferenceorboothattendee_list.php
-
message: '#^Negated boolean expression is always true\.$#'
identifier: booleanNot.alwaysTrue
count: 1
path: ../../../htdocs/expedition/card.php
-
message: '#^Variable \$rowEnd might not be defined\.$#'
identifier: variable.undefined
@@ -12102,54 +12096,6 @@ parameters:
count: 1
path: ../../../htdocs/product/class/productfournisseurprice.class.php
-
message: '#^Negated boolean expression is always true\.$#'
identifier: booleanNot.alwaysTrue
count: 3
path: ../../../htdocs/product/class/propalmergepdfproduct.class.php
-
message: '#^Property Propalmergepdfproduct\:\:\$file_name \(string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 4
path: ../../../htdocs/product/class/propalmergepdfproduct.class.php
-
message: '#^Property Propalmergepdfproduct\:\:\$fk_product \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 4
path: ../../../htdocs/product/class/propalmergepdfproduct.class.php
-
message: '#^Property Propalmergepdfproduct\:\:\$fk_user_author \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../../htdocs/product/class/propalmergepdfproduct.class.php
-
message: '#^Property Propalmergepdfproduct\:\:\$fk_user_mod \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 2
path: ../../../htdocs/product/class/propalmergepdfproduct.class.php
-
message: '#^Property Propalmergepdfproduct\:\:\$lang \(string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 4
path: ../../../htdocs/product/class/propalmergepdfproduct.class.php
-
message: '#^Variable \$i might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../../htdocs/product/composition/card.php
-
message: '#^Variable \$num might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../../htdocs/product/composition/card.php
-
message: '#^If condition is always true\.$#'
identifier: if.alwaysTrue
@@ -14010,12 +13956,6 @@ parameters:
count: 1
path: ../../../htdocs/public/recruitment/index.php
-
message: '#^Variable \$dolibarr_main_url_root might not be defined\.$#'
identifier: variable.undefined
count: 2
path: ../../../htdocs/public/recruitment/index.php
-
message: '#^Left side of && is always true\.$#'
identifier: booleanAnd.leftAlwaysTrue
@@ -14292,12 +14232,6 @@ parameters:
count: 1
path: ../../../htdocs/reception/card.php
-
message: '#^Left side of && is always true\.$#'
identifier: booleanAnd.leftAlwaysTrue
count: 2
path: ../../../htdocs/reception/card.php
-
message: '#^Loose comparison using \=\= between ''''\|''CommandeFournisseur'' and ''commande'' will always evaluate to false\.$#'
identifier: equal.alwaysFalse
@@ -14328,30 +14262,12 @@ parameters:
count: 1
path: ../../../htdocs/reception/card.php
-
message: '#^Variable \$objectsrc might not be defined\.$#'
identifier: variable.undefined
count: 3
path: ../../../htdocs/reception/card.php
-
message: '#^Variable \$originid might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../../htdocs/reception/card.php
-
message: '#^Variable \$reception might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../../htdocs/reception/card.php
-
message: '#^Variable \$result might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../../htdocs/reception/card.php
-
message: '#^Call to function method_exists\(\) with \$this\(Reception\) and ''getLibStatut'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType

View File

@@ -71,6 +71,7 @@ class Categorie extends CommonObject
const TYPE_SUPPLIER_INVOICE = 'supplier_invoice';
const TYPE_SUPPLIER_PROPOSAL = 'supplier_proposal';
const TYPE_PROPOSAL = 'propal';
const TYPE_PROJECT_TASK = 'project_task';
/**
@@ -104,6 +105,7 @@ class Categorie extends CommonObject
'supplier_invoice' => 21,
'supplier_proposal' => 22,
'propal' => 23,
'project_task' => 24,
);
/**
@@ -131,7 +133,10 @@ class Categorie extends CommonObject
16 => 'order',
17 => 'invoice',
20 => 'supplier_order',
21 => 'supplier_invoice'
21 => 'supplier_invoice',
22 => 'supplier_proposal',
23 => 'propal',
24 => 'project_task'
);
*/
@@ -178,7 +183,8 @@ class Categorie extends CommonObject
'supplier_order' => 'CommandeFournisseur',
'supplier_invoice' => 'FactureFournisseur',
'supplier_proposal' => 'SupplierProposal',
'propal' => 'Propal'
'propal' => 'Propal',
'project_task' => 'Task',
);
/**
@@ -206,7 +212,8 @@ class Categorie extends CommonObject
'supplier_order' => 'SuppliersOrders',
'supplier_invoice' => 'SuppliersInvoices',
'propal' => 'Proposals',
'supplier_proposal' => 'SupplierProposals'
'supplier_proposal' => 'SupplierProposals',
'project_task' => 'Tasks'
);
/**
@@ -227,6 +234,7 @@ class Categorie extends CommonObject
'invoice' => 'facture',
'supplier_order' => 'commande_fournisseur',
'supplier_invoice' => 'facture_fourn',
'project_task' => 'projet_task'
);
/**
@@ -295,6 +303,7 @@ class Categorie extends CommonObject
* @see Categorie::TYPE_INVOICE
* @see Categorie::TYPE_SUPPLIER_ORDER
* @see Categorie::TYPE_SUPPLIER_INVOICE
* @see Categorie::TYPE_PROJECT_TASK
*/
public $type;
@@ -769,6 +778,7 @@ class Categorie extends CommonObject
'categorie_user' => 'fk_categorie',
'categorie_product' => 'fk_categorie',
'categorie_project' => 'fk_categorie',
'categorie_project_task' => 'fk_categorie',
'categorie_societe' => 'fk_categorie',
'categorie_ticket' => array('field' => 'fk_categorie', 'enabled' => isModEnabled('ticket')),
'categorie_warehouse' => 'fk_categorie',

View File

@@ -11051,6 +11051,16 @@ abstract class CommonObject
}
}
if (!$error) {
$dir = getMultidirOutput($this)."/".dol_sanitizeFileName($this->ref);
// For remove dir
if (dol_is_dir($dir)) {
if (!dol_delete_dir_recursive($dir)) {
$this->errors[] = 'ErrorFailToDeleteDir';
}
}
}
// Delete linked object
$res = $this->deleteObjectLinked();
if ($res < 0) {

View File

@@ -2448,7 +2448,7 @@ class ExtraFields
$tmpobject->fetch($value);
if (get_class($tmpobject) == 'Categorie') {
// For category object, rendering must use the same method than the one deinfed into showCategories()
// For category object, rendering must use the same method than the one defined into showCategories()
$color = $tmpobject->color;
$sfortag = '<span class="noborderoncategories"' . ($color ? ' style="background: #' . $color . ';"' : ' style="background: #bbb"') . '>';
$sfortag .= $tmpobject->getNomUrl(3);

View File

@@ -137,6 +137,7 @@ function getMultidirOutput($object, $module = '', $forobject = 0, $mode = 'outpu
{
global $conf;
$subdirectory = '';
if (!is_object($object) && empty($module)) {
return null;
}
@@ -151,6 +152,12 @@ function getMultidirOutput($object, $module = '', $forobject = 0, $mode = 'outpu
$module = 'supplier_invoice';
} elseif ($module == 'order_supplier') {
$module = 'supplier_order';
} elseif ($module == 'recruitmentjobposition') {
$module = 'recruitment';
$subdirectory = '/recruitmentjobposition';
} elseif ($module == 'recruitmentcandidature') {
$module = 'recruitment';
$subdirectory = '/recruitmentcandidature';
}
// Get the relative path of directory
@@ -158,7 +165,7 @@ function getMultidirOutput($object, $module = '', $forobject = 0, $mode = 'outpu
if (isset($conf->$module) && property_exists($conf->$module, 'multidir_output')) {
$s = '';
if ($mode != 'outputrel') {
$s = $conf->$module->multidir_output[(empty($object->entity) ? $conf->entity : $object->entity)];
$s = $conf->$module->multidir_output[(empty($object->entity) ? $conf->entity : $object->entity)] . $subdirectory;
}
if ($forobject && $object->id > 0) {
$s .= ($mode != 'outputrel' ? '/' : '') . get_exdir(0, 0, 0, 0, $object);
@@ -167,7 +174,7 @@ function getMultidirOutput($object, $module = '', $forobject = 0, $mode = 'outpu
} elseif (isset($conf->$module) && property_exists($conf->$module, 'dir_output')) {
$s = '';
if ($mode != 'outputrel') {
$s = $conf->$module->dir_output;
$s = $conf->$module->dir_output . $subdirectory;
}
if ($forobject && $object->id > 0) {
$s .= ($mode != 'outputrel' ? '/' : '') . get_exdir(0, 0, 0, 0, $object);

View File

@@ -639,7 +639,7 @@ class Don extends CommonObject
// For remove dir
if (dol_is_dir($dir)) {
if (!dol_delete_dir_recursive($dir)) {
$this->errors[] = $this->error;
$this->errors[] = 'ErrorFailToDeleteDir';
}
}
}

View File

@@ -5,7 +5,7 @@
* Copyright (C) 2013 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2017-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2014-2017 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2020-2021 Udo Tamm <dev@dolibit.de>
* Copyright (C) 2022 Anthony Berton <anthony.berton@bb2a.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
@@ -609,8 +609,8 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') {
if (empty($include_users)) {
print img_warning().' '.$langs->trans("NobodyHasPermissionToValidateHolidays");
} else {
// Defined default approver (the forced approved of user or the supervisor if no forced value defined)
// Note: This use will be set only if the deinfed approvr has permission to approve so is inside include_users
// Defined default approver (the forced approver of user or the supervisor if no forced value defined)
// Note: This use will be set only if the defined approver has permission to approve so is inside include_users
$defaultselectuser = (empty($user->fk_user_holiday_validator) ? $user->fk_user : $user->fk_user_holiday_validator);
if (getDolGlobalString('HOLIDAY_DEFAULT_VALIDATOR')) {
$defaultselectuser = getDolGlobalString('HOLIDAY_DEFAULT_VALIDATOR'); // Can force default approver

View File

@@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2015 Florian HENRY <florian.henry@open-concept.pro>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -44,22 +44,22 @@ class Propalmergepdfproduct extends CommonObject
public $table_element = 'propal_merge_pdf_product';
/**
* @var int Id of product
* @var ?int Id of product
*/
public $fk_product;
/**
* @var string Filename
* @var ?string Filename
*/
public $file_name;
/**
* @var int Id user
* @var ?int Id user
*/
public $fk_user_author;
/**
* @var int Id user
* @var ?int Id user
*/
public $fk_user_mod;
/**
@@ -68,7 +68,7 @@ class Propalmergepdfproduct extends CommonObject
public $datec = '';
/**
* @var string lang code
* @var ?string lang code
*/
public $lang;
@@ -381,16 +381,14 @@ class Propalmergepdfproduct extends CommonObject
$this->db->begin();
if (!$error) {
$sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product";
$sql .= " WHERE rowid=".((int) $this->id);
$sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product";
$sql .= " WHERE rowid=".((int) $this->id);
dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = "Error ".$this->db->lasterror();
}
dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = "Error ".$this->db->lasterror();
}
// Commit or rollback
@@ -425,20 +423,18 @@ class Propalmergepdfproduct extends CommonObject
$this->db->begin();
if (!$error) {
$sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product";
$sql .= " WHERE fk_product = ".((int) $product_id);
$sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product";
$sql .= " WHERE fk_product = ".((int) $product_id);
if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($lang_id)) {
$sql .= " AND lang = '".$this->db->escape($lang_id)."'";
}
if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($lang_id)) {
$sql .= " AND lang = '".$this->db->escape($lang_id)."'";
}
dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = "Error ".$this->db->lasterror();
}
dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = "Error ".$this->db->lasterror();
}
// Commit or rollback
@@ -470,16 +466,14 @@ class Propalmergepdfproduct extends CommonObject
$this->db->begin();
if (!$error) {
$sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product";
$sql .= " WHERE fk_product = ".((int) $this->fk_product)." AND file_name = '".$this->db->escape($this->file_name)."'";
$sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product";
$sql .= " WHERE fk_product = ".((int) $this->fk_product)." AND file_name = '".$this->db->escape($this->file_name)."'";
dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = "Error ".$this->db->lasterror();
}
dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = "Error ".$this->db->lasterror();
}
// Commit or rollback

View File

@@ -7,7 +7,7 @@
* Copyright (C) 2011-2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2023 Benjamin Falière <benjamin.faliere@altairis.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 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
@@ -434,9 +434,10 @@ if ($id > 0 || !empty($ref)) {
print '<th class="liste_titre right">'.$langs->trans("Qty").'</td>';
print '<th class="center">'.$langs->trans('ComposedProductIncDecStock').'</th>';
print '</tr>';
$i = 0;
$num = 0;
if ($resql) {
$num = $db->num_rows($resql);
$i = 0;
if ($num == 0) {
print '<tr><td colspan="4"><span class="opacitymedium">'.$langs->trans("NoMatchFound").'</span></td></tr>';

View File

@@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2020 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 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
@@ -38,26 +38,28 @@ if (!defined('NOBROWSERNOTIF')) {
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Societe $mysoc
* @var Translate $langs
*
* @var string $dolibarr_main_url_root
*/
require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
// Load translation files required by the page
$langs->loadLangs(array("companies", "other", "recruitment"));
// Get parameters
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$SECUREKEY = GETPOST("securekey");
$entity = GETPOSTINT('entity') ? GETPOSTINT('entity') : $conf->entity;
$backtopage = '';
@@ -90,7 +92,7 @@ $object = new RecruitmentJobPosition($db);
$urlwithroot = DOL_MAIN_URL_ROOT; // This is to use same domain name than current. For Paypal payment, we can use internal URL like localhost.
// Security check
if (empty($conf->recruitment->enabled)) {
if (!isModEnabled('recruitment')) {
httponly_accessforbidden('Module Recruitment not enabled');
}
@@ -204,7 +206,7 @@ if (is_array($results)) {
$text = '';
if (getDolGlobalString('RECRUITMENT_NEWFORM_TEXT')) {
$reg = array();
if (preg_match('/^\((.*)\)$/', $conf->global->RECRUITMENT_NEWFORM_TEXT, $reg)) {
if (preg_match('/^\((.*)\)$/', getDolGlobalString('RECRUITMENT_NEWFORM_TEXT'), $reg)) {
$text .= $langs->trans($reg[1])."<br>\n";
} else {
$text .= getDolGlobalString('RECRUITMENT_NEWFORM_TEXT') . "<br>\n";

View File

@@ -504,7 +504,6 @@ class RecruitmentJobPosition extends CommonObject
public function delete(User $user, $notrigger = 0)
{
return $this->deleteCommon($user, $notrigger);
//return $this->deleteCommon($user, $notrigger, 1);
}
/**

View File

@@ -4,7 +4,7 @@
* Copyright (C) 2014 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2016 Charlie Benke <charlie@patas-monkey.com>
* Copyright (C) 2018-2021 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -251,7 +251,9 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi
$outputlangs->loadLangs(array("main", "dict", "companies", "bills"));
if ($conf->recruitment->dir_output) {
$dir = getMultidirOutput($object);
if ($dir) {
// If $object is id instead of object
if (!is_object($object)) {
$id = $object;
@@ -263,7 +265,6 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi
}
}
$dir = $conf->recruitment->multidir_output[isset($object->entity) ? $object->entity : 1].'/recruitmentjobposition/';
$objectref = dol_sanitizeFileName($object->ref);
if (!preg_match('/specimen/i', $objectref)) {
$dir .= "/".$objectref;

View File

@@ -226,16 +226,16 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio
$hidetop = getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE');
}
if ($conf->recruitment->dir_output.'/recruitmentjobposition') {
$dir = getMultidirOutput($object);
if ($dir) {
$object->fetch_thirdparty();
// Definition of $dir and $file
if ($object->specimen) {
$dir = $conf->recruitment->dir_output.'/recruitmentjobposition';
$file = $dir."/SPECIMEN.pdf";
} else {
$objectref = dol_sanitizeFileName($object->ref);
$dir = $conf->recruitment->dir_output.'/recruitmentjobposition/'.$objectref;
$dir .= '/'.$objectref;
$file = $dir."/".$objectref.".pdf";
}
if (!file_exists($dir)) {