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

This commit is contained in:
Laurent Destailleur (aka Eldy)
2025-01-03 16:43:31 +01:00
15 changed files with 122 additions and 41 deletions

View File

@@ -20,12 +20,21 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install GitHub CLI
run: |
sudo apt update
sudo apt install gh -y
#- name: Install GitHub CLI
# run: |
# sudo apt update
# sudo apt install gh -y
- name: Assign reviewer
- name: Assign reviewer method 1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
url: ${{ github.event.pull_request.html_url }}
run: |
gh pr edit "$url" --add-assignee rycks --add-reviewer rycks
gh pr merge "$url" --merge --auto
- name: Assign reviewer method 2
env:
#REVIEWER: "eldy,lvessiller-opendsi,rycks" # Remplacez par le nom d'utilisateur GitHub du reviewer
REVIEWER: "rycks" # Remplacez par le nom d'utilisateur GitHub du reviewer

View File

@@ -9,10 +9,9 @@ on:
env:
ENVGHT: ${{ secrets.GITHUB_TOKEN }}
ENVGHU: ${{ github.token }}
VARAAA: ${{ vars.AAA }}
SECBBB: ${{ secrets.BBB }}
VARREPORGCCC: ${{ vars.CCC }}
ENVFIX: "abc"
TEST_ACCESS_KEY: ${{ secrets.TEST_ACCESS_KEY }}
TEST_VAR_REPO: ${{ vars.TEST_VAR_REPO }}
ENVLOCAL: "varenvlocal"
jobs:
testjob:
@@ -25,14 +24,6 @@ jobs:
echo "secrets.GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}"
echo "GITHUB_EVENT_PATH=$GITHUB_EVENT_PATH"
echo "repo-token: ${{secrets.GITHUB_TOKEN}}"
echo "variable org: ${{vars.AAA}}"
echo "env prg: ${{env.AAA}}"
echo "env prg: ${{env.VARAAA}}"
echo "secret org: ${{secrets.BBB}}"
echo "variable repository of orga: ${{vars.CCC}}"
echo "ENVGHT: ${{env.ENVGHT}}"
echo "ENVGHU: ${{env.ENVGHU}}"
echo "VARAAA: ${{vars.AAA}}"
echo "ENVAAA: ${{env.VARAAA}}"
echo "VARREPORGCCC: ${{env.VARREPORGCCC}}"
echo "ENVFIX: ${{env.ENVFIX}}"
echo "secret repository TEST_ACCESS_KEY: ${{secrets.TEST_ACCESS_KEY}}"
echo "variable repository : ${{vars.TEST_VAR_REPO}}"
echo "ENVLOCAL: ${{env.ENVLOCAL}}"

View File

@@ -217,6 +217,66 @@ The following changes may create regressions for some external modules, but were
* If you were using the substitution key __MEMBER_CIVILITY__, you must now use __MEMBER_TITLE__
***** ChangeLog for 20.0.3 compared to 20.0.2 *****
FIX: 17.0 - missing error handling for FactureRec::fetch in card-rec.php
FIX: 17.0 - warnings due to uninitialized variables + delete code that doesn't apply to recurring invoices (AFAIK, there is no recurring credit note feature)
FIX: #31159 - TVA Account by country is not used (#31984)
FIX: #31724 (#31885)
FIX: #31890 store empty line extrafields (#32152)
FIX: #31997
FIX: #32007 missing parameter on function multiSelectArrayWithCheckbox (#32008)
FIX: #32021
FIX: #32171 (#32172)
FIX: #32178: repair.php: fix missing 'as' with Postgres (#32179)
FIX: #32259
FIX: #32317 Error with report by month sales tax
FIX: #32391
FIX: #32402 Social Contribution - Update - Drop the attached employee
FIX: #32408 Dict - module Event organisation is stable now
FIX: #32467
FIX: Accounting Closure Duplicates, Subledger accounts, Account Labels and more... Update bookkeeping.class.php
FIX: add a line in expensereport refused
FIX: All contacts were loaded even if no thirdparty was selected (#31877)
FIX: asset: missing ref_ext field used in CommonObject::isExistingObject() (#31870)
FIX: assets: division by zero when trying to calculate depreciation on assets that don't have it (#31858)
FIX: avoid php8 warnings
FIX: broken feature, check if module is enabled
FIX: broken feature, entity can not be empty !
FIX: broken feature, wrong GETPOSTINT parameter
FIX: BUG #32454 (Third party creating vendor)
FIX: calculate start date of cloned task from cloned project (#31799)
FIX: can not convert to reduc if draft status
FIX: comparing strings with numbers can be touchy
FIX: Debug option not working replaced by the one that works.
FIX: default user in stat page
FIX: Ensure extraparams cannot be selected by the user (#32132)
FIX: GETPOST "$check" parameter can't be empty
FIX: Hidden dropdown download link in project
FIX: stop doing a full closure without duplicate lines generated by an unclean database
FIX: in projet/element.php total_time is always back to 0
FIX: (invoice): mutlicurrency_tx correct value
FIX: invoice: revenue stamp wrongly converted to int (#31840)
FIX: issue #28222 Edit date extrafield displayed on all on lines (#31914)
FIX: "location_incoterms" is a string
FIX: missing hook parameters
FIX: missing saving MAIN_SECURITY_MAX_NUMBER_FAILED_AUTH
FIX: old copy not needed in supplier order create method (#31733)
FIX: send mail to BCC when email formatted as Fullname <email> (#31983)
FIX: set birthday alert (#32133)
FIX: Status not correct in Public ticket list (#31922)
FIX: swiftmailer: correctly set errors-to header (#31826)
FIX: TakePos barcode rule (#31857)
FIX: Takepos: set the country of the default customer (#31915)
FIX: Update Accounting closure with missing too many A-Nouveau #30039)
FIX: Update on a sold line of bank entry set the type to empty, now it's fixed #22539 (#31888)
FIX: update status on create supplier order for trigger (#31642)
FIX: use tax with code on supplier order line give tax code missing in supplier invoice (#32018)
FIX: warning in agenda when user have no color and AGENDA_NO_TRANSPARENT_ON_NOT_BUSY=1
FIX: when create intervention from propal (or other object), element link is missing after creation (#32035)
FIX: with no perm on supplier, must not see supplier of the best price
FIX: wrong check
FIX: wrong trigger name (MODIFY instead UPDATE)
***** ChangeLog for 20.0.2 compared to 20.0.1 *****
FIX: fatal when updating recurring supplier invoice line with php8 ($remise_percent is '' instead of 0) (#31713)
FIX: supplier invoice template card: buyer and seller swapped in VAT-related function calls (probably a copy-paste from customer invoice templates) (#31446)

View File

@@ -36,7 +36,7 @@ $PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/asso.dolibarr.org/
"RPM_FEDORA"=>"rpmbuild",
"RPM_MANDRIVA"=>"rpmbuild",
"RPM_OPENSUSE"=>"rpmbuild",
"DEB"=>"dpkg dpatch",
"DEB"=>"dpkg",
"FLATPACK"=>"flatpack",
"EXEDOLIWAMP"=>"ISCC.exe",
"SNAPSHOT"=>"tar"

View File

@@ -319,6 +319,7 @@ $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
}
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON t.fk_product = p.rowid";
// Add table from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
@@ -643,7 +644,11 @@ foreach ($object->fields as $key => $val) {
}
$cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
if (!empty($arrayfields['t.'.$key]['checked'])) {
print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''), 0, (empty($val['helplist']) ? '' : $val['helplist']))."\n";
if ($key == "fk_product") {
print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 'p.ref', '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''), 0, (empty($val['helplist']) ? '' : $val['helplist']))."\n";
} else {
print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''), 0, (empty($val['helplist']) ? '' : $val['helplist']))."\n";
}
$totalarray['nbfield']++;
}
}

View File

@@ -224,6 +224,15 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO
} elseif ($val == 'contact') { // Key selected means current contact
$tmparray[] = dol_string_nospecial($contact->getFullName($langs), ' ', array(",")).' <'.$contact->email.'>';
$sendtoid[] = $contact->id;
} elseif ($val && $object->element == 'project' && empty($object->socid)) { // $val is the Id of a contact
$contact = new Contact($db);
$ret = $contact->fetch((int) $val);
if ($ret > 0 && !empty($contact->socid)) {
$thirdparty = new Societe($db);
$thirdparty->fetch($contact->socid);
$tmparray[] = $thirdparty->contact_get_property((int) $val, 'email');
$sendtoid[] = ((int) $val);
}
} elseif ($val) { // $val is the Id of a contact
$tmparray[] = $thirdparty->contact_get_property((int) $val, 'email');
$sendtoid[] = ((int) $val);

View File

@@ -2316,10 +2316,13 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename =
}
if (!empty($message)) {
// Test log level @phan-suppress-next-line PhanPluginDuplicateArrayKey
$logLevels = array(LOG_EMERG => 'EMERG', LOG_ALERT => 'ALERT', LOG_CRIT => 'CRITICAL', LOG_ERR => 'ERR', LOG_WARNING => 'WARN', LOG_NOTICE => 'NOTICE',LOG_INFO => 'INFO', LOG_DEBUG => 'DEBUG');
// Test log level
// @phan-suppress-next-line PhanPluginDuplicateArrayKey
$logLevels = array(LOG_EMERG => 'EMERG', LOG_ALERT => 'ALERT', LOG_CRIT => 'CRITICAL', LOG_ERR => 'ERR', LOG_WARNING => 'WARN', LOG_NOTICE => 'NOTICE', LOG_INFO => 'INFO', LOG_DEBUG => 'DEBUG');
if (!array_key_exists($level, $logLevels)) {
throw new Exception('Incorrect log level');
dol_syslog('Error Bad Log Level '.$level, LOG_ERR);
$level = $logLevels[LOG_ERR];
}
if ($level > getDolGlobalInt('SYSLOG_LEVEL')) {
return;

View File

@@ -36,7 +36,7 @@ if (!defined('DOL_APPLICATION_TITLE')) {
define('DOL_APPLICATION_TITLE', 'Dolibarr');
}
if (!defined('DOL_VERSION')) {
define('DOL_VERSION', '21.0.0-beta'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
define('DOL_VERSION', '21.0.0'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
}
if (!defined('EURO')) {

View File

@@ -64,7 +64,7 @@ if (!$sortorder) {
$sortorder = "ASC";
}
if (!$sortfield) {
$sortfield = "p.name";
$sortfield = "p.lastname";
}
$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
@@ -94,12 +94,12 @@ if (dol_strlen($stcomm)) {
}
if (dol_strlen($begin)) {
$sql .= " AND p.name LIKE '$begin%'";
$sql .= " AND p.lastname LIKE '$begin%'";
}
if ($contactname) {
$sql .= " AND p.name LIKE '%".strtolower($contactname)."%'";
$sortfield = "p.name";
$sql .= " AND p.lastname LIKE '%".strtolower($contactname)."%'";
$sortfield = "p.lastname";
$sortorder = "ASC";
}
@@ -119,7 +119,7 @@ if ($result) {
print '<table class="liste centpercent">';
print '<tr class="liste_titre">';
print_liste_field_titre("Lastname", $_SERVER["PHP_SELF"], "p.name", $begin, "", "", $sortfield, $sortorder);
print_liste_field_titre("Lastname", $_SERVER["PHP_SELF"], "p.lastname", $begin, "", "", $sortfield, $sortorder);
print_liste_field_titre("Firstname", $_SERVER["PHP_SELF"], "p.firstname", $begin, "", "", $sortfield, $sortorder);
print_liste_field_titre("Company", $_SERVER["PHP_SELF"], "s.nom", $begin, "", "", $sortfield, $sortorder);
print_liste_field_titre("Email");

View File

@@ -4155,7 +4155,7 @@ function migrate_delete_old_files($db, $langs, $conf)
foreach ($filetodeletearray as $filetodelete) {
//print '<b>'DOL_DOCUMENT_ROOT.$filetodelete."</b><br>\n";
if (file_exists(DOL_DOCUMENT_ROOT.$filetodelete) || preg_match('/\*/', $filetodelete)) {
if (preg_match('/\*/', $filetodelete) || file_exists(DOL_DOCUMENT_ROOT.$filetodelete)) {
//print "Process file ".$filetodelete."\n";
$result = dol_delete_file(DOL_DOCUMENT_ROOT.$filetodelete, 0, 0, 0, null, true, 0);
if (!$result) {

View File

@@ -97,6 +97,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
* View
*/
$morehtmlright = '';
$form = new Form($db);
$formproject = new FormProjets($db);

View File

@@ -81,6 +81,7 @@ if (empty($reshook)) {
* View
*/
$morehtmlright = '';
$form = new Form($db);
$formproject = new FormProjets($db);

View File

@@ -633,7 +633,7 @@ class FormProduct
$return .= '</select>';
}
$return .= ajax_combobox($name, [], 0, 0, 'resolve', $placeholderID);
$return .= ajax_combobox($name, array(), 0, 0, 'resolve', $placeholderID); // avoid to have hidden value if scale = -1 (eg DM size)
return $return;
}

View File

@@ -3023,18 +3023,18 @@ class Product extends CommonObject
$this->net_measure = $obj->net_measure;
$this->net_measure_units = $obj->net_measure_units;
$this->weight = $obj->weight;
$this->weight_units = $obj->weight_units;
$this->weight_units = (is_null($obj->weight_units) ? 0 : $obj->weight_units);
$this->length = $obj->length;
$this->length_units = $obj->length_units;
$this->length_units = (is_null($obj->length_units) ? 0 : $obj->length_units);
$this->width = $obj->width;
$this->width_units = $obj->width_units;
$this->width_units = (is_null($obj->width_units) ? 0 : $obj->width_units);
$this->height = $obj->height;
$this->height_units = $obj->height_units;
$this->height_units = (is_null($obj->height_units) ? 0 : $obj->height_units);
$this->surface = $obj->surface;
$this->surface_units = $obj->surface_units;
$this->surface_units = (is_null($obj->surface_units) ? 0 : $obj->surface_units);
$this->volume = $obj->volume;
$this->volume_units = $obj->volume_units;
$this->volume_units = (is_null($obj->volume_units) ? 0 : $obj->volume_units);
$this->barcode = $obj->barcode;
$this->barcode_type = $obj->fk_barcode_type;

View File

@@ -2615,7 +2615,8 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
print '<td class="nowraponall">';
if ($action == 'splitline' && GETPOSTINT('lineid') == $task_time->rowid) {
if (empty($object->id)) {
$object->fetch($id);
$idTask = (!empty($id)) ? $id : $task_time->fk_element;
$object->fetch($idTask);
}
$contactsoftask = $object->getListContactId('internal');
if (!in_array($task_time->fk_user, $contactsoftask)) {
@@ -2779,7 +2780,8 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
print '<td class="nowraponall tdoverflowmax100">';
if ($action == 'splitline' && GETPOSTINT('lineid') == $task_time->rowid) {
if (empty($object->id)) {
$object->fetch($id);
$idTask = (!empty($id)) ? $id : $task_time->fk_element;
$object->fetch($idTask);
}
$contactsoftask = $object->getListContactId('internal');
if (!in_array($task_time->fk_user, $contactsoftask)) {