mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2025-12-06 01:28:19 +01:00
Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into develop
This commit is contained in:
19
.github/workflows/pr-18.yaml
vendored
19
.github/workflows/pr-18.yaml
vendored
@@ -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
|
||||
|
||||
21
.github/workflows/test.yaml
vendored
21
.github/workflows/test.yaml
vendored
@@ -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}}"
|
||||
|
||||
60
ChangeLog
60
ChangeLog
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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']++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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')) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -97,6 +97,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
|
||||
* View
|
||||
*/
|
||||
|
||||
$morehtmlright = '';
|
||||
$form = new Form($db);
|
||||
$formproject = new FormProjets($db);
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ if (empty($reshook)) {
|
||||
* View
|
||||
*/
|
||||
|
||||
$morehtmlright = '';
|
||||
$form = new Form($db);
|
||||
$formproject = new FormProjets($db);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user