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

This commit is contained in:
Laurent Destailleur
2023-02-06 14:21:25 +01:00
24 changed files with 71399 additions and 69 deletions

View File

@@ -212,7 +212,7 @@ with
* Fix by replacing
if ($res[0] == PDF_TYPE_OBJECT)
with
if ($res && $res[0] == PDF_TYPE_OBJECT)
if (isset($res[0]) && $res[0] == PDF_TYPE_OBJECT)

View File

@@ -23,7 +23,6 @@ Method to encode/decode ZATCA string is available in test/phpunit/BarcodeTest.ph
* FOR QR-Bill in switzerland - Facture-QR
-----------------------------------------
Syntax of QR Code https://www.swiss-qr-invoice.org/fr/
Syntax of QR Code - See file ig-qr-bill-v2.2-fr.pdf (more doc on https://www.swiss-qr-invoice.org/downloads/)
Syntax of complentary field named "structured information of invoice S1": https://www.swiss-qr-invoice.org/downloads/qr-bill-s1-syntax-fr.pdf
To test/validate: https://www.swiss-qr-invoice.org/validator/

File diff suppressed because one or more lines are too long

View File

@@ -5,7 +5,7 @@
* Copyright (C) 2005-2015 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
* Copyright (C) 2010-2013 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2011-2022 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2011-2023 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2012-2013 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2012-2016 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
@@ -660,6 +660,10 @@ if (empty($reshook)) {
$price_ht_devise = '';
$price_ttc = '';
$price_ttc_devise = '';
$pu_ht = '';
$pu_ttc = '';
$pu_ht_devise = '';
$pu_ttc_devise = '';
if (GETPOST('price_ht') !== '') {
$price_ht = price2num(GETPOST('price_ht'), 'MU', 2);

View File

@@ -453,28 +453,26 @@ if ($search_priv != '0' && $search_priv != '1') {
}
// Search Categories
// Search Contact Categories
// Search Contact Categories
$searchCategoryContactList = $search_categ ? array($search_categ) : array();
$searchCategoryContactOperator = 0;
// Search for tag/category ($searchCategoryContactList is an array of ID)
// Search for tag/category ($searchCategoryContactList is an array of ID)
if (!empty($searchCategoryContactList)) {
$searchCategoryContactSqlList = array();
$listofcategoryid = '';
foreach ($searchCategoryContactList as $searchCategoryContact) {
if (intval($searchCategoryContact) == -2) {
$searchCategoryContactSqlList[] = "NOT EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE s.rowid = ck.fk_socpeople)";
$searchCategoryContactSqlList[] = "NOT EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE p.rowid = ck.fk_socpeople)";
} elseif (intval($searchCategoryContact) > 0) {
if ($searchCategoryContactOperator == 0) {
$searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE s.rowid = ck.fk_socpeople AND ck.fk_categorie = ".((int) $searchCategoryContact).")";
$searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE p.rowid = ck.fk_socpeople AND ck.fk_categorie = ".((int) $searchCategoryContact).")";
} else {
$listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryContact);
}
}
}
if ($listofcategoryid) {
$searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE s.rowid = ck.fk_socpeople AND ck.fk_categorie IN (".$db->sanitize($listofcategoryid)."))";
$searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE p.rowid = ck.fk_socpeople AND ck.fk_categorie IN (".$db->sanitize($listofcategoryid)."))";
}
if ($searchCategoryContactOperator == 1) {
if (!empty($searchCategoryContactSqlList)) {

View File

@@ -1735,6 +1735,7 @@ abstract class CommonInvoice extends CommonObject
$complementaryinfo .= '/30/'.$this->thirdparty->tva_intra;
}
include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
$bankaccount = new Account($this->db);
// Header
@@ -1742,16 +1743,26 @@ abstract class CommonInvoice extends CommonObject
$s .= "SPC\n";
$s .= "0200\n";
$s .= "1\n";
// Info seller
// Info Seller ("Compte / Payable à")
if ($this->fk_account > 0) {
// Bank BAN if country is LI or CH
// TODO Add test on bank iban
// Bank BAN if country is LI or CH. TODO Add a test to check than IBAN start with CH or LI
$bankaccount->fetch($this->fk_account);
$s .= $bankaccount->iban."\n";
} else {
$s .= "\n";
}
// Seller
if ($bankaccount->id > 0 && getDolGlobalString('PDF_SWISS_QRCODE_USE_OWNER_OF_ACCOUNT_AS_CREDITOR')) {
// If a bank account is prodived and we ask to use it as creditor, we use the bank address
// TODO In a future, we may always use this address, and if name/address/zip/town/country differs from $mysoc, we can use the address of $mysoc into the final seller field ?
$s .= "S\n";
$s .= dol_trunc($bankaccount->proprio, 70, 'right', 'UTF-8', 1)."\n";
$addresslinearray = explode("\n", $bankaccount->owner_address);
$s .= dol_trunc(empty($addresslinearray[1]) ? '' : $addresslinearray[1], 70, 'right', 'UTF-8', 1)."\n"; // address line 1
$s .= dol_trunc(empty($addresslinearray[2]) ? '' : $addresslinearray[2], 70, 'right', 'UTF-8', 1)."\n"; // address line 2
/*$s .= dol_trunc($mysoc->zip, 16, 'right', 'UTF-8', 1)."\n";
$s .= dol_trunc($mysoc->town, 35, 'right', 'UTF-8', 1)."\n";
$s .= dol_trunc($mysoc->country_code, 2, 'right', 'UTF-8', 1)."\n";*/
} else {
$s .= "S\n";
$s .= dol_trunc($mysoc->name, 70, 'right', 'UTF-8', 1)."\n";
$addresslinearray = explode("\n", $mysoc->address);
@@ -1760,7 +1771,8 @@ abstract class CommonInvoice extends CommonObject
$s .= dol_trunc($mysoc->zip, 16, 'right', 'UTF-8', 1)."\n";
$s .= dol_trunc($mysoc->town, 35, 'right', 'UTF-8', 1)."\n";
$s .= dol_trunc($mysoc->country_code, 2, 'right', 'UTF-8', 1)."\n";
// Final seller
}
// Final seller (Ultimate seller) ("Créancier final" = "En faveur de")
$s .= "\n";
$s .= "\n";
$s .= "\n";
@@ -1782,13 +1794,18 @@ abstract class CommonInvoice extends CommonObject
$s .= dol_trunc($this->thirdparty->country_code, 2, 'right', 'UTF-8', 1)."\n";
// ID of payment
$s .= "NON\n"; // NON or QRR
$s .= "\n"; // QR Code if previous field is QRR
$s .= "\n"; // QR Code reference if previous field is QRR
// Free text
if ($complementaryinfo) {
$s .= $complementaryinfo."\n";
} else {
$s .= "\n";
}
$s .= "EPD\n";
// More text, complementary info
if ($complementaryinfo) {
$s .= $complementaryinfo."\n";
}
$s .= "\n";
//var_dump($s);exit;
return $s;

View File

@@ -1975,6 +1975,8 @@ class ExtraFields
if (!empty($extrafield_param) && is_array($extrafield_param)) {
$extrafield_param_list = array_keys($extrafield_param['options']);
}
// Set $extrafield_collapse_display_value (do we have to collapse/expand the group after the separator)
$extrafield_collapse_display_value = -1;
$expand_display = false;
if (is_array($extrafield_param_list) && count($extrafield_param_list) > 0) {
@@ -1993,7 +1995,7 @@ class ExtraFields
$out .= '<'.$tagtype_dyn.' '.(!empty($colspan)?'colspan="' . $colspan . '"':'').'>';
// Some js code will be injected here to manage the collapsing of extrafields
// Output the picto
$out .= '<span class="cursorpointer '.($extrafield_collapse_display_value == 0 ? 'fas fa-square opacitymedium' : 'far fa-'.(($expand_display ? 'minus' : 'plus').'-square')).'"></span>';
$out .= '<span class="'.($extrafield_collapse_display_value ? 'cursorpointer ' : '').($extrafield_collapse_display_value == 0 ? 'fas fa-square opacitymedium' : 'far fa-'.(($expand_display ? 'minus' : 'plus').'-square')).'"></span>';
$out .= '&nbsp;';
$out .= '<strong>';
$out .= $langs->trans($this->attributes[$object->table_element]['label'][$key]);

View File

@@ -102,7 +102,7 @@ function check_events() {
var newToken = 'notrequired';
const allMeta = document.getElementsByTagName("meta");
for (let i = 0; i < allMeta.length; i++) {
if (allMeta[i].getAttribute("name") == 'anti-csrf-token') {
if (allMeta[i].getAttribute("name") == 'anti-csrf-currenttoken') {
newToken = allMeta[i].getAttribute('content');
console.log("newToken in page = "+newToken);
}

View File

@@ -1328,6 +1328,10 @@ function dol_string_unaccent($str)
{
global $conf;
if (is_null($str)) {
return '';
}
if (utf8_check($str)) {
if (extension_loaded('intl') && !empty($conf->global->MAIN_UNACCENT_USE_TRANSLITERATOR)) {
$transliterator = \Transliterator::createFromRules(':: Any-Latin; :: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: NFC;', \Transliterator::FORWARD);
@@ -7175,6 +7179,10 @@ function dolGetFirstLineOfText($text, $nboflines = 1, $charset = 'UTF-8')
*/
function dol_nl2br($stringtoencode, $nl2brmode = 0, $forxml = false)
{
if (is_null($stringtoencode)) {
return '';
}
if (!$nl2brmode) {
return nl2br($stringtoencode, $forxml);
} else {
@@ -8948,7 +8956,6 @@ function verifCond($strToEvaluate)
*/
function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1')
{
try {
// Only global variables can be changed by eval function and returned to caller
global $db, $langs, $user, $conf, $website, $websitepage;
global $action, $mainmenu, $leftmenu;
@@ -8959,6 +8966,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
global $obj; // To get $obj used into list when dol_eval is used for computed fields and $obj is not yet $object
global $soc; // For backward compatibility
try {
// Test on dangerous char (used for RCE), we allow only characters to make PHP variable testing
if ($onlysimplestring == '1') {
// We must accept: '1 && getDolGlobalInt("doesnotexist1") && $conf->global->MAIN_FEATURES_LEVEL'

View File

@@ -2867,13 +2867,13 @@ function getTaskProgressView($task, $label = true, $progressNumber = true, $hide
// good
$out .= ' <div class="progress-bar '.$progressBarClass.'" style="width: '.floatval($task->progress).'%" title="'.floatval($task->progress).'%">';
if (!empty($task->progress)) {
$out .= ' <div class="progress-bar progress-bar-consumed" style="width: '.floatval($progressCalculated / $task->progress * 100).'%" title="'.floatval($progressCalculated).'%"></div>';
$out .= ' <div class="progress-bar progress-bar-consumed" style="width: '.floatval($progressCalculated / (floatval($task->progress) === 0 ? 1 : $task->progress) * 100).'%" title="'.floatval($progressCalculated).'%"></div>';
}
$out .= ' </div>';
} else {
// bad
$out .= ' <div class="progress-bar progress-bar-consumed-late" style="width: '.floatval($progressCalculated).'%" title="'.floatval($progressCalculated).'%">';
$out .= ' <div class="progress-bar '.$progressBarClass.'" style="width: '.($task->progress ? floatval($task->progress / $progressCalculated * 100).'%' : '1px').'" title="'.floatval($task->progress).'%"></div>';
$out .= ' <div class="progress-bar '.$progressBarClass.'" style="width: '.($task->progress ? floatval($task->progress / (floatval($progressCalculated) === 0 ? 1 : $progressCalculated) * 100).'%' : '1px').'" title="'.floatval($task->progress).'%"></div>';
$out .= ' </div>';
}
$out .= ' </div>';

View File

@@ -50,7 +50,7 @@ function shipping_prepare_head($object)
if ($conf->delivery_note->enabled && $user->rights->expedition->delivery->lire) {
// delivery link
$object->fetchObjectLinked($object->id, $object->element);
if (is_array($object->linkedObjectsIds['delivery']) && count($object->linkedObjectsIds['delivery']) > 0) { // If there is a delivery
if (isset($object->linkedObjectsIds['delivery']) && is_array($object->linkedObjectsIds['delivery']) && count($object->linkedObjectsIds['delivery']) > 0) { // If there is a delivery
// Take first one element of array
$tmp = reset($object->linkedObjectsIds['delivery']);

View File

@@ -283,7 +283,7 @@ if ($action == 'create') {
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update_extras_line">';
print '<input type="hidden" name="origin" value="'.$origin.'">';
print '<input type="hidden" name="origin" value="'.$object->origin.'">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
print '<input type="hidden" name="ref" value="'.$object->ref.'">';
@@ -568,7 +568,7 @@ if ($action == 'create') {
$description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($object->lines[$i]->description));
//print $description;
print $form->textwithtooltip($text, $description, 3, '', '', $i);
print_date_range($object->lines[$i]->date_start, $object->lines[$i]->date_end);
//print_date_range($object->lines[$i]->date_start, $object->lines[$i]->date_end);
if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) {
print (!empty($object->lines[$i]->description) && $object->lines[$i]->description != $object->lines[$i]->product_label) ? '<br>'.dol_htmlentitiesbr($object->lines[$i]->description) : '';
}
@@ -587,7 +587,7 @@ if ($action == 'create') {
print $text.' '.nl2br($object->lines[$i]->description);
}
print_date_range($objp->date_start, $objp->date_end);
//print_date_range($objp->date_start, $objp->date_end);
print "</td>\n";
}

View File

@@ -3,7 +3,7 @@
* Copyright (C) 2005-2014 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2006-2007 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
* Copyright (C) 2011-2018 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2011-2023 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014-2015 Marcos García <marcosgdf@gmail.com>
*
@@ -819,7 +819,7 @@ class Delivery extends CommonObject
$line->product_type = $obj->fk_product_type;
$line->fk_origin_line = $obj->fk_origin_line;
$line->price = $obj->price;
$line->price = $obj->subprice;
$line->total_ht = $obj->total_ht;
// units

View File

@@ -337,7 +337,7 @@ if (empty($reshook)) {
// Extrafields
$array_options[$i] = $extrafields->getOptionalsFromPost($object->table_element_line, $i);
// Unset extrafield
if (is_array($extrafields->attributes[$object->table_element_line]['label'])) {
if (isset($extrafields->attributes[$object->table_element_line]['label']) && is_array($extrafields->attributes[$object->table_element_line]['label'])) {
// Get extra fields
foreach ($extrafields->attributes[$object->table_element_line]['label'] as $key => $value) {
unset($_POST["options_".$key]);

View File

@@ -1365,7 +1365,7 @@ class tcpdi_parser {
$obj = $this->getObjectVal($obj);
if (isset ($obj[1][1]['/Rotate'])) {
$res = $this->getObjectVal($obj[1][1]['/Rotate']);
if ($res[0] == PDF_TYPE_OBJECT)
if (isset($res[0]) && $res[0] == PDF_TYPE_OBJECT)
return $res[1];
return $res;
} else {
@@ -1373,7 +1373,7 @@ class tcpdi_parser {
return false;
} else {
$res = $this->_getPageRotation($obj[1][1]['/Parent']);
if ($res && $res[0] == PDF_TYPE_OBJECT)
if (isset($res[0]) && $res[0] == PDF_TYPE_OBJECT)
return $res[1];
return $res;
}

View File

@@ -1228,7 +1228,7 @@ INSERT INTO llx_c_departements (fk_region, code_departement, ncc, nom) VALUES (6
INSERT INTO llx_c_departements (fk_region, code_departement, ncc, nom) VALUES (601, 'ZH','ZURICH','Zürich');
-- Taiwan Divisions / Provinces / Counties (rowid country=886)
-- Taiwan Divisions / Provinces / Counties (id country=213)
INSERT INTO llx_c_departements (fk_region, code_departement, cheflieu, tncc, nom) VALUES (21301, 'TW-KLU', 'KLU', NULL, '基隆市');
INSERT INTO llx_c_departements (fk_region, code_departement, cheflieu, tncc, nom) VALUES (21301, 'TW-TPE', 'TPE', NULL, '臺北市');
INSERT INTO llx_c_departements (fk_region, code_departement, cheflieu, tncc, nom) VALUES (21301, 'TW-TPH', 'TPH', NULL, '新北市');

View File

@@ -141,6 +141,9 @@ ALTER TABLE llx_societe_rib ADD COLUMN state_id integer AFTER default_rib;
ALTER TABLE llx_societe_rib ADD COLUMN fk_country integer AFTER state_id;
ALTER TABLE llx_societe_rib ADD COLUMN currency_code varchar(3) AFTER fk_country;
DELETE FROM llx_societe_rib WHERE fk_soc = 0;
ALTER TABLE llx_societe_rib ADD CONSTRAINT llx_societe_rib_fk_societe FOREIGN KEY (fk_soc) REFERENCES llx_societe(rowid);
ALTER TABLE llx_user_rib ADD COLUMN state_id integer AFTER owner_address;
ALTER TABLE llx_user_rib ADD COLUMN fk_country integer AFTER state_id;
ALTER TABLE llx_user_rib ADD COLUMN currency_code varchar(3) AFTER fk_country;

View File

@@ -17,5 +17,5 @@
-- ============================================================================
ALTER TABLE llx_product_attribute_combination_price_level ADD UNIQUE( fk_product_attribute_combination, fk_price_level);
ALTER TABLE llx_product_attribute_combination_price_level ADD UNIQUE INDEX uk_prod_att_comb_price_level(fk_product_attribute_combination, fk_price_level);

View File

@@ -501,7 +501,7 @@ if ((!empty($conf->global->MAIN_VERSION_LAST_UPGRADE) && ($conf->global->MAIN_VE
// Creation of a token against CSRF vulnerabilities
if (!defined('NOTOKENRENEWAL') && !defined('NOSESSION')) {
// No token renewal on .css.php, .js.php and .json.php
// No token renewal on .css.php, .js.php and .json.php (even if the NOTOKENRENEWAL was not provided)
if (!preg_match('/\.(css|js|json)\.php$/', $_SERVER["PHP_SELF"])) {
// Rolling token at each call ($_SESSION['token'] contains token of previous page)
if (isset($_SESSION['newtoken'])) {
@@ -1589,7 +1589,8 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr
print '<meta name="robots" content="'.($disablenoindex ? 'index' : 'noindex').($disablenofollow ? ',follow' : ',nofollow').'">'."\n"; // Do not index
print '<meta name="viewport" content="width=device-width, initial-scale=1.0">'."\n"; // Scale for mobile device
print '<meta name="author" content="Dolibarr Development Team">'."\n";
print '<meta name="anti-csrf-token" content="'.newToken().'">'."\n";
print '<meta name="anti-csrf-newtoken" content="'.newToken().'">'."\n";
print '<meta name="anti-csrf-currenttoken" content="'.currentToken().'">'."\n";
if (getDolGlobalInt('MAIN_FEATURES_LEVEL')) {
print '<meta name="MAIN_FEATURES_LEVEL" content="'.getDolGlobalInt('MAIN_FEATURES_LEVEL').'">'."\n";
}

View File

@@ -2241,7 +2241,7 @@ if (preg_match('/^dopayment/', $action)) { // If we choosed/click on the payme
if (!empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) {
$noidempotency_key = (GETPOSTISSET('noidempotency') ? GETPOST('noidempotency', 'int') : 0); // By default noidempotency is unset, so we must use a different tag/ref for each payment. If set, we can pay several times the same tag/ref.
$paymentintent = $stripe->getPaymentIntent($amount, $currency, $tag, 'Stripe payment: '.$fulltag.(is_object($object) ? ' ref='.$object->ref : ''), $object, $stripecu, $stripeacc, $servicestatus, 0, 'automatic', false, null, 0, $noidempotency_key);
$paymentintent = $stripe->getPaymentIntent($amount, $currency, ($tag ? $tag : $fulltag), 'Stripe payment: '.$fulltag.(is_object($object) ? ' ref='.$object->ref : ''), $object, $stripecu, $stripeacc, $servicestatus, 0, 'automatic', false, null, 0, $noidempotency_key);
// The paymentintnent has status 'requires_payment_method' (even if paymentintent was already paid)
//var_dump($paymentintent);
if ($stripe->error) {

View File

@@ -465,12 +465,14 @@ class Stripe extends CommonObject
"currency" => $currency_code,
"payment_method_types" => $paymentmethodtypes,
"description" => $description,
"statement_descriptor_suffix" => $descriptor, // For card payment, 22 chars that appears on bank receipt (prefix into stripe setup + this suffix)
"statement_descriptor" => $descriptor, // For SEPA, it will take only statement_descriptor, not statement_descriptor_suffix
//"save_payment_method" => true,
"setup_future_usage" => "on_session",
"metadata" => $metadata
);
if ($descriptor) {
$dataforintent["statement_descriptor_suffix"] = $descriptor; // For card payment, 22 chars that appears on bank receipt (prefix into stripe setup + this suffix)
$dataforintent["statement_descriptor"] = $descriptor; // For SEPA, it will take only statement_descriptor, not statement_descriptor_suffix
}
if (!is_null($customer)) {
$dataforintent["customer"] = $customer;
}

View File

@@ -304,9 +304,8 @@ section.setupsection {
div.tabBar textarea:focus {
border: 1px solid #aaa !important;
}
input:focus:not(.button):not(.buttonwebsite):not(.select2-search__field):not(#top-bookmark-search-input):not(.search_component_input):not(.input-search-takepos),
input:focus:not(.button):not(.buttonwebsite):not(.buttonreset):not(.select2-search__field):not(#top-bookmark-search-input):not(.search_component_input):not(.input-search-takepos),
select:focus, .select2-container--open [aria-expanded="false"].select2-selection--single {
/* div.tabBar input:focus, div.tabBar select:focus { */
border-bottom: 1px solid #666 !important;
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;

View File

@@ -345,7 +345,7 @@ if ($mode == 'replacesite') {
$usercanedit = $user->rights->website->write;
$permissiontoadd = $user->rights->website->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles
$permissiontodelete = $user->rights->website->delete;
$permissiontodelete = $user->hasRight('website', 'delete');
/*
@@ -2930,6 +2930,11 @@ if (!GETPOST('hide_websitemenu')) {
print '<input type="submit" class="button bordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("CloneSite")).'" name="createfromclone">';
// Delete website
if (!$permissiontodelete) {
$disabled = ' disabled="disabled"';
$title = $langs->trans("NotEnoughPermissions");
$url = '#';
} else {
if ($website->status == $website::STATUS_VALIDATED) {
$disabled = ' disabled="disabled"';
$title = $langs->trans("WebsiteMustBeDisabled", $langs->transnoentitiesnoconv($website->LibStatut(0, 0)));
@@ -2939,6 +2944,7 @@ if (!GETPOST('hide_websitemenu')) {
$title = $langs->trans("Delete");
$url = $_SERVER["PHP_SELF"].'?action=deletesite&token='.newToken().'&website='.urlencode($website->ref);
}
}
print '<a href="'.$url.'" class="buttonDelete bordertransp'.($disabled ? ' disabled' : '').'"'.$disabled.' title="'.dol_escape_htmltag($title).'">'.img_picto('', 'delete', 'class=""').'<span class="hideonsmartphone paddingleft">'.$langs->trans("Delete").'</span></a>';
// Regenerate all pages