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

This commit is contained in:
Laurent Destailleur (aka Eldy) 2024-12-02 01:58:06 +01:00
commit 4e6d3217bc
17 changed files with 121 additions and 30 deletions

42
.github/workflows/pr-18.yaml vendored Normal file
View File

@ -0,0 +1,42 @@
on:
pull_request:
types: [opened, synchronize, reopened]
branches:
- "18.0"
push:
branches:
- "18.0"
permissions: write-all
jobs:
run:
runs-on: ubuntu-latest
env:
# GH_TOKEN: ${{ secrets.GH_TOKEN }}
GH_TOKEN: ${{ github.token }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install GitHub CLI
run: |
sudo apt update
sudo apt install gh -y
#- name: Authenticate GitHub CLI
# run: |
# echo "GH_TOKEN=$GH_TOKEN"
# gh auth login --with-token <<< "$GH_TOKEN"
- name: Assign reviewer
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
run: |
echo "GH_TOKEN=$GH_TOKEN"
pr_number=$(jq --raw-output .number < $GITHUB_EVENT_PATH)
gh pr edit $pr_number --add-reviewer "$REVIEWER"
continue-on-error: true

19
.github/workflows/test.yaml vendored Normal file
View File

@ -0,0 +1,19 @@
on:
workflow_dispatch:
pull_request:
types: [opened, reopened, synchronize]
branches:
- "18.0"
permissions: write-all
jobs:
testjob:
runs-on: ubuntu-latest
steps:
- name: Log
run: |
echo "variable org: ${{vars.AAA}}"
echo "env prg: ${{env.AAA}}"
echo "secret org: ${{secrets.BBB}}"
echo "variable repository of orga: ${{vars.CCC}}"

View File

@ -3077,11 +3077,13 @@ class Adherent extends CommonObject
$tmp = dol_getdate($now);
$datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), (int) $daysbeforeend, 'd');
$datetosearchforend = dol_time_plus_duree(dol_mktime(23, 59, 59, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), (int) $daysbeforeend, 'd');
$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
$sql .= " WHERE entity = ".((int) $conf->entity); // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only;
$sql .= " AND statut = 1";
$sql .= " AND datefin = '".$this->db->idate($datetosearchfor)."'";
$sql .= " AND datefin >= '".$this->db->idate($datetosearchfor)."'";
$sql .= " AND datefin <= '".$this->db->idate($datetosearchforend)."'";
if ((int) $fk_adherent_type > 0) {
$sql .= " AND fk_adherent_type = ".((int) $fk_adherent_type);
}

View File

@ -757,8 +757,8 @@ if ($search_note_public) {
if ($search_user > 0) {
$sql .= " AND EXISTS (";
$sql .= " SELECT ec.fk_c_type_contact, ec.element_id, ec.fk_socpeople";
$sql .= " FROM llx_element_contact as ec";
$sql .= " INNER JOIN llx_c_type_contact as tc";
$sql .= " FROM ".MAIN_DB_PREFIX."element_contact as ec";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."c_type_contact as tc";
$sql .= " ON ec.fk_c_type_contact = tc.rowid AND tc.element='propal' AND tc.source='internal'";
$sql .= " WHERE ec.element_id = p.rowid AND ec.fk_socpeople = ".((int) $search_user).")";
}

View File

@ -1084,8 +1084,8 @@ if ($search_fk_input_reason > 0) {
if ($search_user > 0) {
$sql .= " AND EXISTS (";
$sql .= " SELECT ec.fk_c_type_contact, ec.element_id, ec.fk_socpeople";
$sql .= " FROM llx_element_contact as ec";
$sql .= " INNER JOIN llx_c_type_contact as tc";
$sql .= " FROM ".MAIN_DB_PREFIX."element_contact as ec";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."c_type_contact as tc";
$sql .= " ON ec.fk_c_type_contact = tc.rowid AND tc.element='commande' AND tc.source='internal'";
$sql .= " WHERE ec.element_id = c.rowid AND ec.fk_socpeople = ".((int) $search_user).")";
}

View File

@ -609,9 +609,9 @@ $sql = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.label, b.rappr
$sql .= " b.fk_account, b.fk_type, b.fk_bordereau,";
$sql .= " ba.rowid as bankid, ba.ref as bankref";
// Add fields from extrafields
if (!empty($extrafields->attributes[$object->table_element]['label'])) {
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
$sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
if (!empty($extrafields->attributes[$extrafieldsobjectkey]['label'])) {
foreach ($extrafields->attributes[$extrafieldsobjectkey]['label'] as $key => $val) {
$sql .= ($extrafields->attributes[$extrafieldsobjectkey]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
}
}
// Add fields from hooks
@ -624,8 +624,8 @@ if ($search_bid > 0) {
}
$sql .= " ".MAIN_DB_PREFIX."bank_account as ba,";
$sql .= " ".MAIN_DB_PREFIX."bank as b";
if (!empty($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 (b.rowid = ef.fk_object)";
if (!empty($extrafields->attributes[$extrafieldsobjectkey]['label']) && is_array($extrafields->attributes[$extrafieldsobjectkey]['label']) && count($extrafields->attributes[$extrafieldsobjectkey]['label'])) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$extrafieldsobjectkey."_extrafields as ef on (b.rowid = ef.fk_object)";
}
// Add fields from hooks
@ -1910,6 +1910,7 @@ if ($resql) {
}
// Extra fields
$obj = $objp; // Because extrafield template use $obj and not $objp as object variable name
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
// Fields from hook
$parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $objp, 'i' => $i, 'totalarray' => &$totalarray);

View File

@ -892,8 +892,8 @@ if ($search_fk_fac_rec_source) {
if ($search_user > 0) {
$sql .= " AND EXISTS (";
$sql .= " SELECT ec.fk_c_type_contact, ec.element_id, ec.fk_socpeople";
$sql .= " FROM llx_element_contact as ec";
$sql .= " INNER JOIN llx_c_type_contact as tc";
$sql .= " FROM ".MAIN_DB_PREFIX."element_contact as ec";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."c_type_contact as tc";
$sql .= " ON ec.fk_c_type_contact = tc.rowid AND tc.element='facture' AND tc.source='internal'";
$sql .= " WHERE ec.element_id = f.rowid AND ec.fk_socpeople = ".((int) $search_user).")";
}

View File

@ -9201,6 +9201,10 @@ abstract class CommonObject
if (($mode == 'create') && !in_array(abs($visibility), array(1, 3))) {
continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list
} elseif (($mode == 'edit') && !in_array(abs($visibility), array(1, 3, 4))) {
// We need to make sure, that the values of hidden extrafields are also part of $_POST. Otherwise, they would be empty after an update of the object. See also getOptionalsFromPost
$ef_name = 'options_' . $key;
$ef_value = $this->array_options[$ef_name];
$out .= '<input type="hidden" name="' . $ef_name . '" id="' . $ef_name . '" value="' . $ef_value . '" />' . "\n";
continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list and <> 4 = not visible at the creation
} elseif ($mode == 'view' && empty($visibility)) {
continue;

View File

@ -13,6 +13,7 @@
* Copyright (C) 2022 Antonin MARCHAL <antonin@letempledujeu.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Benoît PASCAL <contact@p-ben.com>
* Copyright (C) 2024 Joachim Kueter <git-jk@bloxera.com>
*
* 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
@ -2853,7 +2854,11 @@ class ExtraFields
if (!GETPOSTISSET($keyprefix."options_".$key.$keysuffix)) {
continue; // Value was not provided, we should not set it.
}
$value_key = GETPOST($keyprefix."options_".$key.$keysuffix);
if ($value_key === '') {
$value_key = null;
}
}
$array_options[$keyprefix."options_".$key] = $value_key; // No keyprefix here. keyprefix is used only for read.

View File

@ -1895,7 +1895,7 @@ class EmailCollector extends CommonObject
// Note: we can have
// Message-ID=A, In-Reply-To=B, References=B and message can BE an answer or NOT (a transfer rewritten)
$isanswer = 0;
if (preg_match('/Re\s*:\s+/i', $headers['Subject'])) {
if (preg_match('/^(回复|回覆|SV|Antw|VS|RE|Re|AW|Aw|ΑΠ|השב| תשובה | הועבר|Vá|R|RIF|BLS|Atb|RES|Odp|பதில்|YNT|ATB)\s*:\s+/i', $headers['Subject'])) {
$isanswer = 1;
}
//if ($headers['In-Reply-To'] != $headers['Message-ID'] && empty($headers['References'])) $isanswer = 1; // If in-reply-to differs of message-id, this is a reply
@ -1964,7 +1964,7 @@ class EmailCollector extends CommonObject
if ($imapemail->hasHTMLBody()) {
$htmlmsg = $imapemail->getHTMLBody();
}
if ($imapemail->hasTextBody()) {
if ($imapemail->hasTextBody() && $imapemail->getTextBody() != "\n") {
$plainmsg = $imapemail->getTextBody();
}
if ($imapemail->hasAttachments()) {

View File

@ -265,7 +265,7 @@ class ConferenceOrBoothAttendee extends CommonObject
if (isset($conf->global->EVENTORGANIZATION_FILTERATTENDEES_TYPE)
&& getDolGlobalString('EVENTORGANIZATION_FILTERATTENDEES_TYPE') !== ''
&& getDolGlobalString('EVENTORGANIZATION_FILTERATTENDEES_TYPE') !== '-1') {
$this->fields['fk_soc']['type'] .= ' AND client = '.((int) getDolGlobalInt('EVENTORGANIZATION_FILTERATTENDEES_TYPE', 0));
$this->fields['fk_soc']['type'] .= ' AND (client:=:'.((int) getDolGlobalInt('EVENTORGANIZATION_FILTERATTENDEES_TYPE', 0) . ')');
}
// Example to show how to set values of fields definition dynamically

View File

@ -613,7 +613,7 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) {
// Show message
$message = '<a target="_blank" rel="noopener noreferrer" href="'.$urlwithroot.'/public/agenda/agendaexport.php?format=ical'.($conf->entity > 1 ? "&entity=".$conf->entity : "");
$message .= '&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ? urlencode(getDolGlobalString('MAIN_AGENDA_XCAL_EXPORTKEY')) : '...');
$message .= '&exportkey='.(getDolGlobalString('MAIN_AGENDA_XCAL_EXPORTKEY') ? urlencode(getDolGlobalString('MAIN_AGENDA_XCAL_EXPORTKEY')) : '...');
$message .= "&project=".$projectstatic->id.'&module='.urlencode('conforbooth@eventorganization').'&status='.ConferenceOrBooth::STATUS_CONFIRMED.'&output=file">'.$langs->trans('DownloadICSLink').img_picto('', 'download', 'class="paddingleft"').'</a>';
print $message;
print "</td></tr>";

View File

@ -419,6 +419,7 @@ if (empty($reshook)) {
$societe = new Societe($db);
$societe->fetch($cmd->socid);
$objecttmp->vat_reverse_charge = $societe->vat_reverse_charge;
$objecttmp->thirdparty = $societe;
}
$objecttmp->socid = $cmd->socid;
$objecttmp->type = $objecttmp::TYPE_STANDARD;
@ -531,10 +532,16 @@ if (empty($reshook)) {
if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
$fk_parent_line = 0;
}
$tva_tx = $lines[$i]->tva_tx;
if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) {
$tva_tx .= ' ('.$lines[$i]->vat_src_code.')';
}
$result = $objecttmp->addline(
$desc,
$lines[$i]->subprice,
$lines[$i]->tva_tx,
$tva_tx,
$lines[$i]->localtax1_tx,
$lines[$i]->localtax2_tx,
$lines[$i]->qty,

View File

@ -1346,6 +1346,11 @@ if (empty($reshook)) {
$date_end = $lines[$i]->date_end;
}
$tva_tx = $lines[$i]->tva_tx;
if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) {
$tva_tx .= ' ('.$lines[$i]->vat_src_code.')';
}
// FIXME Missing special_code into addline and updateline methods
$object->special_code = $lines[$i]->special_code;
@ -1362,7 +1367,7 @@ if (empty($reshook)) {
$result = $object->addline(
$desc,
$pu,
$lines[$i]->tva_tx,
$tva_tx,
$lines[$i]->localtax1_tx,
$lines[$i]->localtax2_tx,
$lines[$i]->qty,
@ -2733,7 +2738,9 @@ if ($action == 'create') {
require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
print '<tr><td>' . $langs->trans('VATReverseCharge') . '</td><td>';
// Try to propose to use VAT reverse charge even if the VAT reverse charge is not activated in the supplier card, if this corresponds to the context of use, the activation is proposed
if ($vat_reverse_charge == 1 || $societe->vat_reverse_charge == 1 || ($societe->country_code != 'FR' && isInEEC($societe) && !empty($societe->tva_intra))) {
if (GETPOSTISSET('vat_reverse_charge')) { // Check if form was submitted previously
$vat_reverse_charge = (GETPOST('vat_reverse_charge', 'alpha') == 'on' || GETPOST('vat_reverse_charge', 'alpha') == '1') ? 1 : 0;
} elseif ($vat_reverse_charge == 1 || $societe->vat_reverse_charge == 1 || ($societe->country_code != 'FR' && isInEEC($societe) && !empty($societe->tva_intra))) {
$vat_reverse_charge = 1;
} else {
$vat_reverse_charge = 0;
@ -3212,14 +3219,12 @@ if ($action == 'create') {
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
}
if (!$formconfirm) {
$parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
if (empty($reshook)) {
$formconfirm .= $hookmanager->resPrint;
} elseif ($reshook > 0) {
$formconfirm = $hookmanager->resPrint;
}
$parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
if (empty($reshook)) {
$formconfirm .= $hookmanager->resPrint;
} elseif ($reshook > 0) {
$formconfirm = $hookmanager->resPrint;
}
// Print form confirm

View File

@ -422,7 +422,7 @@ drop table tmp_c_shipment_mode;
-- Restore id of user on link for payment of expense report
drop table tmp_bank_url_expense_user;
create table tmp_bank_url_expense_user (select e.fk_user_author, bu2.fk_bank from llx_expensereport as e, llx_bank_url as bu2 where bu2.url_id = e.rowid and bu2.type = 'payment_expensereport');
create table tmp_bank_url_expense_user as (select e.fk_user_author, bu2.fk_bank from llx_expensereport as e, llx_bank_url as bu2 where bu2.url_id = e.rowid and bu2.type = 'payment_expensereport');
update llx_bank_url as bu set url_id = (select e.fk_user_author from tmp_bank_url_expense_user as e where e.fk_bank = bu.fk_bank) where (bu.url_id = 0 OR bu.url_id IS NULL) and bu.type ='user';
drop table tmp_bank_url_expense_user;

View File

@ -948,7 +948,7 @@ foreach ($listofreferent as $key => $value) {
$total_ttc_by_line = $element->total_ttc;
}
// Change sign of $total_ht_by_line and $total_ttc_by_line for some cases
// Change sign of $total_ht_by_line and $total_ttc_by_line for various payments
if ($tablename == 'payment_various') {
if ($element->sens == 1) {
$total_ht_by_line = -$total_ht_by_line;
@ -956,6 +956,12 @@ foreach ($listofreferent as $key => $value) {
}
}
// Change sign of $total_ht_by_line and $total_ttc_by_line for supplier proposal and supplier order
if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_proposal') {
$total_ht_by_line = -$total_ht_by_line;
$total_ttc_by_line = -$total_ttc_by_line;
}
// Add total if we have to
if ($qualifiedfortotal) {
$total_ht += $total_ht_by_line;

View File

@ -431,7 +431,7 @@ if (empty($reshook)) {
// Action to add a message (private or not, with email or not).
// This may also send an email (concatenated with email_intro and email footer if checkbox was selected)
if ($action == 'add_message' && GETPOSTISSET('btn_add_message') && $permissiontoread) {
$ret = $object->newMessage($user, $action, (GETPOST('private_message', 'alpha') == "on" ? 1 : 0), 0);
$ret = $object->newMessage($user, $action, (GETPOST('private_message', 'alpha') == "1" ? 1 : 0), 0);
if ($ret > 0) {
if (!empty($backtopage)) {