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

This commit is contained in:
Laurent Destailleur 2024-11-19 04:04:10 +01:00
commit e9e1175134
20 changed files with 89 additions and 44 deletions

View File

@ -226,6 +226,14 @@ if ($result) {
$vatdata = $vatdata_cache[$tax_id];
} else {
$vatdata = getTaxesFromId($tax_id, $mysoc, $mysoc, 0);
if (getDolGlobalString('SERVICE_ARE_ECOMMERCE_200238EC')) {
$buyer = new Societe($db);
$buyer->fetch($obj->socid);
} else {
$buyer = null; // We don't need the buyer in this case
}
$seller = $mysoc;
$vatdata = getTaxesFromId($tax_id, $buyer, $seller, 0);
$vatdata_cache[$tax_id] = $vatdata;
}
$compta_tva = (!empty($vatdata['accountancy_code_sell']) ? $vatdata['accountancy_code_sell'] : $cpttva);

View File

@ -1129,6 +1129,10 @@ if ($num) {
if (getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')) {
$fieldsforcontent[] = 'content_lines';
}
$parameters = array('fieldsforcontent' => &$fieldsforcontent, 'tabname' => $tabname[$id]);
$hookmanager->executeHooks('editEmailTemplateFieldsForContent', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
foreach ($fieldsforcontent as $tmpfieldlist) {
$showfield = 1;
$css = "left";

View File

@ -2047,6 +2047,7 @@ if ($id > 0) {
// Related contact
print '<tr><td>'.$langs->trans("ActionOnContact").'</td><td>';
print '<div class="maxwidth200onsmartphone">';
print img_picto('', 'contact', 'class="paddingrightonly"');
if (getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT') && $conf->use_javascript_ajax) {
// FIXME Use the select_contact supporting the "multiple"

View File

@ -870,9 +870,9 @@ if ($object->id > 0) {
$filedir = $conf->propal->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
$file_list = null;
if (!empty($filedir)) {
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
}
if (is_array($file_list)) {
if (is_array($file_list) && !empty($file_list)) {
// Defined relative dir to DOL_DATA_ROOT
$relativedir = '';
if ($filedir) {
@ -982,9 +982,9 @@ if ($object->id > 0) {
$filedir = $conf->commande->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
$file_list = null;
if (!empty($filedir)) {
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
}
if (is_array($file_list)) {
if (is_array($file_list) && !empty($file_list)) {
// Defined relative dir to DOL_DATA_ROOT
$relativedir = '';
if ($filedir) {
@ -1076,9 +1076,9 @@ if ($object->id > 0) {
$filedir = $conf->expedition->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
$file_list = null;
if (!empty($filedir)) {
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
}
if (is_array($file_list)) {
if (is_array($file_list) && !empty($file_list)) {
// Defined relative dir to DOL_DATA_ROOT
$relativedir = '';
if ($filedir) {
@ -1182,9 +1182,9 @@ if ($object->id > 0) {
$filedir = $conf->contrat->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
$file_list = null;
if (!empty($filedir)) {
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
}
if (is_array($file_list)) {
if (is_array($file_list) && !empty($file_list)) {
// Defined relative dir to DOL_DATA_ROOT
$relativedir = '';
if ($filedir) {
@ -1273,9 +1273,9 @@ if ($object->id > 0) {
$filedir = $conf->ficheinter->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
$file_list = null;
if (!empty($filedir)) {
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
}
if (is_array($file_list)) {
if (is_array($file_list) && !empty($file_list)) {
// Defined relative dir to DOL_DATA_ROOT
$relativedir = '';
if ($filedir) {
@ -1485,9 +1485,9 @@ if ($object->id > 0) {
$filedir = $conf->facture->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
$file_list = null;
if (!empty($filedir)) {
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
}
if (is_array($file_list)) {
if (is_array($file_list) && !empty($file_list)) {
// Defined relative dir to DOL_DATA_ROOT
$relativedir = '';
if ($filedir) {

View File

@ -911,17 +911,17 @@ if (empty($reshook)) {
// Set unit price to use
if (!empty($price_ht) || $price_ht === '0') {
$pu_ht = price2num($price_ht, 'MU');
$pu_ttc = price2num((float) $pu_ht * (1 + ($tmpvat / 100)), 'MU');
$pu_ht = (float) price2num($price_ht, 'MU');
$pu_ttc = (float) price2num((float) $pu_ht * (1 + ($tmpvat / 100)), 'MU');
} elseif (!empty($price_ttc) || $price_ttc === '0') {
$pu_ttc = price2num($price_ttc, 'MU');
$pu_ht = price2num((float) $pu_ttc / (1 + ($tmpvat / 100)), 'MU');
$pu_ttc = (float) price2num($price_ttc, 'MU');
$pu_ht = (float) price2num((float) $pu_ttc / (1 + ($tmpvat / 100)), 'MU');
} elseif ($tmpvat != $tmpprodvat) {
// Is this still used ?
if ($price_base_type != 'HT') {
$pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU');
$pu_ht = (float) price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU');
} else {
$pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
$pu_ttc = (float) price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
}
}

View File

@ -165,7 +165,8 @@ if ($user->hasRight('banque', 'modifier') && $action == "update") {
$sql .= " SET ";
// Always opened
if (GETPOSTISSET('value')) {
$sql .= " fk_type='".$db->escape(GETPOST('value'))."',";
$type = GETPOST('value');
$sql .= " fk_type='".$db->escape(empty($type) && $object->fk_type == 'SOLD' ? 'SOLD' : $type)."',";
}
if (GETPOSTISSET('num_chq')) {
$sql .= " num_chq='".$db->escape(GETPOST("num_chq"))."',";

View File

@ -2114,7 +2114,9 @@ if ($num > 0) {
}
$filename = dol_sanitizeFileName($obj->ref);
$filedir = $conf->facture->dir_output.'/'.dol_sanitizeFileName($obj->ref);
$filepath = $conf->facture->multidir_output[$obj->entity] ?? $conf->facture->dir_output;
$filedir = $filepath . '/' . $filename;
$urlsource = $_SERVER['PHP_SELF'].'?id='.$obj->id;
print $formfile->getDocumentsLink($facturestatic->element, $filename, $filedir);
print '</td>';

View File

@ -480,6 +480,11 @@ if (!$error && $massaction == 'confirm_presend') {
$substitutionarray['__EMAIL__'] = $thirdparty->email;
$substitutionarray['__CHECK_READ__'] = '<img src="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-read.php?tag=undefined&securitykey='.dol_hash(getDolGlobalString('MAILING_EMAIL_UNSUBSCRIBE_KEY')."-undefined", 'md5').'" width="1" height="1" style="width:1px;height:1px" border="0"/>';
if ($oneemailperrecipient) {
$substitutionarray['__ONLINE_PAYMENT_URL__'] = '';
$substitutionarray['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '';
}
$parameters = array('mode' => 'formemail');
if (!empty($listofobjectthirdparties)) {

View File

@ -324,7 +324,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO
// <img alt="" src="'.$urlwithroot.'viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
$message = preg_replace('/(<img.*src=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^\/]*\/>)/', '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $message);
$sendtobcc = GETPOST('sendtoccc');
$sendtobcc = GETPOST('sendtoccc', 'alphawithlgt');
// Autocomplete the $sendtobcc
// $autocopy can be MAIN_MAIL_AUTOCOPY_PROPOSAL_TO, MAIN_MAIL_AUTOCOPY_ORDER_TO, MAIN_MAIL_AUTOCOPY_INVOICE_TO, MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO...
if (!empty($autocopy)) {

View File

@ -687,7 +687,7 @@ class CMailFile
if (!empty($this->errors_to)) {
try {
$headers->addTextHeader('Errors-To', $this->getArrayAddress($this->errors_to));
$headers->addTextHeader('Errors-To', $this->getValidAddress($this->errors_to, 0));
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
}
@ -762,7 +762,6 @@ class CMailFile
$this->errors[] = $e->getMessage();
}
}
//if (!empty($this->errors_to)) $this->message->setErrorsTo($this->getArrayAddress($this->errors_to));
if (isset($this->deliveryreceipt) && $this->deliveryreceipt == 1) {
try {
$this->message->setReadReceiptTo($this->getArrayAddress($this->addr_from));

View File

@ -1694,7 +1694,7 @@ abstract class CommonObject
$tab = array();
$sql = "SELECT DISTINCT tc.rowid, tc.code, tc.libelle as type_label, tc.position, tc.element";
$sql = "SELECT DISTINCT tc.rowid, tc.code, tc.libelle as type_label, tc.position, tc.element, tc.module";
$sql .= " FROM ".$this->db->prefix()."c_type_contact as tc";
$sqlWhere = array();
@ -1731,7 +1731,7 @@ abstract class CommonObject
$langs->loadLangs(array("propal", "orders", "bills", "suppliers", "contracts", "supplier_proposal"));
while ($obj = $this->db->fetch_object($resql)) {
$modulename = $obj->element;
$modulename = $obj->module ?? $obj->element;
if (strpos($obj->element, 'project') !== false) {
$modulename = 'projet';
} elseif ($obj->element == 'contrat') {
@ -9071,7 +9071,7 @@ abstract class CommonObject
}
}
$datekey = $keyprefix.'options_'.$key.$keysuffix;
$value = (GETPOSTISSET($datekey)) ? dol_mktime(12, 0, 0, GETPOSTINT($datekey.'month', 3), GETPOSTINT($datekey.'day', 3), GETPOSTINT($datekey.'year', 3)) : $datenotinstring;
$value = (GETPOSTISSET($datekey) && $this->id == GETPOST('elrowid', 'int')) ? dol_mktime(12, 0, 0, GETPOSTINT($datekey.'month', 3), GETPOSTINT($datekey.'day', 3), GETPOSTINT($datekey.'year', 3)) : $datenotinstring;
}
if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('datetime'))) {
$datenotinstring = null;

View File

@ -916,12 +916,14 @@ class FormMail extends Form
}
// Complete substitution array with the url to make online payment
$validpaymentmethod = array();
$paymenturl = '';
// Set the online payment url link into __ONLINE_PAYMENT_URL__ key
require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
$validpaymentmethod = getValidOnlinePaymentMethods('');
if (empty($this->substit['__REF__'])) {
$paymenturl = '';
} else {
// Set the online payment url link into __ONLINE_PAYMENT_URL__ key
require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
$langs->loadLangs(array('paypal', 'other'));
$typeforonlinepayment = 'free';
if ($this->param["models"] == 'order' || $this->param["models"] == 'order_send') {
@ -935,14 +937,15 @@ class FormMail extends Form
}
$url = getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']);
$paymenturl = $url;
$validpaymentmethod = getValidOnlinePaymentMethods('');
}
if (count($validpaymentmethod) > 0 && $paymenturl) {
$langs->load('other');
$this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl));
$this->substit['__ONLINE_PAYMENT_URL__'] = $paymenturl;
} elseif (count($validpaymentmethod) > 0) {
$this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '__ONLINE_PAYMENT_TEXT_AND_URL__';
$this->substit['__ONLINE_PAYMENT_URL__'] = '__ONLINE_PAYMENT_URL__';
} else {
$this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '';
$this->substit['__ONLINE_PAYMENT_URL__'] = '';

View File

@ -2436,7 +2436,7 @@ function show_subsidiaries($conf, $langs, $db, $object)
$i = -1;
$sql = "SELECT s.rowid, s.client, s.fournisseur, s.nom as name, s.name_alias, s.email, s.address, s.zip, s.town, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur, s.canvas";
$sql = "SELECT s.rowid, s.client, s.fournisseur, s.nom as name, s.name_alias, s.email, s.address, s.zip, s.town, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur, s.canvas, s.status";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
$sql .= " WHERE s.parent = ".((int) $object->id);
$sql .= " AND s.entity IN (".getEntity('societe').")";
@ -2476,6 +2476,7 @@ function show_subsidiaries($conf, $langs, $db, $object)
$socstatic->canvas = $obj->canvas;
$socstatic->client = $obj->client;
$socstatic->fournisseur = $obj->fournisseur;
$socstatic->status = $obj->status;
print '<tr class="oddeven">';

View File

@ -7108,7 +7108,12 @@ function getTaxesFromId($vatrate, $buyer = null, $seller = null, $firstparamisid
$sql .= ", ".MAIN_DB_PREFIX."c_country as c";
/*if ($mysoc->country_code == 'ES') $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($buyer->country_code)."'"; // vat in spain use the buyer country ??
else $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($seller->country_code)."'";*/
$sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($seller->country_code)."'";
$sql .= " WHERE t.fk_pays = c.rowid";
if (getDolGlobalString('SERVICE_ARE_ECOMMERCE_200238EC')) {
$sql .= " AND c.code = '".$db->escape($buyer->country_code)."'";
} else {
$sql .= " AND c.code = '".$db->escape($seller->country_code)."'";
}
$sql .= " AND t.taux = ".((float) $vatratecleaned)." AND t.active = 1";
$sql .= " AND t.entity IN (".getEntity('c_tva').")";
if ($vatratecode) {

View File

@ -284,6 +284,7 @@ class modTakePos extends DolibarrModules
$societe->client = 1;
$societe->code_client = '-1';
$societe->code_fournisseur = '-1';
$societe->country_id = $mysoc->country_id ? $mysoc->country_id : 1; // By default we consider the default customer is in the same country than the company
$societe->note_private = "Default customer automatically created by Point Of Sale module activation. Can be used as the default generic customer in the Point Of Sale setup. Can also be edited or removed if you don't need a generic customer.";
$searchcompanyid = $societe->create($user);

View File

@ -181,7 +181,7 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
}
// Supplier invoices take invoice date instead of creation date for the mask
$numFinal = get_next_value($db, $mask, 'facture_fourn', 'ref', '', $objsoc, $object->date);
$numFinal = get_next_value($db, $mask, 'facture_fourn', 'ref', '', $objsoc, is_object($object) ?$object->date :'');
return $numFinal;
}

View File

@ -3094,7 +3094,7 @@ class CommandeFournisseur extends CommonOrder
$sql .= $this->db->order("rowid", "ASC");
$sql .= $this->db->plimit(1);
$resql = $this->db->query($sql);
if ($resql) {
if ($resql && $this->db->num_rows($resql)) {
$obj = $this->db->fetch_object($resql);
$prodid = $obj->rowid;
}

View File

@ -954,9 +954,14 @@ class Project extends CommonObject
// Set fk_projet into elements to null
$listoftables = array(
'propal' => 'fk_projet', 'commande' => 'fk_projet', 'facture' => 'fk_projet',
'supplier_proposal' => 'fk_projet', 'commande_fournisseur' => 'fk_projet', 'facture_fourn' => 'fk_projet',
'expensereport_det' => 'fk_projet', 'contrat' => 'fk_projet',
'propal' => 'fk_projet',
'commande' => 'fk_projet',
'facture' => 'fk_projet',
'supplier_proposal' => 'fk_projet',
'commande_fournisseur' => 'fk_projet',
'facture_fourn' => 'fk_projet',
'expensereport_det' => 'fk_projet',
'contrat' => 'fk_projet',
'fichinter' => 'fk_projet',
'don' => array('field' => 'fk_projet', 'module' => 'don'),
'actioncomm' => 'fk_project',

View File

@ -2109,15 +2109,15 @@ class Task extends CommonObjectLine
$projectstatic = new Project($this->db);
$projectstatic->fetch($ori_project_id);
//Origin project start date
$orign_project_dt_start = $projectstatic->date_start;
// Origin project start date
$orign_project_dt_start = (!isset($projectstatic->date_start) || $projectstatic->date_start == '') ? $projectstatic->date_c : $projectstatic->date_start;
//Calculate new task start date with difference between origin proj start date and origin task start date
// Calculate new task start date with difference between origin proj start date and origin task start date
if (!empty($clone_task->date_start)) {
$clone_task->date_start = $now + $clone_task->date_start - $orign_project_dt_start;
}
//Calculate new task end date with difference between origin proj end date and origin task end date
// Calculate new task end date with difference between origin proj start date and origin task end date
if (!empty($clone_task->date_end)) {
$clone_task->date_end = $now + $clone_task->date_end - $orign_project_dt_start;
}

View File

@ -762,8 +762,18 @@ if ($id > 0) {
$('#fill_end_of_month').click(function(){
var clone_date_startmonth = +$('#clone_date_startmonth').val();
var clone_date_startyear = +$('#clone_date_startyear').val();
var end_date = new Date(clone_date_startyear, clone_date_startmonth, 0);
end_date.setMonth(clone_date_startmonth - 1);
var end_date;
if (clone_date_startmonth && clone_date_startyear) {
end_date = new Date(clone_date_startyear, clone_date_startmonth , 0);
} else {
var currentDate = new Date();
var currentDay = currentDate.getDate();
if (currentDay <= 15) {
end_date = new Date(currentDate.getFullYear(), currentDate.getMonth(), 0);
} else {
end_date = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0);
}
}
$('#clone_date_end').val(formatDate(end_date,'".$langs->trans("FormatDateShortJavaInput")."'));
$('#clone_date_endday').val(end_date.getDate());
$('#clone_date_endmonth').val(end_date.getMonth() + 1);