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

This commit is contained in:
Laurent Destailleur 2024-03-11 13:46:08 +01:00
commit 0f2121e3ba
15 changed files with 70 additions and 43 deletions

View File

@ -150,8 +150,7 @@ if ($action == 'updateMask') {
$ret = addDocumentModel($value, $type, $label, $scandir);
}
} elseif ($action == 'setmod') {
// TODO Verifier si module numerotation choisi peut etre active
// par appel method canBeActivated
// TODO Check if numbering module chosen can ba activated by calling method canBeActivated()
dolibarr_set_const($db, "FACTURE_ADDON", $value, 'chaine', 0, '', $conf->entity);
} elseif ($action == 'setribchq') {
@ -629,10 +628,10 @@ if (getDolGlobalString('INVOICE_USE_DEFAULT_DOCUMENT')) { // Hidden conf
print "</tr>\n";
$listtype = array(
Facture::TYPE_STANDARD => $langs->trans("InvoiceStandard"),
Facture::TYPE_REPLACEMENT => $langs->trans("InvoiceReplacement"),
Facture::TYPE_CREDIT_NOTE => $langs->trans("InvoiceAvoir"),
Facture::TYPE_DEPOSIT => $langs->trans("InvoiceDeposit"),
Facture::TYPE_STANDARD=>$langs->trans("InvoiceStandard"),
Facture::TYPE_REPLACEMENT=>$langs->trans("InvoiceReplacement"),
Facture::TYPE_CREDIT_NOTE=>$langs->trans("InvoiceAvoir"),
Facture::TYPE_DEPOSIT=>$langs->trans("InvoiceDeposit"),
);
if (getDolGlobalInt('INVOICE_USE_SITUATION')) {
$listtype[Facture::TYPE_SITUATION] = $langs->trans("InvoiceSituation");

View File

@ -341,12 +341,13 @@ if (!getDolGlobalString('SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF')) {
}
print '<strong>$dolibarr_main_stream_to_disable</strong>: ';
// $arrayofstreamtodisable is defined into filefunc.inc.php
if (empty($dolibarr_main_stream_to_disable)) {
print '<span class="opacitymedium">'.$langs->trans("Undefined").' = '.implode(', ', $arrayofstreamtodisable).'</span>';
} else {
print implode(', ', $dolibarr_main_stream_to_disable);
}
print '<span class="bold"> -> PHP streams allowed = </span>';
print '<span class="bold"> -> Current PHP streams allowed = </span>';
$arrayofstreams = stream_get_wrappers();
if (!empty($arrayofstreams)) {
sort($arrayofstreams);

View File

@ -228,6 +228,7 @@ if ($id > 0 && !preg_match('/^add/i', $action)) {
print '<div class="underbanner clearboth"></div>';
print '<table class="border centpercent tableforfield">';
// Title
print '<tr><td class="titlefield">';
if ($action == 'edit') {
print '<span class="fieldrequired">';
@ -247,6 +248,7 @@ if ($id > 0 && !preg_match('/^add/i', $action)) {
}
print '</td></tr>';
// URL
print '<tr><td>';
if ($action == 'edit') {
print '<span class="fieldrequired">';
@ -255,7 +257,7 @@ if ($id > 0 && !preg_match('/^add/i', $action)) {
if ($action == 'edit') {
print '</span>';
}
print '</td><td>';
print '</td><td class="tdoverflowmax500">';
if ($action == 'edit') {
print '<input class="flat minwidth500 quatrevingtpercent" name="url" value="'.(GETPOSTISSET("url") ? GETPOST("url") : $object->url).'">';
} else {

View File

@ -12,7 +12,7 @@
* Copyright (C) 2013 Jean-Francois FERRY <jfefe@aternatik.fr>
* Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* Copyright (C) 2014-2019 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2014-2024 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2018-2023 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
@ -1662,7 +1662,7 @@ if (empty($reshook)) {
null,
0,
'',
1
(!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA)?0:1)
);
}

View File

@ -7392,7 +7392,7 @@ abstract class CommonObject
$isDependList = 1;
}
$tmpselect .= (!empty($parent) ? ' parent="'.$parent.'"' : '');
$tmpselect .= '>'.$valb.'</option>';
$tmpselect .= '>'.$langs->trans($valb).'</option>';
}
$out .= '<select class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam ? $moreparam : '').'>';
@ -8022,7 +8022,7 @@ abstract class CommonObject
} elseif ($type == 'select') {
$value = isset($param['options'][$value]) ? $param['options'][$value] : '';
if (strpos($value, "|") !== false) {
$value = explode('|', $value)[0];
$value = $langs->trans(explode('|', $value)[0]);
}
} elseif ($type == 'sellist') {
$param_list = array_keys($param['options']);

View File

@ -10395,6 +10395,8 @@ function complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type,
$newtab[1] = $label;
$newtab[2] = str_replace('+', '', $values[1]);
$h++;
} else {
continue;
}
} elseif (count($values) == 5) { // case deprecated
dol_syslog('Passing 5 values in tabs module_parts is deprecated. Please update to 6 with permissions.', LOG_WARNING);

View File

@ -741,7 +741,7 @@ class ImportCsv extends ModeleImports
// ...
}
// Define $listfields and $listvalues to build SQL request
// Define $listfields and $listvalues to build the SQL request
if (isModEnabled("socialnetworks") && strpos($fieldname, "socialnetworks") !== false) {
if (!in_array("socialnetworks", $listfields)) {
$listfields[] = "socialnetworks";
@ -768,7 +768,7 @@ class ImportCsv extends ModeleImports
$listfields[] = $fieldname;
// Note: arrayrecord (and 'type') is filled with ->import_read_record called by import.php page before calling import_insert
if (empty($newval) && $arrayrecord[($key - 1)]['type'] < 0) {
$listvalues[] = ($newval == '0' ? $newval : "null");
$listvalues[] = ($newval == '0' ? (int) $newval : "null");
} elseif (empty($newval) && $arrayrecord[($key - 1)]['type'] == 0) {
$listvalues[] = "''";
} else {
@ -796,7 +796,7 @@ class ImportCsv extends ModeleImports
$lastinsertid = (isset($last_insert_id_array[$tmp[1]])) ? $last_insert_id_array[$tmp[1]] : 0;
$keyfield = preg_replace('/^'.preg_quote($alias, '/').'\./', '', $tmpkey);
$listfields[] = $keyfield;
$listvalues[] = $lastinsertid;
$listvalues[] = (int) $lastinsertid;
//print $tmpkey."-".$tmpval."-".$listfields."-".$listvalues."<br>";exit;
} elseif (preg_match('/^const-/', $tmpval)) {
$tmp = explode('-', $tmpval, 2);
@ -809,6 +809,7 @@ class ImportCsv extends ModeleImports
$file = (empty($objimport->array_import_convertvalue[0][$fieldname]['classfile']) ? $objimport->array_import_convertvalue[0][$fieldname]['file'] : $objimport->array_import_convertvalue[0][$fieldname]['classfile']);
$class = $objimport->array_import_convertvalue[0][$fieldname]['class'];
$method = $objimport->array_import_convertvalue[0][$fieldname]['method'];
$type = $objimport->array_import_convertvalue[0][$fieldname]['type'];
$resultload = dol_include_once($file);
if (empty($resultload)) {
dol_print_error(null, 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method);
@ -821,8 +822,16 @@ class ImportCsv extends ModeleImports
if (count($fieldArr) > 0) {
$fieldname = $fieldArr[1];
}
// Set $listfields and $listvalues
$listfields[] = $fieldname;
$listvalues[] = $res;
if ($type == 'int') {
$listvalues[] = (int) $res;
} elseif ($type == 'double') {
$listvalues[] = (float) $res;
} else {
$listvalues[] = "'".$this->db->escape($res)."'";
}
} else {
$this->errors[$error]['type'] = 'CLASSERROR';
$this->errors[$error]['lib'] = implode(
@ -964,7 +973,7 @@ class ImportCsv extends ModeleImports
$data = array_combine($listfields, $listvalues);
$set = array();
foreach ($data as $key => $val) {
$set[] = $key." = ".$val;
$set[] = $key." = ".$val; // $val was escaped/sanitized previously
}
$sqlstart .= " SET ".implode(', ', $set).", import_key = '".$this->db->escape($importid)."'";

View File

@ -787,7 +787,7 @@ class ImportXlsx extends ModeleImports
// ...
}
// Define $listfields and $listvalues to build SQL request
// Define $listfields and $listvalues to build the SQL request
if (isModEnabled("socialnetworks") && strpos($fieldname, "socialnetworks") !== false) {
if (!in_array("socialnetworks", $listfields)) {
$listfields[] = "socialnetworks";
@ -813,7 +813,7 @@ class ImportXlsx extends ModeleImports
// Note: arrayrecord (and 'type') is filled with ->import_read_record called by import.php page before calling import_insert
if (empty($newval) && $arrayrecord[($key)]['type'] < 0) {
$listvalues[] = ($newval == '0' ? $newval : "null");
$listvalues[] = ($newval == '0' ? (int) $newval : "null");
} elseif (empty($newval) && $arrayrecord[($key)]['type'] == 0) {
$listvalues[] = "''";
} else {
@ -841,7 +841,7 @@ class ImportXlsx extends ModeleImports
$lastinsertid = (isset($last_insert_id_array[$tmp[1]])) ? $last_insert_id_array[$tmp[1]] : 0;
$keyfield = preg_replace('/^' . preg_quote($alias, '/') . '\./', '', $key);
$listfields[] = $keyfield;
$listvalues[] = $lastinsertid;
$listvalues[] = (int) $lastinsertid;
//print $key."-".$val."-".$listfields."-".$listvalues."<br>";exit;
} elseif (preg_match('/^const-/', $val)) {
$tmp = explode('-', $val, 2);
@ -854,6 +854,7 @@ class ImportXlsx extends ModeleImports
$file = (empty($objimport->array_import_convertvalue[0][$fieldname]['classfile']) ? $objimport->array_import_convertvalue[0][$fieldname]['file'] : $objimport->array_import_convertvalue[0][$fieldname]['classfile']);
$class = $objimport->array_import_convertvalue[0][$fieldname]['class'];
$method = $objimport->array_import_convertvalue[0][$fieldname]['method'];
$type = $objimport->array_import_convertvalue[0][$fieldname]['type'];
$resultload = dol_include_once($file);
if (empty($resultload)) {
dol_print_error(null, 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method);
@ -865,8 +866,16 @@ class ImportXlsx extends ModeleImports
if (count($fieldArr) > 0) {
$fieldname = $fieldArr[1];
}
// Set $listfields and $listvalues
$listfields[] = $fieldname;
$listvalues[] = $res;
if ($type == 'int') {
$listvalues[] = (int) $res;
} elseif ($type == 'double') {
$listvalues[] = (float) $res;
} else {
$listvalues[] = "'".$this->db->escape($res)."'";
}
} else {
$this->errors[$error]['type'] = 'CLASSERROR';
$this->errors[$error]['lib'] = implode(
@ -1011,7 +1020,7 @@ class ImportXlsx extends ModeleImports
$data = array_combine($listfields, $listvalues);
$set = array();
foreach ($data as $key => $val) {
$set[] = $key." = ".$val;
$set[] = $key." = ".$val; // $val was escaped/sanitized previously
}
$sqlstart .= " SET " . implode(', ', $set) . ", import_key = '" . $this->db->escape($importid) . "'";

View File

@ -362,14 +362,14 @@ class modAccounting extends DolibarrModules
'b.sens'=>'rule-computeDirection'
); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent)
$this->import_convertvalue_array[$r]=array(
'b.piece_num' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanValue', 'element' => 'Accountancy'),
'b.piece_num' => array('rule' => 'compute', 'type' => 'int', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanValue', 'element' => 'Accountancy'),
'b.numero_compte'=>array('rule'=>'accountingaccount'),
'b.subledger_account'=>array('rule'=>'accountingaccount'),
'b.debit' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanAmount', 'element' => 'Accountancy'),
'b.credit' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanAmount', 'element' => 'Accountancy'),
'b.multicurrency_amount' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanAmount', 'element' => 'Accountancy'),
'b.montant' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'computeAmount', 'element' => 'Accountancy'),
'b.sens' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'computeDirection', 'element' => 'Accountancy'),
'b.debit' => array('rule' => 'compute', 'type' => 'double', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanAmount', 'element' => 'Accountancy'),
'b.credit' => array('rule' => 'compute', 'type' => 'double', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanAmount', 'element' => 'Accountancy'),
'b.multicurrency_amount' => array('rule' => 'compute', 'type' => 'double', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanAmount', 'element' => 'Accountancy'),
'b.montant' => array('rule' => 'compute', 'type' => 'double', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'computeAmount', 'element' => 'Accountancy'),
'b.sens' => array('rule' => 'compute', 'type' => 'varchar', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'computeDirection', 'element' => 'Accountancy'),
);
$this->import_regex_array[$r] = array(
//'b.doc_date'=>'^\d{4}\d{2}\d{2}$',

View File

@ -1479,7 +1479,7 @@ if ($action == 'create') {
$nbofsuggested = 0;
foreach ($product->stock_warehouse as $warehouse_id => $stock_warehouse) {
if ($stock_warehouse->real > 0) {
if ($stock_warehouse->real > 0 || !empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER)) {
$nbofsuggested++;
}
}
@ -1492,7 +1492,7 @@ if ($action == 'create') {
}
$tmpwarehouseObject->fetch($warehouse_id);
if ($stock_warehouse->real > 0) {
if ($stock_warehouse->real > 0 || !empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER)) {
$stock = + $stock_warehouse->real; // Convert it to number
$deliverableQty = min($quantityToBeDelivered, $stock);
$deliverableQty = max(0, $deliverableQty);
@ -1603,7 +1603,7 @@ if ($action == 'create') {
// Define nb of lines suggested for this order line
$nbofsuggested = 0;
foreach ($product->stock_warehouse as $warehouse_id => $stock_warehouse) {
if (($stock_warehouse->real > 0) && (count($stock_warehouse->detail_batch))) {
if (($stock_warehouse->real > 0 || !empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER)) && (count($stock_warehouse->detail_batch))) {
$nbofsuggested += count($stock_warehouse->detail_batch);
}
}
@ -1616,7 +1616,7 @@ if ($action == 'create') {
}
$tmpwarehouseObject->fetch($warehouse_id);
if (($stock_warehouse->real > 0) && (count($stock_warehouse->detail_batch))) {
if (($stock_warehouse->real > 0 || !empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER)) && (count($stock_warehouse->detail_batch))) {
foreach ($stock_warehouse->detail_batch as $dbatch) {
$batchStock = + $dbatch->qty; // To get a numeric
if (isset($alreadyQtyBatchSetted[$line->fk_product][$dbatch->batch][intval($warehouse_id)])) {
@ -1707,6 +1707,9 @@ if ($action == 'create') {
$disabled = 'disabled="disabled"';
}
print '<input class="qtyl right" name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="0"'.($disabled ? ' '.$disabled : '').'> ';
if (empty($disabled) && getDolGlobalString('STOCK_ALLOW_NEGATIVE_TRANSFER')) {
print '<input name="ent1' . $indiceAsked . '_' . $subj . '" type="hidden" value="' . $warehouse_selected_id . '">';
}
} else {
print $langs->trans("NA");
}

View File

@ -1934,7 +1934,7 @@ class FactureFournisseur extends CommonInvoice
// Set new ref and define current statut
if (!$error) {
$this->ref = $num;
$this->ref = $this->newref;
$this->statut = self::STATUS_VALIDATED;
//$this->date_validation=$now; this is stored into log table
}

View File

@ -414,10 +414,10 @@ class ProductFournisseur extends Product
$fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $multicurrency_code);
}
$buyprice = price2num($buyprice, 'MU');
$charges = price2num($charges, 'MU');
$qty = price2num($qty, 'MS');
$unitBuyPrice = price2num($buyprice / $qty, 'MU');
$buyprice = (float) price2num($buyprice, 'MU');
$charges = (float) price2num($charges, 'MU');
$qty = (float) price2num($qty, 'MS');
$unitBuyPrice = (float) price2num($buyprice / $qty, 'MU');
// We can have a purchase ref that need to buy 100 min for a given price and with a packaging of 50.
//$packaging = price2num(((empty($this->packaging) || $this->packaging < $qty) ? $qty : $this->packaging), 'MS');
@ -446,10 +446,6 @@ class ProductFournisseur extends Product
$localtax2 = 0; // If = '' then = 0
}
// Check parameters
if ($buyprice != '' && !is_numeric($buyprice)) {
}
$this->db->begin();
if ($this->product_fourn_price_id > 0) {
@ -478,6 +474,7 @@ class ProductFournisseur extends Product
}
$sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price";
$sql .= " SET fk_user = ".((int) $user->id)." ,";
$sql .= " datec = '".$this->db->idate($now)."' ,"; // Note: Even if this is an update, we update the creation date as the log of each change is tracked into product_fournisseur_log.
$sql .= " ref_fourn = '".$this->db->escape($ref_fourn)."',";
$sql .= " desc_fourn = '".$this->db->escape($desc_fourn)."',";
$sql .= " price = ".((float) $buyprice).",";

View File

@ -2717,7 +2717,11 @@ if ($action == 'create') {
print '<td>'.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).'</td>';
print '<td class="maxwidthonsmartphone">';
print img_picto('', 'currency', 'class="pictofixedwidth"');
print $form->selectMultiCurrency((GETPOSTISSET('multicurrency_code') ? GETPOST('multicurrency_code', 'alpha') : $currency_code), 'multicurrency_code');
$used_currency_code = $currency_code;
if (!GETPOST('changecompany')) {
$used_currency_code = GETPOSTISSET('multicurrency_code') ? GETPOST('multicurrency_code', 'alpha') : $currency_code;
}
print $form->selectMultiCurrency($used_currency_code, 'multicurrency_code');
print '</td></tr>';
}

View File

@ -48,6 +48,7 @@ $action = GETPOST('action', 'alpha');
$massaction = GETPOST('massaction', 'alpha');
$optioncss = GETPOST('optioncss', 'alpha');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'vendorpaymentlist';
$mode = GETPOST('mode', 'aZ');
$socid = GETPOSTINT('socid');

View File

@ -383,7 +383,7 @@ div.paymentbordline
margin: 0 auto;
width: 100%;
height: 55%;
overflow: hidden;
overflow-x: hidden;
}
.div1{