dolibarr 21.0.0-alpha
list.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
3 * Copyright (C) 2013-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
4 * Copyright (C) 2014-2015 Ari Elbaz (elarifr) <github@accedinfo.com>
5 * Copyright (C) 2013-2021 Florian Henry <florian.henry@open-concept.pro>
6 * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
8 * Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
29require '../../main.inc.php';
30
31require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
34require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
35require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
36require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
40
41// Load translation files required by the page
42$langs->loadLangs(array("bills", "companies", "compta", "accountancy", "other", "productbatch", "products"));
43
44$action = GETPOST('action', 'aZ09');
45$massaction = GETPOST('massaction', 'alpha');
46$confirm = GETPOST('confirm', 'alpha');
47$toselect = GETPOST('toselect', 'array');
48$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'accountancycustomerlist'; // To manage different context of search
49$optioncss = GETPOST('optioncss', 'alpha');
50
51$default_account = GETPOSTINT('default_account');
52
53// Select Box
54$mesCasesCochees = GETPOST('toselect', 'array');
55
56// Search Getpost
57$search_societe = GETPOST('search_societe', 'alpha');
58$search_lineid = GETPOST('search_lineid', 'alpha'); // Can be '> 100'
59$search_ref = GETPOST('search_ref', 'alpha');
60$search_invoice = GETPOST('search_invoice', 'alpha');
61$search_label = GETPOST('search_label', 'alpha');
62$search_desc = GETPOST('search_desc', 'alpha');
63$search_amount = GETPOST('search_amount', 'alpha');
64$search_account = GETPOST('search_account', 'alpha');
65$search_vat = GETPOST('search_vat', 'alpha');
66$search_date_startday = GETPOSTINT('search_date_startday');
67$search_date_startmonth = GETPOSTINT('search_date_startmonth');
68$search_date_startyear = GETPOSTINT('search_date_startyear');
69$search_date_endday = GETPOSTINT('search_date_endday');
70$search_date_endmonth = GETPOSTINT('search_date_endmonth');
71$search_date_endyear = GETPOSTINT('search_date_endyear');
72$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver
73$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
74$search_country = GETPOST('search_country', 'aZ09');
75$search_tvaintra = GETPOST('search_tvaintra', 'alpha');
76
77// Define begin binding date
78if (empty($search_date_start) && getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
79 $search_date_start = $db->idate(getDolGlobalString('ACCOUNTING_DATE_START_BINDING'));
80}
81
82// Load variable for pagination
83$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : getDolGlobalString('ACCOUNTING_LIMIT_LIST_VENTILATION', $conf->liste_limit);
84$sortfield = GETPOST('sortfield', 'aZ09comma');
85$sortorder = GETPOST('sortorder', 'aZ09comma');
86$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
87if (empty($page) || $page < 0) {
88 $page = 0;
89}
90$offset = $limit * $page;
91$pageprev = $page - 1;
92$pagenext = $page + 1;
93if (!$sortfield) {
94 $sortfield = "f.datef, f.ref, l.rowid";
95}
96if (!$sortorder) {
97 if (getDolGlobalInt('ACCOUNTING_LIST_SORT_VENTILATION_TODO') > 0) {
98 $sortorder = "DESC";
99 } else {
100 $sortorder = "ASC";
101 }
102}
103
104// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
105$hookmanager->initHooks(array('accountancycustomerlist'));
106
107$formaccounting = new FormAccounting($db);
108$accountingAccount = new AccountingAccount($db);
109
110$chartaccountcode = dol_getIdFromCode($db, getDolGlobalInt('CHARTOFACCOUNTS'), 'accounting_system', 'rowid', 'pcg_version');
111
112// Security check
113if (!isModEnabled('accounting')) {
115}
116if ($user->socid > 0) {
118}
119if (!$user->hasRight('accounting', 'bind', 'write')) {
121}
122
123
124/*
125 * Actions
126 */
127
128if (GETPOST('cancel', 'alpha')) {
129 $action = 'list';
130 $massaction = '';
131}
132if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
133 $massaction = '';
134}
135
136$parameters = array();
137$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
138if ($reshook < 0) {
139 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
140}
141
142if (empty($reshook)) {
143 // Purge search criteria
144 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All test are required to be compatible with all browsers
145 $search_societe = '';
146 $search_lineid = '';
147 $search_ref = '';
148 $search_invoice = '';
149 $search_label = '';
150 $search_desc = '';
151 $search_amount = '';
152 $search_account = '';
153 $search_vat = '';
154 $search_date_startday = '';
155 $search_date_startmonth = '';
156 $search_date_startyear = '';
157 $search_date_endday = '';
158 $search_date_endmonth = '';
159 $search_date_endyear = '';
160 $search_date_start = '';
161 $search_date_end = '';
162 $search_country = '';
163 $search_tvaintra = '';
164 }
165
166 // Mass actions
167 $objectclass = 'AccountingAccount';
168 $permissiontoread = $user->hasRight('accounting', 'read');
169 $permissiontodelete = $user->hasRight('accounting', 'delete');
170 $uploaddir = $conf->accounting->dir_output;
171 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
172}
173
174
175if ($massaction == 'ventil' && $user->hasRight('accounting', 'bind', 'write')) {
176 $msg = '';
177
178 //print '<div><span style="color:red">' . $langs->trans("Processing") . '...</span></div>';
179 if (!empty($mesCasesCochees)) {
180 $msg = '<div>'.$langs->trans("SelectedLines").': '.count($mesCasesCochees).'</div>';
181 $msg .= '<div class="detail">';
182 $cpt = 0;
183 $ok = 0;
184 $ko = 0;
185
186 foreach ($mesCasesCochees as $maLigneCochee) {
187 $maLigneCourante = explode("_", $maLigneCochee);
188 $monId = $maLigneCourante[0];
189 $monCompte = GETPOST('codeventil'.$monId);
190
191 if ($monCompte <= 0) {
192 $msg .= '<div><span style="color:red">'.$langs->trans("Lineofinvoice").' '.$monId.' - '.$langs->trans("NoAccountSelected").'</span></div>';
193 $ko++;
194 } else {
195 $sql = " UPDATE ".MAIN_DB_PREFIX."facturedet";
196 $sql .= " SET fk_code_ventilation = ".((int) $monCompte);
197 $sql .= " WHERE rowid = ".((int) $monId);
198
199 $accountventilated = new AccountingAccount($db);
200 $accountventilated->fetch($monCompte, '', 1);
201
202 dol_syslog("accountancy/customer/list.php", LOG_DEBUG);
203 if ($db->query($sql)) {
204 $msg .= '<div><span style="color:green">'.$langs->trans("Lineofinvoice").' '.$monId.' - '.$langs->trans("VentilatedinAccount").' : '.length_accountg($accountventilated->account_number).'</span></div>';
205 $ok++;
206 } else {
207 $msg .= '<div><span style="color:red">'.$langs->trans("ErrorDB").' : '.$langs->trans("Lineofinvoice").' '.$monId.' - '.$langs->trans("NotVentilatedinAccount").' : '.length_accountg($accountventilated->account_number).'<br> <pre>'.$sql.'</pre></span></div>';
208 $ko++;
209 }
210 }
211
212 $cpt++;
213 }
214 $msg .= '</div>';
215 $msg .= '<div>'.$langs->trans("EndProcessing").'</div>';
216 }
217}
218
219if (GETPOST('sortfield') == 'f.datef, f.ref, l.rowid') {
220 $value = (GETPOST('sortorder') == 'asc,asc,asc' ? 0 : 1);
221 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
222 $res = dolibarr_set_const($db, "ACCOUNTING_LIST_SORT_VENTILATION_TODO", $value, 'yesno', 0, '', $conf->entity);
223}
224
225
226/*
227 * View
228 */
229
230$form = new Form($db);
231$formother = new FormOther($db);
232
233$help_url = 'EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double#Liaisons_comptables';
234
235llxHeader('', $langs->trans("CustomersVentilation"), $help_url, '', 0, 0, '', '', '', 'bodyforlist mod-accountancy accountancy-customer page-list');
236
237if (empty($chartaccountcode)) {
238 print $langs->trans("ErrorChartOfAccountSystemNotSelected");
239 // End of page
240 llxFooter();
241 $db->close();
242 exit;
243}
244
245// Customer Invoice lines
246$sql = "SELECT f.rowid as facid, f.ref, f.datef, f.type as ftype, f.situation_cycle_ref, f.fk_facture_source,";
247$sql .= " l.rowid, l.fk_product, l.description, l.total_ht, l.situation_percent, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,";
248$sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.tva_tx as tva_tx_prod,";
249if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
250 $sql .= " ppe.accountancy_code_sell as code_sell, ppe.accountancy_code_sell_intra as code_sell_intra, ppe.accountancy_code_sell_export as code_sell_export,";
251 $sql .= " ppe.accountancy_code_buy as code_buy, ppe.accountancy_code_buy_intra as code_buy_intra, ppe.accountancy_code_buy_export as code_buy_export,";
252} else {
253 $sql .= " p.accountancy_code_sell as code_sell, p.accountancy_code_sell_intra as code_sell_intra, p.accountancy_code_sell_export as code_sell_export,";
254 $sql .= " p.accountancy_code_buy as code_buy, p.accountancy_code_buy_intra as code_buy_intra, p.accountancy_code_buy_export as code_buy_export,";
255}
256$sql .= " p.tosell as status, p.tobuy as status_buy,";
257$sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export, aa4.rowid as aarowid_thirdparty,";
258$sql .= " co.code as country_code, co.label as country_label,";
259$sql .= " s.rowid as socid, s.nom as name, s.tva_intra, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur,";
260if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
261 $sql .= " spe.accountancy_code_customer as code_compta_client,";
262 $sql .= " spe.accountancy_code_supplier as code_compta_fournisseur,";
263 $sql .= " spe.accountancy_code_sell as company_code_sell";
264} else {
265 $sql .= " s.code_compta as code_compta_client,";
266 $sql .= " s.code_compta_fournisseur,";
267 $sql .= " s.accountancy_code_sell as company_code_sell";
268}
269$parameters = array();
270$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
271$sql .= $hookmanager->resPrint;
272$sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
273$sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc";
274if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
275 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity);
276}
277$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = s.fk_pays ";
278$sql .= " INNER JOIN ".MAIN_DB_PREFIX."facturedet as l ON f.rowid = l.fk_facture";
279$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = l.fk_product";
280if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
281 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity);
282}
283$alias_societe_perentity = !getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED') ? "s" : "spe";
284$alias_product_perentity = !getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED') ? "p" : "ppe";
285$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON " . $alias_product_perentity . ".accountancy_code_sell = aa.account_number AND aa.active = 1 AND aa.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa.entity = ".$conf->entity;
286$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON " . $alias_product_perentity . ".accountancy_code_sell_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity;
287$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON " . $alias_product_perentity . ".accountancy_code_sell_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity;
288$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON " . $alias_societe_perentity . ".accountancy_code_sell = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity;
289
290$sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0";
291$sql .= " AND l.product_type <= 2";
292// Add search filter like
293if ($search_societe) {
294 $sql .= natural_search('s.nom', $search_societe);
295}
296if ($search_lineid) {
297 $sql .= natural_search("l.rowid", $search_lineid, 1);
298}
299if (strlen(trim($search_invoice))) {
300 $sql .= natural_search("f.ref", $search_invoice);
301}
302if (strlen(trim($search_ref))) {
303 $sql .= natural_search("p.ref", $search_ref);
304}
305if (strlen(trim($search_label))) {
306 $sql .= natural_search("p.label", $search_label);
307}
308if (strlen(trim($search_desc))) {
309 $sql .= natural_search("l.description", $search_desc);
310}
311if (strlen(trim($search_amount))) {
312 $sql .= natural_search("l.total_ht", $search_amount, 1);
313}
314if (strlen(trim($search_account))) {
315 $sql .= natural_search("aa.account_number", $search_account);
316}
317if (strlen(trim($search_vat))) {
318 $sql .= natural_search("l.tva_tx", price2num($search_vat), 1);
319}
320if ($search_date_start) {
321 $sql .= " AND f.datef >= '".$db->idate($search_date_start)."'";
322}
323if ($search_date_end) {
324 $sql .= " AND f.datef <= '".$db->idate($search_date_end)."'";
325}
326if (strlen(trim($search_country))) {
327 $arrayofcode = getCountriesInEEC();
328 $country_code_in_EEC = $country_code_in_EEC_without_me = '';
329 foreach ($arrayofcode as $key => $value) {
330 $country_code_in_EEC .= ($country_code_in_EEC ? "," : "")."'".$value."'";
331 if ($value != $mysoc->country_code) {
332 $country_code_in_EEC_without_me .= ($country_code_in_EEC_without_me ? "," : "")."'".$value."'";
333 }
334 }
335 if ($search_country == 'special_allnotme') {
336 $sql .= " AND co.code <> '".$db->escape($mysoc->country_code)."'";
337 } elseif ($search_country == 'special_eec') {
338 $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC, 1).")";
339 } elseif ($search_country == 'special_eecnotme') {
340 $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC_without_me, 1).")";
341 } elseif ($search_country == 'special_noteec') {
342 $sql .= " AND co.code NOT IN (".$db->sanitize($country_code_in_EEC, 1).")";
343 } else {
344 $sql .= natural_search("co.code", $search_country);
345 }
346}
347if (strlen(trim($search_tvaintra))) {
348 $sql .= natural_search("s.tva_intra", $search_tvaintra);
349}
350if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
351 $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_SITUATION.")";
352} else {
353 $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_DEPOSIT.",".Facture::TYPE_SITUATION.")";
354}
355$sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy
356
357// Add where from hooks
358$parameters = array();
359$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
360$sql .= $hookmanager->resPrint;
361
362$sql .= $db->order($sortfield, $sortorder);
363
364// Count total nb of records
365$nbtotalofrecords = '';
366if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
367 $result = $db->query($sql);
368 $nbtotalofrecords = $db->num_rows($result);
369 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
370 $page = 0;
371 $offset = 0;
372 }
373}
374
375$sql .= $db->plimit($limit + 1, $offset);
376
377dol_syslog("accountancy/customer/list.php", LOG_DEBUG);
378// MAX_JOIN_SIZE can be very low (ex: 300000) on some limited configurations (ex: https://www.online.net/fr/hosting/online-perso)
379// This big SELECT command may exceed the MAX_JOIN_SIZE limit => Therefore we use SQL_BIG_SELECTS=1 to disable the MAX_JOIN_SIZE security
380if ($db->type == 'mysqli') {
381 $db->query("SET SQL_BIG_SELECTS=1");
382}
383
384$result = $db->query($sql);
385if ($result) {
386 $num_lines = $db->num_rows($result);
387 $i = 0;
388
389 $arrayofselected = is_array($toselect) ? $toselect : array();
390
391 $param = '';
392 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
393 $param .= '&contextpage='.urlencode($contextpage);
394 }
395 if ($limit > 0 && $limit != $conf->liste_limit) {
396 $param .= '&limit='.((int) $limit);
397 }
398 if ($search_societe) {
399 $param .= '&search_societe='.urlencode($search_societe);
400 }
401 if ($search_lineid) {
402 $param .= '&search_lineid='.urlencode((string) ($search_lineid));
403 }
404 if ($search_date_startday) {
405 $param .= '&search_date_startday='.urlencode((string) ($search_date_startday));
406 }
407 if ($search_date_startmonth) {
408 $param .= '&search_date_startmonth='.urlencode((string) ($search_date_startmonth));
409 }
410 if ($search_date_startyear) {
411 $param .= '&search_date_startyear='.urlencode((string) ($search_date_startyear));
412 }
413 if ($search_date_endday) {
414 $param .= '&search_date_endday='.urlencode((string) ($search_date_endday));
415 }
416 if ($search_date_endmonth) {
417 $param .= '&search_date_endmonth='.urlencode((string) ($search_date_endmonth));
418 }
419 if ($search_date_endyear) {
420 $param .= '&search_date_endyear='.urlencode((string) ($search_date_endyear));
421 }
422 if ($search_invoice) {
423 $param .= '&search_invoice='.urlencode($search_invoice);
424 }
425 if ($search_ref) {
426 $param .= '&search_ref='.urlencode($search_ref);
427 }
428 if ($search_label) {
429 $param .= '&search_label='.urlencode($search_label);
430 }
431 if ($search_desc) {
432 $param .= '&search_desc='.urlencode($search_desc);
433 }
434 if ($search_amount) {
435 $param .= '&search_amount='.urlencode($search_amount);
436 }
437 if ($search_vat) {
438 $param .= '&search_vat='.urlencode($search_vat);
439 }
440 if ($search_country) {
441 $param .= "&search_country=".urlencode($search_country);
442 }
443 if ($search_tvaintra) {
444 $param .= "&search_tvaintra=".urlencode($search_tvaintra);
445 }
446
447 $arrayofmassactions = array(
448 'set_default_account' => img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("ConfirmPreselectAccount"),
449 'ventil' => img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Ventilate")
450 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
451 //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
452 );
453 //if ($user->hasRight('mymodule', 'supprimer')) $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
454 //if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
455 $massactionbutton = '';
456 if ($massaction !== 'set_default_account') {
457 $massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1);
458 }
459
460 print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">'."\n";
461 print '<input type="hidden" name="action" value="ventil">';
462 if ($optioncss != '') {
463 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
464 }
465 print '<input type="hidden" name="token" value="'.newToken().'">';
466 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
467 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
468 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
469 print '<input type="hidden" name="page" value="'.$page.'">';
470
471 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
472 print_barre_liste($langs->trans("InvoiceLines"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
473
474 if ($massaction == 'set_default_account') {
475 $formquestion = array();
476 $formquestion[] = array('type' => 'other',
477 'name' => 'set_default_account',
478 'label' => $langs->trans("AccountancyCode"),
479 'value' => $formaccounting->select_account('', 'default_account', 1, array(), 0, 0, 'maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'));
480 print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmPreselectAccount"), $langs->trans("ConfirmPreselectAccountQuestion", count($toselect)), "confirm_set_default_account", $formquestion, 1, 0, 200, 500, 1);
481 }
482
483 print '<span class="opacitymedium">'.$langs->trans("DescVentilTodoCustomer").'</span></br><br>';
484
485 if (!empty($msg)) {
486 print $msg.'<br>';
487 }
488
489 $moreforfilter = '';
490
491 print '<div class="div-table-responsive">';
492 print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
493
494 // We add search filter
495 print '<tr class="liste_titre_filter">';
496 print '<td class="liste_titre"><input type="text" class="flat maxwidth25" name="search_lineid" value="'.dol_escape_htmltag($search_lineid).'"></td>';
497 print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="'.dol_escape_htmltag($search_invoice).'"></td>';
498 print '<td class="liste_titre center">';
499 print '<div class="nowrapfordate">';
500 print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
501 print '</div>';
502 print '<div class="nowrapfordate">';
503 print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
504 print '</div>';
505 print '</td>';
506 print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="'.dol_escape_htmltag($search_ref).'"></td>';
507 print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="search_desc" value="'.dol_escape_htmltag($search_desc).'"></td>';
508 print '<td class="liste_titre right"><input type="text" class="flat maxwidth50 right" name="search_amount" value="'.dol_escape_htmltag($search_amount).'"></td>';
509 print '<td class="liste_titre right"><input type="text" class="flat maxwidth50 right" name="search_vat" placeholder="%" size="1" value="'.dol_escape_htmltag($search_vat).'"></td>';
510 print '<td class="liste_titre"><input type="text" class="flat maxwidth75imp" name="search_societe" value="'.dol_escape_htmltag($search_societe).'"></td>';
511 print '<td class="liste_titre">';
512 print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth100', 'code2', 1, 0, 1);
513 //print '<input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '">';
514 print '</td>';
515 print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_tvaintra" value="'.dol_escape_htmltag($search_tvaintra).'"></td>';
516 print '<td class="liste_titre"></td>';
517 print '<td class="liste_titre"></td>';
518 print '<td class="center liste_titre">';
519 $searchpicto = $form->showFilterButtons();
520 print $searchpicto;
521 print '</td>';
522 print "</tr>\n";
523
524 print '<tr class="liste_titre">';
525 print_liste_field_titre("LineId", $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder);
526 print_liste_field_titre("Invoice", $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder);
527 print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, '', $sortfield, $sortorder, 'center ');
528 print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder);
529 //print_liste_field_titre("ProductLabel", $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder);
530 print_liste_field_titre("ProductDescription", $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder);
531 print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "l.total_ht", "", $param, '', $sortfield, $sortorder, 'right maxwidth50 ');
532 print_liste_field_titre("VATRate", $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, '', $sortfield, $sortorder, 'right ', '', 1);
533 print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "s.nom", "", $param, '', $sortfield, $sortorder);
534 print_liste_field_titre("Country", $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder);
535 print_liste_field_titre("VATIntraShort", $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder);
536 print_liste_field_titre("DataUsedToSuggestAccount", '', '', '', '', '', '', '', 'nowraponall ');
537 print_liste_field_titre("AccountAccountingSuggest", '', '', '', '', '', '', '', 'center ');
538 $checkpicto = '';
539 if ($massactionbutton) {
540 $checkpicto = $form->showCheckAddButtons('checkforselect', 1);
541 }
542 print_liste_field_titre($checkpicto, '', '', '', '', '', '', '', 'center ');
543 print "</tr>\n";
544
545 $thirdpartystatic = new Societe($db);
546 $facture_static = new Facture($db);
547 $facture_static_det = new FactureLigne($db);
548 $product_static = new Product($db);
549
550
551 $accountingaccount_codetotid_cache = array();
552
553 while ($i < min($num_lines, $limit)) {
554 $objp = $db->fetch_object($result);
555
556 // product_type: 0 = service, 1 = product
557 // if product does not exist we use the value of product_type provided in facturedet to define if this is a product or service
558 // issue : if we change product_type value in product DB it should differ from the value stored in facturedet DB !
559 $code_sell_l = '';
560 $code_sell_p = '';
561 $code_sell_t = '';
562
563 $thirdpartystatic->id = $objp->socid;
564 $thirdpartystatic->name = $objp->name;
565 $thirdpartystatic->client = $objp->client;
566 $thirdpartystatic->fournisseur = $objp->fournisseur;
567 $thirdpartystatic->code_client = $objp->code_client;
568 $thirdpartystatic->code_compta = $objp->code_compta_client; // For backward compatibility
569 $thirdpartystatic->code_compta_client = $objp->code_compta_client;
570 $thirdpartystatic->code_fournisseur = $objp->code_fournisseur;
571 $thirdpartystatic->code_compta_fournisseur = $objp->code_compta_fournisseur;
572 $thirdpartystatic->email = $objp->email;
573 $thirdpartystatic->country_code = $objp->country_code;
574 $thirdpartystatic->tva_intra = $objp->tva_intra;
575 $thirdpartystatic->code_compta_product = $objp->company_code_sell; // The accounting account for product stored on thirdparty object (for level3 suggestion)
576
577 $product_static->ref = $objp->product_ref;
578 $product_static->id = $objp->product_id;
579 $product_static->type = $objp->type;
580 $product_static->label = $objp->product_label;
581 $product_static->status = $objp->status;
582 $product_static->status_buy = $objp->status_buy;
583 $product_static->accountancy_code_sell = $objp->code_sell;
584 $product_static->accountancy_code_sell_intra = $objp->code_sell_intra;
585 $product_static->accountancy_code_sell_export = $objp->code_sell_export;
586 $product_static->accountancy_code_buy = $objp->code_buy;
587 $product_static->accountancy_code_buy_intra = $objp->code_buy_intra;
588 $product_static->accountancy_code_buy_export = $objp->code_buy_export;
589 $product_static->tva_tx = $objp->tva_tx_prod;
590
591 $facture_static->ref = $objp->ref;
592 $facture_static->id = $objp->facid;
593 $facture_static->type = $objp->ftype;
594 $facture_static->date = $db->jdate($objp->datef);
595 $facture_static->fk_facture_source = $objp->fk_facture_source;
596
597 $facture_static_det->id = $objp->rowid;
598 $facture_static_det->total_ht = $objp->total_ht;
599 $facture_static_det->tva_tx = $objp->tva_tx_line;
600 $facture_static_det->vat_src_code = $objp->vat_src_code;
601 $facture_static_det->product_type = $objp->type_l;
602 $facture_static_det->desc = $objp->description;
603
604 $accountingAccountArray = array(
605 'dom' => $objp->aarowid,
606 'intra' => $objp->aarowid_intra,
607 'export' => $objp->aarowid_export,
608 'thirdparty' => $objp->aarowid_thirdparty);
609
610 $code_sell_p_notset = '';
611 $code_sell_t_notset = '';
612
613 $suggestedid = 0;
614
615 $return = $accountingAccount->getAccountingCodeToBind($thirdpartystatic, $mysoc, $product_static, $facture_static, $facture_static_det, $accountingAccountArray, 'customer');
616 if (!is_array($return) && $return < 0) {
617 setEventMessage($accountingAccount->error, 'errors');
618 } else {
619 $suggestedid = $return['suggestedid'];
620 $suggestedaccountingaccountfor = $return['suggestedaccountingaccountfor'];
621 $suggestedaccountingaccountbydefaultfor = $return['suggestedaccountingaccountbydefaultfor'];
622 $code_sell_l = $return['code_l'];
623 $code_sell_p = $return['code_p'];
624 $code_sell_t = $return['code_t'];
625 }
626 //var_dump($return);
627
628 if (!empty($code_sell_p)) {
629 // Value was defined previously
630 } else {
631 $code_sell_p_notset = 'color:orange';
632 }
633 if (empty($code_sell_l) && empty($code_sell_p)) {
634 $code_sell_p_notset = 'color:red';
635 }
636 if ($suggestedaccountingaccountfor == 'eecwithoutvatnumber' && empty($code_sell_p_notset)) {
637 $code_sell_p_notset = 'color:orange';
638 }
639
640 // $code_sell_l is now default code of product/service
641 // $code_sell_p is now code of product/service
642 // $code_sell_t is now code of thirdparty
643 //var_dump($code_sell_l.' - '.$code_sell_p.' - '.$code_sell_t.' -> '.$suggestedid.' ('.$suggestedaccountingaccountbydefaultfor.' '.$suggestedaccountingaccountfor.')');
644
645 print '<tr class="oddeven">';
646
647 // Line id
648 print '<td>'.$facture_static_det->id.'</td>';
649
650 // Ref Invoice
651 print '<td class="nowraponall">'.$facture_static->getNomUrl(1).'</td>';
652
653 print '<td class="center">'.dol_print_date($facture_static->date, 'day').'</td>';
654
655 // Ref Product
656 print '<td class="tdoverflowmax100">';
657 if ($product_static->id > 0) {
658 print $product_static->getNomUrl(1);
659 }
660 if ($product_static->label) {
661 print '<br><span class="opacitymedium small">'.dol_escape_htmltag($product_static->label).'</span>';
662 }
663 print '</td>';
664
665 // Description of line
666 $text = dolGetFirstLineOfText(dol_string_nohtmltag($facture_static_det->desc, 1));
667 print '<td class="tdoverflowmax150 small classfortooltip" title="'.dol_escape_htmltag($text).'">';
668 $trunclength = getDolGlobalInt('ACCOUNTING_LENGTH_DESCRIPTION');
669 print dol_trunc($text, $trunclength);
670 print '</td>';
671
672 // Amount
673 print '<td class="right nowraponall amount">';
674
675 // Create a compensation rate for old situation invoice feature.
676 $situation_ratio = 1;
677 if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
678 if ($objp->situation_cycle_ref) {
679 // Avoid divide by 0
680 if ($objp->situation_percent == 0) {
681 $situation_ratio = 0;
682 } else {
683 $line = new FactureLigne($db);
684 $line->fetch($objp->rowid);
685
686 // Situation invoices handling
687 $prev_progress = $line->get_prev_progress($objp->facid);
688
689 $situation_ratio = ($objp->situation_percent - $prev_progress) / $objp->situation_percent;
690 }
691 }
692 print price($objp->total_ht * $situation_ratio);
693 } else {
694 print price($objp->total_ht);
695 }
696 print '</td>';
697
698 // Vat rate
699 $code_vat_differ = '';
700 if ($product_static->tva_tx !== $facture_static_det->tva_tx && price2num($product_static->tva_tx) && price2num($facture_static_det->tva_tx)) { // Note: having a vat rate of 0 is often the normal case when sells is intra b2b or to export
701 $code_vat_differ = 'warning bold';
702 }
703 print '<td class="right'.($code_vat_differ ? ' '.$code_vat_differ : '').'">';
704 print vatrate($facture_static_det->tva_tx.($facture_static_det->vat_src_code ? ' ('.$facture_static_det->vat_src_code.')' : ''));
705 print '</td>';
706
707 // Thirdparty
708 print '<td class="tdoverflowmax100">'.$thirdpartystatic->getNomUrl(1, 'customer').'</td>';
709
710 // Country
711 $labelcountry = ($objp->country_code && ($langs->trans("Country".$objp->country_code) != "Country".$objp->country_code)) ? $langs->trans("Country".$objp->country_code) : $objp->country_label;
712 print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($labelcountry).'">';
713 print dol_escape_htmltag($labelcountry);
714 print '</td>';
715
716 // VAT Num
717 print '<td class="tdoverflowmax80" title="'.dol_escape_htmltag($objp->tva_intra).'">'.dol_escape_htmltag($objp->tva_intra).'</td>';
718
719 // Found accounts
720 print '<td class="small">';
721 // First show default account for any products
722 $s = '1. '.(($facture_static_det->product_type == 1) ? $langs->trans("DefaultForService") : $langs->trans("DefaultForProduct")).': ';
723 $shelp = '';
724 $ttype = 'help';
725 if ($suggestedaccountingaccountbydefaultfor == 'eec') {
726 $shelp .= $langs->trans("SaleEEC");
727 } elseif ($suggestedaccountingaccountbydefaultfor == 'eecwithvat') {
728 $shelp = $langs->trans("SaleEECWithVAT");
729 } elseif ($suggestedaccountingaccountbydefaultfor == 'eecwithoutvatnumber') {
730 $shelp = $langs->trans("SaleEECWithoutVATNumber");
731 $ttype = 'warning';
732 } elseif ($suggestedaccountingaccountbydefaultfor == 'export') {
733 $shelp .= $langs->trans("SaleExport");
734 }
735 $s .= ($code_sell_l > 0 ? length_accountg($code_sell_l) : '<span style="'.$code_sell_p_notset.'">'.$langs->trans("NotDefined").'</span>');
736 print $form->textwithpicto($s, $shelp, 1, $ttype, '', 0, 2, '', 1);
737 // Now show account for product
738 if ($product_static->id > 0) {
739 print '<br>';
740 $s = '2. '.(($facture_static_det->product_type == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': ';
741 $shelp = '';
742 $ttype = 'help';
743 if ($suggestedaccountingaccountfor == 'eec') {
744 $shelp = $langs->trans("SaleEEC");
745 } elseif ($suggestedaccountingaccountfor == 'eecwithvat') {
746 $shelp = $langs->trans("SaleEECWithVAT");
747 } elseif ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') {
748 $shelp = $langs->trans("SaleEECWithoutVATNumber");
749 $ttype = 'warning';
750 } elseif ($suggestedaccountingaccountfor == 'export') {
751 $shelp = $langs->trans("SaleExport");
752 }
753 $s .= (empty($code_sell_p) ? '<span style="'.$code_sell_p_notset.'">'.$langs->trans("NotDefined").'</span>' : length_accountg($code_sell_p));
754 print $form->textwithpicto($s, $shelp, 1, $ttype, '', 0, 2, '', 1);
755 } else {
756 print '<br>';
757 $s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': ';
758 $shelp = '';
759 $s .= $langs->trans("NotDefined");
760 print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
761 }
762 if (getDolGlobalString('ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY')) {
763 print '<br>';
764 $s = '3. '.(($facture_static_det->product_type == 1) ? $langs->trans("ServiceForThisThirdparty") : $langs->trans("ProductForThisThirdparty")).': ';
765 $shelp = '';
766 $s .= ($code_sell_t > 0 ? length_accountg($code_sell_t) : '<span style="'.$code_sell_t_notset.'">'.$langs->trans("NotDefined").'</span>');
767 print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
768 }
769 print '</td>';
770
771 // Suggested accounting account
772 print '<td>';
773 print $formaccounting->select_account(($default_account > 0 && $confirm === 'yes' && in_array($objp->rowid."_".$i, $toselect)) ? $default_account : $suggestedid, 'codeventil'.$facture_static_det->id, 1, array(), 0, 0, 'codeventil maxwidth150 maxwidthonsmartphone', 'cachewithshowemptyone');
774 print '</td>';
775
776 // Column with checkbox
777 print '<td class="center">';
778 $ischecked = 0;
779 if (!empty($suggestedid) && $suggestedaccountingaccountfor != '' && $suggestedaccountingaccountfor != 'eecwithoutvatnumber') {
780 $ischecked = 1;
781 }
782
783 if (!empty($toselect)) {
784 $ischecked = 0;
785 if (in_array($objp->rowid."_".$i, $toselect)) {
786 $ischecked = 1;
787 }
788 }
789
790 print '<input type="checkbox" class="flat checkforselect checkforselect'.$facture_static_det->id.'" name="toselect[]" value="'.$facture_static_det->id."_".$i.'"'.($ischecked ? " checked" : "").'/>';
791 print '</td>';
792
793 print '</tr>';
794 $i++;
795 }
796 if ($num_lines == 0) {
797 print '<tr><td colspan="13"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
798 }
799
800 print '</table>';
801 print "</div>";
802
803 print '</form>';
804} else {
805 print $db->error();
806}
807if ($db->type == 'mysqli') {
808 $db->query("SET SQL_BIG_SELECTS=0"); // Enable MAX_JOIN_SIZE limitation
809}
810
811// Add code to auto check the box when we select an account
812print '<script type="text/javascript">
813jQuery(document).ready(function() {
814 jQuery(".codeventil").change(function() {
815 var s=$(this).attr("id").replace("codeventil", "")
816 console.log(s+" "+$(this).val());
817 if ($(this).val() == -1) jQuery(".checkforselect"+s).prop("checked", false);
818 else jQuery(".checkforselect"+s).prop("checked", true);
819 });
820});
821</script>';
822
823// End of page
824llxFooter();
825$db->close();
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:70
Class to manage accounting accounts.
Class to manage invoices.
const TYPE_REPLACEMENT
Replacement invoice.
const TYPE_SITUATION
Situation invoice.
const TYPE_DEPOSIT
Deposit invoice.
const TYPE_CREDIT_NOTE
Credit note invoice.
Class to manage invoice lines.
Class to manage generation of HTML components for accounting management.
Class to manage generation of HTML components Only common components must be here.
Class permettant la generation de composants html autre Only common components are here.
Class to manage products or services.
Class to manage third parties objects (customers, suppliers, prospects...)
getCountriesInEEC()
Return list of countries that are inside the EEC (European Economic Community) Note: Try to keep this...
llxFooter()
Footer empty.
Definition document.php:107
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dolGetFirstLineOfText($text, $nboflines=1, $charset='UTF-8')
Return first line of text.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0)
Set event message in dol_events session object.
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='')
Return an id or code from a code or id.
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.