Automated merge from 23.0 to develop
This commit is contained in:
commit
ad4ceba536
37 changed files with 322 additions and 90 deletions
|
|
@ -467,3 +467,13 @@ Edit CSS to restore line removed between 4.0.5 and 4.0.6. It generates this bug:
|
||||||
JS JCROP:
|
JS JCROP:
|
||||||
----------
|
----------
|
||||||
* Remove analytics tag into file index.html
|
* Remove analytics tag into file index.html
|
||||||
|
|
||||||
|
|
||||||
|
PHP MIKE42 ESCPOS:
|
||||||
|
------------------
|
||||||
|
* In htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php
|
||||||
|
Replace:
|
||||||
|
if (!is_resource($im)) {
|
||||||
|
With:
|
||||||
|
if (!($im instanceof \GdImage) && !is_resource($im)) {
|
||||||
|
PHP 8.0+ returns GdImage objects from imagecreate*; the upstream guard with is_resource() alone fails on PHP 8 and throws 'Failed to load image' on receipts that contain an image.
|
||||||
|
|
|
||||||
|
|
@ -2618,6 +2618,10 @@ if ($id > 0) {
|
||||||
$valuetoshow = $langs->trans($valuetoshow ? $valuetoshow : $tmpid);
|
$valuetoshow = $langs->trans($valuetoshow ? $valuetoshow : $tmpid);
|
||||||
} elseif ($tabname[$id] == 'c_exp_tax_cat') {
|
} elseif ($tabname[$id] == 'c_exp_tax_cat') {
|
||||||
$valuetoshow = $langs->trans($valuetoshow);
|
$valuetoshow = $langs->trans($valuetoshow);
|
||||||
|
} elseif ($value == 'libelle' && ($tabname[$id] == 'c_stcomm' || $tabname[$id] == 'c_stcommcontact')) {
|
||||||
|
$key = 'StatusProspect'.$obj->rowid;
|
||||||
|
$trans = $langs->trans($key);
|
||||||
|
$valuetoshow = ($trans != $key ? $trans : $obj->{$value});
|
||||||
} elseif ($value == 'label' && $tabname[$id] == 'c_units') {
|
} elseif ($value == 'label' && $tabname[$id] == 'c_units') {
|
||||||
$langs->load('other');
|
$langs->load('other');
|
||||||
$key = $langs->trans($obj->label);
|
$key = $langs->trans($obj->label);
|
||||||
|
|
|
||||||
|
|
@ -69,10 +69,19 @@ $form = new Form($db);
|
||||||
$formSetup = new FormSetup($db);
|
$formSetup = new FormSetup($db);
|
||||||
|
|
||||||
|
|
||||||
// Setup conf MYMODULE_MYPARAM4 : example of quick define write style
|
// INVOICE_USE_SITUATION is a 3-state flag (0=off, 1=cumulative/legacy, 2=progressive), see admin/invoice.php.
|
||||||
$formSetup->newItem('INVOICE_USE_SITUATION')
|
// A yes/no toggle can only write 0 or 1 and deletes the const when turned off (ajax_constantonoff calls
|
||||||
->setAsYesNo()
|
// dolibarr_del_const): mode 2 could not be selected and was silently dropped. Use a 3-value select, which
|
||||||
->nameText = $langs->trans('UseSituationInvoices');
|
// writes the literal value via dolibarr_set_const and never deletes the const.
|
||||||
|
$item = $formSetup->newItem('INVOICE_USE_SITUATION');
|
||||||
|
$item->setAsSelect(array(
|
||||||
|
0 => $langs->trans('Disabled'),
|
||||||
|
1 => $langs->trans('SituationInvoiceModeCumulative'),
|
||||||
|
2 => $langs->trans('SituationInvoiceModeProgressive'),
|
||||||
|
));
|
||||||
|
$situationModeHelp = $langs->trans('SituationInvoiceModeHelp')
|
||||||
|
.'<br><b>'.$langs->trans('SituationInvoiceModeWarning').'</b>';
|
||||||
|
$item->nameText = $langs->trans('SituationInvoiceMode').info_admin($situationModeHelp, 0, 0, 'warning', 'clearboth');
|
||||||
|
|
||||||
$item = $formSetup->newItem('INVOICE_USE_SITUATION_CREDIT_NOTE')
|
$item = $formSetup->newItem('INVOICE_USE_SITUATION_CREDIT_NOTE')
|
||||||
->setAsYesNo()
|
->setAsYesNo()
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,42 @@ class Boms extends DolibarrApi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate BOM
|
||||||
|
*
|
||||||
|
* @param int $id BOM ID
|
||||||
|
* @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
||||||
|
* @return Object Object with cleaned properties
|
||||||
|
*
|
||||||
|
* @url POST {id}/validate
|
||||||
|
*
|
||||||
|
* @throws RestException 304
|
||||||
|
* @throws RestException 401
|
||||||
|
* @throws RestException 404
|
||||||
|
* @throws RestException 500 System error
|
||||||
|
*/
|
||||||
|
public function validate($id, $notrigger = 0)
|
||||||
|
{
|
||||||
|
if (!DolibarrApiAccess::$user->hasRight('bom', 'write')) {
|
||||||
|
throw new RestException(403);
|
||||||
|
}
|
||||||
|
$result = $this->bom->fetch($id);
|
||||||
|
if (!$result) {
|
||||||
|
throw new RestException(404, 'Bom not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->bom->validate(DolibarrApiAccess::$user, $notrigger);
|
||||||
|
if ($result == 0) {
|
||||||
|
throw new RestException(304, 'Error nothing done. May be object is already validated');
|
||||||
|
}
|
||||||
|
if ($result < 0) {
|
||||||
|
throw new RestException(500, 'Error when validating BOM: '.$this->bom->error);
|
||||||
|
}
|
||||||
|
$result = $this->bom->fetch($id);
|
||||||
|
|
||||||
|
return $this->_cleanObjectDatas($this->bom);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete bom
|
* Delete bom
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1266,7 +1266,7 @@ if ($socid > 0) {
|
||||||
$sql .= " rc.multicurrency_amount_ht, rc.multicurrency_amount_tva, rc.multicurrency_amount_ttc,";
|
$sql .= " rc.multicurrency_amount_ht, rc.multicurrency_amount_tva, rc.multicurrency_amount_ttc,";
|
||||||
$sql .= " rc.datec as dc, rc.description, rc.fk_invoice_supplier_line,";
|
$sql .= " rc.datec as dc, rc.description, rc.fk_invoice_supplier_line,";
|
||||||
$sql .= " rc.fk_invoice_supplier_source,";
|
$sql .= " rc.fk_invoice_supplier_source,";
|
||||||
$sql .= " u.login, u.rowid as user_id, u.statut as user_status, u.firstname, u.lastname, u.photo,";
|
$sql .= " u.login, u.rowid as user_id, u.statut as status, u.firstname, u.lastname, u.photo,";
|
||||||
$sql .= " f.rowid as invoiceid, f.ref as ref,";
|
$sql .= " f.rowid as invoiceid, f.ref as ref,";
|
||||||
$sql .= " fa.ref as invoice_source_ref, fa.type as type";
|
$sql .= " fa.ref as invoice_source_ref, fa.type as type";
|
||||||
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
|
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
|
||||||
|
|
@ -1286,7 +1286,7 @@ if ($socid > 0) {
|
||||||
$sql2 .= " rc.multicurrency_amount_ht, rc.multicurrency_amount_tva, rc.multicurrency_amount_ttc,";
|
$sql2 .= " rc.multicurrency_amount_ht, rc.multicurrency_amount_tva, rc.multicurrency_amount_ttc,";
|
||||||
$sql2 .= " rc.datec as dc, rc.description, rc.fk_invoice_supplier,";
|
$sql2 .= " rc.datec as dc, rc.description, rc.fk_invoice_supplier,";
|
||||||
$sql2 .= " rc.fk_invoice_supplier_source,";
|
$sql2 .= " rc.fk_invoice_supplier_source,";
|
||||||
$sql2 .= " u.login, u.rowid as user_id, u.statut as user_status, u.firstname, u.lastname, u.photo,";
|
$sql2 .= " u.login, u.rowid as user_id, u.statut as status, u.firstname, u.lastname, u.photo,";
|
||||||
$sql2 .= " f.rowid as invoiceid, f.ref as ref,";
|
$sql2 .= " f.rowid as invoiceid, f.ref as ref,";
|
||||||
$sql2 .= " fa.ref as invoice_source_ref, fa.type as type";
|
$sql2 .= " fa.ref as invoice_source_ref, fa.type as type";
|
||||||
$sql2 .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
|
$sql2 .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
|
||||||
|
|
|
||||||
|
|
@ -508,6 +508,22 @@ class Account extends CommonObject
|
||||||
public function add_url_line($line_id, $url_id, $url, $label, $type)
|
public function add_url_line($line_id, $url_id, $url, $label, $type)
|
||||||
{
|
{
|
||||||
// phpcs:enable
|
// phpcs:enable
|
||||||
|
// Avoid uk_bank_url collision when the same target (line_id, url_id, type) is linked twice
|
||||||
|
// e.g. two distinct credit transfers for the same employee dispatched on the same bank line.
|
||||||
|
$sqlcheck = "SELECT rowid FROM ".MAIN_DB_PREFIX."bank_url";
|
||||||
|
$sqlcheck .= " WHERE fk_bank = ".((int) $line_id);
|
||||||
|
$sqlcheck .= " AND url_id = ".((int) $url_id);
|
||||||
|
$sqlcheck .= " AND type = '".$this->db->escape($type)."'";
|
||||||
|
$resqlcheck = $this->db->query($sqlcheck);
|
||||||
|
if ($resqlcheck) {
|
||||||
|
$obj = $this->db->fetch_object($resqlcheck);
|
||||||
|
if ($obj) {
|
||||||
|
$this->db->free($resqlcheck);
|
||||||
|
return (int) $obj->rowid;
|
||||||
|
}
|
||||||
|
$this->db->free($resqlcheck);
|
||||||
|
}
|
||||||
|
|
||||||
$sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
|
$sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
|
||||||
$sql .= "fk_bank";
|
$sql .= "fk_bank";
|
||||||
$sql .= ", url_id";
|
$sql .= ", url_id";
|
||||||
|
|
|
||||||
|
|
@ -7449,7 +7449,10 @@ abstract class CommonObject
|
||||||
$extrafields = new ExtraFields($this->db);
|
$extrafields = new ExtraFields($this->db);
|
||||||
}
|
}
|
||||||
$extrafields->fetch_name_optionals_label($this->table_element);
|
$extrafields->fetch_name_optionals_label($this->table_element);
|
||||||
|
if (!isset($extrafields->attributes[$this->table_element]['type'][$key])) {
|
||||||
|
// Extrafield not defined for this object type: nothing to update
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
$value = $this->array_options["options_".$key];
|
$value = $this->array_options["options_".$key];
|
||||||
|
|
||||||
$attributeKey = $key;
|
$attributeKey = $key;
|
||||||
|
|
|
||||||
|
|
@ -934,7 +934,8 @@ class DiscountAbsolute extends CommonObject
|
||||||
/**
|
/**
|
||||||
* Helper method to create a discount from an amount.
|
* Helper method to create a discount from an amount.
|
||||||
* Used by Service.class:set_remise_except()
|
* Used by Service.class:set_remise_except()
|
||||||
* @param float $amount Currency amount to process
|
*
|
||||||
|
* @param float $amount Currency amount to process (with or without tax, depending on $amount_type)
|
||||||
* @param int<0,1> $amount_type 0 = Amount includes no taxes, 1 = Amount includes all the taxes
|
* @param int<0,1> $amount_type 0 = Amount includes no taxes, 1 = Amount includes all the taxes
|
||||||
* @param float $tva_tx TVA (main tax) percentage (>1)
|
* @param float $tva_tx TVA (main tax) percentage (>1)
|
||||||
* @param float $localtax1_tx localtax1 percentage (>1)
|
* @param float $localtax1_tx localtax1 percentage (>1)
|
||||||
|
|
@ -957,15 +958,15 @@ class DiscountAbsolute extends CommonObject
|
||||||
if ($amount_type == 1) {
|
if ($amount_type == 1) {
|
||||||
// TTC
|
// TTC
|
||||||
|
|
||||||
$this->amount_ttc = price2num($amount, 'MT');
|
$this->total_ttc = price2num($amount, 'MT');
|
||||||
|
|
||||||
if (!$localtax1_type2 && !$localtax2_type2) {
|
if (!$localtax1_type2 && !$localtax2_type2) {
|
||||||
$diviseur = 1 + $tva_tx_pct + $localtax1_tx_pct + $localtax2_tx_pct;
|
$diviseur = 1 + $tva_tx_pct + $localtax1_tx_pct + $localtax2_tx_pct;
|
||||||
$this->amount_ht = price2num((float) $amount / $diviseur, 'MT');
|
$this->total_ht = price2num((float) $amount / $diviseur, 'MT');
|
||||||
$this->amount_tva = price2num((float) $this->amount_ht * $tva_tx_pct, 'MT');
|
$this->total_tva = price2num((float) $this->total_ht * $tva_tx_pct, 'MT');
|
||||||
} else {
|
} else {
|
||||||
$diviseur = 1 + $tva_tx_pct * ($localtax1_tx_pct > 0 ? $localtax1_tx_pct : 1) * ($localtax2_tx_pct > 0 ? $localtax2_tx_pct : 1);
|
$diviseur = 1 + $tva_tx_pct * ($localtax1_tx_pct > 0 ? $localtax1_tx_pct : 1) * ($localtax2_tx_pct > 0 ? $localtax2_tx_pct : 1);
|
||||||
$lt1 = 0; $lt2 = 0; $ttc = (float) $this->amount_ttc;
|
$lt1 = 0; $lt2 = 0; $ttc = (float) $this->total_ttc;
|
||||||
if ($localtax2_tx_pct > 0) {
|
if ($localtax2_tx_pct > 0) {
|
||||||
$lt2 = $ttc - $ttc / (1 + $localtax2_tx_pct);
|
$lt2 = $ttc - $ttc / (1 + $localtax2_tx_pct);
|
||||||
}
|
}
|
||||||
|
|
@ -973,24 +974,35 @@ class DiscountAbsolute extends CommonObject
|
||||||
$lt1 = $ttc - $lt2 - ($ttc - $lt2)/ (1 + $localtax1_tx_pct);
|
$lt1 = $ttc - $lt2 - ($ttc - $lt2)/ (1 + $localtax1_tx_pct);
|
||||||
}
|
}
|
||||||
$tva = ($ttc - $lt2 - $lt1) - ($ttc - $lt2 - $lt1) / ( 1 + $tva_tx_pct);
|
$tva = ($ttc - $lt2 - $lt1) - ($ttc - $lt2 - $lt1) / ( 1 + $tva_tx_pct);
|
||||||
$this->amount_tva = price2num($tva, 'MT');
|
$this->total_tva = price2num($tva, 'MT');
|
||||||
$this->total_localtax1 = $lt1;
|
$this->total_localtax1 = $lt1;
|
||||||
$this->total_localtax2 = $lt2;
|
$this->total_localtax2 = $lt2;
|
||||||
$this->amount_ht = price2num((float) $this->amount_ttc- $this->total_localtax1 - $this->total_localtax2 - (float) $this->amount_tva, 'MT');
|
$this->total_ht = price2num((float) $this->total_ttc- $this->total_localtax1 - $this->total_localtax2 - (float) $this->total_tva, 'MT');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->multicurrency_amount_ttc = price2num($amount * (float) $this->multicurrency_tx, 'MT');
|
$this->multicurrency_total_ttc = price2num($amount * (float) $this->multicurrency_tx, 'MT');
|
||||||
$this->multicurrency_amount_ht = $this->amount_ht;
|
$this->multicurrency_total_ht = price2num((float) $amount / (1 + $tva_tx_pct) * (float) $this->multicurrency_tx, 'MT');
|
||||||
$this->multicurrency_amount_tva = price2num((float) $this->amount_ht * $tva_tx_pct * (float) $this->multicurrency_tx, 'MT');
|
$this->multicurrency_total_tva = price2num($this->multicurrency_total_ttc - $this->multicurrency_total_ht, 'MT');
|
||||||
} elseif ($amount_type == 0) {
|
} elseif ($amount_type == 0) {
|
||||||
// HT
|
// HT
|
||||||
$this->amount_ht = price2num($amount, 'MT');
|
$this->total_ht = price2num($amount, 'MT');
|
||||||
$this->amount_tva = price2num((float) $this->amount_ht * $tva_tx_pct, 'MT');
|
$this->total_tva = price2num((float) $this->total_ht * $tva_tx_pct, 'MT');
|
||||||
|
$this->total_ttc = price2num((float) $this->total_ht + (float) $this->total_tva, 'MT');
|
||||||
|
|
||||||
$this->multicurrency_amount_ht = price2num($amount * (float) $this->multicurrency_tx, 'MT');
|
$this->multicurrency_total_ht = price2num($amount * (float) $this->multicurrency_tx, 'MT');
|
||||||
$this->multicurrency_amount_tva = price2num(((float) $amount * $tva_tx_pct) * (float) $this->multicurrency_tx, 'MT');
|
$this->multicurrency_total_tva = price2num(((float) $amount * $tva_tx_pct) * (float) $this->multicurrency_tx, 'MT');
|
||||||
|
$this->multicurrency_total_ttc = price2num(((float) $this->total_ht + (float) $this->total_tva) * (float) $this->multicurrency_tx, 'MT');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For backward compatibility
|
||||||
|
$this->amount_ht = $this->total_ht;
|
||||||
|
$this->amount_tva = $this->total_tva;
|
||||||
|
$this->amount_ttc = $this->total_ttc;
|
||||||
|
$this->multicurrency_amount_ht = $this->multicurrency_total_ht;
|
||||||
|
$this->multicurrency_amount_tva = $this->multicurrency_total_tva;
|
||||||
|
$this->multicurrency_amount_ttc = $this->multicurrency_total_ttc;
|
||||||
|
|
||||||
|
|
||||||
$this->tva_tx = $tva_tx;
|
$this->tva_tx = $tva_tx;
|
||||||
$this->localtax1_tx = $localtax1_tx;
|
$this->localtax1_tx = $localtax1_tx;
|
||||||
$this->localtax1_type = $localtax1_type;
|
$this->localtax1_type = $localtax1_type;
|
||||||
|
|
@ -998,22 +1010,26 @@ class DiscountAbsolute extends CommonObject
|
||||||
$this->localtax2_type = $localtax2_type;
|
$this->localtax2_type = $localtax2_type;
|
||||||
|
|
||||||
if ($localtax1_type2 == 0) {
|
if ($localtax1_type2 == 0) {
|
||||||
$this->total_localtax1 = (float) $this->amount_ht * $localtax1_tx_pct;
|
$this->total_localtax1 = (float) $this->total_ht * $localtax1_tx_pct;
|
||||||
} elseif ($localtax1_type2 == 1) {
|
} elseif ($localtax1_type2 == 1) {
|
||||||
$this->total_localtax1 = ((float) $this->amount_ht + (float) $this->amount_tva) * $localtax1_tx_pct;
|
$this->total_localtax1 = ((float) $this->total_ht + (float) $this->total_tva) * $localtax1_tx_pct;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($localtax2_type2 == 0) {
|
if ($localtax2_type2 == 0) {
|
||||||
$this->total_localtax2 = (float) $this->amount_ht * $localtax2_tx_pct;
|
$this->total_localtax2 = (float) $this->total_ht * $localtax2_tx_pct;
|
||||||
} elseif ($localtax2_type2 == 1) {
|
} elseif ($localtax2_type2 == 1) {
|
||||||
$this->total_localtax2 = ((float) $this->amount_ht + (float) $this->amount_tva + $this->total_localtax1) * $localtax2_tx_pct;
|
$this->total_localtax2 = ((float) $this->total_ht + (float) $this->total_tva + $this->total_localtax1) * $localtax2_tx_pct;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($this->amount_ttc)) {
|
if (empty($this->total_ttc)) {
|
||||||
// If the total amount comes from a split discount, we take it as-is
|
// If the total amount comes from a split discount, we take it as-is
|
||||||
// because recalculating the total amount from the net amount creates precision errors.
|
// because recalculating the total amount from the net amount creates precision errors.
|
||||||
$this->amount_ttc = price2num((float) $this->amount_ht + (float) $this->amount_tva + $this->total_localtax1 + $this->total_localtax2, 'MT');
|
$this->total_ttc = price2num((float) $this->total_ht + (float) $this->total_tva + $this->total_localtax1 + $this->total_localtax2, 'MT');
|
||||||
$this->multicurrency_amount_ttc = price2num(((float) $this->amount_ht + (float) $this->amount_tva + $this->total_localtax1 + $this->total_localtax2) * (float) $this->multicurrency_tx, 'MT');
|
$this->multicurrency_total_ttc = price2num(((float) $this->total_ht + (float) $this->total_tva + $this->total_localtax1 + $this->total_localtax2) * (float) $this->multicurrency_tx, 'MT');
|
||||||
|
|
||||||
|
// For backward compatibility
|
||||||
|
$this->amount_ttc = $this->total_ttc;
|
||||||
|
$this->multicurrency_amount_ttc = $this->multicurrency_total_ttc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $err;
|
return $err;
|
||||||
|
|
|
||||||
|
|
@ -4330,11 +4330,11 @@ class Form
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($stocktag == 1) {
|
if ($stocktag == 1) {
|
||||||
$opt .= ' class="product_line_stock_ok"';
|
$opt .= ' class="product_line_stock_ok" data-html="'.dolPrintHTMLForAttribute($labeltoshowhtml, 0, array('strong')).dolPrintHTMLForAttribute($outvalUnits).$labeltoshowhtmlprice.dolPrintHTMLForAttribute($labeltoshowhtmlstock).'"';
|
||||||
//$opt .= ' class="product_line_stock_ok"';
|
//$opt .= ' class="product_line_stock_ok"';
|
||||||
}
|
}
|
||||||
if ($stocktag == -1) {
|
if ($stocktag == -1) {
|
||||||
$opt .= ' class="product_line_stock_too_low"';
|
$opt .= ' class="product_line_stock_too_low" data-html="'.dolPrintHTMLForAttribute($labeltoshowhtml, 0, array('strong')).dolPrintHTMLForAttribute($outvalUnits).$labeltoshowhtmlprice.dolPrintHTMLForAttribute($labeltoshowhtmlstock).'"';
|
||||||
//$opt .= ' class="product_line_stock_too_low"';
|
//$opt .= ' class="product_line_stock_too_low"';
|
||||||
}
|
}
|
||||||
$opt .= ' data-html="'.$optionhtmlforattribute.'" data-select-html="'.$optionhtmlforattribute.'"';
|
$opt .= ' data-html="'.$optionhtmlforattribute.'" data-select-html="'.$optionhtmlforattribute.'"';
|
||||||
|
|
|
||||||
|
|
@ -359,7 +359,10 @@ class Ldap
|
||||||
dol_syslog(get_class($this)."::connectBind serverPing true, we try ldap_connect to ".$host, LOG_DEBUG);
|
dol_syslog(get_class($this)."::connectBind serverPing true, we try ldap_connect to ".$host, LOG_DEBUG);
|
||||||
}
|
}
|
||||||
if (version_compare(PHP_VERSION, '8.3.0', '>=')) {
|
if (version_compare(PHP_VERSION, '8.3.0', '>=')) {
|
||||||
$uri = $host.':'.$this->serverPort;
|
// Since PHP 8.3, ldap_connect() expects a single URI argument. A scheme-less
|
||||||
|
// host (ex: localhost, 192.168.0.2) must be turned into a valid ldap:// URI,
|
||||||
|
// otherwise the host is parsed as the URI scheme and the later bind fails.
|
||||||
|
$uri = preg_match('/^ldaps?:\/\//i', $host) ? $host : 'ldap://'.$host.':'.$this->serverPort;
|
||||||
$this->connection = ldap_connect($uri);
|
$this->connection = ldap_connect($uri);
|
||||||
} else {
|
} else {
|
||||||
$this->connection = ldap_connect($host, $this->serverPort);
|
$this->connection = ldap_connect($host, $this->serverPort);
|
||||||
|
|
@ -372,7 +375,7 @@ class Ldap
|
||||||
dol_syslog(get_class($this)."::connectBind serverPing false, we try ldap_connect to ".$host, LOG_DEBUG);
|
dol_syslog(get_class($this)."::connectBind serverPing false, we try ldap_connect to ".$host, LOG_DEBUG);
|
||||||
}
|
}
|
||||||
if (version_compare(PHP_VERSION, '8.3.0', '>=')) {
|
if (version_compare(PHP_VERSION, '8.3.0', '>=')) {
|
||||||
$uri = $host.':'.$this->serverPort;
|
$uri = preg_match('/^ldaps?:\/\//i', $host) ? $host : 'ldap://'.$host.':'.$this->serverPort;
|
||||||
$this->connection = ldap_connect($uri);
|
$this->connection = ldap_connect($uri);
|
||||||
} else {
|
} else {
|
||||||
$this->connection = ldap_connect($host, $this->serverPort);
|
$this->connection = ldap_connect($host, $this->serverPort);
|
||||||
|
|
|
||||||
|
|
@ -56,11 +56,13 @@ if (!getDolGlobalString('WYSIWYG_ALLOW_UPLOAD_MEDIA_FILES')) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If upload has been allowed with WYSIWYG_ALLOW_UPLOAD_MEDIA_FILES set, we check permissions.
|
// If upload has been allowed with WYSIWYG_ALLOW_UPLOAD_MEDIA_FILES set, we check permissions.
|
||||||
|
// This connector browses and writes into the medias directory, so it must be
|
||||||
|
// restricted the same way as on the newer branches. Without this check any
|
||||||
|
// authenticated user (even with no module right) could reach the file manager.
|
||||||
if (empty($user->admin) && !$user->hasRight('website', 'write')) {
|
if (empty($user->admin) && !$user->hasRight('website', 'write')) {
|
||||||
accessforbidden('Need to have website write permission to upload files in medias directory.');
|
accessforbidden('Need to have website write permission to upload files in medias directory.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// SECURITY: You must explicitly enable this "connector". (Set it to "true").
|
// SECURITY: You must explicitly enable this "connector". (Set it to "true").
|
||||||
// WARNING: don't just set "$Config['Enabled'] = true ;", you must be sure that only
|
// WARNING: don't just set "$Config['Enabled'] = true ;", you must be sure that only
|
||||||
// authenticated users can access this file or use some kind of session checking.
|
// authenticated users can access this file or use some kind of session checking.
|
||||||
|
|
|
||||||
|
|
@ -552,7 +552,7 @@ function checkES($IentOfi, $InumCta)
|
||||||
|
|
||||||
$sum = 0;
|
$sum = 0;
|
||||||
|
|
||||||
for ($i = 0; $i < 11; $i++) {
|
for ($i = 0; $i < 10; $i++) {
|
||||||
$sum += $values[$i] * (int) substr($InumCta, $i, 1); //int to cast result of substr to a number
|
$sum += $values[$i] * (int) substr($InumCta, $i, 1); //int to cast result of substr to a number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9093,9 +9093,9 @@ function dol_string_nohtmltag($stringtoclean, $removelinefeed = 1, $pagecodeto =
|
||||||
$temp = str_replace(array("\r\n", "\r", "\n"), " ", $temp);
|
$temp = str_replace(array("\r\n", "\r", "\n"), " ", $temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// And double quotes
|
// And double spaces
|
||||||
if ($removedoublespaces) {
|
if ($removedoublespaces) {
|
||||||
while (strpos($temp, " ")) {
|
while (strpos($temp, " ") !== false) {
|
||||||
$temp = str_replace(" ", " ", $temp);
|
$temp = str_replace(" ", " ", $temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3228,9 +3228,11 @@ function pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails =
|
||||||
|
|
||||||
if (empty($hidedetails) || $hidedetails > 1) {
|
if (empty($hidedetails) || $hidedetails > 1) {
|
||||||
if (empty($multicurrency)) {
|
if (empty($multicurrency)) {
|
||||||
return (float) price2num($sign * (($object->lines[$i]->subprice * (float) $object->lines[$i]->qty) - $object->lines[$i]->total_ht), 'MT', 1);
|
$diff = (float) price2num($sign * $object->lines[$i]->subprice * (float) $object->lines[$i]->qty, 'MT', 1) - $object->lines[$i]->total_ht;
|
||||||
|
return (float) price2num($diff, 'MT', 1);
|
||||||
} else {
|
} else {
|
||||||
return (float) price2num($sign * (($object->lines[$i]->multicurrency_subprice * (float) $object->lines[$i]->qty) - $object->lines[$i]->multicurrency_total_ht), 'MT', 1);
|
$diff = (float) price2num($sign * $object->lines[$i]->multicurrency_subprice * (float) $object->lines[$i]->qty, 'MT', 1) - $object->lines[$i]->multicurrency_total_ht;
|
||||||
|
return (float) price2num($diff, 'MT', 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it
|
||||||
public $boxes = array();
|
public $boxes = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<int,array{0:string,1:string,2:string|int,3:string,4?:int<0,1>,5?:string,6?:int<0,1>}> Module constants
|
* @var array<array{0:string,1:string,2:string|int,3?:string,4?:int<0,1>,5?:string,6?:int<0,1>}> Module constants
|
||||||
* (0:name,1:type,2:val,3:note,4:visible,5:entity,6:deleteonunactive)
|
* (0:name,1:type,2:val,3:note,4:visible,5:entity,6:deleteonunactive)
|
||||||
*/
|
*/
|
||||||
public $const = array();
|
public $const = array();
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,11 @@ class ExportCsv extends ModeleExports
|
||||||
$newvalue = $outputlangs->transnoentitiesnoconv($newvalue);
|
$newvalue = $outputlangs->transnoentitiesnoconv($newvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Label may be stored HTML encoded (for example extrafield labels saved through Translate::trans()),
|
||||||
|
// so decode entities and remove HTML to keep the header consistent with the data cells.
|
||||||
|
$newvalue = dol_string_nohtmltag($newvalue);
|
||||||
|
$decodedlabel = $newvalue;
|
||||||
|
|
||||||
// Clean data and add encloser if required (depending on value of USE_STRICT_CSV_RULES)
|
// Clean data and add encloser if required (depending on value of USE_STRICT_CSV_RULES)
|
||||||
include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||||
$newvalue = csvClean($newvalue, getDolGlobalString('EXPORT_CSV_FORCE_CHARSET'), $this->separator);
|
$newvalue = csvClean($newvalue, getDolGlobalString('EXPORT_CSV_FORCE_CHARSET'), $this->separator);
|
||||||
|
|
@ -219,7 +224,9 @@ class ExportCsv extends ModeleExports
|
||||||
$typefield = isset($array_types[$code]) ? $array_types[$code] : '';
|
$typefield = isset($array_types[$code]) ? $array_types[$code] : '';
|
||||||
|
|
||||||
if (preg_match('/^Select:/i', $typefield) && $typefield = substr($typefield, 7)) {
|
if (preg_match('/^Select:/i', $typefield) && $typefield = substr($typefield, 7)) {
|
||||||
$selectlabel[$code."_label"] = $newvalue."_label";
|
// Append the "_label" suffix before cleaning so the derived column stays valid CSV
|
||||||
|
// even when the decoded label contains the separator or a quote.
|
||||||
|
$selectlabel[$code."_label"] = csvClean($decodedlabel."_label", $outputlangs->charset_output, $this->separator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,11 @@ class ImportXlsx extends ModeleImports
|
||||||
*/
|
*/
|
||||||
public $headers;
|
public $headers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $countcolumns = 0; // cached column count to avoid re-parsing the file on each row
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
|
@ -339,9 +344,13 @@ class ImportXlsx extends ModeleImports
|
||||||
}
|
}
|
||||||
$array = array();
|
$array = array();
|
||||||
|
|
||||||
|
if (empty($this->countcolumns)) {
|
||||||
$xlsx = new Xlsx();
|
$xlsx = new Xlsx();
|
||||||
$info = $xlsx->listWorksheetinfo($this->file);
|
$info = $xlsx->listWorksheetinfo($this->file);
|
||||||
$countcolumns = $info[0]['totalColumns'];
|
$this->countcolumns = $info[0]['totalColumns'];
|
||||||
|
unset($xlsx);
|
||||||
|
}
|
||||||
|
$countcolumns = $this->countcolumns;
|
||||||
|
|
||||||
for ($col = 1; $col <= $countcolumns; $col++) {
|
for ($col = 1; $col <= $countcolumns; $col++) {
|
||||||
$tmpcell = $this->workbook->getActiveSheet()->getCellByColumnAndRow($col, $this->record);
|
$tmpcell = $this->workbook->getActiveSheet()->getCellByColumnAndRow($col, $this->record);
|
||||||
|
|
@ -359,8 +368,6 @@ class ImportXlsx extends ModeleImports
|
||||||
}
|
}
|
||||||
$this->record++;
|
$this->record++;
|
||||||
|
|
||||||
unset($xlsx);
|
|
||||||
|
|
||||||
return $array;
|
return $array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -944,6 +944,9 @@ class modCategorie extends DolibarrModules
|
||||||
if (isModEnabled("order")) {
|
if (isModEnabled("order")) {
|
||||||
$this->_load_tables('/install/mysql/', 'commande');
|
$this->_load_tables('/install/mysql/', 'commande');
|
||||||
}
|
}
|
||||||
|
if (isModEnabled("propal")) {
|
||||||
|
$this->_load_tables('/install/mysql/', 'propal');
|
||||||
|
}
|
||||||
|
|
||||||
// Permissions
|
// Permissions
|
||||||
$this->remove($options);
|
$this->remove($options);
|
||||||
|
|
|
||||||
|
|
@ -101,12 +101,6 @@ class modCommande extends DolibarrModules
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
/*$r++;
|
|
||||||
$this->const[$r][0] = "COMMANDE_DRAFT_WATERMARK";
|
|
||||||
$this->const[$r][1] = "chaine";
|
|
||||||
$this->const[$r][2] = "__(Draft)__";
|
|
||||||
$this->const[$r][3] = 'Watermark to show on draft orders';
|
|
||||||
$this->const[$r][4] = 0;*/
|
|
||||||
|
|
||||||
// Boxes
|
// Boxes
|
||||||
$this->boxes = array(
|
$this->boxes = array(
|
||||||
|
|
|
||||||
|
|
@ -81,14 +81,6 @@ class modPaymentByBankTransfer extends DolibarrModules
|
||||||
$this->const = array();
|
$this->const = array();
|
||||||
$r = 0;
|
$r = 0;
|
||||||
|
|
||||||
/*$this->const[$r][0] = "BANK_ADDON_PDF";
|
|
||||||
$this->const[$r][1] = "chaine";
|
|
||||||
$this->const[$r][2] = "sepamandate";
|
|
||||||
$this->const[$r][3] = 'Name of manager to generate SEPA mandate';
|
|
||||||
$this->const[$r][4] = 0;
|
|
||||||
$r++;*/
|
|
||||||
|
|
||||||
|
|
||||||
// Boxes
|
// Boxes
|
||||||
$this->boxes = array();
|
$this->boxes = array();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -561,7 +561,7 @@ class modProduct extends DolibarrModules
|
||||||
'p.price_min' => "MinPrice",
|
'p.price_min' => "MinPrice",
|
||||||
'p.price_ttc' => "SellingPriceTTC", //with tax
|
'p.price_ttc' => "SellingPriceTTC", //with tax
|
||||||
'p.price_min_ttc' => "SellingMinPriceTTC",
|
'p.price_min_ttc' => "SellingMinPriceTTC",
|
||||||
'p.price_base_type' => "PriceBaseType", //price base: with-tax (TTC) or without (HT) tax. Displays accordingly in Product card
|
'p.price_base_type' => "PriceBaseType*", //price base: with-tax (TTC) or without (HT) tax. Displays accordingly in Product card
|
||||||
'p.tva_tx' => 'VATRate',
|
'p.tva_tx' => 'VATRate',
|
||||||
'p.default_vat_code' => 'VATCode', // to use the correct vat line when there is several lines with the same vat rate for your country
|
'p.default_vat_code' => 'VATCode', // to use the correct vat line when there is several lines with the same vat rate for your country
|
||||||
'p.datec' => 'DateCreation',
|
'p.datec' => 'DateCreation',
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,8 @@ class modStock extends DolibarrModules
|
||||||
$this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode' => 'product'));
|
$this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode' => 'product'));
|
||||||
}
|
}
|
||||||
$this->export_aggregate_array[$r] = array('ps.reel' => 'SUM'); // TODO Not used yet
|
$this->export_aggregate_array[$r] = array('ps.reel' => 'SUM'); // TODO Not used yet
|
||||||
$this->export_dependencies_array[$r] = array('stockbatch' => array('pb.rowid'), 'batch' => array('pb.rowid')); // We must keep this until the aggregate_array is used. To add unique key if we ask a field of a child to avoid the DISTINCT to discard them.
|
// We must keep this until the aggregate_array is used. To add unique key if we ask a field of a child to avoid the DISTINCT to discard them.
|
||||||
|
$this->export_dependencies_array[$r] = array('stockbatch' => array('pb.rowid'), 'batch' => array('pb.rowid'), 'movement' => array('e.rowid','p.rowid','pb.batch'));
|
||||||
$keyforselect = 'product_lot';
|
$keyforselect = 'product_lot';
|
||||||
$keyforelement = 'batch';
|
$keyforelement = 'batch';
|
||||||
$keyforaliasextra = 'extra';
|
$keyforaliasextra = 'extra';
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ class mod_ticket_universal extends ModeleNumRefTicket
|
||||||
$entity = getEntity('ticketnumber', 1, $ticket);
|
$entity = getEntity('ticketnumber', 1, $ticket);
|
||||||
|
|
||||||
$date = empty($ticket->datec) ? dol_now() : $ticket->datec;
|
$date = empty($ticket->datec) ? dol_now() : $ticket->datec;
|
||||||
$numFinal = get_next_value($db, $mask, 'ticket', 'ref', '', $objsoc->code_client, $date, 'next', false, null, $entity);
|
$numFinal = get_next_value($db, $mask, 'ticket', 'ref', '', (is_object($objsoc) ? $objsoc->code_client : ''), $date, 'next', false, null, $entity);
|
||||||
|
|
||||||
return $numFinal;
|
return $numFinal;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ if (isset($totalarray['pos'])) {
|
||||||
$i++;
|
$i++;
|
||||||
if (!empty($totalarray['pos'][$i])) {
|
if (!empty($totalarray['pos'][$i])) {
|
||||||
$fieldname = preg_replace('/[^a-z0-9]/', '', $totalarray['pos'][$i]);
|
$fieldname = preg_replace('/[^a-z0-9]/', '', $totalarray['pos'][$i]);
|
||||||
printTotalValCell($totalarray['type'][$i], $sumsarray[$fieldname]);
|
printTotalValCell($totalarray['type'][$i] ?? '', $sumsarray[$fieldname]);
|
||||||
} else {
|
} else {
|
||||||
if ($i == 1) {
|
if ($i == 1) {
|
||||||
print '<td>';
|
print '<td>';
|
||||||
|
|
|
||||||
|
|
@ -692,7 +692,13 @@ if ($step == 2 && $datatoexport) {
|
||||||
$tablename = getablenamefromfield($code, $sqlmaxforexport);
|
$tablename = getablenamefromfield($code, $sqlmaxforexport);
|
||||||
$htmltext = '<b>'.$langs->trans("Name").":</b> ".$text.'<br>';
|
$htmltext = '<b>'.$langs->trans("Name").":</b> ".$text.'<br>';
|
||||||
if (!empty($objexport->array_export_special[0][$code])) {
|
if (!empty($objexport->array_export_special[0][$code])) {
|
||||||
$htmltext .= '<b>'.$langs->trans("ComputedField")." -> ".$langs->trans("Method")." :</b> ".$objexport->array_export_special[0][$code]."<br>";
|
$htmltext .= '<b>'.$langs->trans("ComputedField")." -> ".$langs->trans("Method")." :</b> ";
|
||||||
|
if (isset($objexport->array_export_special[0][$code]['method'])) {
|
||||||
|
$htmltext .= $objexport->array_export_special[0][$code]['method'];
|
||||||
|
} elseif (!is_array($objexport->array_export_special[0][$code])) {
|
||||||
|
$htmltext .= $objexport->array_export_special[0][$code];
|
||||||
|
}
|
||||||
|
$htmltext .= "<br>";
|
||||||
} else {
|
} else {
|
||||||
$htmltext .= '<b>'.$langs->trans("Table")." -> ".$langs->trans("Field").":</b> ".$tablename." -> ".preg_replace('/^.*\./', '', $code)."<br>";
|
$htmltext .= '<b>'.$langs->trans("Table")." -> ".$langs->trans("Field").":</b> ".$tablename." -> ".preg_replace('/^.*\./', '', $code)."<br>";
|
||||||
}
|
}
|
||||||
|
|
@ -887,7 +893,13 @@ if ($step == 3 && $datatoexport) {
|
||||||
$tablename = getablenamefromfield($code, $sqlmaxforexport);
|
$tablename = getablenamefromfield($code, $sqlmaxforexport);
|
||||||
$htmltext = '<b>'.$langs->trans("Name").':</b> '.$text.'<br>';
|
$htmltext = '<b>'.$langs->trans("Name").':</b> '.$text.'<br>';
|
||||||
if (!empty($objexport->array_export_special[0][$code])) {
|
if (!empty($objexport->array_export_special[0][$code])) {
|
||||||
$htmltext .= '<b>'.$langs->trans("ComputedField")." -> ".$langs->trans("Method")." :</b> ".$objexport->array_export_special[0][$code]."<br>";
|
$htmltext .= '<b>'.$langs->trans("ComputedField")." -> ".$langs->trans("Method")." :</b> ";
|
||||||
|
if (isset($objexport->array_export_special[0][$code]['method'])) {
|
||||||
|
$htmltext .= $objexport->array_export_special[0][$code]['method'];
|
||||||
|
} elseif (!is_array($objexport->array_export_special[0][$code])) {
|
||||||
|
$htmltext .= $objexport->array_export_special[0][$code];
|
||||||
|
}
|
||||||
|
$htmltext .= "<br>";
|
||||||
} else {
|
} else {
|
||||||
$htmltext .= '<b>'.$langs->trans("Table")." -> ".$langs->trans("Field").":</b> ".$tablename." -> ".preg_replace('/^.*\./', '', $code)."<br>";
|
$htmltext .= '<b>'.$langs->trans("Table")." -> ".$langs->trans("Field").":</b> ".$tablename." -> ".preg_replace('/^.*\./', '', $code)."<br>";
|
||||||
}
|
}
|
||||||
|
|
@ -1098,7 +1110,13 @@ if ($step == 4 && $datatoexport) {
|
||||||
$tablename = getablenamefromfield($code, $sqlmaxforexport);
|
$tablename = getablenamefromfield($code, $sqlmaxforexport);
|
||||||
$htmltext = '<b>'.$langs->trans("Name").':</b> '.$text.'<br>';
|
$htmltext = '<b>'.$langs->trans("Name").':</b> '.$text.'<br>';
|
||||||
if (!empty($objexport->array_export_special[0][$code])) {
|
if (!empty($objexport->array_export_special[0][$code])) {
|
||||||
$htmltext .= '<b>'.$langs->trans("ComputedField")." -> ".$langs->trans("Method")." :</b> ".$objexport->array_export_special[0][$code]."<br>";
|
$htmltext .= '<b>'.$langs->trans("ComputedField")." -> ".$langs->trans("Method")." :</b> ";
|
||||||
|
if (isset($objexport->array_export_special[0][$code]['method'])) {
|
||||||
|
$htmltext .= $objexport->array_export_special[0][$code]['method'];
|
||||||
|
} elseif (!is_array($objexport->array_export_special[0][$code])) {
|
||||||
|
$htmltext .= $objexport->array_export_special[0][$code];
|
||||||
|
}
|
||||||
|
$htmltext .= "<br>";
|
||||||
} else {
|
} else {
|
||||||
$htmltext .= '<b>'.$langs->trans("Table")." -> ".$langs->trans("Field").":</b> ".$tablename." -> ".preg_replace('/^.*\./', '', $code)."<br>";
|
$htmltext .= '<b>'.$langs->trans("Table")." -> ".$langs->trans("Field").":</b> ".$tablename." -> ".preg_replace('/^.*\./', '', $code)."<br>";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,11 @@
|
||||||
* Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
|
* Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
|
||||||
* Copyright (C) 2014 Marcos García <marcosgdf@gmail.com>
|
* Copyright (C) 2014 Marcos García <marcosgdf@gmail.com>
|
||||||
* Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
|
* Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
|
||||||
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
|
* Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
|
||||||
* Copyright (C) 2023 Joachim Kueter <git-jk@bloxera.com>
|
* Copyright (C) 2023 Joachim Kueter <git-jk@bloxera.com>
|
||||||
* Copyright (C) 2023 Sylvain Legrand <technique@infras.fr>
|
* Copyright (C) 2023 Sylvain Legrand <technique@infras.fr>
|
||||||
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
|
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
|
||||||
|
* Copyright (C) 2026 Lionel Vessiller <lvessiller@open-dsi.fr>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -204,16 +205,31 @@ class PaiementFourn extends Paiement
|
||||||
$this->error = $langs->trans('FailedToFoundTheConversionRateForInvoice');
|
$this->error = $langs->trans('FailedToFoundTheConversionRateForInvoice');
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (empty($currencyofpayment)) {
|
// Fallback: read invoice multicurrency code/tx if caller did not fill the arrays
|
||||||
$currencyofpayment = $this->multicurrency_code[$key];
|
$invoice_multicurrency_code = $this->multicurrency_code[$key] ?? '';
|
||||||
|
$invoice_multicurrency_tx = $this->multicurrency_tx[$key] ?? '';
|
||||||
|
if (empty($invoice_multicurrency_code) || empty($invoice_multicurrency_tx)) {
|
||||||
|
$tmparray = MultiCurrency::getInvoiceRate($key, 'facture_fourn');
|
||||||
|
if ($tmparray !== false) {
|
||||||
|
if (empty($invoice_multicurrency_code)) {
|
||||||
|
$invoice_multicurrency_code = $tmparray['invoice_multicurrency_code'];
|
||||||
}
|
}
|
||||||
if ($currencyofpayment != $this->multicurrency_code[$key]) {
|
if (empty($invoice_multicurrency_tx)) {
|
||||||
|
$invoice_multicurrency_tx = $tmparray['invoice_multicurrency_tx'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($currencyofpayment)) {
|
||||||
|
$currencyofpayment = $invoice_multicurrency_code;
|
||||||
|
}
|
||||||
|
if ($currencyofpayment != $invoice_multicurrency_code) {
|
||||||
// If we have invoices with different currencies in the payment, we stop here
|
// If we have invoices with different currencies in the payment, we stop here
|
||||||
$this->error = 'ErrorYouTryToPayInvoicesWithDifferentCurrenciesInSamePayment';
|
$this->error = 'ErrorYouTryToPayInvoicesWithDifferentCurrenciesInSamePayment';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (empty($currencytxofpayment)) {
|
if (empty($currencytxofpayment)) {
|
||||||
$currencytxofpayment = $this->multicurrency_tx[$key];
|
$currencytxofpayment = $invoice_multicurrency_tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
$totalamount_converted += $value_converted;
|
$totalamount_converted += $value_converted;
|
||||||
|
|
@ -340,18 +356,25 @@ class PaiementFourn extends Paiement
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($amount_ht as $tva_tx => $xxx) {
|
foreach ($amount_ht as $tva_tx => $xxx) {
|
||||||
$discount->amount_ht = abs($amount_ht[$tva_tx]);
|
|
||||||
$discount->amount_tva = abs($amount_tva[$tva_tx]);
|
|
||||||
$discount->amount_ttc = abs($amount_ttc[$tva_tx]);
|
|
||||||
$discount->total_ht = abs($amount_ht[$tva_tx]);
|
$discount->total_ht = abs($amount_ht[$tva_tx]);
|
||||||
$discount->total_tva = abs($amount_tva[$tva_tx]);
|
$discount->total_tva = abs($amount_tva[$tva_tx]);
|
||||||
$discount->total_ttc = abs($amount_ttc[$tva_tx]);
|
$discount->total_ttc = abs($amount_ttc[$tva_tx]);
|
||||||
$discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$tva_tx]);
|
|
||||||
$discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$tva_tx]);
|
// keep compatibility
|
||||||
$discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$tva_tx]);
|
$discount->amount_ht = $discount->total_ht;
|
||||||
|
$discount->amount_tva = $discount->total_tva;
|
||||||
|
$discount->amount_ttc = $discount->total_ttc;
|
||||||
|
|
||||||
|
// multi-currency
|
||||||
$discount->multicurrency_total_ht = abs($multicurrency_amount_ht[$tva_tx]);
|
$discount->multicurrency_total_ht = abs($multicurrency_amount_ht[$tva_tx]);
|
||||||
$discount->multicurrency_total_tva = abs($multicurrency_amount_tva[$tva_tx]);
|
$discount->multicurrency_total_tva = abs($multicurrency_amount_tva[$tva_tx]);
|
||||||
$discount->multicurrency_total_ttc = abs($multicurrency_amount_ttc[$tva_tx]);
|
$discount->multicurrency_total_ttc = abs($multicurrency_amount_ttc[$tva_tx]);
|
||||||
|
|
||||||
|
// keep compatibility
|
||||||
|
$discount->multicurrency_amount_ht = $discount->multicurrency_total_ht;
|
||||||
|
$discount->multicurrency_amount_tva = $discount->multicurrency_total_tva;
|
||||||
|
$discount->multicurrency_amount_ttc = $discount->multicurrency_total_ttc;
|
||||||
|
|
||||||
$discount->tva_tx = abs((float) $tva_tx);
|
$discount->tva_tx = abs((float) $tva_tx);
|
||||||
|
|
||||||
$result = $discount->create($user);
|
$result = $discount->create($user);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
* Copyright (C) 2023 Nick Fragoulis
|
* Copyright (C) 2023 Nick Fragoulis
|
||||||
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
|
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
|
||||||
* Copyright (C) 2026 Vincent de Grandpré <vincent@de-grandpre.quebec>
|
* Copyright (C) 2026 Vincent de Grandpré <vincent@de-grandpre.quebec>
|
||||||
|
* Copyright (C) 2026 Lionel Vessiller <lvessiller@open-dsi.fr>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -724,6 +725,15 @@ if (empty($reshook)) {
|
||||||
$discount->tva_tx = 0;
|
$discount->tva_tx = 0;
|
||||||
$discount->vat_src_code = '';
|
$discount->vat_src_code = '';
|
||||||
|
|
||||||
|
// multi-currency
|
||||||
|
$discount->multicurrency_code = $object->multicurrency_code;
|
||||||
|
$discount->multicurrency_tx = $object->multicurrency_tx;
|
||||||
|
$discount->multicurrency_total_ht = $discount->multicurrency_total_ttc = (float) price2num((float) $discount->amount_ttc * (float) $object->multicurrency_tx, 'MT');
|
||||||
|
$discount->multicurrency_total_tva = 0;
|
||||||
|
// keep compatibility
|
||||||
|
$discount->multicurrency_amount_ht = $discount->multicurrency_amount_ttc = $discount->multicurrency_total_ttc;
|
||||||
|
$discount->multicurrency_amount_tva = 0;
|
||||||
|
|
||||||
$result = $discount->create($user);
|
$result = $discount->create($user);
|
||||||
if ($result < 0) {
|
if ($result < 0) {
|
||||||
$error++;
|
$error++;
|
||||||
|
|
@ -734,9 +744,16 @@ if (empty($reshook)) {
|
||||||
$discount->amount_ht = abs((float) $amount_ht[$tva_tx]);
|
$discount->amount_ht = abs((float) $amount_ht[$tva_tx]);
|
||||||
$discount->amount_tva = abs((float) $amount_tva[$tva_tx]);
|
$discount->amount_tva = abs((float) $amount_tva[$tva_tx]);
|
||||||
$discount->amount_ttc = abs((float) $amount_ttc[$tva_tx]);
|
$discount->amount_ttc = abs((float) $amount_ttc[$tva_tx]);
|
||||||
$discount->multicurrency_amount_ht = abs((float) $multicurrency_amount_ht[$tva_tx]);
|
// multi-currency
|
||||||
$discount->multicurrency_amount_tva = abs((float) $multicurrency_amount_tva[$tva_tx]);
|
$discount->multicurrency_code = $object->multicurrency_code;
|
||||||
$discount->multicurrency_amount_ttc = abs((float) $multicurrency_amount_ttc[$tva_tx]);
|
$discount->multicurrency_tx = $object->multicurrency_tx;
|
||||||
|
$discount->multicurrency_total_ht = abs((float) $multicurrency_amount_ht[$tva_tx]);
|
||||||
|
$discount->multicurrency_total_tva = abs((float) $multicurrency_amount_tva[$tva_tx]);
|
||||||
|
$discount->multicurrency_total_ttc = abs((float) $multicurrency_amount_ttc[$tva_tx]);
|
||||||
|
// keep compatibility
|
||||||
|
$discount->multicurrency_amount_ht = abs((float) $discount->multicurrency_total_ht);
|
||||||
|
$discount->multicurrency_amount_tva = abs((float) $discount->multicurrency_total_tva);
|
||||||
|
$discount->multicurrency_amount_ttc = abs((float) $discount->multicurrency_total_ttc);
|
||||||
|
|
||||||
// Clean vat code
|
// Clean vat code
|
||||||
$reg = array();
|
$reg = array();
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
|
||||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/import.lib.php';
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/import.lib.php';
|
||||||
|
|
||||||
// Load translation files required by the page
|
// Load translation files required by the page
|
||||||
$langs->loadLangs(array('exports', 'compta', 'errors', 'projects', 'admin'));
|
$langs->loadLangs(array('exports', 'compta', 'errors', 'projects', 'admin', 'products', 'margins'));
|
||||||
|
|
||||||
// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
|
// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
|
||||||
$hookmanager->initHooks(array('imports'));
|
$hookmanager->initHooks(array('imports'));
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,10 @@ class Odf
|
||||||
$this->tmpfile = $this->tmpdir.'/'.$md5uniqid.'.odt'; // We keep .odt extension to allow OpenOffice usage during debug.
|
$this->tmpfile = $this->tmpdir.'/'.$md5uniqid.'.odt'; // We keep .odt extension to allow OpenOffice usage during debug.
|
||||||
|
|
||||||
// A working directory is required for some zip proxy like PclZipProxy
|
// A working directory is required for some zip proxy like PclZipProxy
|
||||||
|
if (in_array($this->config['ZIP_PROXY'], array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) {
|
||||||
|
$result = mkdir($this->config['PATH_TO_TMP']);
|
||||||
|
}
|
||||||
|
// Check the dir has been created
|
||||||
if (in_array($this->config['ZIP_PROXY'], array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) {
|
if (in_array($this->config['ZIP_PROXY'], array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) {
|
||||||
throw new OdfException('Temporary directory '.$this->config['PATH_TO_TMP'].' must exists');
|
throw new OdfException('Temporary directory '.$this->config['PATH_TO_TMP'].' must exists');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,8 @@ UPDATE llx_accounting_account as acc SET acc.centralized = 1 WHERE acc.account_n
|
||||||
-- invert constant STOCK_ALLOW_NEGATIVE_TRANSFER because it was automatically set to 1, deleting the user config.
|
-- invert constant STOCK_ALLOW_NEGATIVE_TRANSFER because it was automatically set to 1, deleting the user config.
|
||||||
INSERT INTO llx_const (name, entity, value, type, visible, note) SELECT DISTINCT 'STOCK_DISALLOW_NEGATIVE_TRANSFER', entity, '1', 'chaine', 0, '' FROM llx_const as c1 WHERE NOT EXISTS (SELECT rowid FROM llx_const as c2 WHERE c2.name = 'STOCK_ALLOW_NEGATIVE_TRANSFER' AND c2.value = '1' AND c2.entity = c1.entity);
|
INSERT INTO llx_const (name, entity, value, type, visible, note) SELECT DISTINCT 'STOCK_DISALLOW_NEGATIVE_TRANSFER', entity, '1', 'chaine', 0, '' FROM llx_const as c1 WHERE NOT EXISTS (SELECT rowid FROM llx_const as c2 WHERE c2.name = 'STOCK_ALLOW_NEGATIVE_TRANSFER' AND c2.value = '1' AND c2.entity = c1.entity);
|
||||||
UPDATE llx_const SET name = 'STOCK_DISALLOW_NEGATIVE_TRANSFER', value = '1' WHERE name = 'STOCK_ALLOW_NEGATIVE_TRANSFER' AND value = '0';
|
UPDATE llx_const SET name = 'STOCK_DISALLOW_NEGATIVE_TRANSFER', value = '1' WHERE name = 'STOCK_ALLOW_NEGATIVE_TRANSFER' AND value = '0';
|
||||||
DELETE FROM llx_const WHERE name = 'STOCK_ALLOW_NEGATIVE_TRANSFER' AND value = '1';
|
-- Do not delete this const, otherwise the 'INSERT INTO...' will be triggered on next update
|
||||||
|
-- DELETE FROM llx_const WHERE name = 'STOCK_ALLOW_NEGATIVE_TRANSFER' AND value = '1';
|
||||||
|
|
||||||
ALTER TABLE llx_links ADD COLUMN share varchar(128) NULL AFTER objectid;
|
ALTER TABLE llx_links ADD COLUMN share varchar(128) NULL AFTER objectid;
|
||||||
ALTER TABLE llx_links ADD COLUMN share_pass varchar(32) NULL AFTER share;
|
ALTER TABLE llx_links ADD COLUMN share_pass varchar(32) NULL AFTER share;
|
||||||
|
|
|
||||||
|
|
@ -242,6 +242,11 @@ AmountOfBillsHT=Amount of invoices (net of tax)
|
||||||
AmountOfBillsByMonthHT=Amount of invoices by month (net of tax)
|
AmountOfBillsByMonthHT=Amount of invoices by month (net of tax)
|
||||||
UseSituationInvoices=Allow situation invoice
|
UseSituationInvoices=Allow situation invoice
|
||||||
UseSituationInvoicesCreditNote=Allow situation invoice credit note
|
UseSituationInvoicesCreditNote=Allow situation invoice credit note
|
||||||
|
SituationInvoiceMode=Situation invoice mode
|
||||||
|
SituationInvoiceModeCumulative=Cumulative mode (legacy)
|
||||||
|
SituationInvoiceModeProgressive=Progressive mode (recommended)
|
||||||
|
SituationInvoiceModeHelp=Cumulative mode (value 1) is the legacy implementation, flagged as unstable in the code. Progressive mode (value 2) is the recommended one.
|
||||||
|
SituationInvoiceModeWarning=Do not change this mode once situation invoices exist: amounts already stored would be interpreted differently.
|
||||||
RetainedWarranty=Retained warranty
|
RetainedWarranty=Retained warranty
|
||||||
RetainedWarrantyShort=Ret. warranty
|
RetainedWarrantyShort=Ret. warranty
|
||||||
AllowedInvoiceForRetainedWarranty=Retained warranty usable on the following types of invoices
|
AllowedInvoiceForRetainedWarranty=Retained warranty usable on the following types of invoices
|
||||||
|
|
|
||||||
|
|
@ -301,6 +301,47 @@ class Mos extends DolibarrApi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate MO
|
||||||
|
*
|
||||||
|
* @param int $id MO ID
|
||||||
|
* @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
||||||
|
* @return Object Object with cleaned properties
|
||||||
|
*
|
||||||
|
* @url POST {id}/validate
|
||||||
|
*
|
||||||
|
* @throws RestException 304
|
||||||
|
* @throws RestException 401
|
||||||
|
* @throws RestException 404
|
||||||
|
* @throws RestException 500 System error
|
||||||
|
*/
|
||||||
|
public function validate($id, $notrigger = 0)
|
||||||
|
{
|
||||||
|
if (!DolibarrApiAccess::$user->hasRight('mrp', 'write')) {
|
||||||
|
throw new RestException(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->mo->fetch($id);
|
||||||
|
if (!$result) {
|
||||||
|
throw new RestException(404, 'MO not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DolibarrApi::_checkAccessToResource('mrp', $this->mo->id, 'mrp_mo')) {
|
||||||
|
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->mo->validate(DolibarrApiAccess::$user, $notrigger);
|
||||||
|
if ($result == 0) {
|
||||||
|
throw new RestException(304, 'Error nothing done. May be object is already validated');
|
||||||
|
}
|
||||||
|
if ($result < 0) {
|
||||||
|
throw new RestException(500, 'Error when validating MO: '.$this->mo->error);
|
||||||
|
}
|
||||||
|
$result = $this->mo->fetch($id);
|
||||||
|
|
||||||
|
return $this->_cleanObjectDatas($this->mo);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete MO
|
* Delete MO
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -265,6 +265,9 @@ if (empty($reshook)) {
|
||||||
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
|
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
|
||||||
|| GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
|
|| GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
|
||||||
$massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
|
$massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
|
||||||
|
if ($action == 'confirm_reverse') { // Test on permission not required here, we only cancel a pending action
|
||||||
|
$action = 'list'; // Protection to avoid the reverse if we force a new search during the reverse confirmation
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mass actions
|
// Mass actions
|
||||||
|
|
@ -631,8 +634,9 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse movement of stock
|
// reverse movement of stock
|
||||||
if ($action == 'confirm_reverse' && $confirm == "yes" && $permissiontoadd) {
|
if (!$error && $action == 'confirm_reverse' && $confirm == "yes" && $permissiontoadd) {
|
||||||
$toselect = array_map('intval', $toselect);
|
$toselect = array_map('intval', $toselect);
|
||||||
|
$error = 0;
|
||||||
|
|
||||||
$db->begin();
|
$db->begin();
|
||||||
|
|
||||||
|
|
@ -644,7 +648,6 @@ if ($action == 'confirm_reverse' && $confirm == "yes" && $permissiontoadd) {
|
||||||
if ($resql) {
|
if ($resql) {
|
||||||
$num = $db->num_rows($resql);
|
$num = $db->num_rows($resql);
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$error =0;
|
|
||||||
while ($i < $num) {
|
while ($i < $num) {
|
||||||
$obj = $db->fetch_object($resql);
|
$obj = $db->fetch_object($resql);
|
||||||
|
|
||||||
|
|
@ -1163,7 +1166,7 @@ $modelmail = "movementstock";
|
||||||
$objecttmp = new MouvementStock($db);
|
$objecttmp = new MouvementStock($db);
|
||||||
$trackid = 'mov'.$warehouse->id;
|
$trackid = 'mov'.$warehouse->id;
|
||||||
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
|
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
|
||||||
if ($massaction == 'prereverse') {
|
if ($massaction == 'prereverse' && count($toselect) <= getDolGlobalInt('MAIN_LIMIT_FOR_MASS_ACTIONS', 1000)) {
|
||||||
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassReverse"), $langs->trans("ConfirmMassReverseQuestion", count($toselect)), "confirm_reverse", null, '', 0, 200, 500, 1, 'Yes');
|
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassReverse"), $langs->trans("ConfirmMassReverseQuestion", count($toselect)), "confirm_reverse", null, '', 0, 200, 500, 1, 'Yes');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2764,7 +2764,11 @@ class Societe extends CommonObject
|
||||||
|
|
||||||
$discount->discount_type = $discount_type;
|
$discount->discount_type = $discount_type;
|
||||||
$discount->multicurrency_code = $this->multicurrency_code;
|
$discount->multicurrency_code = $this->multicurrency_code;
|
||||||
list($this->fk_multicurrency, $this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code);
|
|
||||||
|
$tmparray = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code);
|
||||||
|
$this->fk_multicurrency = $tmparray[0];
|
||||||
|
$this->multicurrency_tx = $tmparray[1];
|
||||||
|
|
||||||
$discount->multicurrency_tx = $this->multicurrency_tx;
|
$discount->multicurrency_tx = $this->multicurrency_tx;
|
||||||
|
|
||||||
$vat_tx = (float) price2num($vatrate);
|
$vat_tx = (float) price2num($vatrate);
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,7 @@ if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT
|
||||||
|
|
||||||
// VAT
|
// VAT
|
||||||
print '<tr><td>'.$langs->trans("VATRate").'</td><td>';
|
print '<tr><td>'.$langs->trans("VATRate").'</td><td>';
|
||||||
print $form->load_tva("tva_tx", GETPOST("tva_tx", "alpha"), $mysoc, null, $object->id, 0, '', false, 1);
|
print $form->load_tva("tva_tx", GETPOST("tva_tx", "alpha"), $mysoc, $object, 0, 0, '', false, 1);
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Price base
|
// Price base
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,7 @@ if ($reshook < 0) {
|
||||||
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$sectionwithinvoicelink = '';
|
$sectionwithinvoicelink = '';
|
||||||
$CUSTOMER_DISPLAY_line1 = '';
|
$CUSTOMER_DISPLAY_line1 = '';
|
||||||
$CUSTOMER_DISPLAY_line2 = '';
|
$CUSTOMER_DISPLAY_line2 = '';
|
||||||
|
|
@ -265,6 +266,16 @@ $headerorder = '';
|
||||||
$footerorder = '';
|
$footerorder = '';
|
||||||
$printer = null;
|
$printer = null;
|
||||||
$idoflineadded = 0;
|
$idoflineadded = 0;
|
||||||
|
|
||||||
|
// Enforce the "edit lines" permission on every action that modifies an existing line
|
||||||
|
// (delete, quantity, price, discount). Adding a line, a free zone or a note is gated by
|
||||||
|
// the "run" permission elsewhere and must stay available to a plain cashier (#38949).
|
||||||
|
if (in_array($action, array('deleteline', 'updateqty', 'updateprice', 'updatereduction', 'update_reduction_global')) && !$user->hasRight('takepos', 'editlines')) {
|
||||||
|
dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), array(), 1);
|
||||||
|
$action = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (empty($reshook)) {
|
if (empty($reshook)) {
|
||||||
// Test that period is not close
|
// Test that period is not close
|
||||||
$tmpcurrentday = dol_getdate(dol_now());
|
$tmpcurrentday = dol_getdate(dol_now());
|
||||||
|
|
|
||||||
|
|
@ -3072,13 +3072,13 @@ class Ticket extends CommonObject
|
||||||
if (is_array($external_contacts) && count($external_contacts) === 0) {
|
if (is_array($external_contacts) && count($external_contacts) === 0) {
|
||||||
if (!empty($object->fk_soc)) {
|
if (!empty($object->fk_soc)) {
|
||||||
$object->fetch_thirdparty($object->fk_soc);
|
$object->fetch_thirdparty($object->fk_soc);
|
||||||
$array_company = array(array('firstname' => '', 'lastname' => $object->thirdparty->name, 'email' => $object->thirdparty->email, 'libelle' => $langs->transnoentities('Customer'), 'socid' => $object->thirdparty->id));
|
$array_company = array(array('id' => -1, 'firstname' => '', 'lastname' => $object->thirdparty->name, 'email' => $object->thirdparty->email, 'libelle' => $langs->transnoentities('Customer'), 'socid' => $object->thirdparty->id));
|
||||||
$external_contacts = array_merge($external_contacts, $array_company);
|
$external_contacts = array_merge($external_contacts, $array_company);
|
||||||
} elseif (empty($object->fk_soc) && !empty($object->origin_replyto)) {
|
} elseif (empty($object->fk_soc) && !empty($object->origin_replyto)) {
|
||||||
$array_external = array(array('firstname' => '', 'lastname' => $object->origin_replyto, 'email' => $object->origin_replyto, 'libelle' => $langs->transnoentities('Customer'), 'socid' => 0));
|
$array_external = array(array('id' => -1, 'firstname' => '', 'lastname' => $object->origin_replyto, 'email' => $object->origin_replyto, 'libelle' => $langs->transnoentities('Customer'), 'socid' => 0));
|
||||||
$external_contacts = array_merge($external_contacts, $array_external);
|
$external_contacts = array_merge($external_contacts, $array_external);
|
||||||
} elseif (empty($object->fk_soc) && !empty($object->origin_email)) {
|
} elseif (empty($object->fk_soc) && !empty($object->origin_email)) {
|
||||||
$array_external = array(array('firstname' => '', 'lastname' => $object->origin_email, 'email' => $object->thirdparty->email, 'libelle' => $langs->transnoentities('Customer'), 'socid' => $object->thirdparty->id));
|
$array_external = array(array('id' => -1, 'firstname' => '', 'lastname' => $object->origin_email, 'email' => $object->thirdparty->email, 'libelle' => $langs->transnoentities('Customer'), 'socid' => $object->thirdparty->id));
|
||||||
$external_contacts = array_merge($external_contacts, $array_external);
|
$external_contacts = array_merge($external_contacts, $array_external);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue