Merge branch 'develop' of github.com:Dolibarr/dolibarr into new-emailcollector-substitute-date-now

This commit is contained in:
VESSILLER 2022-12-06 16:01:38 +01:00
commit fc44801581
90 changed files with 723 additions and 321 deletions

View File

@ -209,6 +209,32 @@ Following changes may create regressions for some external modules, but were nec
* Rename the substitution for project label instead of project title in substitution variables
***** ChangeLog for 16.0.3 compared to 16.0.2 *****
FIX: $sign is useless
FIX: #18304 Member subscription confirmation email sent even if mandatory fields are missing
FIX: #19828
FIX: #19877
FIX: #22509 default value on integer fields don't retrieve by setSaveQuery
FIX: #22786
FIX: #22813
FIX: #22824 Accountancy - Journal - Search on subledger when list of subledger is disabled
FIX: Backup using the low memory mode
FIX: Bankaccounts API fetch with 'id' and 'socid'
FIX: base64_decode should be forbiden in dol_eval
FIX: Broken Permissions check, $object is null.
FIX: compute next value when year is on one digit for reset counter
FIX: copy same behaviour in other accountancy files
FIX: Fix the position of the verification condition of the test field in case of multi entities
FIX: for #22882
FIX: for #22952
FIX: merge errors on mailing card
FIX: PaymentBankTransfer Type page management with Select and Input on create.php
FIX: remove not initialized variable
FIX: SQL request parenthesis
FIX: Use the Hook addMoreActionsButtons resPrint
FIX: Wrong Extrafields Element For Assets
***** ChangeLog for 16.0.2 compared to 16.0.1 *****
FIX: 16.0 - computed extrafields are not displayed if the object has no other extrafields

View File

@ -1,3 +1,3 @@
# Use bzip2 instead of gzip
compression = "bzip2"
compression-level = 9
# Force use of gzip compression by dpkg-buildpackage
compression = "gzip"
#compression-level = 9

View File

@ -678,7 +678,7 @@ if ($nboftargetok) {
mkdir($DESTI.'/standard');
if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; }
}
print "Remove target $FILENAMETGZ.tgz...\n";
unlink("$NEWDESTI/$FILENAMETGZ.tgz");
@ -1064,7 +1064,8 @@ if ($nboftargetok) {
$ret=`mv $BUILDROOT/*_all.deb "$NEWDESTI/"`;
$ret=`mv $BUILDROOT/*.dsc "$NEWDESTI/"`;
$ret=`mv $BUILDROOT/*.orig.tar.gz "$NEWDESTI/"`;
$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`;
#$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option
$ret=`mv $BUILDROOT/*.debian.tar.gz "$NEWDESTI/"`;
$ret=`mv $BUILDROOT/*.changes "$NEWDESTI/"`;
next;
}
@ -1146,7 +1147,8 @@ if ($nboftargetok) {
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}_all.deb"=>'Dolibarr installer for Debian-Ubuntu (DoliDeb)',
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}_amd64.changes"=>'none', # none means it won't be published on SF
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.dsc"=>'none', # none means it won't be published on SF
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.debian.tar.xz"=>'none', # none means it won't be published on SF
#"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.debian.tar.xz"=>'none', # none means it won't be published on SF
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.debian.tar.gz"=>'none', # none means it won't be published on SF
"$DESTI/package_debian-ubuntu/${FILENAMEDEBSHORT}.orig.tar.gz"=>'none', # none means it won't be published on SF
"$DESTI/package_windows/$FILENAMEEXEDOLIWAMP.exe"=>'Dolibarr installer for Windows (DoliWamp)',
"$DESTI/standard/$FILENAMETGZ.tgz"=>'Dolibarr ERP-CRM',

View File

@ -1162,19 +1162,24 @@ if (empty($action) || $action == 'view') {
//var_dump($tabpay[$key]);
print '<!-- Bank bank.rowid='.$key.' type='.$tabpay[$key]['type'].' ref='.$tabpay[$key]['ref'].'-->';
print '<tr class="oddeven">';
// Date
print "<td>".$date."</td>";
print "<td>".$ref."</td>";
// Ref
print "<td>".dol_escape_htmltag($ref)."</td>";
// Ledger account
print "<td>";
$accounttoshow = length_accountg($k);
if (empty($accounttoshow) || $accounttoshow == 'NotDefined') {
print '<span class="error">'.$langs->trans("BankAccountNotDefined").'</span>';
} else {
print $accounttoshow;
$accounttoshow = '<span class="error">'.$langs->trans("BankAccountNotDefined").'</span>';
}
print '<td class="maxwidth300" title="'.dol_escape_htmltag(dol_string_nohtmltag($accounttoshow)).'">';
print $accounttoshow;
print "</td>";
// Subledger account
print "<td>";
print '<td class="maxwidth300">';
/*$accounttoshow = length_accountg($k);
if (empty($accounttoshow) || $accounttoshow == 'NotDefined')
{
@ -1182,9 +1187,12 @@ if (empty($action) || $action == 'view') {
}
else print $accounttoshow;*/
print "</td>";
print "<td>";
print $reflabel;
// Label operation
print '<td>';
print $reflabel; // This is already html escaped content
print "</td>";
print '<td class="center">'.$val["type_payment"]."</td>";
print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
@ -1208,10 +1216,14 @@ if (empty($action) || $action == 'view') {
print '<!-- Thirdparty bank.rowid='.$key.' -->';
print '<tr class="oddeven">';
// Date
print "<td>".$date."</td>";
print "<td>".$ref."</td>";
// Ref
print "<td>".dol_escape_htmltag($ref)."</td>";
// Ledger account
print "<td>";
$account_ledger = $k;
// Try to force general ledger account depending on type
if ($tabtype[$key] == 'payment') {
@ -1240,9 +1252,9 @@ if (empty($action) || $action == 'view') {
if ($tabtype[$key] == 'unknown') {
// We will accept writing, but into a waiting account
if (empty($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) || $conf->global->ACCOUNTING_ACCOUNT_SUSPENSE == '-1') {
print '<span class="error small">'.$langs->trans('UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking').'</span>';
$accounttoshow = '<span class="error small">'.$langs->trans('UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking').'</span>';
} else {
print '<span class="warning small">'.$langs->trans('UnknownAccountForThirdparty', length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE)).'</span>'; // We will use a waiting account
$accounttoshow = '<span class="warning small">'.$langs->trans('UnknownAccountForThirdparty', length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE)).'</span>'; // We will use a waiting account
}
} else {
// We will refuse writing
@ -1265,15 +1277,15 @@ if (empty($action) || $action == 'view') {
if ($tabtype[$key] == 'member') {
$errorstring = 'MainAccountForSubscriptionPaymentNotDefined';
}
print '<span class="error small">'.$langs->trans($errorstring).'</span>';
$accounttoshow = '<span class="error small">'.$langs->trans($errorstring).'</span>';
}
} else {
print $accounttoshow;
}
print '<td class="maxwidth300" title="'.dol_escape_htmltag(dol_string_nohtmltag($accounttoshow)).'">';
print $accounttoshow;
print "</td>";
// Subledger account
print "<td>";
$accounttoshowsubledger = '';
if (in_array($tabtype[$key], array('payment', 'payment_supplier', 'payment_expensereport', 'payment_salary', 'payment_various'))) { // Type of payments that uses a subledger
$accounttoshowsubledger = length_accounta($k);
if ($accounttoshow != $accounttoshowsubledger) {
@ -1285,18 +1297,20 @@ if (empty($action) || $action == 'view') {
if (!empty($tabcompany[$key]['code_compta'])) {
if (in_array($tabtype[$key], array('payment_various', 'payment_salary'))) {
// For such case, if subledger is not defined, we won't use subledger accounts.
print '<span class="warning small">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored").'</span>';
$accounttoshowsubledger = '<span class="warning small">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored").'</span>';
} else {
print '<span class="warning small">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown", $tabcompany[$key]['code_compta']).'</span>';
$accounttoshowsubledger = '<span class="warning small">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown", $tabcompany[$key]['code_compta']).'</span>';
}
} else {
print '<span class="error small">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking").'</span>';
$accounttoshowsubledger = '<span class="error small">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking").'</span>';
}
} else {
print $accounttoshowsubledger;
}
} else {
$accounttoshowsubledger = '';
}
}
print '<td class="maxwidth300">';
print $accounttoshowsubledger;
print "</td>";
print "<td>".$reflabel."</td>";

View File

@ -843,7 +843,7 @@ if (!empty($arrayfields['d.statut']['checked'])) {
Adherent::STATUS_RESILIATED => $langs->trans("MemberStatusResiliatedShort"),
Adherent::STATUS_EXCLUDED =>$langs->trans("MemberStatusExcludedShort")
);
print $form->selectarray('search_status', $liststatus, $search_status, -3);
print $form->selectarray('search_status', $liststatus, $search_status, -3, 0, 0, '', 0, 0, 0, '', 'onrightofpage');
print '</td>';
}
if (!empty($arrayfields['d.import_key']['checked'])) {

View File

@ -94,6 +94,7 @@ $head = company_admin_prepare_head();
print dol_get_fiche_head($head, 'socialnetworks', '', -1, '');
print '<span class="opacitymedium">'.$langs->trans("CompanyFundationDesc", $langs->transnoentities("Save"))."</span><br>\n";
print '<span class="opacitymedium">'.$langs->trans("MoreNetworksAvailableWithModule")."</span><br>\n";
print "<br>\n";

View File

@ -507,7 +507,9 @@ class Documents extends DolibarrApi
}
$objectType = $modulepart;
if (! empty($object->id) && ! empty($object->table_element)) $objectType = $object->table_element;
if (! empty($object->id) && ! empty($object->table_element)) {
$objectType = $object->table_element;
}
$filearray = dol_dir_list($upload_dir, $type, $recursive, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ?SORT_DESC:SORT_ASC), 1);
if (empty($filearray)) {

View File

@ -2345,7 +2345,8 @@ if ($id > 0) {
if (isModEnabled("societe")) {
// Related company
print '<tr><td class="titlefield">'.$langs->trans("ActionOnCompany").'</td><td>'.($object->thirdparty->id ? $object->thirdparty->getNomUrl(1) : ('<span class="opacitymedium">'.$langs->trans("None").'</span>'));
print '<tr><td class="titlefield">'.$langs->trans("ActionOnCompany").'</td>';
print '<td>'.(is_object($object->thirdparty) && $object->thirdparty->id ? $object->thirdparty->getNomUrl(1) : ('<span class="opacitymedium">'.$langs->trans("None").'</span>'));
if (is_object($object->thirdparty) && $object->thirdparty->id > 0 && $object->type_code == 'AC_TEL') {
if ($object->thirdparty->fetch($object->thirdparty->id)) {
print "<br>".dol_print_phone($object->thirdparty->phone);

View File

@ -1432,7 +1432,7 @@ if ($resql) {
// Status
if (!empty($arrayfields['p.fk_statut']['checked'])) {
print '<td class="liste_titre maxwidthonsmartphone right">';
$formpropal->selectProposalStatus($search_status, 1, 0, 1, 'customer', 'search_statut');
$formpropal->selectProposalStatus($search_status, 1, 0, 1, 'customer', 'search_statut', 'search_status maxwidth125 onrightofpage');
print '</td>';
}
// Action column
@ -1486,22 +1486,22 @@ if ($resql) {
print_liste_field_titre($arrayfields['state.nom']['label'], $_SERVER["PHP_SELF"], "state.nom", "", $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['country.code_iso']['checked'])) {
print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, 'align="center"', $sortfield, $sortorder);
print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, 'class="center"', $sortfield, $sortorder);
}
if (!empty($arrayfields['typent.code']['checked'])) {
print_liste_field_titre($arrayfields['typent.code']['label'], $_SERVER["PHP_SELF"], "typent.code", "", $param, 'align="center"', $sortfield, $sortorder);
print_liste_field_titre($arrayfields['typent.code']['label'], $_SERVER["PHP_SELF"], "typent.code", "", $param, 'class="center"', $sortfield, $sortorder);
}
if (!empty($arrayfields['p.date']['checked'])) {
print_liste_field_titre($arrayfields['p.date']['label'], $_SERVER["PHP_SELF"], 'p.datep', '', $param, 'align="center"', $sortfield, $sortorder);
print_liste_field_titre($arrayfields['p.date']['label'], $_SERVER["PHP_SELF"], 'p.datep', '', $param, 'class="center"', $sortfield, $sortorder);
}
if (!empty($arrayfields['p.fin_validite']['checked'])) {
print_liste_field_titre($arrayfields['p.fin_validite']['label'], $_SERVER["PHP_SELF"], 'dfv', '', $param, 'align="center"', $sortfield, $sortorder);
print_liste_field_titre($arrayfields['p.fin_validite']['label'], $_SERVER["PHP_SELF"], 'dfv', '', $param, 'class="center"', $sortfield, $sortorder);
}
if (!empty($arrayfields['p.date_livraison']['checked'])) {
print_liste_field_titre($arrayfields['p.date_livraison']['label'], $_SERVER["PHP_SELF"], 'p.date_livraison', '', $param, 'align="center"', $sortfield, $sortorder);
print_liste_field_titre($arrayfields['p.date_livraison']['label'], $_SERVER["PHP_SELF"], 'p.date_livraison', '', $param, 'class="center"', $sortfield, $sortorder);
}
if (!empty($arrayfields['p.date_signature']['checked'])) {
print_liste_field_titre($arrayfields['p.date_signature']['label'], $_SERVER["PHP_SELF"], 'p.date_signature', '', $param, 'align="center"', $sortfield, $sortorder);
print_liste_field_titre($arrayfields['p.date_signature']['label'], $_SERVER["PHP_SELF"], 'p.date_signature', '', $param, 'class="center"', $sortfield, $sortorder);
}
if (!empty($arrayfields['ava.rowid']['checked'])) {
print_liste_field_titre($arrayfields['ava.rowid']['label'], $_SERVER["PHP_SELF"], 'availability', '', $param, '', $sortfield, $sortorder);
@ -1555,7 +1555,7 @@ if ($resql) {
print_liste_field_titre($arrayfields['p.multicurrency_total_invoiced']['label'], $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder);
}
if (!empty($arrayfields['u.login']['checked'])) {
print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER["PHP_SELF"], 'u.login', '', $param, 'align="center"', $sortfield, $sortorder);
print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER["PHP_SELF"], 'u.login', '', $param, 'class="center"', $sortfield, $sortorder);
}
if (!empty($arrayfields['sale_representative']['checked'])) {
print_liste_field_titre($arrayfields['sale_representative']['label'], $_SERVER["PHP_SELF"], "", "", "$param", '', $sortfield, $sortorder);

View File

@ -1726,7 +1726,7 @@ if ($resql) {
-2=>$langs->trans("StatusOrderValidatedShort").'+'.$langs->trans("StatusOrderSentShort"),
Commande::STATUS_CANCELED=>$langs->trans("StatusOrderCanceledShort")
);
print $form->selectarray('search_status', $liststatus, $search_status, -5, 0, 0, '', 0, 0, 0, '', 'maxwidth125', 1);
print $form->selectarray('search_status', $liststatus, $search_status, -5, 0, 0, '', 0, 0, 0, '', 'maxwidth125 onrightofpage', 1);
print '</td>';
}
// Action column

View File

@ -504,6 +504,7 @@ if ($resql) {
print '</tr>';
print '<tr class="liste_titre">';
if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER_IN_LIST)) {

View File

@ -2505,12 +2505,12 @@ if (empty($reshook)) {
// Check price is not lower than minimum (check is done only for standard or replacement invoices)
if ($usermustrespectpricemin && ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT)) {
if ($pu_ht && $price_min && ((price2num($pu_ht) * (1 - $remise_percent / 100)) < price2num($price_min))) {
if ($pu_ht && $price_min && (((float) price2num($pu_ht) * (1 - (float) $remise_percent / 100)) < (float) price2num($price_min))) {
$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
setEventMessages($mesg, null, 'errors');
$error++;
$action = 'editline';
} elseif ($pu_ttc && $price_min_ttc && ((price2num($pu_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc))) {
} elseif ($pu_ttc && $price_min_ttc && ((price2num($pu_ttc) * (1 - (float) $remise_percent / 100)) < price2num($price_min_ttc))) {
$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
setEventMessages($mesg, null, 'errors');
$error++;

View File

@ -620,7 +620,7 @@ if ($resql) {
1=>$langs->trans("Active"),
-1=>$langs->trans("Disabled"),
);
print $form->selectarray('search_status', $liststatus, $search_status, -2, 0, 0, '', 0, 0, 0, '', 'width100');
print $form->selectarray('search_status', $liststatus, $search_status, -2, 0, 0, '', 0, 0, 0, '', 'width100 onrightofpage');
print '</td>';
}
// Action column

View File

@ -1585,7 +1585,7 @@ if ($resql) {
if (!empty($arrayfields['f.fk_statut']['checked'])) {
print '<td class="liste_titre maxwidthonsmartphone right">';
$liststatus = array('0'=>$langs->trans("BillShortStatusDraft"), '0,1'=>$langs->trans("BillShortStatusDraft").'+'.$langs->trans("BillShortStatusNotPaid"), '1'=>$langs->trans("BillShortStatusNotPaid"), '1,2'=>$langs->trans("BillShortStatusNotPaid").'+'.$langs->trans("BillShortStatusPaid"), '2'=>$langs->trans("BillShortStatusPaid"), '3'=>$langs->trans("BillShortStatusCanceled"));
print $form->selectarray('search_status', $liststatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', '', 1);
print $form->selectarray('search_status', $liststatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', 'width100 onrightofpage', 1);
print '</td>';
}
// Action column

View File

@ -378,14 +378,24 @@ foreach ($data as $val) {
print '</tr>';
}
if ($mode == 'supplier') {
$greennb = (empty($val['nb_diff']) || $val['nb_diff'] <= 0);
$greentotal = (empty($val['total_diff']) || $val['total_diff'] <= 0);
$greenavg = (empty($val['avg_diff']) || $val['avg_diff'] <= 0);
} else {
$greennb = (empty($val['nb_diff']) || $val['nb_diff'] >= 0);
$greentotal = (empty($val['total_diff']) || $val['total_diff'] >= 0);
$greenavg = (empty($val['avg_diff']) || $val['avg_diff'] >= 0);
}
print '<tr class="oddeven" height="24">';
print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&amp;mode='.$mode.($socid > 0 ? '&socid='.$socid : '').($userid > 0 ? '&userid='.$userid : '').'">'.$year.'</a></td>';
print '<td class="right">'.$val['nb'].'</td>';
print '<td class="right opacitylow" style="'.((empty($val['nb_diff']) || $val['nb_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.(!empty($val['nb_diff']) && $val['nb_diff'] < 0 ? '' : '+').round(!empty($val['nb_diff']) ? $val['nb_diff'] : 0).'%</td>';
print '<td class="right opacitylow" style="'.($greennb ? 'color: green;' : 'color: red;').'">'.(!empty($val['nb_diff']) && $val['nb_diff'] < 0 ? '' : '+').round(!empty($val['nb_diff']) ? $val['nb_diff'] : 0).'%</td>';
print '<td class="right"><span class="amount">'.price(price2num($val['total'], 'MT'), 1).'</span></td>';
print '<td class="right opacitylow" style="'.((empty($val['total_diff']) || $val['total_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.( !empty($val['total_diff']) && $val['total_diff'] < 0 ? '' : '+').round(!empty($val['total_diff']) ? $val['total_diff'] : 0).'%</td>';
print '<td class="right opacitylow" style="'.($greentotal ? 'color: green;' : 'color: red;').'">'.( !empty($val['total_diff']) && $val['total_diff'] < 0 ? '' : '+').round(!empty($val['total_diff']) ? $val['total_diff'] : 0).'%</td>';
print '<td class="right"><span class="amount">'.price(price2num($val['avg'], 'MT'), 1).'</span></td>';
print '<td class="right opacitylow" style="'.((empty($val['avg_diff']) || $val['avg_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.(!empty($val['avg_diff']) && $val['avg_diff'] < 0 ? '' : '+').round(!empty($val['avg_diff']) ? $val['avg_diff'] : 0).'%</td>';
print '<td class="right opacitylow" style="'.($greenavg ? 'color: green;' : 'color: red;').'">'.(!empty($val['avg_diff']) && $val['avg_diff'] < 0 ? '' : '+').round(!empty($val['avg_diff']) ? $val['avg_diff'] : 0).'%</td>';
print '</tr>';
$oldyear = $year;
}

View File

@ -503,7 +503,7 @@ if (!empty($arrayfields['cs.amount']['checked'])) {
if (!empty($arrayfields['cs.paye']['checked'])) {
print '<td class="liste_titre maxwidthonsmartphone right">';
$liststatus = array('0'=>$langs->trans("Unpaid"), '1'=>$langs->trans("Paid"));
print $form->selectarray('search_status', $liststatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100', 1);
print $form->selectarray('search_status', $liststatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100 onrightofpage', 1);
print '</td>';
}

View File

@ -400,7 +400,7 @@ if (!empty($arrayfields['t.amount']['checked'])) {
if (!empty($arrayfields['t.status']['checked'])) {
print '<td class="liste_titre maxwidthonsmartphone right">';
$liststatus = array('0' => $langs->trans("Unpaid"), '1' => $langs->trans("Paid"));
print $form->selectarray('search_status', $liststatus, $search_status, 1);
print $form->selectarray('search_status', $liststatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', 'onrightofpage');
print '</td>';
}

View File

@ -1761,6 +1761,7 @@ abstract class CommonInvoice extends CommonObject
}
// Header
$s = '';
$s .= "SPC\n";
$s .= "0200\n";
$s .= "1\n";

View File

@ -8066,8 +8066,10 @@ abstract class CommonObject
$out .= '<!-- commonobject:showOptionals --> ';
$out .= "\n";
$nbofextrafieldsshown = 0;
$extrafields_collapse_num = '';
$e = 0;
$e = 0; // var to manage the modulo (odd/even)
foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $label) {
// Show only the key field in params
if (is_array($params) && array_key_exists('onlykey', $params) && $key != $params['onlykey']) {
@ -8151,6 +8153,8 @@ abstract class CommonObject
break;
}
$nbofextrafieldsshown++;
// Output value of the current field
if ($extrafields->attributes[$this->table_element]['type'][$key] == 'separate') {
$extrafields_collapse_num = '';
@ -8247,7 +8251,7 @@ abstract class CommonObject
$out .= '<td class="titlefieldcreate wordbreak';
} elseif ($display_type == 'line') {
$out .= '<div '.($html_id ? 'id="'.$html_id.'" ' : '').$csstyle.' class="fieldline_options_'.$key.' '.$class.$this->element.'_extras_'.$key.' trextrafields_collapse'.$extrafields_collapse_num.(!empty($this->id)?'_'.$this->id:'').'" '.$domData.' >';
$out .= '<div style="display: inline-block; padding-right:4px" class="titlefieldcreate wordbreak';
$out .= '<div style="display: inline-block; padding-right:4px" class="wordbreak';
}
//$out .= "titlefield";
//if (GETPOST('action', 'restricthtml') == 'create') $out.='create';
@ -8305,6 +8309,7 @@ abstract class CommonObject
} else {
$out .= ($display_type=='card' ? '</tr>' : '</div>');
}
$e++;
}
}
@ -8315,6 +8320,10 @@ abstract class CommonObject
}
$out .= '<!-- commonobject:showOptionals end --> '."\n";
if (empty($nbofextrafieldsshown)) {
$out = '';
}
}
}
@ -9068,7 +9077,7 @@ abstract class CommonObject
/**
* Function to concat keys of fields
*
* @param string $alias String of alias of table for fields. For example 't'.
* @param string $alias String of alias of table for fields. For example 't'. It is recommended to use '' and set alias into fields defintion.
* @return string list of alias fields
*/
public function getFieldList($alias = '')

View File

@ -10,6 +10,7 @@
* Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2017 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2018-2022 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2022 Antonin MARCHAL <antonin@letempledujeu.fr>
*
* 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
@ -1758,7 +1759,12 @@ class ExtraFields
dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING);
}
} elseif ($type == 'radio') {
$value = $langs->trans($param['options'][$value]);
if (!isset($param['options'][$value])) {
$langs->load('errors');
$value = $langs->trans('ErrorNoValueForRadioType');
} else {
$value = $langs->trans($param['options'][$value]);
}
} elseif ($type == 'checkbox') {
$value_arr = explode(',', $value);
$value = '';

View File

@ -6279,8 +6279,10 @@ class Form
// Definition du taux a pre-selectionner (si defaulttx non force et donc vaut -1 ou '')
if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) {
$tmpthirdparty = new Societe($this->db);
$defaulttx = get_default_tva($societe_vendeuse, (is_object($societe_acheteuse) ? $societe_acheteuse : $tmpthirdparty), $idprod);
$defaultnpr = get_default_npr($societe_vendeuse, (is_object($societe_acheteuse) ? $societe_acheteuse : $tmpthirdparty), $idprod);
if (preg_match('/\((.*)\)/', $defaulttx, $reg)) {
$defaultcode = $reg[1];
$defaulttx = preg_replace('/\s*\(.*\)/', '', $defaulttx);
@ -6290,13 +6292,22 @@ class Form
}
}
// Si taux par defaut n'a pu etre determine, on prend dernier de la liste.
// Comme ils sont tries par ordre croissant, dernier = plus eleve = taux courant
// If we fails to find a default vat rate, we take the last one in list
// Because they are sorted in ascending order, the last one will be the higher one (we suppose the higher one is the current rate)
if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) {
if (empty($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS)) {
// We take the last one found in list
$defaulttx = $this->cache_vatrates[$num - 1]['txtva'];
} else {
$defaulttx = ($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS == 'none' ? '' : $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS);
// We will use the rate defined into MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS
$defaulttx = '';
if ($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS != 'none') {
$defaulttx = $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS;
}
if (preg_match('/\((.*)\)/', $defaulttx, $reg)) {
$defaultcode = $reg[1];
$defaulttx = preg_replace('/\s*\(.*\)/', '', $defaulttx);
}
}
}
@ -6307,7 +6318,7 @@ class Form
// Override/enable VAT for expense report regardless of global setting - needed if expense report used for business expenses instead
// of using supplier invoices (this is a very bad idea !)
if (empty($conf->global->EXPENSEREPORT_OVERRIDE_VAT)) {
$title = ' title="'.$langs->trans('VATIsNotUsed').'"';
$title = ' title="'.dol_escape_htmltag($langs->trans('VATIsNotUsed')).'"';
$disabled = true;
}
}
@ -6346,12 +6357,16 @@ class Form
}
}
$return .= '>';
//if (!empty($conf->global->MAIN_VAT_SHOW_POSITIVE_RATES))
// Show label of VAT
if ($mysoc->country_code == 'IN' || !empty($conf->global->MAIN_VAT_LABEL_IS_POSITIVE_RATES)) {
// Label with all localtax and code. For example: x.y / a.b / c.d (CODE)'
$return .= $rate['labelpositiverates'];
} else {
// Simple label
$return .= vatrate($rate['label']);
}
//$return.=($rate['code']?' '.$rate['code']:'');
$return .= (empty($rate['code']) && $rate['nprtva']) ? ' *' : ''; // We show the * (old behaviour only if new vat code is not used)
@ -6360,7 +6375,7 @@ class Form
if (!$options_only) {
$return .= '</select>';
//$return .= ajax_combobox($htmlname); // This break for the moment dynamic autoselection of a value when selecting a product in object lines
//$return .= ajax_combobox($htmlname); // This break for the moment the dynamic autoselection of a value when selecting a product in object lines
}
} else {
$return .= $this->error;
@ -8059,7 +8074,7 @@ class Form
if (empty($nohtmlescape)) {
$selectOptionValue = dol_escape_htmltag($maxlen ?dol_trunc($value, $maxlen) : $value);
} else {
$selectOptionValue = $maxlen ?dol_trunc($value, $maxlen) : $value;
$selectOptionValue = $maxlen ? dol_trunc($value, $maxlen) : $value;
}
if ($value == '' || $value == '-') {
$selectOptionValue = '&nbsp;';
@ -9059,7 +9074,7 @@ class Form
$resultyesno .= '</select>'."\n";
if ($addjscombo) {
$resultyesno .= ajax_combobox($htmlname);
$resultyesno .= ajax_combobox($htmlname, array(), 0, 0, 'resolve', ($useempty < 0 ? (string) $useempty : '-1'), $morecss);
}
return $resultyesno;

View File

@ -218,25 +218,25 @@ class FormMargin
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
} elseif (empty($reshook)) {
if (!empty($conf->global->MARGIN_ADD_SHOWHIDE_BUTTON)) { // TODO Warning this feature rely on an external js file that may be removed. Using native js function document.cookie should be better
print $langs->trans('ShowMarginInfos') . ' : ';
if (!empty($conf->global->MARGIN_ADD_SHOWHIDE_BUTTON)) {
print $langs->trans('ShowMarginInfos') . ' ';
$hidemargininfos = preg_replace('/[^a-zA-Z0-9_\-]/', '', $_COOKIE['DOLUSER_MARGININFO_HIDE_SHOW']); // Clean cookie
print '<span id="showMarginInfos" class="linkobject ' . (!empty($hidemargininfos) ? '' : 'hideobject') . '">' . img_picto($langs->trans("Disabled"), 'switch_off') . '</span>';
print '<span id="hideMarginInfos" class="linkobject ' . (!empty($hidemargininfos) ? 'hideobject' : '') . '">' . img_picto($langs->trans("Enabled"), 'switch_on') . '</span>';
print '<span id="showMarginInfos" class="linkobject valignmiddle ' . (!empty($hidemargininfos) ? '' : 'hideobject') . '">' . img_picto($langs->trans("Disabled"), 'switch_off') . '</span>';
print '<span id="hideMarginInfos" class="linkobject valignmiddle ' . (!empty($hidemargininfos) ? 'hideobject' : '') . '">' . img_picto($langs->trans("Enabled"), 'switch_on') . '</span>';
print '<script>$(document).ready(function() {
$("span#showMarginInfos").click(function() { $.getScript( "' . dol_buildpath('/includes/jquery/plugins/jquerytreeview/lib/jquery.cookie.js', 1) . '", function( data, textStatus, jqxhr ) { $.cookie("DOLUSER_MARGININFO_HIDE_SHOW", 0); $(".margininfos").show(); $("span#showMarginInfos").addClass("hideobject"); $("span#hideMarginInfos").removeClass("hideobject");})});
$("span#hideMarginInfos").click(function() { $.getScript( "' . dol_buildpath('/includes/jquery/plugins/jquerytreeview/lib/jquery.cookie.js', 1) . '", function( data, textStatus, jqxhr ) { $.cookie("DOLUSER_MARGININFO_HIDE_SHOW", 1); $(".margininfos").hide(); $("span#hideMarginInfos").addClass("hideobject"); $("span#showMarginInfos").removeClass("hideobject");})});
$("span#showMarginInfos").click(function() { console.log("click on showMargininfos"); date = new Date(); date.setTime(date.getTime()+(30*86400000)); document.cookie = "DOLUSER_MARGININFO_HIDE_SHOW=0; expires=" + date.toGMTString() + "; path=/ "; $(".margintable").show(); $("span#showMarginInfos").addClass("hideobject"); $("span#hideMarginInfos").removeClass("hideobject"); });
$("span#hideMarginInfos").click(function() { console.log("click on hideMarginInfos"); date = new Date(); date.setTime(date.getTime()+(30*86400000)); document.cookie = "DOLUSER_MARGININFO_HIDE_SHOW=1; expires=" + date.toGMTString() + "; path=/ "; $(".margintable").hide(); $("span#hideMarginInfos").addClass("hideobject"); $("span#showMarginInfos").removeClass("hideobject"); });
});</script>';
if (!empty($hidemargininfos)) {
print '<script>$(document).ready(function() {$(".margininfos").hide();});</script>';
print '<script>$(document).ready(function() { console.log("hide the margin info"); $("#margintable").hide(); });</script>';
}
}
print '<div class="div-table-responsive-no-min">';
print '<!-- Margin table -->' . "\n";
print '<table class="noborder margintable centpercent">';
print '<table class="noborder margintable centpercent" id="margintable">';
print '<tr class="liste_titre">';
print '<td class="liste_titre">' . $langs->trans('Margins') . '</td>';
print '<td class="liste_titre right">' . $langs->trans('SellingPrice') . '</td>';

View File

@ -134,6 +134,6 @@ class FormPropal
}
print '</select>';
print ajax_combobox($htmlname);
print ajax_combobox($htmlname, array(), 0, 0, 'resolve', ($showempty < 0 ? (string) $showempty : '-1'), $morecss);
}
}

View File

@ -107,6 +107,25 @@ abstract class DoliDB implements Database
return '';
}
/**
* Format a SQL REGEXP
*
* @param string $subject string tested
* @param string $pattern SQL pattern to match
* @param string $sqlstring whether or not the string being tested is an SQL expression
* @return string SQL string
*/
public function regexpsql($subject, $pattern, $sqlstring = false)
{
if ($sqlstring) {
return "(". $subject ." REGEXP '" . $pattern . "')";
}
return "('". $subject ."' REGEXP '" . $pattern . "')";
}
/**
* Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date field.
* Function to use to build INSERT, UPDATE or WHERE predica

View File

@ -757,6 +757,24 @@ class DoliDBPgsql extends DoliDB
return '(CASE WHEN '.$test.' THEN '.$resok.' ELSE '.$resko.' END)';
}
/**
* Format a SQL REGEXP
*
* @param string $subject string tested
* @param string $pattern SQL pattern to match
* @param string $sqlstring whether or not the string being tested is an SQL expression
* @return string SQL string
*/
public function regexpsql($subject, $pattern, $sqlstring = false)
{
if ($sqlstring) {
return "(". $subject ." ~ '" . $pattern . "')";
}
return "('". $subject ."' ~ '" . $pattern . "')";
}
/**
* Renvoie le code erreur generique de l'operation precedente.
*
@ -1220,7 +1238,7 @@ class DoliDBPgsql extends DoliDB
// phpcs:enable
$sql = "ALTER TABLE ".$table;
$sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type'];
if (in_array($field_desc['type'], array('double', 'tinyint', 'int', 'varchar')) && $field_desc['value']) {
if (in_array($field_desc['type'], array('double', 'varchar')) && $field_desc['value']) {
$sql .= "(".$field_desc['value'].")";
}

View File

@ -165,7 +165,9 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
price_unit_ht_locale: item.price_unit_ht_locale,
description : item.description,
ref_customer: item.ref_customer,
tva_tx: item.tva_tx }
tva_tx: item.tva_tx,
default_vat_code: item.default_vat_code
}
}));
} else {
console.error("Error: Ajax url '.$url.($urloption ? '?'.$urloption : '').' has returned an empty page. Should be an empty json array.");
@ -178,7 +180,8 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
console.log("We will trigger change on input '.$htmlname.' because of the select definition of autocomplete code for input#search_'.$htmlname.'");
console.log("Selected id = "+ui.item.id+" - If this value is null, it means you select a record with key that is null so selection is not effective");
console.log("Propagate before some properties retrieved by ajax into data-xxx properties");
console.log("Propagate before some properties retrieved by ajax into data-xxx properties of #'.$htmlnamejquery.' component");
//console.log(ui.item);
// For supplier price and customer when price by quantity is off
$("#'.$htmlnamejquery.'").attr("data-up", ui.item.price_ht);
@ -189,6 +192,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
$("#'.$htmlnamejquery.'").attr("data-description", ui.item.description);
$("#'.$htmlnamejquery.'").attr("data-ref-customer", ui.item.ref_customer);
$("#'.$htmlnamejquery.'").attr("data-tvatx", ui.item.tva_tx);
$("#'.$htmlnamejquery.'").attr("data-default-vat-code", ui.item.default_vat_code);
';
if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) {
$script .= '

View File

@ -1183,7 +1183,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '', $showuserl
if (!empty($arrayfields['t.'.$key]['checked']) || !empty($arrayfields['sc.'.$key]['checked'])) {
print '<td class="liste_titre'.($align ? ' '.$align : '').'">';
if (in_array($key, array('statut'))) {
print $form->selectarray('search_status', array('-1'=>'', '0'=>$contactstatic->LibStatut(0, 1), '1'=>$contactstatic->LibStatut(1, 1)), $search_status);
print $form->selectarray('search_status', array('-1'=>'', '0'=>$contactstatic->LibStatut(0, 1), '1'=>$contactstatic->LibStatut(1, 1)), $search_status, 0, 0, 0, '', 0, 0, 0, '', 'onrightofpage');
} elseif (in_array($key, array('role'))) {
print $formcompany->showRoles("search_roles", $contactstatic, 'edit', $search_roles, 'minwidth200 maxwidth300');
} else {

View File

@ -4070,7 +4070,8 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
'shapes', 'square', 'stop-circle', 'supplier', 'supplier_proposal', 'supplier_order', 'supplier_invoice',
'timespent', 'title_setup', 'title_accountancy', 'title_bank', 'title_hrm', 'title_agenda',
'uncheck', 'url', 'user-cog', 'user-injured', 'user-md', 'vat', 'website', 'workstation', 'webhook', 'world', 'private',
'conferenceorbooth', 'eventorganization'
'conferenceorbooth', 'eventorganization',
'stamp', 'signature'
))) {
$fakey = $pictowithouttext;
$facolor = '';
@ -6264,10 +6265,10 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi
* Return vat rate of a product in a particular country, or default country vat if product is unknown.
* Function called by get_default_tva().
*
* @param int $idprod Id of product or 0 if not a predefined product
* @param Societe $thirdpartytouse Thirdparty with a ->country_code defined (FR, US, IT, ...)
* @param int $idprodfournprice Id product_fournisseur_price (for "supplier" proposal/order/invoice)
* @return float|string Vat rate to use with format 5.0 or '5.0 (XXX)'
* @param int $idprod Id of product or 0 if not a predefined product
* @param Societe $thirdpartytouse Thirdparty with a ->country_code defined (FR, US, IT, ...)
* @param int $idprodfournprice Id product_fournisseur_price (for "supplier" proposal/order/invoice)
* @return float|string Vat rate to use with format 5.0 or '5.0 (XXX)'
* @see get_product_localtax_for_country()
*/
function get_product_vat_for_country($idprod, $thirdpartytouse, $idprodfournprice = 0)
@ -6282,7 +6283,7 @@ function get_product_vat_for_country($idprod, $thirdpartytouse, $idprodfournpric
if ($idprod > 0) {
// Load product
$product = new Product($db);
$result = $product->fetch($idprod);
$product->fetch($idprod);
if ($mysoc->country_code == $thirdpartytouse->country_code) { // If country to consider is ours
if ($idprodfournprice > 0) { // We want vat for product for a "supplier" object
@ -6306,11 +6307,11 @@ function get_product_vat_for_country($idprod, $thirdpartytouse, $idprodfournpric
if (!$found) {
if (empty($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS)) {
// If vat of product for the country not found or not defined, we return the first higher vat of country.
// If vat of product for the country not found or not defined, we return the first rate found (sorting on use_default, then on higher vat of country).
$sql = "SELECT t.taux as vat_rate, t.code as default_vat_code";
$sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c";
$sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code='".$db->escape($thirdpartytouse->country_code)."'";
$sql .= " ORDER BY t.taux DESC, t.code ASC, t.recuperableonly ASC";
$sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code = '".$db->escape($thirdpartytouse->country_code)."'";
$sql .= " ORDER BY t.use_default DESC, t.taux DESC, t.code ASC, t.recuperableonly ASC";
$sql .= $db->plimit(1);
$resql = $db->query($sql);
@ -6327,7 +6328,17 @@ function get_product_vat_for_country($idprod, $thirdpartytouse, $idprodfournpric
dol_print_error($db);
}
} else {
$ret = $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS; // Forced value if autodetect fails
// Forced value if autodetect fails. MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS can be '1.23' or '1.23 (CODE)'
$defaulttx = '';
if ($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS != 'none') {
$defaulttx = $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS;
}
/*if (preg_match('/\((.*)\)/', $defaulttx, $reg)) {
$defaultcode = $reg[1];
$defaulttx = preg_replace('/\s*\(.*\)/', '', $defaulttx);
}*/
$ret = $defaulttx;
}
}
@ -6898,7 +6909,6 @@ function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1,
$stringtoclean = preg_replace('/&colon;/i', ':', $stringtoclean);
$stringtoclean = preg_replace('/&#58;|&#0+58|&#x3A/i', '', $stringtoclean); // refused string ':' encoded (no reason to have a : encoded like this) to disable 'javascript:...'
$stringtoclean = preg_replace('/javascript\s*:/i', '', $stringtoclean);
$temp = strip_tags($stringtoclean, $allowed_tags_string); // Warning: This remove also undesired </> changing string obfuscated with </> that pass injection detection into harmfull string
@ -6912,7 +6922,7 @@ function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1,
// Remove 'javascript:' that we should not find into a text with
// Warning: This is not reliable to fight against obfuscated javascript, there is a lot of other solution to include js into a common html tag (only filtered by a GETPOST(.., powerfullfilter)).
if ($cleanalsojavascript) {
$temp = preg_replace('/javascript\s*:/i', '', $temp);
$temp = preg_replace('/j\s*a\s*v\s*a\s*s\s*c\s*r\s*i\s*p\s*t\s*:/i', '', $temp);
}
$temp = str_replace('__!DOCTYPE_HTML__', '<!DOCTYPE html>', $temp); // Restore the DOCTYPE
@ -7138,6 +7148,9 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = '
}
}
// Clean some html entities that are useless so text is cleaner
$out = preg_replace('/&(tab|newline);/i', ' ', $out);
// Ckeditor use the numeric entitic for apostrophe so we force it to text entity (all other special chars are
// encoded using text entities) so we can then exclude all numeric entities.
$out = preg_replace('/&#39;/i', '&apos;', $out);
@ -7145,24 +7158,24 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = '
// We replace chars from a/A to z/Z encoded with numeric HTML entities with the real char so we won't loose the chars at the next step (preg_replace).
// No need to use a loop here, this step is not to sanitize (this is done at next step, this is to try to save chars, even if they are
// using a non coventionnel way to be encoded, to not have them sanitized just after)
//$out = preg_replace_callback('/&#(x?[0-9][0-9a-f]+;?)/i', 'realCharForNumericEntities', $out);
$out = preg_replace_callback('/&#(x?[0-9][0-9a-f]+;?)/i', function ($m) {
return realCharForNumericEntities($m); }, $out);
$out = preg_replace_callback('/&#(x?[0-9][0-9a-f]+;?)/i', function ($m) {
return realCharForNumericEntities($m); }, $out);
// Now we remove all remaining HTML entities starting with a number. We don't want such entities.
$out = preg_replace('/&#x?[0-9]+/i', '', $out); // For example if we have j&#x61vascript with an entities without the ; to hide the 'a' of 'javascript'.
// Now we remove all remaining HTML entities starting with a number. We don't want such entities.
$out = preg_replace('/&#x?[0-9]+/i', '', $out); // For example if we have j&#x61vascript with an entities without the ; to hide the 'a' of 'javascript'.
$out = dol_string_onlythesehtmltags($out, 0, 1, 1);
// Keep only some html tags and remove also some 'javascript:' strings
$out = dol_string_onlythesehtmltags($out, 0, 1, 1);
// We should also exclude non expected HTML attributes and clean content of some attributes.
// We should also exclude non expected HTML attributes and clean content of some attributes (keep only alt=, title=...).
if (!empty($conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES)) {
// Warning, the function may add a LF so we are forced to trim to compare with old $out without having always a difference and an infinit loop.
$out = dol_string_onlythesehtmlattributes($out);
}
// Restore entity &apos; into &#39; (restricthtml is for html content so we can use html entity)
$out = preg_replace('/&apos;/i', "&#39;", $out);
// Restore entity &apos; into &#39; (restricthtml is for html content so we can use html entity)
$out = preg_replace('/&apos;/i', "&#39;", $out);
} while ($oldstringtoclean != $out);
// Check the limit of external links in a Rich text content. We count '<img' and 'url('
@ -8011,7 +8024,9 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null,
if (empty($exclude) || !in_array('date', $exclude)) {
include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
$tmp = dol_getdate(dol_now(), true);
$now = dol_now();
$tmp = dol_getdate($now, true);
$tmp2 = dol_get_prev_day($tmp['mday'], $tmp['mon'], $tmp['year']);
$tmp3 = dol_get_prev_month($tmp['mon'], $tmp['year']);
$tmp4 = dol_get_next_day($tmp['mday'], $tmp['mon'], $tmp['year']);
@ -8020,6 +8035,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null,
$daytext = $outputlangs->trans('Day'.$tmp['wday']);
$substitutionarray = array_merge($substitutionarray, array(
'__NOW_TMS__' => (int) $now,
'__NOW_TMS_YMD__' => dol_print_date($now, 'day', 0, $outputlangs),
'__DAY__' => (string) $tmp['mday'],
'__DAY_TEXT__' => $daytext, // Monday
'__DAY_TEXT_SHORT__' => dol_trunc($daytext, 3, 'right', 'UTF-8', 1), // Mon

View File

@ -1282,6 +1282,12 @@ function get_next_value($db, $mask, $table, $field, $where = '', $objsoc = '', $
$sql .= " FROM ".MAIN_DB_PREFIX.$table;
$sql .= " WHERE ".$field." LIKE '".$db->escape($maskLike)."'";
$sql .= " AND ".$field." NOT LIKE '(PROV%)'";
// To ensure that all variables within the MAX() brackets are integers
if (getDolGlobalInt('MAIN_NUMBERING_FILTER_ON_INT_ONLY')) {
$sql .= " AND ". $db->regexpsql($sqlstring, '^[0-9]+$', true);
}
if ($bentityon) { // only if entity enable
$sql .= " AND entity IN (".getEntity($sharetable).")";
} elseif (!empty($forceentity)) {

View File

@ -209,6 +209,19 @@ function project_prepare_head(Project $project, $moreparam = '')
$h++;
}
if (isModEnabled('ticket') && $user->hasRight('ticket', 'read')) {
require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php';
$Tickettatic = new Ticket($db);
$nbTicket = count($Tickettatic->getAllItemsLinkedByObjectID($project->id, '*', 'fk_project', 'ticket'));
$head[$h][0] = DOL_URL_ROOT.'/ticket/list.php?projectid='.((int) $project->id);
$head[$h][1] = $langs->trans("Ticket");
if ($nbTicket > 0) {
$head[$h][1] .= '<span class="badge marginleftonlyshort">'.($nbTicket).'</span>';
}
$head[$h][2] = 'ticket';
$h++;
}
if (isModEnabled('eventorganization') && !empty($project->usage_organize_event)) {
$langs->load('eventorganization');
$head[$h][0] = DOL_URL_ROOT . '/eventorganization/conferenceorbooth_list.php?projectid=' . $project->id;

View File

@ -318,27 +318,32 @@ function dolGetLdapPasswordHash($password, $type = 'md5')
* If GETPOST('action','aZ09') defined, we also check write and delete permission.
* This method check permission on module then call checkUserAccessToObject() for permission on object (according to entity and socid of user).
*
* @param User $user User to check
* @param string $features Features to check (it must be module $object->element. Can be a 'or' check with 'levela|levelb'.
* Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...)
* This is used to check permission $user->rights->features->...
* @param int $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional).
* @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany module. Param not used if objectid is null (optional).
* @param string $feature2 Feature to check, second level of permission (optional). Can be a 'or' check with 'sublevela|sublevelb'.
* This is used to check permission $user->rights->features->feature2...
* @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional)
* @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional)
* @param int $isdraft 1=The object with id=$objectid is a draft
* @param int $mode Mode (0=default, 1=return without dieing)
* @return int If mode = 0 (default): Always 1, die process if not allowed. If mode = 1: Return 0 if access not allowed.
* @param User $user User to check
* @param string $features Features to check (it must be module $object->element. Can be a 'or' check with 'levela|levelb'.
* Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...)
* This is used to check permission $user->rights->features->...
* @param int|string|object $object Object or Object ID or list of Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional).
* @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany module. Param not used if objectid is null (optional).
* @param string $feature2 Feature to check, second level of permission (optional). Can be a 'or' check with 'sublevela|sublevelb'.
* This is used to check permission $user->rights->features->feature2...
* @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional). Can use '' if NA.
* @param string $dbt_select Field name for select if not "rowid". Not used if objectid is null (optional)
* @param int $isdraft 1=The object with id=$objectid is a draft
* @param int $mode Mode (0=default, 1=return without dieing)
* @return int If mode = 0 (default): Always 1, die process if not allowed. If mode = 1: Return 0 if access not allowed.
* @see dol_check_secure_access_document(), checkUserAccessToObject()
*/
function restrictedArea(User $user, $features, $objectid = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0)
function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0)
{
global $db, $conf;
global $hookmanager;
$objectid = ((int) $objectid); // For the case value is coming from a non sanitized user input
if (is_object($object)) {
$objectid = $object->id;
} else {
$objectid = $object; // $objectid can be X or 'X,Y,Z'
}
$objectid = preg_replace('/[^0-9\.\,]/', '', $objectid); // For the case value is coming from a non sanitized user input
//dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
//print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid;
@ -391,11 +396,6 @@ function restrictedArea(User $user, $features, $objectid = 0, $tableandshare = '
return 1;
}
// To avoid access forbidden with numeric ref
if ($dbt_select != 'rowid' && $dbt_select != 'id') {
$objectid = "'".$objectid."'";
}
// Features/modules to check
$featuresarray = array($features);
if (preg_match('/&/', $features)) {
@ -426,7 +426,7 @@ function restrictedArea(User $user, $features, $objectid = 0, $tableandshare = '
}
if ($feature == 'societe') {
if (!$user->hasRight('societe', 'lire') && empty($user->rights->fournisseur->lire)) {
if (!$user->hasRight('societe', 'lire') && !$user->hasRight('fournisseur', 'lire')) {
$readok = 0;
$nbko++;
}
@ -436,12 +436,12 @@ function restrictedArea(User $user, $features, $objectid = 0, $tableandshare = '
$nbko++;
}
} elseif ($feature == 'produit|service') {
if (!$user->rights->produit->lire && !$user->rights->service->lire) {
if (empty($user->rights->produit->lire) && empty($user->rights->service->lire)) {
$readok = 0;
$nbko++;
}
} elseif ($feature == 'prelevement') {
if (!$user->rights->prelevement->bons->lire) {
if (empty($user->rights->prelevement->bons->lire)) {
$readok = 0;
$nbko++;
}
@ -451,12 +451,12 @@ function restrictedArea(User $user, $features, $objectid = 0, $tableandshare = '
$nbko++;
}
} elseif ($feature == 'projet') {
if (!$user->rights->projet->lire && empty($user->rights->projet->all->lire)) {
if (empty($user->rights->projet->lire) && empty($user->rights->projet->all->lire)) {
$readok = 0;
$nbko++;
}
} elseif ($feature == 'payment') {
if (!$user->rights->facture->lire) {
if (empty($user->rights->facture->lire)) {
$readok = 0;
$nbko++;
}
@ -716,7 +716,7 @@ function restrictedArea(User $user, $features, $objectid = 0, $tableandshare = '
// If we have a particular object to check permissions on, we check if $user has permission
// for this given object (link to company, is contact for project, ...)
if (!empty($objectid) && $objectid > 0) {
$ok = checkUserAccessToObject($user, $featuresarray, $objectid, $tableandshare, $feature2, $dbt_keyfield, $dbt_select, $parentfortableentity);
$ok = checkUserAccessToObject($user, $featuresarray, $object, $tableandshare, $feature2, $dbt_keyfield, $dbt_select, $parentfortableentity);
$params = array('objectid' => $objectid, 'features' => join(',', $featuresarray), 'features2' => $feature2);
//print 'checkUserAccessToObject ok='.$ok;
if ($mode) {
@ -737,9 +737,9 @@ function restrictedArea(User $user, $features, $objectid = 0, $tableandshare = '
* @param array $featuresarray Features/modules to check. Example: ('user','service','member','project','task',...)
* @param int|string|Object $object Full object or object ID or list of object id. For example if we want to check a particular record (optional) is linked to a owned thirdparty (optional).
* @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany modume. Param not used if objectid is null (optional).
* @param string $feature2 Feature to check, second level of permission (optional). Can be or check with 'level1|level2'.
* @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional)
* @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional)
* @param array|string $feature2 Feature to check, second level of permission (optional). Can be or check with 'level1|level2'.
* @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional). Can use '' if NA.
* @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional).
* @param string $parenttableforentity Parent table for entity. Example 'fk_website@website'
* @return bool True if user has access, False otherwise
* @see restrictedArea()
@ -753,9 +753,10 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl
} else {
$objectid = $object; // $objectid can be X or 'X,Y,Z'
}
$objectid = preg_replace('/[^0-9\.\,]/', '', $objectid); // For the case value is coming from a non sanitized user input
//dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
//print "user_id=".$user->id.", features=".join(',', $featuresarray).", feature2=".$feature2.", objectid=".$objectid;
//print "user_id=".$user->id.", features=".join(',', $featuresarray).", objectid=".$objectid;
//print ", tableandshare=".$tableandshare.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select."<br>";
// More parameters
@ -783,12 +784,13 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl
// Array to define rules of checks to do
$check = array('adherent', 'banque', 'bom', 'don', 'mrp', 'user', 'usergroup', 'payment', 'payment_supplier', 'product', 'produit', 'service', 'produit|service', 'categorie', 'resource', 'expensereport', 'holiday', 'salaries', 'website', 'recruitment'); // Test on entity only (Objects with no link to company)
$checksoc = array('societe'); // Test for societe object
$checksoc = array('societe'); // Test for object Societe
$checkother = array('contact', 'agenda'); // Test on entity + link to third party on field $dbt_keyfield. Allowed if link is empty (Ex: contacts...).
$checkproject = array('projet', 'project'); // Test for project object
$checktask = array('projet_task'); // Test for task object
$checkhierarchy = array('expensereport', 'holiday');
$checkhierarchy = array('expensereport', 'holiday'); // check permission among the hierarchy of user
$nocheck = array('barcode', 'stock'); // No test
//$checkdefault = 'all other not already defined'; // Test on entity + link to third party on field $dbt_keyfield. Not allowed if link is empty (Ex: invoice, orders...).
// If dbtablename not defined, we use same name for table than module name
@ -797,6 +799,11 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl
$sharedelement = (!empty($params[1]) ? $params[1] : $dbtablename); // We change dbtablename, so we set sharedelement too.
}
// To avoid an access forbidden with a numeric ref
if ($dbt_select != 'rowid' && $dbt_select != 'id') {
$objectid = "'".$objectid."'"; // Note: $objectid was already cast into int at begin of this method.
}
// Check permission for objectid on entity only
if (in_array($feature, $check) && $objectid > 0) { // For $objectid = 0, no check
$sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";

View File

@ -193,22 +193,24 @@ if (!function_exists('dol_loginfunction')) {
$sessiontimeout = 'DOLSESSTIMEOUT_'.$prefix;
if (!empty($conf->global->MAIN_SESSION_TIMEOUT)) {
if (PHP_VERSION_ID < 70300) {
session_set_cookie_params(0, '/', null, ((empty($dolibarr_main_force_https) && isHTTPS() === false) ? false : true), true); // Add tag secure and httponly on session cookie (same as setting session.cookie_httponly into php.ini). Must be called before the session_start.
} else {
// Only available for php >= 7.3
$sessioncookieparams = array(
'lifetime' => 0,
'path' => '/',
//'domain' => '.mywebsite.com', // the dot at the beginning allows compatibility with subdomains
'secure' => ((empty($dolibarr_main_force_https) && isHTTPS() === false) ? false : true),
'httponly' => true,
'samesite' => 'Lax' // None || Lax || Strict
);
session_set_cookie_params($sessioncookieparams);
}
if (session_status() != PHP_SESSION_ACTIVE) {
if (PHP_VERSION_ID < 70300) {
session_set_cookie_params(0, '/', null, ((empty($dolibarr_main_force_https) && isHTTPS() === false) ? false : true), true); // Add tag secure and httponly on session cookie (same as setting session.cookie_httponly into php.ini). Must be called before the session_start.
} else {
// Only available for php >= 7.3
$sessioncookieparams = array(
'lifetime' => 0,
'path' => '/',
//'domain' => '.mywebsite.com', // the dot at the beginning allows compatibility with subdomains
'secure' => ((empty($dolibarr_main_force_https) && isHTTPS() === false) ? false : true),
'httponly' => true,
'samesite' => 'Lax' // None || Lax || Strict
);
session_set_cookie_params($sessioncookieparams);
}
setcookie($sessiontimeout, $conf->global->MAIN_SESSION_TIMEOUT, 0, "/", null, (empty($dolibarr_main_force_https) ? false : true), true);
setcookie($sessiontimeout, $conf->global->MAIN_SESSION_TIMEOUT, 0, "/", null, (empty($dolibarr_main_force_https) ? false : true), true);
}
}
if (GETPOST('urlfrom', 'alpha')) {

View File

@ -1726,10 +1726,10 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef
if ($nature) {
$langs->load('accountancy');
$journallabel = $langs->transnoentities($objp->label); // Labels in this table are set by loading llx_accounting_abc.sql. Label can be 'ACCOUNTING_SELL_JOURNAL', 'InventoryJournal', ...
$journallabel = $langs->transnoentities($objp->label); // Label of bank account in llx_accounting_journal
$key = $langs->trans("AccountingJournalType".strtoupper($objp->nature));
$transferlabel = ($objp->nature && $key != "AccountingJournalType".strtoupper($langs->trans($objp->nature)) ? $key : $objp->label);
$transferlabel = ($objp->nature && $key != "AccountingJournalType".strtoupper($langs->trans($objp->nature)) ? $key.($journallabel != $key ? ' '.$journallabel : ''): $journallabel);
$newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_journal='.$objp->rowid, $transferlabel, 2, $user->hasRight('accounting', 'comptarapport', 'lire'));
}

View File

@ -752,10 +752,18 @@ class pdf_crabe extends ModelePDFFactures
// retrieve global local tax
if ($localtax1_type && $localtax1ligne != 0) {
$this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
if (empty($this->localtax1[$localtax1_type][$localtax1_rate])) {
$this->localtax1[$localtax1_type][$localtax1_rate] = $localtax1ligne;
} else {
$this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
}
}
if ($localtax2_type && $localtax2ligne != 0) {
$this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
if (empty($this->localtax2[$localtax2_type][$localtax2_rate])) {
$this->localtax2[$localtax2_type][$localtax2_rate] = $localtax2ligne;
} else {
$this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
}
}
if (($object->lines[$i]->info_bits & 0x01) == 0x01) {

View File

@ -214,7 +214,7 @@ class modProjet extends DolibarrModules
$this->menu = 1; // This module add menu entries. They are coded into menu manager.
//Exports
// Exports
//--------
$r = 1;
@ -291,6 +291,40 @@ class modProjet extends DolibarrModules
}
$this->export_sql_end[$r] .= " WHERE p.entity IN (".getEntity('project').")";
// Import project/opportunities
$r++;
$this->import_code[$r] = 'projects';
$this->import_label[$r] = 'ImportDatasetProjects';
$this->import_icon[$r] = 'project';
$this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon
$this->import_tables_array[$r] = array('t'=>MAIN_DB_PREFIX.'projet', 'extra'=>MAIN_DB_PREFIX.'projet_extrafields'); // List of tables to insert into (insert done in same order)
$this->import_fields_array[$r] = array('t.ref'=>'ProjectRef*', 't.title'=>'Label*', 't.description'=>"Description", 't.fk_soc' => 'ThirdPartyName', 't.public'=>"Public", 't.fk_statut'=>"Status");
$this->import_fields_array[$r] = array_merge($this->import_fields_array[$r], array('t.fk_opp_status'=>"OpportunityStatus", 't.opp_percent'=>"OpportunityProbability", 't.opp_amount'=>"OpportunityAmount", 't.note_public'=>"NotePublic", 't.note_private'=>"NotePrivate", 't.budget_amount'=>"Budget", 't.dateo'=>"DateStart", 't.datee'=>"DateEnd"));
// Add extra fields
$sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'projet' AND entity IN (0,".$conf->entity.")";
$resql = $this->db->query($sql);
if ($resql) { // This can fail when class is used on old database (during migration for example)
while ($obj = $this->db->fetch_object($resql)) {
$fieldname = 'extra.'.$obj->name;
$fieldlabel = ucfirst($obj->label);
$this->import_fields_array[$r][$fieldname] = $fieldlabel.($obj->fieldrequired ? '*' : '');
}
}
// End add extra fields
$this->import_fieldshidden_array[$r] = array('t.fk_user_creat'=>'user->id', 'extra.fk_object'=>'lastrowid-'.MAIN_DB_PREFIX.'projet'); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent)
$this->import_convertvalue_array[$r] = array(
't.ref'=>array('rule'=>'getrefifauto', 'class'=>(empty($conf->global->PROJECT_ADDON) ? 'mod_project_simple' : $conf->global->PROJECT_ADDON), 'path'=>"/core/modules/project/".(empty($conf->global->PROJECT_ADDON) ? 'mod_project_simple' : $conf->global->PROJECT_ADDON).'.php'),
't.fk_soc' => array(
'rule' => 'fetchidfromref',
'file' => '/societe/class/societe.class.php',
'class' => 'Societe',
'method' => 'fetch',
'element' => 'ThirdParty'
),
);
//$this->import_convertvalue_array[$r]=array('s.fk_soc'=>array('rule'=>'lastrowid',table='t');
$this->import_regex_array[$r] = array('t.dateo'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', 't.datee'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', 't.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]( [0-9][0-9]:[0-9][0-9]:[0-9][0-9])?$');
$this->import_examplevalues_array[$r] = array('t.fk_soc'=>'ThirdParty', 't.ref'=>"auto or PJ2010-1234", 't.title'=>"My project", 't.fk_statut'=>'0,1 or 2', 't.datec'=>'1972-10-10', 't.note_private'=>"My private note", 't.note_public'=>"My public note");
// Import list of tasks
if (empty($conf->global->PROJECT_HIDE_TASKS)) {

View File

@ -124,7 +124,6 @@ class modTicket extends DolibarrModules
$this->tabs = array(
'thirdparty:+ticket:Tickets:ticket:$user->rights->ticket->read:/ticket/list.php?socid=__ID__',
'project:+ticket:Tickets:ticket:$user->rights->ticket->read:/ticket/list.php?projectid=__ID__',
);
// Dictionaries

View File

@ -971,7 +971,15 @@ if (!empty($usemargins) && $user->rights->margins->creer) {
var tva_tx = parseFloat($('option:selected', this).attr('data-tvatx')); // When select is done from HTML select
if (isNaN(tva_tx)) { tva_tx = parseFloat(jQuery('#idprodfournprice').attr('data-tvatx'));} // When select is done from HTML input with ajax autocomplete
console.log("objectline_create.tpl We find supplier price : up = "+up+", up_locale = "+up_locale+", qty = "+qty+", tva_tx = "+tva_tx+", discount = "+discount+" for product "+jQuery('#idprodfournprice').val());
var default_vat_code = $('option:selected', this).attr('data-default-vat-code'); // When select is done from HTML select
if (typeof default_vat_code === 'undefined') { default_vat_code = jQuery('#idprodfournprice').attr('data-default-vat-code');} // When select is done from HTML input with ajax autocomplete
var stringforvatrateselection = tva_tx;
if (typeof default_vat_code != 'undefined') {
stringforvatrateselection = stringforvatrateselection+' ('+default_vat_code+')';
}
console.log("objectline_create.tpl We find supplier price : up = "+up+", up_locale = "+up_locale+", qty = "+qty+", tva_tx = "+tva_tx+", default_vat_code = "+default_vat_code+", stringforvatrateselection="+stringforvatrateselection+", discount = "+discount+" for product supplier ref id = "+jQuery('#idprodfournprice').val());
if (typeof up_locale === 'undefined') {
jQuery("#price_ht").val(up);
@ -979,8 +987,13 @@ if (!empty($usemargins) && $user->rights->margins->creer) {
jQuery("#price_ht").val(up_locale);
}
/* $('#tva_tx option').removeAttr('selected').filter('[value='+tva_tx+']').prop('selected', true); */
$('#tva_tx option').val(tva_tx);
// Set vat rate if field is an input box
$('#tva_tx').val(tva_tx);
// Set vat rate by selecting the combo
//$('#tva_tx option').val(tva_tx); // This is bugged, it replaces the vat key of all options
$('#tva_tx option').removeAttr('selected');
console.log("stringforvatrateselection="+stringforvatrateselection+" -> value of option for this selection="+$('#tva_tx option[value="'+stringforvatrateselection+'"]').val());
$('#tva_tx option[value="'+stringforvatrateselection+'"]').prop('selected', true);
if (jQuery("#qty").val() < qty) {
jQuery("#qty").val(qty);

View File

@ -353,19 +353,27 @@ if ($line->special_code == 3) { ?>
if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
$tooltiponprice = $langs->transcountry("TotalHT", $mysoc->country_code).'='.price($line->total_ht);
$tooltiponprice .= '<br>'.$langs->transcountry("TotalVAT", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'='.price($line->total_tva);
if (!$senderissupplier && is_object($object->thirdparty)) {
if (is_object($object->thirdparty)) {
if ($senderissupplier) {
$seller = $object->thirdparty;
$buyer = $mysoc;
} else {
$seller = $mysoc;
$buyer = $object->thirdparty;
}
if ($mysoc->useLocalTax(1)) {
if (($mysoc->country_code == $object->thirdparty->country_code) || $object->thirdparty->useLocalTax(1)) {
$tooltiponprice .= '<br>'.$langs->transcountry("TotalLT1", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'='.price($line->total_localtax1);
if (($seller->country_code == $buyer->country_code) || $line->total_localtax1 || $seller->useLocalTax(1)) {
$tooltiponprice .= '<br>'.$langs->transcountry("TotalLT1", $seller->country_code).'='.price($line->total_localtax1);
} else {
$tooltiponprice .= '<br>'.$langs->transcountry("TotalLT1", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'=<span class="opacitymedium">'.$langs->trans("NotUsedForThisCustomer").'</span>';
$tooltiponprice .= '<br>'.$langs->transcountry("TotalLT1", $seller->country_code).'=<span class="opacitymedium">'.$langs->trans($senderissupplier ? "NotUsedForThisSupplier" : "NotUsedForThisCustomer").'</span>';
}
}
if ($mysoc->useLocalTax(2)) {
if (($mysoc->country_code == $object->thirdparty->country_code) || $object->thirdparty->useLocalTax(2)) {
$tooltiponprice .= '<br>'.$langs->transcountry("TotalLT2", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'='.price($line->total_localtax2);
if (($seller->country_code == $buyer->thirdparty->country_code) || $line->total_localtax2 || $seller->useLocalTax(2)) {
$tooltiponprice .= '<br>'.$langs->transcountry("TotalLT2", $seller->country_code).'='.price($line->total_localtax2);
} else {
$tooltiponprice .= '<br>'.$langs->transcountry("TotalLT2", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'=<span class="opacitymedium">'.$langs->trans("NotUsedForThisCustomer").'</span>';
$tooltiponprice .= '<br>'.$langs->transcountry("TotalLT2", $seller->country_code).'=<span class="opacitymedium">'.$langs->trans($senderissupplier ? "NotUsedForThisSupplier" : "NotUsedForThisCustomer").'</span>';
}
}
}

View File

@ -742,7 +742,7 @@ class InterfaceActionsAuto extends DolibarrTriggers
if (!is_object($member)) { // This should not happen
include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
$member = new Adherent($this->db);
$member->fetch($this->fk_adherent);
$member->fetch($object->fk_adherent);
}
if (empty($object->actionmsg2)) {

View File

@ -448,7 +448,7 @@ print '<td class="liste_titre center"><input type="text" class="width50" name="s
print '<td class="liste_titre">&nbsp;</td>';
print '<td class="liste_titre">&nbsp;</td>';
print '<td class="liste_titre center">';
print $form->selectarray('search_status', array('0'=>$langs->trans("Disabled"), '1'=>$langs->trans("Scheduled")), $search_status, 1);
print $form->selectarray('search_status', array('0'=>$langs->trans("Disabled"), '1'=>$langs->trans("Scheduled")), $search_status, 1, 0, 0, '', 0, 0, 0, '', 'onrightofpage');
print '</td><td class="liste_titre right">';
$searchpicto = $form->showFilterButtons();
print $searchpicto;

View File

@ -48,6 +48,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
$langs->loadLangs(array('bills', 'companies', 'donations', 'users'));
$id = GETPOST('rowid') ?GETPOST('rowid', 'int') : GETPOST('id', 'int');
$ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$confirm = GETPOST('confirm', 'alpha');
@ -58,10 +59,11 @@ $projectid = (GETPOST('projectid') ? GETPOST('projectid', 'int') : 0);
$public_donation = (int) GETPOST("public", 'int');
$object = new Don($db);
$extrafields = new ExtraFields($db);
if ($id > 0 || $ref) {
$object->fetch($id, $ref);
}
// Security check
$result = restrictedArea($user, 'don', $id);
$extrafields = new ExtraFields($db);
// fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);
@ -71,6 +73,11 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen
$hookmanager->initHooks(array('doncard', 'globalcard'));
$upload_dir = $conf->don->dir_output;
// Security check
$result = restrictedArea($user, 'don', $object->id);
$permissiontoadd = $user->rights->don->creer;

View File

@ -49,13 +49,6 @@ $action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$projectid = (GETPOST('projectid') ? GETPOST('projectid', 'int') : 0);
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'don', $id, '');
// Get parameters
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'aZ09comma');
@ -74,13 +67,20 @@ if (!$sortfield) {
$sortfield = "name";
}
$object = new Don($db);
$object->fetch($id, $ref);
if ($id > 0 || $ref) {
$object->fetch($id, $ref);
}
$upload_dir = $conf->don->dir_output.'/'.get_exdir($id, 0, 0, 0, $object, 'donation').'/'.dol_sanitizeFileName($object->ref);
$modulepart = 'don';
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'don', $object->id);
$permissiontoadd = $user->rights->don->creer; // Used by the include of actions_dellink.inc.php

View File

@ -35,11 +35,11 @@ $hookmanager->initHooks(array('donationindex'));
$langs->load("donations");
$donation_static = new Don($db);
// Security check
$result = restrictedArea($user, 'don');
$donation_static = new Don($db);
/*
* Actions

View File

@ -38,14 +38,17 @@ $ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$projectid = (GETPOST('projectid') ? GETPOST('projectid', 'int') : 0);
$object = new Don($db);
if ($id > 0 || $ref) {
$object->fetch($id, $ref);
}
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'don', $id, '');
$result = restrictedArea($user, 'don', $object->id);
$object = new Don($db);
$object->fetch($id);
/*

View File

@ -88,6 +88,11 @@ $fieldstosearchall = array(
'd.firstname'=>'Firstname',
);
// Security check
$result = restrictedArea($user, 'don');
/*
* View
@ -234,7 +239,7 @@ if ($resql) {
Don::STATUS_PAID=>$langs->trans("DonationStatusPaid"),
Don::STATUS_CANCELED=>$langs->trans("Canceled")
);
print $form->selectarray('search_status', $liststatus, $search_status, -4, 0, 0, '', 0, 0, 0, '', 'maxwidth100');
print $form->selectarray('search_status', $liststatus, $search_status, -4, 0, 0, '', 0, 0, 0, '', 'maxwidth100 onrightofpage');
print '</td>';
print '<td class="liste_titre maxwidthsearch">';
$searchpicto = $form->showFilterAndCheckAddButtons(0);

View File

@ -43,17 +43,19 @@ $ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$projectid = (GETPOST('projectid') ? GETPOST('projectid', 'int') : 0);
$hookmanager->initHooks(array('donnote'));
$object = new Don($db);
if ($id > 0 || $ref) {
$object->fetch($id, $ref);
}
// Security check
$socid = 0;
if ($user->socid) {
$socid = $user->socid;
}
$hookmanager->initHooks(array('donnote'));
$result = restrictedArea($user, 'don', $id, '');
$object = new Don($db);
$object->fetch($id);
$result = restrictedArea($user, 'don', $object->id, '');
$permissionnote = $user->rights->don->creer; // Used by the include of actions_setnotes.inc.php

View File

@ -85,7 +85,7 @@ class EmailCollectorAction extends CommonObject
'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",),
'fk_emailcollector' => array('type'=>'integer', 'label'=>'Id of emailcollector', 'foreignkey'=>'emailcollector.rowid'),
'type' => array('type'=>'varchar(128)', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>10, 'notnull'=>1, 'index'=>1),
'actionparam' => array('type'=>'varchar(255)', 'label'=>'ParamForAction', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'notnull'=>-1),
'actionparam' => array('type'=>'text', 'label'=>'ParamForAction', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'notnull'=>-1),
'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>500, 'notnull'=>1,),
'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'position'=>501, 'notnull'=>1,),
'fk_user_creat' => array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-2, 'position'=>510, 'notnull'=>1, 'foreignkey'=>'llx_user.rowid',),

View File

@ -787,7 +787,7 @@ if (!empty($arrayfields['e.tms']['checked'])) {
// Status
if (!empty($arrayfields['e.fk_statut']['checked'])) {
print '<td class="liste_titre maxwidthonsmartphone right">';
print $form->selectarray('search_status', array('0'=>$langs->trans('StatusSendingDraftShort'), '1'=>$langs->trans('StatusSendingValidatedShort'), '2'=>$langs->trans('StatusSendingProcessedShort')), $search_status, 1);
print $form->selectarray('search_status', array('0'=>$langs->trans('StatusSendingDraftShort'), '1'=>$langs->trans('StatusSendingValidatedShort'), '2'=>$langs->trans('StatusSendingProcessedShort')), $search_status, 1, 0, 0, '', 0, 0, 0, '', 'onrightofpage');
print '</td>';
}
// Status billed

View File

@ -2297,7 +2297,7 @@ if ($action == 'create') {
}
}
$tredited = 'tredited';
$tredited = 'tredited'; // Case the addfile and linkto file is used for edit (used by following tpl)
include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_addfile.tpl.php';
include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_linktofile.tpl.php';
@ -2455,6 +2455,7 @@ if ($action == 'create') {
print '</script>'."\n";
print '</td></tr>';
$tredited = ''; // Case the addfile and linkto file is used for edit (used by following tpl)
include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_linktofile.tpl.php';
include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_addfile.tpl.php';
@ -2517,6 +2518,7 @@ if ($action == 'create') {
print '<td class="right inputvat">';
$defaultvat = -1;
if (!empty($conf->global->EXPENSEREPORT_NO_DEFAULT_VAT)) {
// If option to have no default VAT on expense report is on, we force MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS
$conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none';
}
print $form->load_tva('vatrate', (!empty($vatrate) ? $vatrate : $defaultvat), $mysoc, '', 0, 0, '', false, 1);

View File

@ -136,8 +136,18 @@ if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) {
print '</td></tr>';
} else {
print '<tr class="oddeven nohover trattachnewfilenow"'.(!GETPOSTISSET('sendit') && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ' style="display: none"' : '').'>';
print '<td colspan="'.$colspan.'">';
if (empty($tredited)) {
$css = 'oddeven nohover trattachnewfilenow';
$newcolspan = $colspan;
} else {
$css = 'trattachnewfilenow tredited';
$newcolspan = $colspan - 1;
}
print '<tr class="'.$css.'"'.(!GETPOSTISSET('sendit') && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ' style="display: none"' : '').'>';
if (!empty($tredited)) {
print '<td></td>';
}
print '<td colspan="'.($newcolspan).'">';
print '<span class="opacitymedium">'.$langs->trans("NoFilesUploadedYet").'</span>';
print '</td></tr>';
}

View File

@ -575,7 +575,7 @@ if (!empty($arrayfields['f.fk_statut']['checked'])) {
if (empty($conf->global->FICHINTER_CLASSIFY_BILLED)) {
unset($liststatus[2]); // Option deprecated. In a future, billed must be managed with a dedicated field to 0 or 1
}
print $form->selectarray('search_status', $liststatus, $search_status, 1, 0, 0, '', 1);
print $form->selectarray('search_status', $liststatus, $search_status, 1, 0, 0, '', 1, 0, 0, '', 'onrightofpage');
print '</td>';
}
// Fields of detail line

View File

@ -413,7 +413,7 @@ if (empty($reshook)) {
// Add a product line
if ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && GETPOST('vatforalllines', 'alpha') && $usercancreate) {
// Define vat_rate
// Define new vat_rate for all lines
$vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0);
$vat_rate = str_replace('*', '', $vat_rate);
$localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);

View File

@ -1469,7 +1469,7 @@ if ($resql) {
// Status billed
if (!empty($arrayfields['cf.billed']['checked'])) {
print '<td class="liste_titre center">';
print $form->selectyesno('search_billed', $search_billed, 1, 0, 1, 1);
print $form->selectyesno('search_billed', $search_billed, 1, false, 1, 1, 'maxwidth100 onrightofpage');
print '</td>';
}
// Date valid

View File

@ -1299,10 +1299,13 @@ if (empty($reshook)) {
// Edit line
$db->begin();
if (! $object->fetch($id) > 0) dol_print_error($db);
if (! $object->fetch($id) > 0) {
dol_print_error($db);
}
$object->fetch_thirdparty();
$tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
$tva_tx = str_replace('*', '', $tva_tx);
if (GETPOST('price_ht') != '' || GETPOST('multicurrency_subprice') != '') {
$up = price2num(GETPOST('price_ht'), '', 2);
@ -1360,7 +1363,27 @@ if (empty($reshook)) {
}
}
$result = $object->updateline(GETPOST('lineid', 'int'), $label, $up, $tva_tx, $localtax1_tx, $localtax2_tx, price2num(GETPOST('qty'), 'MS'), GETPOST('productid', 'int'), $price_base_type, $info_bits, $type, $remise_percent, 0, $date_start, $date_end, $array_options, GETPOST('units'), $pu_devise, GETPOST('fourn_ref', 'alpha'));
$result = $object->updateline(
GETPOST('lineid', 'int'),
$label,
$up,
$tva_tx,
$localtax1_tx,
$localtax2_tx,
price2num(GETPOST('qty'), 'MS'),
GETPOST('productid', 'int'),
$price_base_type,
$info_bits,
$type,
$remise_percent,
0,
$date_start,
$date_end,
$array_options,
GETPOST('units', 'alpha'),
$pu_devise,
GETPOST('fourn_ref', 'alpha')
);
if ($result >= 0) {
unset($_POST['label']);
unset($_POST['fourn_ref']);
@ -2588,7 +2611,6 @@ if ($action == 'create') {
//
// View or edit mode
//
$now = dol_now();
$productstatic = new Product($db);
@ -2918,15 +2940,15 @@ if ($action == 'create') {
if ($object->type == FactureFournisseur::TYPE_REPLACEMENT) {
$facreplaced = new FactureFournisseur($db);
$facreplaced->fetch($object->fk_facture_source);
print ' &nbsp; '.$langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1));
print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1)).'</span>';
}
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
$facusing = new FactureFournisseur($db);
if ($object->fk_facture_source > 0) {
$facusing->fetch($object->fk_facture_source);
print ' &nbsp; '.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1));
print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)).'</span>';
} else {
print ' &nbsp; '.$langs->transnoentities("CorrectedInvoiceNotFound");
print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("CorrectedInvoiceNotFound").'</span>';
}
}
@ -2938,12 +2960,13 @@ if ($action == 'create') {
$facavoir->fetch($id);
$invoicecredits[] = $facavoir->getNomUrl(1);
}
print ' ('.$langs->transnoentities("InvoiceHasAvoir") . (count($invoicecredits) ? ' ' : '') . implode(',', $invoicecredits) . ')';
print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("InvoiceHasAvoir") . (count($invoicecredits) ? ' ' : '') . implode(',', $invoicecredits);
print '</span>';
}
if (isset($objectidnext) && $objectidnext > 0) {
$facthatreplace = new FactureFournisseur($db);
$facthatreplace->fetch($facidnext);
print ' ('.$langs->transnoentities("ReplacedByInvoice", $facthatreplace->getNomUrl(1)).')';
print ' <span class="opacitymediumbycolor paddingleft">'.str_replace('{s1}', $facthatreplace->getNomUrl(1), $langs->transnoentities("ReplacedByInvoice", '{s1}')).'</span>';
}
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) {
$discount = new DiscountAbsolute($db);

View File

@ -1221,7 +1221,7 @@ if (!empty($arrayfields['f.tms']['checked'])) {
if (!empty($arrayfields['f.fk_statut']['checked'])) {
print '<td class="liste_titre maxwidthonsmartphone right">';
$liststatus = array('0'=>$langs->trans("Draft"), '1'=>$langs->trans("Unpaid"), '2'=>$langs->trans("Paid"));
print $form->selectarray('search_status', $liststatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', '', 1);
print $form->selectarray('search_status', $liststatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', 'onrightofpage', 1);
print '</td>';
}
// Action column

View File

@ -388,3 +388,6 @@ ALTER TABLE llx_user ADD COLUMN birth_place varchar(64);
ALTER TABLE llx_opensurvey_user_studs ADD COLUMN date_creation datetime NULL;
ALTER TABLE llx_opensurvey_comments ADD COLUMN date_creation datetime NULL;
ALTER TABLE llx_c_tva ADD COLUMN use_default tinyint DEFAULT 0;

View File

@ -28,6 +28,7 @@ create table llx_c_tva
localtax1_type varchar(10) NOT NULL DEFAULT '0',
localtax2 varchar(20) NOT NULL DEFAULT '0',
localtax2_type varchar(10) NOT NULL DEFAULT '0',
use_default tinyint DEFAULT 0, -- set to 1 to be the default vat when no vat defined on product
recuperableonly integer NOT NULL DEFAULT 0,
note varchar(128),
active tinyint DEFAULT 1 NOT NULL,

View File

@ -87,7 +87,8 @@ if ($id > 0 || !empty($ref)) {
// Security check - Protection if external user
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$result = restrictedArea($user, 'knowledgemanagement', $object->id);
$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, '', 'rowid', $isdraft);
$permissiontoadd = $user->rights->knowledgemanagement->knowledgerecord->write; // Used by the include of actions_addupdatedelete.inc.php

View File

@ -85,8 +85,8 @@ $upload_dir = $conf->knowledgemanagement->multidir_output[isset($object->entity)
// Security check - Protection if external user
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
//restrictedArea($user, $object->element, $object->id, '', '', 'fk_soc', 'rowid', $isdraft);
$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, '', 'rowid', $isdraft);
//if (empty($conf->knowledgemanagement->enabled)) accessforbidden();
//if (empty($permissiontoread)) accessforbidden();

View File

@ -53,12 +53,14 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be includ
// Security check - Protection if external user
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$result = restrictedArea($user, 'knowledgemanagement', $object->id);
$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, '', 'rowid', $isdraft);
$permission = $user->rights->knowledgemanagement->knowledgerecord->write;
/*
* Add a new contact
* Actions
*/
if ($action == 'addcontact' && $permission) {
@ -108,16 +110,10 @@ $contactstatic = new Contact($db);
$userstatic = new User($db);
/* *************************************************************************** */
/* */
/* View and edit mode */
/* */
/* *************************************************************************** */
// View and edit mode
if ($object->id) {
/*
* Show tabs
*/
// Show tabs
$head = knowledgerecordPrepareHead($object);
print dol_get_fiche_head($head, 'contact', $langs->trans("KnowledgeRecord"), -1, $object->picto);

View File

@ -78,7 +78,8 @@ if ($id > 0 || !empty($ref)) {
// Security check - Protection if external user
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$result = restrictedArea($user, 'knowledgemanagement', $object->id);
$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, '', 'rowid', $isdraft);
$permissiontoadd = $user->rights->knowledgemanagement->knowledgerecord->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php

View File

@ -153,7 +153,7 @@ if ($user->socid > 0) { // Protection if external user
//$socid = $user->socid;
accessforbidden();
}
//$result = restrictedArea($user, 'knowledgemanagement');
$result = restrictedArea($user, 'knowledgemanagement', 0, '', 'knowledgerecord');
//if (!$permissiontoread) accessforbidden();

View File

@ -46,11 +46,6 @@ $hookmanager->initHooks(array('knowledgerecordnote', 'globalcard')); // Note tha
// Fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);
// Security check - Protection if external user
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$result = restrictedArea($user, 'knowledgemanagement', $id);
// Load object
include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
if ($id > 0 || !empty($ref)) {
@ -60,6 +55,11 @@ if ($id > 0 || !empty($ref)) {
$permissionnote = $user->rights->knowledgemanagement->knowledgerecord->write; // Used by the include of actions_setnotes.inc.php
$permissiontoadd = $user->rights->knowledgemanagement->knowledgerecord->write; // Used by the include of actions_addupdatedelete.inc.php
// Security check - Protection if external user
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, '', 'rowid', $isdraft);
/*

View File

@ -1250,6 +1250,7 @@ AreaForAdminOnly=Setup parameters can be set by <b>administrator users</b> only.
SystemInfoDesc=System information is miscellaneous technical information you get in read only mode and visible for administrators only.
SystemAreaForAdminOnly=This area is available to administrator users only. Dolibarr user permissions cannot change this restriction.
CompanyFundationDesc=Edit the information of your company/organization. Click on "%s" button at the bottom of the page when done.
MoreNetworksAvailableWithModule=More social networks may be available by enabling the module "Social networks".
AccountantDesc=If you have an external accountant/bookkeeper, you can edit here its information.
AccountantFileNumber=Accountant code
DisplayDesc=Parameters affecting the look and presentation of the application can be modified here.

View File

@ -206,6 +206,7 @@ Valid=Valid
Approve=Approve
Disapprove=Disapprove
ReOpen=Re-Open
OpenVerb=Open
Upload=Upload
ToLink=Link
Select=Select

View File

@ -23,6 +23,7 @@ TasksPublicDesc=This view presents all projects and tasks you are allowed to rea
TasksDesc=This view presents all projects and tasks (your user permissions grant you permission to view everything).
AllTaskVisibleButEditIfYouAreAssigned=All tasks for qualified projects are visible, but you can enter time only for task assigned to selected user. Assign task if you need to enter time on it.
OnlyYourTaskAreVisible=Only tasks assigned to you are visible. If you need to enter time on a task and if the task is not visible here, then you need to assign the task to yourself.
ImportDatasetProjects=Projects or opportunities
ImportDatasetTasks=Tasks of projects
ProjectCategories=Project tags/categories
NewProject=New project

View File

@ -89,18 +89,22 @@ function testSqlAndScriptInject($val, $type)
// Decode string first because a lot of things are obfuscated by encoding or multiple encoding.
// So <svg o&#110;load='console.log(&quot;123&quot;)' become <svg onload='console.log(&quot;123&quot;)'
// So "&colon;&apos;" become ":'" (due to ENT_HTML5)
// So "&Tab;&NewLine;" become ""
// So "&lpar;&rpar;" become "()"
// Loop to decode until no more things to decode.
//print "before decoding $val\n";
do {
$oldval = $val;
$val = html_entity_decode($val, ENT_QUOTES | ENT_HTML5);
//$val = preg_replace_callback('/&#(x?[0-9][0-9a-f]+;?)/i', 'realCharForNumericEntities', $val); // Sometimes we have entities without the ; at end so html_entity_decode does not work but entities is still interpreted by browser.
$val = html_entity_decode($val, ENT_QUOTES | ENT_HTML5); // Decode '&colon;', '&apos;', '&Tab;', '&NewLine', ...
// Sometimes we have entities without the ; at end so html_entity_decode does not work but entities is still interpreted by browser.
$val = preg_replace_callback('/&#(x?[0-9][0-9a-f]+;?)/i', function ($m) {
// Decode '&#110;', ...
return realCharForNumericEntities($m); }, $val);
// We clean html comments because some hacks try to obfuscate evil strings by inserting HTML comments. Example: on<!-- -->error=alert(1)
$val = preg_replace('/<!--[^>]*-->/', '', $val);
$val = preg_replace('/[\r\n]/', '', $val);
$val = preg_replace('/[\r\n\t]/', '', $val);
} while ($oldval != $val);
//print "type = ".$type." after decoding: ".$val."\n";
@ -123,11 +127,12 @@ function testSqlAndScriptInject($val, $type)
// For SQL Injection (only GET are used to scan for such injection strings)
if ($type == 1 || $type == 3) {
$inj += preg_match('/delete\s+from/i', $val);
$inj += preg_match('/create\s+table/i', $val);
$inj += preg_match('/insert\s+into/i', $val);
$inj += preg_match('/select\s+from/i', $val);
$inj += preg_match('/into\s+(outfile|dumpfile)/i', $val);
// Note the \s+ is replaced into \s* because some spaces may have been modified in previous loop
$inj += preg_match('/delete\s*from/i', $val);
$inj += preg_match('/create\s*table/i', $val);
$inj += preg_match('/insert\s*into/i', $val);
$inj += preg_match('/select\s*from/i', $val);
$inj += preg_match('/into\s*(outfile|dumpfile)/i', $val);
$inj += preg_match('/user\s*\(/i', $val); // avoid to use function user() or mysql_user() that return current database login
$inj += preg_match('/information_schema/i', $val); // avoid to use request that read information_schema database
$inj += preg_match('/<svg/i', $val); // <svg can be allowed in POST
@ -135,7 +140,8 @@ function testSqlAndScriptInject($val, $type)
$inj += preg_match('/union.+select/i', $val);
}
if ($type == 3) {
$inj += preg_match('/select|update|delete|truncate|replace|group\s+by|concat|count|from|union/i', $val);
// Note the \s+ is replaced into \s* because some spaces may have been modified in previous loop
$inj += preg_match('/select|update|delete|truncate|replace|group\s*by|concat|count|from|union/i', $val);
}
if ($type != 2) { // Not common key strings, so we can check them both on GET and POST
$inj += preg_match('/updatexml\(/i', $val);
@ -180,7 +186,7 @@ function testSqlAndScriptInject($val, $type)
//$inj += preg_match('/on[A-Z][a-z]+\*=/', $val); // To lock event handlers onAbort(), ...
$inj += preg_match('/&#58;|&#0000058|&#x3A/i', $val); // refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...'
$inj += preg_match('/javascript\s*:/i', $val);
$inj += preg_match('/j\s*a\s*v\s*a\s*s\s*c\s*r\s*i\s*p\s*t\s*:/i', $val);
$inj += preg_match('/vbscript\s*:/i', $val);
// For XSS Injection done by adding javascript closing html tags like with onmousemove, etc... (closing a src or href tag with not cleaned param)
if ($type == 1 || $type == 3) {

View File

@ -110,7 +110,7 @@ class MyObject extends CommonObject
// BEGIN MODULEBUILDER PROPERTIES
/**
* @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
* @var array Array with all fields into database and their property. Do not use it as a static var. It may be modified by constructor.
*/
public $fields = array(
'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'noteditable'=>1, 'notnull'=> 1, 'index'=>1, 'position'=>1, 'comment'=>'Id', 'css'=>'left'),
@ -736,7 +736,7 @@ class MyObject extends CommonObject
public function reopen($user, $notrigger = 0)
{
// Protection
if ($this->status != self::STATUS_CANCELED) {
if ($this->status == self::STATUS_VALIDATED) {
return 0;
}

View File

@ -145,7 +145,7 @@ if ($enablepermissioncheck) {
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
//restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
if (!isModEnabled("mymodule")) {
accessforbidden();
}

View File

@ -145,7 +145,7 @@ $upload_dir = $conf->mymodule->multidir_output[isset($object->entity) ? $object-
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$isdraft = (isset($object->status) && ($object->status == $object::STATUS_DRAFT) ? 1 : 0);
//restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
if (!isModEnabled("mymodule")) {
accessforbidden();
}

View File

@ -93,7 +93,7 @@ if ($enablepermissioncheck) {
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
//restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
if (!isModEnabled("mymodule")) {
accessforbidden();
}

View File

@ -137,7 +137,7 @@ if ($enablepermissioncheck) {
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
//restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
if (!isModEnabled("mymodule")) {
accessforbidden();
}

View File

@ -196,7 +196,7 @@ if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) accessforbidden();
//$socid = 0; if ($user->socid > 0) $socid = $user->socid;
//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
//restrictedArea($user, $object->element, 0, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
//restrictedArea($user, $object->module, 0, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
if (!isModEnabled("mymodule")) {
accessforbidden('Module mymodule not enabled');
}

View File

@ -117,7 +117,7 @@ if ($enablepermissioncheck) {
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
//restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
if (!isModEnabled("mymodule")) {
accessforbidden();
}

View File

@ -343,7 +343,7 @@ print '<td class="liste_titre"></td>';
print '<td class="liste_titre"></td>';
print '<td class="liste_titre"></td>';
$arraystatus = array('-1'=>'&nbsp;', '0'=>$langs->trans("Draft"), '1'=>$langs->trans("Opened"), '2'=>$langs->trans("Closed"));
print '<td class="liste_titre" align="center">'.$form->selectarray('search_status', $arraystatus, $search_status).'</td>';
print '<td class="liste_titre" align="center">'.$form->selectarray('search_status', $arraystatus, $search_status, 0, 0, 0, '', 0, 0, 0, '', 'onroghtofpage').'</td>';
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';

View File

@ -2159,7 +2159,7 @@ class Product extends CommonObject
}
} else {
$price = price2num($newprice, 'MU');
$price_ttc = ($newnpr != 1) ? price2num($newprice) * (1 + ($newvat / 100)) : $price;
$price_ttc = ($newnpr != 1) ? (float) price2num($newprice) * (1 + ($newvat / 100)) : $price;
$price_ttc = price2num($price_ttc, 'MU');
if ($newminprice !== '' || $newminprice === 0) {
@ -2179,12 +2179,34 @@ class Product extends CommonObject
$localtax1 = $localtaxes_array['1'];
$localtaxtype2 = $localtaxes_array['2'];
$localtax2 = $localtaxes_array['3'];
} else // old method. deprecated because ot can't retrieve type
{
$localtaxtype1 = '0';
$localtax1 = get_localtax($newvat, 1);
$localtaxtype2 = '0';
$localtax2 = get_localtax($newvat, 2);
} else {
// if array empty, we try to use the vat code
if (!empty($newdefaultvatcode)) {
global $mysoc;
// Get record from code
$sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
$sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c";
$sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$this->db->escape($mysoc->country_code)."'";
$sql .= " AND t.taux = ".((float) $newdefaultvatcode)." AND t.active = 1";
$sql .= " AND t.code = '".$this->db->escape($newdefaultvatcode)."'";
$resql = $this->db->query($sql);
if ($resql) {
$obj = $this->db->fetch_object($resql);
if ($obj) {
$npr = $obj->recuperableonly;
$localtax1 = $obj->localtax1;
$localtax2 = $obj->localtax2;
$localtaxtype1 = $obj->localtax1_type;
$localtaxtype2 = $obj->localtax2_type;
}
}
} else {
// old method. deprecated because we can't retrieve type
$localtaxtype1 = '0';
$localtax1 = get_localtax($newvat, 1);
$localtaxtype2 = '0';
$localtax2 = get_localtax($newvat, 2);
}
}
if (empty($localtax1)) {
$localtax1 = 0; // If = '' then = 0

View File

@ -791,16 +791,11 @@ END;
// Barcode type
print '<tr>';
print '<td>'.$langs->trans('BarcodeType').'</td>';
print '<td>'.$langs->trans('GencodBuyPrice').'</td>';
print '<td>';
print $formbarcode->selectBarcodeType(($rowid ? $object->supplier_fk_barcode_type : getDolGlobalint("PRODUIT_DEFAULT_BARCODE_TYPE")), 'fk_barcode_type', 1);
print '</td>';
print '</tr>';
// Barcode value
print '<tr>';
print '<td>'.$langs->trans('BarcodeValue').'</td>';
print '<td>'.img_picto('', 'barcode', 'class="pictofixedwidth"').'<input class="flat" name="barcode" value="'.($rowid ? $object->supplier_barcode : '').'"></td>';
print img_picto('', 'barcode', 'class="pictofixedwidth"');
print $formbarcode->selectBarcodeType((GETPOSTISSET('fk_barcode_type') ? GETPOST('fk_barcode_type', 'int') : ($rowid ? $object->supplier_fk_barcode_type : getDolGlobalint("PRODUIT_DEFAULT_BARCODE_TYPE"))), 'fk_barcode_type', 1);
print ' <input class="flat" name="barcode" value="'.(GETPOSTISSET('barcode') ? GETPOST('barcode') : ($rowid ? $object->supplier_barcode : '')).'"></td>';
print '</tr>';
}

View File

@ -136,6 +136,7 @@ if (empty($reshook)) {
$npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0;
$localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0';
// If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes
if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) {
// We look into database using code (we can't use get_localtax() because it depends on buyer that is not known). Same in create product.
$vatratecode = $reg[1];
@ -229,7 +230,7 @@ if (empty($reshook)) {
$oldnpr = $object->tva_npr;
//$localtaxarray=array('0'=>$localtax1_type,'1'=>$localtax1,'2'=>$localtax2_type,'3'=>$localtax2);
$localtaxarray = array(); // We do not store localtaxes into product, we will use instead the "vat code" to retrieve them.
$localtaxarray = array(); // We do not store localtaxes into product, we will use instead the "vat code" to retrieve them when required.
$level = 0;
$ret = $object->updatePrice($oldprice, $oldpricebasetype, $user, $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode);
@ -877,7 +878,7 @@ dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref');
print '<div class="fichecenter">';
print '<div class="underbanner clearboth"></div>';
print '<table class="border tableforfield" width="100%">';
print '<table class="border tableforfield centpercent">';
// Price per customer segment/level
if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
@ -1000,6 +1001,7 @@ if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_
print '<!-- Default VAT Rate -->';
print '<tr><td class="titlefieldcreate">'.$langs->trans("DefaultTaxRate").'</td><td>';
// TODO We show localtax from $object, but this properties may not be correct. Only value $object->default_vat_code is guaranted.
$positiverates = '';
if (price2num($object->tva_tx)) {
$positiverates .= ($positiverates ? '<span class="opacitymedium">/</span>' : '').price2num($object->tva_tx);
@ -1013,6 +1015,7 @@ if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_
if (empty($positiverates)) {
$positiverates = '0';
}
print vatrate($positiverates.($object->default_vat_code ? ' ('.$object->default_vat_code.')' : ''), true, $object->tva_npr, 1);
/*
if ($object->default_vat_code)
@ -1026,7 +1029,7 @@ if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_
print '<br>';
print '<table class="noborder tableforfield" width="100%">';
print '<table class="noborder tableforfield centpercent">';
print '<tr class="liste_titre"><td>';
print $langs->trans("PriceLevel");
if ($user->admin) {

View File

@ -533,7 +533,7 @@ print $hookmanager->resPrint;
// Status
if (!empty($arrayfields['t.statut']['checked'])) {
print '<td class="liste_titre center">';
print $form->selectarray('search_status', $warehouse->statuts, $search_status, 1, 0, 0, '', 1);
print $form->selectarray('search_status', $warehouse->statuts, $search_status, 1, 0, 0, '', 1, 0, 0, '', 'onrightofpage');
print '</td>';
}

View File

@ -544,7 +544,7 @@ class Tasks extends DolibarrApi
$this->task->timespent_datehour = $newdate;
$this->task->timespent_withhour = 1;
$this->task->timespent_duration = $duration;
$this->task->timespent_fk_user = $user_id;
$this->task->timespent_fk_user = $uid;
$this->task->timespent_note = $note;
$result = $this->task->addTimeSpent(DolibarrApiAccess::$user, 0);

View File

@ -306,7 +306,7 @@ class Project extends CommonObject
'tms' =>array('type'=>'timestamp', 'label'=>'DateModificationShort', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>405),
'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserCreation', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'position'=>410),
'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModification', 'enabled'=>1, 'visible'=>0, 'position'=>415),
'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>0, 'position'=>420),
'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'position'=>420),
'email_msgid'=>array('type'=>'varchar(255)', 'label'=>'EmailMsgID', 'enabled'=>1, 'visible'=>-1, 'position'=>450, 'help'=>'EmailMsgIDWhenSourceisEmail'),
'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'position'=>500),
);

View File

@ -414,7 +414,7 @@ $distinct = 'DISTINCT'; // We add distinct until we are added a protection to be
$sql = "SELECT ".$distinct." p.rowid as id, p.ref, p.title, p.fk_statut as status, p.fk_opp_status, p.public, p.fk_user_creat,";
$sql .= " p.datec as date_creation, p.dateo as date_start, p.datee as date_end, p.opp_amount, p.opp_percent, (p.opp_amount*p.opp_percent/100) as opp_weighted_amount, p.tms as date_update, p.budget_amount,";
$sql .= " p.usage_opportunity, p.usage_task, p.usage_bill_time, p.usage_organize_event,";
$sql .= " p.email_msgid,";
$sql .= " p.email_msgid, p.import_key,";
$sql .= " p.accept_conference_suggestions, p.accept_booth_suggestions, p.price_registration, p.price_booth,";
$sql .= " s.rowid as socid, s.nom as name, s.name_alias as alias, s.email, s.email, s.phone, s.fax, s.address, s.town, s.zip, s.fk_pays, s.client, s.code_client,";
$sql .= " country.code as country_code,";
@ -1170,6 +1170,11 @@ if (!empty($arrayfields['p.email_msgid']['checked'])) {
print '<td class="liste_titre">';
print '</td>';
}
if (!empty($arrayfields['p.import_key']['checked'])) {
// Import key
print '<td class="liste_titre">';
print '</td>';
}
if (!empty($arrayfields['p.fk_statut']['checked'])) {
print '<td class="liste_titre nowrap right">';
$arrayofstatus = array();
@ -1177,7 +1182,7 @@ if (!empty($arrayfields['p.fk_statut']['checked'])) {
$arrayofstatus[$key] = $langs->trans($val);
}
$arrayofstatus['99'] = $langs->trans("NotClosed").' ('.$langs->trans('Draft').' + '.$langs->trans('Opened').')';
print $form->selectarray('search_status', $arrayofstatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', 'minwidth75imp maxwidth125 selectarrowonleft');
print $form->selectarray('search_status', $arrayofstatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', 'minwidth75imp maxwidth125 selectarrowonleft onrightofpage');
print ajax_combobox('search_status');
print '</td>';
}
@ -1278,6 +1283,9 @@ if (!empty($arrayfields['p.tms']['checked'])) {
if (!empty($arrayfields['p.email_msgid']['checked'])) {
print_liste_field_titre($arrayfields['p.email_msgid']['label'], $_SERVER["PHP_SELF"], "p.email_msgid", "", $param, '', $sortfield, $sortorder, 'center ');
}
if (!empty($arrayfields['p.import_key']['checked'])) {
print_liste_field_titre($arrayfields['p.import_key']['label'], $_SERVER["PHP_SELF"], "p.import_key", "", $param, '', $sortfield, $sortorder, '');
}
if (!empty($arrayfields['p.fk_statut']['checked'])) {
print_liste_field_titre($arrayfields['p.fk_statut']['label'], $_SERVER["PHP_SELF"], "p.fk_statut", "", $param, '', $sortfield, $sortorder, 'right ');
}
@ -1731,6 +1739,13 @@ while ($i < $imaxinloop) {
print '</td>';
if (!$i) $totalarray['nbfield']++;
}
// Import key
if (!empty($arrayfields['p.import_key']['checked'])) {
print '<td class="right">'.dol_escape_htmltag($obj->import_key).'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
}
// Status
if (!empty($arrayfields['p.fk_statut']['checked'])) {
print '<td class="right">'.$object->getLibStatut(5).'</td>';

View File

@ -685,7 +685,7 @@ if ($action == 'create' && $permissiontoadd) {
);
} else {
alert("'.dol_escape_js($langs->trans("FillFieldFirst")).'");
alert("'.dol_escape_js($langs->transnoentitiesnoconv("FillFieldFirst")).'");
}
});

View File

@ -701,8 +701,7 @@ class PaymentSalary extends CommonObject
$link = '<a href="'.DOL_URL_ROOT.'/salaries/payment_salary/card.php?id='.$this->id.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
$linkend = '</a>';
if ($withpicto) $result .= ($link.img_object($label, 'payment', 'class="classfortooltip"').$linkend.' ');
if ($withpicto && $withpicto != 2) $result .= ' ';
if ($withpicto) $result .= ($link.img_object($label, 'payment', 'class="classfortooltip pictofixedwidth"').$linkend);
if ($withpicto != 2) $result .= $link.($maxlen ?dol_trunc($this->ref, $maxlen) : $this->ref).$linkend;
}

View File

@ -544,7 +544,7 @@ class Salary extends CommonObject
$linkend = '</a>';
$result .= $linkstart;
if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright pictofixedwidth"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip pictofixedwidth"'), 0, 0, $notooltip ? 0 : 1);
if ($withpicto != 2) $result .= $this->ref;
$result .= $linkend;
//if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');

View File

@ -448,9 +448,10 @@ if (isModEnabled("banque")) {
// Amount
print '<td class="liste_titre right"><input name="search_amount" class="flat" type="text" size="8" value="'.$db->escape($search_amount).'"></td>';
//Status
print '<td class="liste_titre maxwidthonsmartphone right">';
$liststatus = array('0' => $langs->trans("Unpaid"), '1' => $langs->trans("Paid"));
print $form->selectarray('search_status', $liststatus, $search_status, 1);
print $form->selectarray('search_status', $liststatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', 'onrightofpage');
print '</td>';
// Extra fields

View File

@ -845,7 +845,7 @@ if ($resql) {
// Status
if (!empty($arrayfields['sp.fk_statut']['checked'])) {
print '<td class="liste_titre right">';
$formpropal->selectProposalStatus($search_status, 1, 0, 1, 'supplier', 'search_status', 'minwidth75imp');
$formpropal->selectProposalStatus($search_status, 1, 0, 1, 'supplier', 'search_status', 'minwidth75imp onrightofpage');
print '</td>';
}
// Action column

View File

@ -307,6 +307,9 @@ if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
$listofexpandedmodules = array();
print "\n";
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
@ -316,9 +319,9 @@ print '<td>'.$langs->trans("Module").'</td>';
if (($caneditperms && empty($objMod->rights_admin_allowed)) || empty($object->admin)) {
if ($caneditperms) {
print '<td class="center nowrap">';
print '<a class="reposition commonlink" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&token='.newToken().'&entity='.$entity.'&module=allmodules&confirm=yes">'.$langs->trans("All")."</a>";
print '<a class="reposition commonlink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&token='.newToken().'&entity='.$entity.'&module=allmodules&confirm=yes">'.$langs->trans("All")."</a>";
print ' / ';
print '<a class="reposition commonlink" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&token='.newToken().'&entity='.$entity.'&module=allmodules&confirm=yes">'.$langs->trans("None")."</a>";
print '<a class="reposition commonlink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&token='.newToken().'&entity='.$entity.'&module=allmodules&confirm=yes">'.$langs->trans("None")."</a>";
print '</td>';
} else {
print '<td>&nbsp;</td>';
@ -329,7 +332,7 @@ if (($caneditperms && empty($objMod->rights_admin_allowed)) || empty($object->ad
print '<td>&nbsp;</td>';
}
print '<td>'.$langs->trans("Permissions").'</td>';
print '<td></td>';
print '<td class="right nowrap">';
print '<a class="showallperms" title="'.dol_escape_htmltag($langs->trans("ShowAllPerms")).'" alt="'.dol_escape_htmltag($langs->trans("ShowAllPerms")).'" href="#">'.img_picto('', 'folder-open', 'class="paddingright"').'<span class="hideonsmartphone">'.$langs->trans("ExpandAll").'</span></a>';
print ' | ';
@ -417,9 +420,13 @@ $sql .= " ORDER BY r.family_position, r.module_position, r.module, r.id";
$result = $db->query($sql);
if ($result) {
$num = $db->num_rows($result);
$i = 0;
$i = 0; $j = 0;
$oldmod = '';
$cookietohidegroup = (empty($_COOKIE["DOLUSER_PERMS_HIDE_GRP"]) ? '' : preg_replace('/^,/', '', $_COOKIE["DOLUSER_PERMS_HIDE_GRP"]));
$cookietohidegrouparray = explode(',', $cookietohidegroup);
//var_dump($cookietohidegrouparray);
while ($i < $num) {
$obj = $db->fetch_object($result);
@ -469,53 +476,71 @@ if ($result) {
}
*/
$isexpanded = ($updatedmodulename == $obj->module || $module == "allmodules");
if (!$action) {
$isexpanded = 1; // By default (no action done) we have lines expanded
if (GETPOSTISSET('forbreakperms_'.$obj->module)) {
$ishidden = GETPOST('forbreakperms_'.$obj->module, 'int');
} elseif (in_array($j, $cookietohidegrouparray)) { // If j is among list of hidden group
$ishidden = 1;
} else {
$ishidden = 0;
}
$isexpanded = ! $ishidden;
//var_dump("isexpanded=".$isexpanded);
// Break found, it's a new module to catch
if (isset($obj->module) && ($oldmod <> $obj->module)) {
$oldmod = $obj->module;
$j++;
if (GETPOSTISSET('forbreakperms_'.$obj->module)) {
$ishidden = GETPOST('forbreakperms_'.$obj->module, 'int');
} elseif (in_array($j, $cookietohidegrouparray)) { // If j is among list of hidden group
$ishidden = 1;
} else {
$ishidden = 0;
}
$isexpanded = ! $ishidden;
//var_dump('$obj->module='.$obj->module.' isexpanded='.$isexpanded);
// Break detected, we get objMod
$objMod = $modules[$obj->module];
$picto = ($objMod->picto ? $objMod->picto : 'generic');
// Show break line
print '<tr class="oddeven">';
print '<td class="maxwidthonsmartphone tdoverflowonsmartphone">';
print '<tr class="oddeven trforbreakperms" data-hide-perms="'.$obj->module.'" data-j="'.$j.'">';
print '<td class="maxwidthonsmartphone tdoverflowonsmartphone tdforbreakperms" data-hide-perms="'.$obj->module.'">';
print '<input type="hidden" name="forbreakperms_'.$obj->module.'" id="idforbreakperms_'.$obj->module.'" css="cssforfieldishiden" data-j="'.$j.'" value="'.($isexpanded ? '0' : "1").'">';
print img_object('', $picto, 'class="pictoobjectwidth paddingright"').' '.$objMod->getName();
print '<a name="'.$objMod->getName().'"></a>';
print '</td>';
if (($caneditperms && empty($objMod->rights_admin_allowed)) || empty($object->admin)) {
if ($caneditperms) {
print '<td class="center nowrap permtohide_'.$obj->module.'"'.(!$isexpanded ? ' style="display:none"' : '').'>';
print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&token='.newToken().'&entity='.$entity.'&module='.$obj->module.'&confirm=yes&updatedmodulename='.$obj->module.'">'.$langs->trans("All")."</a>";
print '<td class="center wraponsmartphone permtohide_'.$obj->module.'"'.(!$isexpanded ? ' style="display:none"' : '').'>';
print '<a class="reposition alink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&token='.newToken().'&entity='.$entity.'&module='.$obj->module.'&confirm=yes&updatedmodulename='.$obj->module.'">'.$langs->trans("All")."</a>";
print ' / ';
print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&token='.newToken().'&entity='.$entity.'&module='.$obj->module.'&confirm=yes&updatedmodulename='.$obj->module.'">'.$langs->trans("None")."</a>";
print '<a class="reposition alink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&token='.newToken().'&entity='.$entity.'&module='.$obj->module.'&confirm=yes&updatedmodulename='.$obj->module.'">'.$langs->trans("None")."</a>";
print '</td>';
print '<td class="permtoshow_'.$obj->module.'"'.($isexpanded ? ' style="display:none"' : '').'>&nbsp;</td>';
print '<td class="permtoshow_'.$obj->module.' tdforbreakperms" data-hide-perms="'.$obj->module.'"'.($isexpanded ? ' style="display:none"' : '').'>&nbsp;</td>';
} else {
print '<td>&nbsp;</td>';
print '<td class="tdforbreakperms" data-hide-perms="'.$obj->module.'">&nbsp;</td>';
}
print '<td>&nbsp;</td>';
print '<td class="tdforbreakperms" data-hide-perms="'.$obj->module.'">&nbsp;</td>';
} else {
if ($caneditperms) {
print '<td class="center wraponsmartphone permtohide_'.$obj->module.'"'.(!$isexpanded ? ' style="display:none"' : '').'>';
print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&token='.newToken().'&entity='.$entity.'&module='.$obj->module.'&confirm=yes&updatedmodulename='.$obj->module.'">'.$langs->trans("All")."</a>";
/*print '<a class="reposition alink" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&token='.newToken().'&entity='.$entity.'&module='.$obj->module.'&confirm=yes&updatedmodulename='.$obj->module.'">'.$langs->trans("All")."</a>";
print ' / ';
print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&token='.newToken().'&entity='.$entity.'&module='.$obj->module.'&confirm=yes&updatedmodulename='.$obj->module.'">'.$langs->trans("None")."</a>";
print '<a class="reposition alink" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&token='.newToken().'&entity='.$entity.'&module='.$obj->module.'&confirm=yes&updatedmodulename='.$obj->module.'">'.$langs->trans("None")."</a>";
*/
print '</td>';
print '<td class="permtoshow_'.$obj->module.'"'.($isexpanded ? ' style="display:none"' : '').'>&nbsp;</td>';
print '<td class="permtoshow_'.$obj->module.' tdforbreakperms" data-hide-perms="'.$obj->module.'"'.($isexpanded ? ' style="display:none"' : '').'>&nbsp;</td>';
} else {
print '<td class="right"></td>';
print '<td class="right tdforbreakperms" data-hide-perms="'.$obj->module.'"></td>';
}
print '<td>&nbsp;</td>';
print '<td class="tdforbreakperms" data-hide-perms="'.$obj->module.'">&nbsp;</td>';
}
print '<td>&nbsp;</td>';
print '<td class="tdforbreakperms" data-hide-perms="'.$obj->module.'">&nbsp;</td>';
print '<td class="maxwidthonsmartphone right trforbreakperms" data-hide-perms="'.$obj->module.'" data-hidden-perms="'.($isexpanded ? '0' : "1").'">';
print '<td class="maxwidthonsmartphone right tdforbreakperms" data-hide-perms="'.$obj->module.'">';
print '<div class="switchfolderperms folderperms_'.$obj->module.'"'.($isexpanded ? ' style="display:none;"' : '').'>';
print img_picto('', 'folder', 'class="marginright"');
print '</div>';
@ -546,7 +571,8 @@ if ($result) {
print '</td>';
} elseif (in_array($obj->id, $permsuser)) { // Permission granted by user
if ($caneditperms) {
print '<td class="center"><a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delrights&token='.newToken().'&entity='.$entity.'&rights='.$obj->id.'&confirm=yes&updatedmodulename='.$obj->module.'">';
print '<td class="center">';
print '<a class="reposition addexpandedmodulesinparamlist" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&token='.newToken().'&entity='.$entity.'&rights='.$obj->id.'&confirm=yes&updatedmodulename='.$obj->module.'">';
//print img_edit_remove($langs->trans("Remove"));
print img_picto($langs->trans("Remove"), 'switch_on');
print '</a></td>';
@ -571,7 +597,8 @@ if ($result) {
} else {
// Do not own permission
if ($caneditperms) {
print '<td class="center"><a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&entity='.$entity.'&rights='.$obj->id.'&confirm=yes&token='.newToken().'&updatedmodulename='.$obj->module.'">';
print '<td class="center">';
print '<a class="reposition addexpandedmodulesinparamlist" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&entity='.$entity.'&rights='.$obj->id.'&confirm=yes&token='.newToken().'&updatedmodulename='.$obj->module.'">';
//print img_edit_add($langs->trans("Add"));
print img_picto($langs->trans("Add"), 'switch_off');
print '</a></td>';
@ -583,7 +610,8 @@ if ($result) {
} else {
// Do not own permission
if ($caneditperms) {
print '<td class="center"><a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&entity='.$entity.'&rights='.$obj->id.'&confirm=yes&token='.newToken().'&updatedmodulename='.$obj->module.'">';
print '<td class="center">';
print '<a class="reposition addexpandedmodulesinparamlist" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&entity='.$entity.'&rights='.$obj->id.'&confirm=yes&token='.newToken().'&updatedmodulename='.$obj->module.'">';
//print img_edit_add($langs->trans("Add"));
print img_picto($langs->trans("Add"), 'switch_off');
print '</a></td>';
@ -629,46 +657,74 @@ print '</table>';
print '</div>';
print '<script>';
print '$(".trforbreakperms").on("click", function(){
console.log("Click on trforbreakperms");
print '$(".tdforbreakperms:not(.alink)").on("click", function(){
console.log("Click on tdforbreakperms");
moduletohide = $(this).data("hide-perms");
if ($(this).data("hidden-perms") == 1){
j = $(this).data("j");
if ($("#idforbreakperms_"+moduletohide).val() == 1) {
console.log("idforbreakperms_"+moduletohide+" has value hidden=1");
$(".trtohide_"+moduletohide).show();
$(".permtoshow_"+moduletohide).hide();
$(".permtohide_"+moduletohide).show();
$(".folderperms_"+moduletohide).hide();
console.log()
$(".folderopenperms_"+moduletohide).show();
$(this).data("hidden-perms", 0);
$("#idforbreakperms_"+moduletohide).val("0");
} else {
console.log("idforbreakperms_"+moduletohide+" has value hidden=0");
$(".trtohide_"+moduletohide).hide();
$(".folderopenperms_"+moduletohide).hide();
$(".folderperms_"+moduletohide).show();
$(".permtoshow_"+moduletohide).show();
$(".permtohide_"+moduletohide).hide();
$(this).data("hidden-perms", 1);
$("#idforbreakperms_"+moduletohide).val("1");
}
})';
// Now rebuild the value for cookie
var hideuserperm="";
$(".trforbreakperms").each(function(index) {
//console.log( index + ": " + $( this ).data("j") + " " + $( this ).data("hide-perms") + " " + $("input[data-j="+(index+1)+"]").val());
if ($("input[data-j="+(index+1)+"]").val() == 1) {
hideuserperm=hideuserperm+","+(index+1);
}
});
// set cookie by js
date = new Date(); date.setTime(date.getTime()+(30*86400000));
if (hideuserperm) {
console.log("set cookie DOLUSER_PERMS_HIDE_GRP="+hideuserperm);
document.cookie = "DOLUSER_PERMS_HIDE_GRP=" + hideuserperm + "; expires=" + date.toGMTString() + "; path=/ ";
} else {
console.log("delete cookie DOLUSER_PERMS_HIDE_GRP");
document.cookie = "DOLUSER_PERMS_HIDE_GRP=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/ ";
}
});';
print "\n";
// Button expand / collapse all
print '$(".showallperms").on("click", function(){
console.log("Click on showallperms");
$(".trforbreakperms").each( function(){
if($(this).data("hidden-perms") != 0){
$(this).trigger("click");
}
})
})';
print "\n";
print '$(".hideallperms").on("click", function(){
console.log("Click on hideallperms");
$(".trforbreakperms").each( function(){
if($(this).data("hidden-perms") != 1){
$(this).trigger("click");
console.log("delete cookie DOLUSER_PERMS_HIDE_GRP from showallperms click");
document.cookie = "DOLUSER_PERMS_HIDE_GRP=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/ ";
$(".tdforbreakperms").each( function(){
moduletohide = $(this).data("hide-perms");
//console.log(moduletohide);
if ($("#idforbreakperms_"+moduletohide).val() != 0) {
$(this).trigger("click"); // emulate the click, so the cooki will be resaved
}
})
})';
});
$(".hideallperms").on("click", function(){
console.log("Click on hideallperms");
$(".tdforbreakperms").each( function(){
moduletohide = $(this).data("hide-perms");
//console.log(moduletohide);
if ($("#idforbreakperms_"+moduletohide).val() != 1) {
$(this).trigger("click"); // emulate the click, so the cooki will be resaved
}
})
});';
print "\n";
print '</script>';

View File

@ -2723,7 +2723,7 @@ $moreheadjs .= '<script type="text/javascript">'."\n";
$moreheadjs .= 'var indicatorBlockUI = \''.DOL_URL_ROOT."/theme/".$conf->theme."/img/working.gif".'\';'."\n";
$moreheadjs .= '</script>'."\n";
llxHeader($moreheadcss.$moreheadjs, $langs->trans("WebsiteSetup"), $helpurl, '', 0, 0, $arrayofjs, $arrayofcss, '', '', '<!-- Begin div class="fiche" -->'."\n".'<div class="fichebutwithotherclass">');
llxHeader($moreheadcss.$moreheadjs, $langs->trans("Website").(empty($website->ref) ? '' : ' - '.$website->ref), $helpurl, '', 0, 0, $arrayofjs, $arrayofcss, '', '', '<!-- Begin div class="fiche" -->'."\n".'<div class="fichebutwithotherclass">');
print "\n";
print '<!-- Open form for all page -->'."\n";

View File

@ -221,6 +221,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase
$result=testSqlAndScriptInject($test, 1);
$this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for SQL2a. Should find an attack on GET param and did not.');
$test = "delete\nfrom";
$result=testSqlAndScriptInject($test, 1);
$this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for SQL2b. Should find an attack on GET param and did not.');
$test = 'action=update& ... set ... =';
$result=testSqlAndScriptInject($test, 1);
$this->assertEquals(0, $result, 'Error on testSqlAndScriptInject for SQL2b. Should not find an attack on GET param and did.');
@ -332,7 +336,11 @@ class SecurityTest extends PHPUnit\Framework\TestCase
$test="Text with ' encoded with the numeric html entity converted into text entity &#39; (like when submited by CKEditor)";
$result=testSqlAndScriptInject($test, 0); // result must be 0
$this->assertEquals(0, $result, 'Error on testSqlAndScriptInject mmm');
$this->assertEquals(0, $result, 'Error on testSqlAndScriptInject mmm, result should be 0 and is not');
$test ='<a href="j&Tab;a&Tab;v&Tab;asc&NewLine;ri&Tab;pt:&lpar;a&Tab;l&Tab;e&Tab;r&Tab;t&Tab;(document.cookie)&rpar;">XSS</a>';
$result=testSqlAndScriptInject($test, 0);
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject nnn, result should be >= 1 and is not');
$test="/dolibarr/htdocs/index.php/".chr('246')."abc"; // Add the char %F6 into the variable
$result=testSqlAndScriptInject($test, 2);
@ -385,9 +393,8 @@ class SecurityTest extends PHPUnit\Framework\TestCase
$_POST["param16"]='<a style="z-index: 1000">abc</a>';
$_POST["param17"]='<span style="background-image: url(logout.php)">abc</span>';
$_POST["param18"]='<span style="background-image: url(...?...action=aaa)">abc</span>';
//$_POST["param13"]='javascript%26colon%26%23x3B%3Balert(1)';
//$_POST["param14"]='javascripT&javascript#x3a alert(1)';
$_POST["param19"]='<a href="j&Tab;a&Tab;v&Tab;asc&NewLine;ri&Tab;pt:&lpar;alert(document.cookie)&rpar;">XSS</a>';
//$_POST["param19"]='<a href="javascript:alert(document.cookie)">XSS</a>';
$result=GETPOST('id', 'int'); // Must return nothing
print __METHOD__." result=".$result."\n";
@ -507,7 +514,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase
print __METHOD__." result=".$result."\n";
$this->assertEquals(trim($_POST["param11"]), $result, 'Test an email string with alphawithlgt');
// Test with restricthtml we must remove html open/close tag and content but not htmlentities (we can decode html entities for ascii chars like &#110;)
// Test with restricthtml: we must remove html open/close tag and content but not htmlentities (we can decode html entities for ascii chars like &#110;)
$result=GETPOST("param6", 'restricthtml');
print __METHOD__." result param6=".$result."\n";
@ -541,6 +548,11 @@ class SecurityTest extends PHPUnit\Framework\TestCase
print __METHOD__." result=".$result."\n";
$this->assertEquals("<img onerror=alert(document.domain) src=>0xbeefed", $result, 'Test 15'); // The GETPOST return a harmull string
$result=GETPOST("param19", 'restricthtml');
print __METHOD__." result=".$result."\n";
$this->assertEquals('<a href="&lpar;alert(document.cookie)&rpar;">XSS</a>', $result, 'Test 19');
// Test with restricthtml + MAIN_RESTRICTHTML_ONLY_VALID_HTML to test disabling of bad atrributes
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 1;