dolibarr  x.y.z
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-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
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 
29 require '../../main.inc.php';
30 
31 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
39 require_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 $show_files = GETPOST('show_files', 'int');
47 $confirm = GETPOST('confirm', 'alpha');
48 $toselect = GETPOST('toselect', 'array');
49 $optioncss = GETPOST('optioncss', 'alpha');
50 $default_account = GETPOST('default_account', 'int');
51 
52 // Select Box
53 $mesCasesCochees = GETPOST('toselect', 'array');
54 
55 // Search Getpost
56 $search_societe = GETPOST('search_societe', 'alpha');
57 $search_lineid = GETPOST('search_lineid', 'int');
58 $search_ref = GETPOST('search_ref', 'alpha');
59 $search_invoice = GETPOST('search_invoice', 'alpha');
60 $search_label = GETPOST('search_label', 'alpha');
61 $search_desc = GETPOST('search_desc', 'alpha');
62 $search_amount = GETPOST('search_amount', 'alpha');
63 $search_account = GETPOST('search_account', 'alpha');
64 $search_vat = GETPOST('search_vat', 'alpha');
65 $search_date_startday = GETPOST('search_date_startday', 'int');
66 $search_date_startmonth = GETPOST('search_date_startmonth', 'int');
67 $search_date_startyear = GETPOST('search_date_startyear', 'int');
68 $search_date_endday = GETPOST('search_date_endday', 'int');
69 $search_date_endmonth = GETPOST('search_date_endmonth', 'int');
70 $search_date_endyear = GETPOST('search_date_endyear', 'int');
71 $search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver
72 $search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
73 $search_country = GETPOST('search_country', 'alpha');
74 $search_tvaintra = GETPOST('search_tvaintra', 'alpha');
75 
76 $btn_ventil = GETPOST('ventil', 'alpha');
77 
78 // Load variable for pagination
79 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
80 $sortfield = GETPOST('sortfield', 'aZ09comma');
81 $sortorder = GETPOST('sortorder', 'aZ09comma');
82 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
83 if (empty($page) || $page < 0) {
84  $page = 0;
85 }
86 $offset = $limit * $page;
87 $pageprev = $page - 1;
88 $pagenext = $page + 1;
89 if (!$sortfield) {
90  $sortfield = "f.datef, f.ref, l.rowid";
91 }
92 if (!$sortorder) {
93  if ($conf->global->ACCOUNTING_LIST_SORT_VENTILATION_TODO > 0) {
94  $sortorder = "DESC";
95  }
96 }
97 
98 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
99 $hookmanager->initHooks(array('accountancycustomerlist'));
100 
101 $formaccounting = new FormAccounting($db);
102 $accountingAccount = new AccountingAccount($db);
103 
104 $chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
105 
106 // Security check
107 if (!isModEnabled('accounting')) {
108  accessforbidden();
109 }
110 if ($user->socid > 0) {
111  accessforbidden();
112 }
113 if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
114  accessforbidden();
115 }
116 
117 
118 /*
119  * Actions
120  */
121 
122 if (GETPOST('cancel', 'alpha')) {
123  $action = 'list'; $massaction = '';
124 }
125 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
126  $massaction = '';
127 }
128 
129 $parameters = array();
130 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
131 if ($reshook < 0) {
132  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
133 }
134 
135 if (empty($reshook)) {
136  // Purge search criteria
137  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
138  $search_societe = '';
139  $search_lineid = '';
140  $search_ref = '';
141  $search_invoice = '';
142  $search_label = '';
143  $search_desc = '';
144  $search_amount = '';
145  $search_account = '';
146  $search_vat = '';
147  $search_date_startday = '';
148  $search_date_startmonth = '';
149  $search_date_startyear = '';
150  $search_date_endday = '';
151  $search_date_endmonth = '';
152  $search_date_endyear = '';
153  $search_date_start = '';
154  $search_date_end = '';
155  $search_country = '';
156  $search_tvaintra = '';
157  }
158 
159  // Mass actions
160  $objectclass = 'AccountingAccount';
161  $permissiontoread = $user->hasRight('accounting', 'read');
162  $permissiontodelete = $user->hasRight('accounting', 'delete');
163  $uploaddir = $conf->accounting->dir_output;
164  include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
165 }
166 
167 
168 if ($massaction == 'ventil' && $user->rights->accounting->bind->write) {
169  $msg = '';
170 
171  //print '<div><span style="color:red">' . $langs->trans("Processing") . '...</span></div>';
172  if (!empty($mesCasesCochees)) {
173  $msg = '<div>'.$langs->trans("SelectedLines").': '.count($mesCasesCochees).'</div>';
174  $msg .= '<div class="detail">';
175  $cpt = 0;
176  $ok = 0;
177  $ko = 0;
178 
179  foreach ($mesCasesCochees as $maLigneCochee) {
180  $maLigneCourante = explode("_", $maLigneCochee);
181  $monId = $maLigneCourante[0];
182  $monCompte = GETPOST('codeventil'.$monId);
183 
184  if ($monCompte <= 0) {
185  $msg .= '<div><span style="color:red">'.$langs->trans("Lineofinvoice").' '.$monId.' - '.$langs->trans("NoAccountSelected").'</span></div>';
186  $ko++;
187  } else {
188  $sql = " UPDATE ".MAIN_DB_PREFIX."facturedet";
189  $sql .= " SET fk_code_ventilation = ".((int) $monCompte);
190  $sql .= " WHERE rowid = ".((int) $monId);
191 
192  $accountventilated = new AccountingAccount($db);
193  $accountventilated->fetch($monCompte, '', 1);
194 
195  dol_syslog("accountancy/customer/list.php", LOG_DEBUG);
196  if ($db->query($sql)) {
197  $msg .= '<div><span style="color:green">'.$langs->trans("Lineofinvoice").' '.$monId.' - '.$langs->trans("VentilatedinAccount").' : '.length_accountg($accountventilated->account_number).'</span></div>';
198  $ok++;
199  } else {
200  $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>';
201  $ko++;
202  }
203  }
204 
205  $cpt++;
206  }
207  $msg .= '</div>';
208  $msg .= '<div>'.$langs->trans("EndProcessing").'</div>';
209  }
210 }
211 
212 
213 
214 /*
215  * View
216  */
217 
218 $form = new Form($db);
219 $formother = new FormOther($db);
220 
221 llxHeader('', $langs->trans("Ventilation"));
222 
223 if (empty($chartaccountcode)) {
224  print $langs->trans("ErrorChartOfAccountSystemNotSelected");
225  // End of page
226  llxFooter();
227  $db->close();
228  exit;
229 }
230 
231 // Customer Invoice lines
232 $sql = "SELECT f.rowid as facid, f.ref, f.datef, f.type as ftype, f.fk_facture_source,";
233 $sql .= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,";
234 $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,";
235 if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
236  $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,";
237  $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,";
238 } else {
239  $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,";
240  $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,";
241 }
242 $sql .= " p.tosell as status, p.tobuy as status_buy,";
243 $sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export, aa4.rowid as aarowid_thirdparty,";
244 $sql .= " co.code as country_code, co.label as country_label,";
245 $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,";
246 if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) {
247  $sql .= " spe.accountancy_code_customer as code_compta_client,";
248  $sql .= " spe.accountancy_code_supplier as code_compta_fournisseur,";
249  $sql .= " spe.accountancy_code_sell as company_code_sell";
250 } else {
251  $sql .= " s.code_compta as code_compta_client,";
252  $sql .= " s.code_compta_fournisseur,";
253  $sql .= " s.accountancy_code_sell as company_code_sell";
254 }
255 $parameters = array();
256 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
257 $sql .= $hookmanager->resPrint;
258 $sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
259 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc";
260 if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) {
261  $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity);
262 }
263 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = s.fk_pays ";
264 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."facturedet as l ON f.rowid = l.fk_facture";
265 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = l.fk_product";
266 if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
267  $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity);
268 }
269 $alias_societe_perentity = empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED) ? "s" : "spe";
270 $alias_product_perentity = empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED) ? "p" : "ppe";
271 $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;
272 $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;
273 $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;
274 $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;
275 
276 $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0";
277 $sql .= " AND l.product_type <= 2";
278 // Define begin binding date
279 if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) {
280  $sql .= " AND f.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'";
281 }
282 // Add search filter like
283 if ($search_societe) {
284  $sql .= natural_search('s.nom', $search_societe);
285 }
286 if ($search_lineid) {
287  $sql .= natural_search("l.rowid", $search_lineid, 1);
288 }
289 if (strlen(trim($search_invoice))) {
290  $sql .= natural_search("f.ref", $search_invoice);
291 }
292 if (strlen(trim($search_ref))) {
293  $sql .= natural_search("p.ref", $search_ref);
294 }
295 if (strlen(trim($search_label))) {
296  $sql .= natural_search("p.label", $search_label);
297 }
298 if (strlen(trim($search_desc))) {
299  $sql .= natural_search("l.description", $search_desc);
300 }
301 if (strlen(trim($search_amount))) {
302  $sql .= natural_search("l.total_ht", $search_amount, 1);
303 }
304 if (strlen(trim($search_account))) {
305  $sql .= natural_search("aa.account_number", $search_account);
306 }
307 if (strlen(trim($search_vat))) {
308  $sql .= natural_search("l.tva_tx", price2num($search_vat), 1);
309 }
310 if ($search_date_start) {
311  $sql .= " AND f.datef >= '".$db->idate($search_date_start)."'";
312 }
313 if ($search_date_end) {
314  $sql .= " AND f.datef <= '".$db->idate($search_date_end)."'";
315 }
316 if (strlen(trim($search_country))) {
317  $arrayofcode = getCountriesInEEC();
318  $country_code_in_EEC = $country_code_in_EEC_without_me = '';
319  foreach ($arrayofcode as $key => $value) {
320  $country_code_in_EEC .= ($country_code_in_EEC ? "," : "")."'".$value."'";
321  if ($value != $mysoc->country_code) {
322  $country_code_in_EEC_without_me .= ($country_code_in_EEC_without_me ? "," : "")."'".$value."'";
323  }
324  }
325  if ($search_country == 'special_allnotme') {
326  $sql .= " AND co.code <> '".$db->escape($mysoc->country_code)."'";
327  } elseif ($search_country == 'special_eec') {
328  $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC, 1).")";
329  } elseif ($search_country == 'special_eecnotme') {
330  $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC_without_me, 1).")";
331  } elseif ($search_country == 'special_noteec') {
332  $sql .= " AND co.code NOT IN (".$db->sanitize($country_code_in_EEC, 1).")";
333  } else {
334  $sql .= natural_search("co.code", $search_country);
335  }
336 }
337 if (strlen(trim($search_tvaintra))) {
338  $sql .= natural_search("s.tva_intra", $search_tvaintra);
339 }
340 if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
341  $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_SITUATION.")";
342 } else {
343  $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_DEPOSIT.",".Facture::TYPE_SITUATION.")";
344 }
345 $sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy
346 
347 // Add where from hooks
348 $parameters = array();
349 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
350 $sql .= $hookmanager->resPrint;
351 
352 $sql .= $db->order($sortfield, $sortorder);
353 
354 // Count total nb of records
355 $nbtotalofrecords = '';
356 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
357  $result = $db->query($sql);
358  $nbtotalofrecords = $db->num_rows($result);
359  if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
360  $page = 0;
361  $offset = 0;
362  }
363 }
364 
365 $sql .= $db->plimit($limit + 1, $offset);
366 
367 dol_syslog("accountancy/customer/list.php", LOG_DEBUG);
368 // MAX_JOIN_SIZE can be very low (ex: 300000) on some limited configurations (ex: https://www.online.net/fr/hosting/online-perso)
369 // 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
370 if ($db->type == 'mysqli') {
371  $db->query("SET SQL_BIG_SELECTS=1");
372 }
373 
374 $result = $db->query($sql);
375 if ($result) {
376  $num_lines = $db->num_rows($result);
377  $i = 0;
378 
379  $arrayofselected = is_array($toselect) ? $toselect : array();
380 
381  $param = '';
382  if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
383  $param .= '&contextpage='.urlencode($contextpage);
384  }
385  if ($limit > 0 && $limit != $conf->liste_limit) {
386  $param .= '&limit='.urlencode($limit);
387  }
388  if ($search_societe) {
389  $param .= '&search_societe='.urlencode($search_societe);
390  }
391  if ($search_lineid) {
392  $param .= '&search_lineid='.urlencode($search_lineid);
393  }
394  if ($search_date_startday) {
395  $param .= '&search_date_startday='.urlencode($search_date_startday);
396  }
397  if ($search_date_startmonth) {
398  $param .= '&search_date_startmonth='.urlencode($search_date_startmonth);
399  }
400  if ($search_date_startyear) {
401  $param .= '&search_date_startyear='.urlencode($search_date_startyear);
402  }
403  if ($search_date_endday) {
404  $param .= '&search_date_endday='.urlencode($search_date_endday);
405  }
406  if ($search_date_endmonth) {
407  $param .= '&search_date_endmonth='.urlencode($search_date_endmonth);
408  }
409  if ($search_date_endyear) {
410  $param .= '&search_date_endyear='.urlencode($search_date_endyear);
411  }
412  if ($search_invoice) {
413  $param .= '&search_invoice='.urlencode($search_invoice);
414  }
415  if ($search_ref) {
416  $param .= '&search_ref='.urlencode($search_ref);
417  }
418  if ($search_label) {
419  $param .= '&search_label='.urlencode($search_label);
420  }
421  if ($search_desc) {
422  $param .= '&search_desc='.urlencode($search_desc);
423  }
424  if ($search_amount) {
425  $param .= '&search_amount='.urlencode($search_amount);
426  }
427  if ($search_vat) {
428  $param .= '&search_vat='.urlencode($search_vat);
429  }
430  if ($search_country) {
431  $param .= "&search_country=".urlencode($search_country);
432  }
433  if ($search_tvaintra) {
434  $param .= "&search_tvaintra=".urlencode($search_tvaintra);
435  }
436 
437  $arrayofmassactions = array(
438  'ventil'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Ventilate")
439  ,'set_default_account'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("ConfirmPreselectAccount")
440  //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
441  //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
442  );
443  //if ($user->rights->mymodule->supprimer) $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
444  //if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
445  if ($massaction !== 'set_default_account') {
446  $massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1);
447  }
448 
449  print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">'."\n";
450  print '<input type="hidden" name="action" value="ventil">';
451  if ($optioncss != '') {
452  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
453  }
454  print '<input type="hidden" name="token" value="'.newToken().'">';
455  print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
456  print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
457  print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
458  print '<input type="hidden" name="page" value="'.$page.'">';
459 
460  print_barre_liste($langs->trans("InvoiceLines"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
461 
462  if ($massaction == 'set_default_account') {
463  $formquestion[]=array('type' => 'other',
464  'name' => 'set_default_account',
465  'label' => $langs->trans("AccountancyCode"),
466  'value' => $formaccounting->select_account('', 'default_account', 1, array(), 0, 0, 'maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'));
467  print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmPreselectAccount"), $langs->trans("ConfirmPreselectAccountQuestion", count($toselect)), "confirm_set_default_account", $formquestion, 1, 0, 200, 500, 1);
468  }
469 
470  print '<span class="opacitymedium">'.$langs->trans("DescVentilTodoCustomer").'</span></br><br>';
471 
472  if (!empty($msg)) {
473  print $msg.'<br>';
474  }
475 
476  $moreforfilter = '';
477 
478  print '<div class="div-table-responsive">';
479  print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
480 
481  // We add search filter
482  print '<tr class="liste_titre_filter">';
483  print '<td class="liste_titre"><input type="text" class="flat maxwidth25" name="search_lineid" value="'.dol_escape_htmltag($search_lineid).'"></td>';
484  print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="'.dol_escape_htmltag($search_invoice).'"></td>';
485  print '<td class="liste_titre center">';
486  print '<div class="nowrap">';
487  print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
488  print '</div>';
489  print '<div class="nowrap">';
490  print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
491  print '</div>';
492  print '</td>';
493  print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="'.dol_escape_htmltag($search_ref).'"></td>';
494  print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="search_desc" value="'.dol_escape_htmltag($search_desc).'"></td>';
495  print '<td class="liste_titre right"><input type="text" class="flat maxwidth50 right" name="search_amount" value="'.dol_escape_htmltag($search_amount).'"></td>';
496  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>';
497  print '<td class="liste_titre"><input type="text" class="flat maxwidth75imp" name="search_societe" value="'.dol_escape_htmltag($search_societe).'"></td>';
498  print '<td class="liste_titre">';
499  print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth100', 'code2', 1, 0, 1);
500  //print '<input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '">';
501  print '</td>';
502  print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_tvaintra" value="'.dol_escape_htmltag($search_tvaintra).'"></td>';
503  print '<td class="liste_titre"></td>';
504  print '<td class="liste_titre"></td>';
505  print '<td class="center liste_titre">';
506  $searchpicto = $form->showFilterButtons();
507  print $searchpicto;
508  print '</td>';
509  print "</tr>\n";
510 
511  print '<tr class="liste_titre">';
512  print_liste_field_titre("LineId", $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder);
513  print_liste_field_titre("Invoice", $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder);
514  print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, '', $sortfield, $sortorder, 'center ');
515  print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder);
516  //print_liste_field_titre("ProductLabel", $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder);
517  print_liste_field_titre("ProductDescription", $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder);
518  print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "l.total_ht", "", $param, '', $sortfield, $sortorder, 'right maxwidth50 ');
519  print_liste_field_titre("VATRate", $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, '', $sortfield, $sortorder, 'right ', '', 1);
520  print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "s.nom", "", $param, '', $sortfield, $sortorder);
521  print_liste_field_titre("Country", $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder);
522  print_liste_field_titre("VATIntraShort", $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder);
523  print_liste_field_titre("AccountAccountingSuggest", '', '', '', '', '', '', '', 'nowraponall ');
524  print_liste_field_titre("IntoAccount", '', '', '', '', '', '', '', 'center ');
525  $checkpicto = '';
526  if ($massactionbutton) {
527  $checkpicto = $form->showCheckAddButtons('checkforselect', 1);
528  }
529  print_liste_field_titre($checkpicto, '', '', '', '', '', '', '', 'center ');
530  print "</tr>\n";
531 
532  $thirdpartystatic = new Societe($db);
533  $facture_static = new Facture($db);
534  $facture_static_det = new FactureLigne($db);
535  $product_static = new Product($db);
536 
537 
538  $accountingaccount_codetotid_cache = array();
539 
540  while ($i < min($num_lines, $limit)) {
541  $objp = $db->fetch_object($result);
542 
543  // product_type: 0 = service, 1 = product
544  // if product does not exist we use the value of product_type provided in facturedet to define if this is a product or service
545  // issue : if we change product_type value in product DB it should differ from the value stored in facturedet DB !
546  $code_sell_l = '';
547  $code_sell_p = '';
548  $code_sell_t = '';
549 
550  $thirdpartystatic->id = $objp->socid;
551  $thirdpartystatic->name = $objp->name;
552  $thirdpartystatic->client = $objp->client;
553  $thirdpartystatic->fournisseur = $objp->fournisseur;
554  $thirdpartystatic->code_client = $objp->code_client;
555  $thirdpartystatic->code_compta = $objp->code_compta_client; // For backward compatibility
556  $thirdpartystatic->code_compta_client = $objp->code_compta_client;
557  $thirdpartystatic->code_fournisseur = $objp->code_fournisseur;
558  $thirdpartystatic->code_compta_fournisseur = $objp->code_compta_fournisseur;
559  $thirdpartystatic->email = $objp->email;
560  $thirdpartystatic->country_code = $objp->country_code;
561  $thirdpartystatic->tva_intra = $objp->tva_intra;
562  $thirdpartystatic->code_compta_product = $objp->company_code_sell; // The accounting account for product stored on thirdparty object (for level3 suggestion)
563 
564  $product_static->ref = $objp->product_ref;
565  $product_static->id = $objp->product_id;
566  $product_static->type = $objp->type;
567  $product_static->label = $objp->product_label;
568  $product_static->status = $objp->status;
569  $product_static->status_buy = $objp->status_buy;
570  $product_static->accountancy_code_sell = $objp->code_sell;
571  $product_static->accountancy_code_sell_intra = $objp->code_sell_intra;
572  $product_static->accountancy_code_sell_export = $objp->code_sell_export;
573  $product_static->accountancy_code_buy = $objp->code_buy;
574  $product_static->accountancy_code_buy_intra = $objp->code_buy_intra;
575  $product_static->accountancy_code_buy_export = $objp->code_buy_export;
576  $product_static->tva_tx = $objp->tva_tx_prod;
577 
578  $facture_static->ref = $objp->ref;
579  $facture_static->id = $objp->facid;
580  $facture_static->type = $objp->ftype;
581  $facture_static->date = $db->jdate($objp->datef);
582  $facture_static->fk_facture_source = $objp->fk_facture_source;
583 
584  $facture_static_det->id = $objp->rowid;
585  $facture_static_det->total_ht = $objp->total_ht;
586  $facture_static_det->tva_tx = $objp->tva_tx_line;
587  $facture_static_det->vat_src_code = $objp->vat_src_code;
588  $facture_static_det->product_type = $objp->type_l;
589  $facture_static_det->desc = $objp->description;
590 
591  $accountingAccountArray = array(
592  'dom'=>$objp->aarowid,
593  'intra'=>$objp->aarowid_intra,
594  'export'=>$objp->aarowid_export,
595  'thirdparty' =>$objp->aarowid_thirdparty);
596 
597  $code_sell_p_notset = '';
598  $code_sell_t_notset = '';
599 
600  $suggestedid = 0;
601 
602  $return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $mysoc, $product_static, $facture_static, $facture_static_det, $accountingAccountArray, 'customer');
603  if (!is_array($return) && $return<0) {
604  setEventMessage($accountingAccount->error, 'errors');
605  } else {
606  $suggestedid=$return['suggestedid'];
607  $suggestedaccountingaccountfor=$return['suggestedaccountingaccountfor'];
608  $suggestedaccountingaccountbydefaultfor=$return['suggestedaccountingaccountbydefaultfor'];
609  $code_sell_l=$return['code_l'];
610  $code_sell_p=$return['code_p'];
611  $code_sell_t=$return['code_t'];
612  }
613  //var_dump($return);
614 
615  if (!empty($code_sell_p)) {
616  // Value was defined previously
617  } else {
618  $code_sell_p_notset = 'color:orange';
619  }
620  if (empty($code_sell_l) && empty($code_sell_p)) {
621  $code_sell_p_notset = 'color:red';
622  }
623  if ($suggestedaccountingaccountfor == 'eecwithoutvatnumber' && empty($code_sell_p_notset)) {
624  $code_sell_p_notset = 'color:orange';
625  }
626 
627  // $code_sell_l is now default code of product/service
628  // $code_sell_p is now code of product/service
629  // $code_sell_t is now code of thirdparty
630  //var_dump($code_sell_l.' - '.$code_sell_p.' - '.$code_sell_t.' -> '.$suggestedid.' ('.$suggestedaccountingaccountbydefaultfor.' '.$suggestedaccountingaccountfor.')');
631 
632  print '<tr class="oddeven">';
633 
634  // Line id
635  print '<td>'.$facture_static_det->id.'</td>';
636 
637  // Ref Invoice
638  print '<td class="nowraponall">'.$facture_static->getNomUrl(1).'</td>';
639 
640  print '<td class="center">'.dol_print_date($facture_static->date, 'day').'</td>';
641 
642  // Ref Product
643  print '<td class="tdoverflowmax150">';
644  if ($product_static->id > 0) {
645  print $product_static->getNomUrl(1);
646  }
647  if ($product_static->label) {
648  print '<br><span class="opacitymedium small">'.dol_escape_htmltag($product_static->label).'</span>';
649  }
650  print '</td>';
651 
652  // Description
653  print '<td class="tdoverflowonsmartphone small">';
654  $text = dolGetFirstLineOfText(dol_string_nohtmltag($facture_static_det->desc, 1));
655  $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION;
656  print $form->textwithtooltip(dol_trunc($text, $trunclength), $facture_static_det->desc);
657  print '</td>';
658 
659  print '<td class="right nowraponall amount">';
660  print price($objp->total_ht);
661  print '</td>';
662 
663  // Vat rate
664  $code_vat_differ = '';
665  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
666  $code_vat_differ = 'warning bold';
667  }
668  print '<td class="right'.($code_vat_differ?' '.$code_vat_differ:'').'">';
669  print vatrate($facture_static_det->tva_tx.($facture_static_det->vat_src_code ? ' ('.$facture_static_det->vat_src_code.')' : ''));
670  print '</td>';
671 
672  // Thirdparty
673  print '<td class="tdoverflowmax100">'.$thirdpartystatic->getNomUrl(1, 'customer').'</td>';
674 
675  // Country
676  $labelcountry = ($objp->country_code && ($langs->trans("Country".$objp->country_code) != "Country".$objp->country_code)) ? $langs->trans("Country".$objp->country_code) : $objp->country_label;
677  print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($labelcountry).'">';
678  print dol_escape_htmltag($labelcountry);
679  print '</td>';
680 
681  // VAT Num
682  print '<td class="tdoverflowmax80" title="'.dol_escape_htmltag($objp->tva_intra).'">'.dol_escape_htmltag($objp->tva_intra).'</td>';
683 
684  // Found accounts
685  print '<td class="small">';
686  $s = '1. '.(($facture_static_det->product_type == 1) ? $langs->trans("DefaultForService") : $langs->trans("DefaultForProduct")).': ';
687  $shelp = '';
688  if ($suggestedaccountingaccountbydefaultfor == 'eec') {
689  $shelp .= $langs->trans("SaleEEC");
690  } elseif ($suggestedaccountingaccountbydefaultfor == 'export') {
691  $shelp .= $langs->trans("SaleExport");
692  }
693  $s .= ($code_sell_l > 0 ? length_accountg($code_sell_l) : '<span style="'.$code_sell_p_notset.'">'.$langs->trans("NotDefined").'</span>');
694  print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
695  if ($product_static->id > 0) {
696  print '<br>';
697  $s = '2. '.(($facture_static_det->product_type == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': ';
698  $shelp = ''; $ttype = 'help';
699  if ($suggestedaccountingaccountfor == 'eec') {
700  $shelp = $langs->trans("SaleEEC");
701  } elseif ($suggestedaccountingaccountfor == 'eecwithvat') {
702  $shelp = $langs->trans("SaleEECWithVAT");
703  } elseif ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') {
704  $shelp = $langs->trans("SaleEECWithoutVATNumber");
705  $ttype = 'warning';
706  } elseif ($suggestedaccountingaccountfor == 'export') {
707  $shelp = $langs->trans("SaleExport");
708  }
709  $s .= (empty($code_sell_p) ? '<span style="'.$code_sell_p_notset.'">'.$langs->trans("NotDefined").'</span>' : length_accountg($code_sell_p));
710  print $form->textwithpicto($s, $shelp, 1, $ttype, '', 0, 2, '', 1);
711  } else {
712  print '<br>';
713  $s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': ';
714  $shelp = '';
715  $s .= $langs->trans("NotDefined");
716  print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
717  }
718  if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) {
719  print '<br>';
720  $s = '3. '.(($facture_static_det->product_type == 1) ? $langs->trans("ServiceForThisThirdparty") : $langs->trans("ProductForThisThirdparty")).': ';
721  $shelp = '';
722  $s .= ($code_sell_t > 0 ? length_accountg($code_sell_t) : '<span style="'.$code_sell_t_notset.'">'.$langs->trans("NotDefined").'</span>');
723  print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
724  }
725  print '</td>';
726 
727  // Suggested accounting account
728  print '<td>';
729  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');
730  print '</td>';
731 
732  // Column with checkbox
733  print '<td class="center">';
734  $ischecked = 0;
735  if (!empty($suggestedid) && $suggestedaccountingaccountfor != '' && $suggestedaccountingaccountfor != 'eecwithoutvatnumber') {
736  $ischecked = 1;
737  }
738 
739  if (!empty($toselect)) {
740  $ischecked = 0;
741  if (in_array($objp->rowid."_".$i, $toselect)) {
742  $ischecked=1;
743  }
744  }
745 
746  print '<input type="checkbox" class="flat checkforselect checkforselect'.$facture_static_det->id.'" name="toselect[]" value="'.$facture_static_det->id."_".$i.'"'.($ischecked ? " checked" : "").'/>';
747  print '</td>';
748 
749  print '</tr>';
750  $i++;
751  }
752  if ($num_lines == 0) {
753  print '<tr><td colspan="13"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
754  }
755 
756  print '</table>';
757  print "</div>";
758 
759  print '</form>';
760 } else {
761  print $db->error();
762 }
763 if ($db->type == 'mysqli') {
764  $db->query("SET SQL_BIG_SELECTS=0"); // Enable MAX_JOIN_SIZE limitation
765 }
766 
767 // Add code to auto check the box when we select an account
768 print '<script type="text/javascript">
769 jQuery(document).ready(function() {
770  jQuery(".codeventil").change(function() {
771  var s=$(this).attr("id").replace("codeventil", "")
772  console.log(s+" "+$(this).val());
773  if ($(this).val() == -1) jQuery(".checkforselect"+s).prop("checked", false);
774  else jQuery(".checkforselect"+s).prop("checked", true);
775  });
776 });
777 </script>';
778 
779 // End of page
780 llxFooter();
781 $db->close();
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
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.
Classe 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...
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
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 '.
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...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
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.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessage($mesgs, $style='mesgs')
Set event message in dol_events session object.
print_barre_liste($titre, $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.
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.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
$nbtotalofrecords
Count total nb of records.
Definition: list.php:329
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.